Numerous fixes + a new command
+= ConvertTo-Zip - autodetects unrar, prefers it on 7-zip - resolves issues with some RAR extraction methods 7-zip does not support += Invoke-ExpressionEx - Added suppot for -WhatIf switch ++ Move-3Way - folder content comparative duplication was written to normalize a comics media folder == Moved aliases to base, they were wrongly created in docker.
This commit is contained in:
parent
f5e1f3e9af
commit
79e85bb21d
|
@ -9,10 +9,11 @@
|
||||||
[string]$MoveProcessedTo="done",
|
[string]$MoveProcessedTo="done",
|
||||||
[switch]$Flatten,
|
[switch]$Flatten,
|
||||||
[switch]$MuteSkipped,
|
[switch]$MuteSkipped,
|
||||||
[switch]$Force
|
[switch]$Force,
|
||||||
|
[ScriptBlock]$GetExtractCmd
|
||||||
)
|
)
|
||||||
|
|
||||||
function Get7zExtractCmd {
|
$local:Get7zExtractCmd = {
|
||||||
param([string]$ArchivePath,[string]$TmpPath)
|
param([string]$ArchivePath,[string]$TmpPath)
|
||||||
$local:7zCmd = "7z "
|
$local:7zCmd = "7z "
|
||||||
if( $Flatten ) {
|
if( $Flatten ) {
|
||||||
|
@ -24,6 +25,16 @@ function Get7zExtractCmd {
|
||||||
|
|
||||||
$7zCmd
|
$7zCmd
|
||||||
}
|
}
|
||||||
|
$local:GetUnrarExtractCmd = {
|
||||||
|
param([string]$ArchivePath,[string]$TmpPath)
|
||||||
|
"unrar x $(Get-ShellSafePath $ArchivePath)"
|
||||||
|
}
|
||||||
|
if( -not $GetExtractCmd ) {
|
||||||
|
$GetExtractCmd = $Get7zExtractCmd
|
||||||
|
if( Get-Command unrar -ErrorAction Ignore ) {
|
||||||
|
$GetExtractCmd = $GetUnrarExtractCmd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Get7zCompressCmd {
|
function Get7zCompressCmd {
|
||||||
param([string]$ArchivePath),[string]$CompressOptions
|
param([string]$ArchivePath),[string]$CompressOptions
|
||||||
|
@ -41,12 +52,11 @@ $local:DonePath = [string]::Empty
|
||||||
if( $MoveProcessedTo ) {
|
if( $MoveProcessedTo ) {
|
||||||
$DonePath = Get-Path $MoveProcessedTo
|
$DonePath = Get-Path $MoveProcessedTo
|
||||||
}
|
}
|
||||||
Write-Verbose "`n`tTempPath: $TempPath;`n`tDestPathRoot: $DestPathRoot;`n`tDonePath: $DonePath"
|
|
||||||
|
|
||||||
$local:runTimeSpan = [System.Diagnostics.Stopwatch]::StartNew()
|
$local:runTimeSpan = [System.Diagnostics.Stopwatch]::StartNew()
|
||||||
$local:lastStatus = $runTimeSpan.Elapsed
|
$local:lastStatus = $runTimeSpan.Elapsed
|
||||||
|
|
||||||
$SourcePath = Get-Path "$SourcePath/"
|
$SourcePath = Get-Path $SourcePath
|
||||||
$local:srcSet = Get-ChildItem -Recurse:$Recurse -LiteralPath $SourcePath -Include $SourceSet
|
$local:srcSet = Get-ChildItem -Recurse:$Recurse -LiteralPath $SourcePath -Include $SourceSet
|
||||||
|
|
||||||
$local:progress = [ordered]@{
|
$local:progress = [ordered]@{
|
||||||
|
@ -56,6 +66,8 @@ $local:progress = [ordered]@{
|
||||||
Elapsed = $runTimeSpan.Elapsed
|
Elapsed = $runTimeSpan.Elapsed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Write-Verbose "`n`tSourcePath: $SourcePath;`n`tTempPath: $TempPath;`n`tDestPathRoot: $DestPathRoot;`n`tDonePath: $DonePath"
|
||||||
|
|
||||||
foreach( $local:srcFile in $srcSet ) {
|
foreach( $local:srcFile in $srcSet ) {
|
||||||
Write-Verbose "Processing $($srcFile.Name)..."
|
Write-Verbose "Processing $($srcFile.Name)..."
|
||||||
$progress.ItemProgress++
|
$progress.ItemProgress++
|
||||||
|
@ -66,41 +78,43 @@ foreach( $local:srcFile in $srcSet ) {
|
||||||
if( Test-Path -LiteralPath $TempPath ) {
|
if( Test-Path -LiteralPath $TempPath ) {
|
||||||
Remove-Item -Recurse -Force -LiteralPath $TempPath -ErrorAction Stop
|
Remove-Item -Recurse -Force -LiteralPath $TempPath -ErrorAction Stop
|
||||||
}
|
}
|
||||||
|
$null = New-Item -ItemType Directory -Force -Path $TempPath -ErrorAction Stop -WhatIf:$false
|
||||||
|
|
||||||
$local:relPath = $srcFile.DirectoryName.Replace($SourcePath,[string]::Empty)
|
$local:relPath = $srcFile.DirectoryName.Replace($SourcePath,[string]::Empty)
|
||||||
$local:destPath = $srcFile.DirectoryName.Replace($SourcePath,$DestPathRoot)
|
$local:destPath = $srcFile.DirectoryName.Replace($SourcePath,$DestPathRoot)
|
||||||
$local:destZipPath = $(Join-Path $destPath "$($srcFile.BaseName)$ZipExtension")
|
$local:destZipPath = $(Join-Path $destPath "$($srcFile.BaseName)$ZipExtension")
|
||||||
|
|
||||||
|
# Write-Verbose "relPath = $relPath`ndestPath = $destPath`ndestZipPath = $destZipPath"
|
||||||
|
|
||||||
$local:ActionStatus = "Failed"
|
$local:ActionStatus = "Failed"
|
||||||
Write-Verbose "Dest: $destZipPath"
|
Write-Verbose "Dest: $destZipPath"
|
||||||
if( -not $Force -and (Test-Path -LiteralPath $destZipPath) ) {
|
if( -not $Force -and (Test-Path -LiteralPath $destZipPath) ) {
|
||||||
Write-Verbose "Skipping, dest already exists: `"$($destZipPath.Replace($DestPathRoot,[string]::Empty))`""
|
Write-Verbose "Skipping, dest already exists: `"$($destZipPath.Replace($DestPathRoot,[string]::Empty))`""
|
||||||
$ActionStatus = "Skipped"
|
$ActionStatus = "Skipped"
|
||||||
} else {
|
} else {
|
||||||
$local:nextCmd = Get7zExtractCmd -ArchivePath $srcFile.FullName -TmpPath $TempPath
|
Push-Location -LiteralPath $TempPath -ErrorAction Stop
|
||||||
|
$local:nextCmd = Invoke-Command $GetExtractCmd -ArgumentList @( $srcFile.FullName, $TempPath )
|
||||||
$null = Invoke-ExpressionEx $nextCmd
|
$null = Invoke-ExpressionEx $nextCmd
|
||||||
if( -not (Test-Path -PathType Container -LiteralPath $TempPath) ) {
|
if( -not (Get-ChildItem -Recurse -File -LiteralPath $TempPath).Length ) {
|
||||||
Write-Warning "Failed to convert file:`n`t$($srcFile.FullName)"
|
Write-Warning "Failed to convert file:`n`t$($srcFile.FullName)"
|
||||||
$ActionStatus = "Failed"
|
$ActionStatus = "Failed"
|
||||||
} else {
|
} else {
|
||||||
Push-Location -LiteralPath $TempPath -ErrorAction Stop
|
|
||||||
|
|
||||||
$local:destFile = Join-Path $destPath "$([System.io.path]::GetRandomFileName()).zip"
|
$local:destFile = Join-Path $destPath "$([System.io.path]::GetRandomFileName()).zip"
|
||||||
$nextCmd = Get7zCompressCmd -ArchivePath $destFile
|
$nextCmd = Get7zCompressCmd -ArchivePath $destFile
|
||||||
$null = Invoke-ExpressionEx $nextCmd
|
$null = Invoke-ExpressionEx $nextCmd
|
||||||
Pop-Location
|
|
||||||
|
|
||||||
if( -not (Test-Path -LiteralPath $destPath ) ) {
|
if( -not (Test-Path -LiteralPath $destPath ) ) {
|
||||||
New-Item -Type Directory -LiteralPath $destPath
|
$null = New-Item -Type Directory -Path $destPath
|
||||||
}
|
}
|
||||||
$null = Move-Item -Force:$Force -LiteralPath $destFile $destZipPath
|
$null = Move-Item -Force:$Force -LiteralPath $destFile $destZipPath
|
||||||
|
|
||||||
$ActionStatus = "Processed"
|
$ActionStatus = "Processed"
|
||||||
}
|
}
|
||||||
|
Pop-Location
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Test-Path -PathType Container -LiteralPath $TempPath ) {
|
if( Test-Path -PathType Container -LiteralPath $TempPath ) {
|
||||||
Remove-Item -Recurse -Force -LiteralPath $TempPath
|
Remove-Item -Recurse -Force -LiteralPath $TempPath -WhatIf:$false
|
||||||
}
|
}
|
||||||
|
|
||||||
if( $DonePath ) {
|
if( $DonePath ) {
|
||||||
|
|
|
@ -134,6 +134,7 @@ function Invoke-ExpressionEx {
|
||||||
[switch]$Force,
|
[switch]$Force,
|
||||||
[string]$Function,
|
[string]$Function,
|
||||||
[switch]$MarshalOutput,
|
[switch]$MarshalOutput,
|
||||||
|
[string[]]$sudoArgs,
|
||||||
[Parameter(Position = 1, ValueFromRemainingArguments = $true)]
|
[Parameter(Position = 1, ValueFromRemainingArguments = $true)]
|
||||||
[string[]]$expr
|
[string[]]$expr
|
||||||
)
|
)
|
||||||
|
@ -157,7 +158,11 @@ function Invoke-ExpressionEx {
|
||||||
if ( "$sudo_exec" -match 'not found' ) { $sudo_exec = [string]::Empty }
|
if ( "$sudo_exec" -match 'not found' ) { $sudo_exec = [string]::Empty }
|
||||||
}
|
}
|
||||||
if ( $sudo_exec ) {
|
if ( $sudo_exec ) {
|
||||||
& $sudo_exec $sudo_cmd
|
if( [bool]$WhatIfPreference.IsPresent ) {
|
||||||
|
Write-Host "What if: using sudo [$sudo_exec] to run [$sudo_cmd]"
|
||||||
|
} else {
|
||||||
|
& $sudo_exec "$sudoArgs" $sudo_cmd
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Error "Didn't find a known sudo command"
|
Write-Error "Didn't find a known sudo command"
|
||||||
|
@ -165,7 +170,12 @@ function Invoke-ExpressionEx {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $PSVersionTable.Platform -eq 'Unix' ) {
|
if ( $PSVersionTable.Platform -eq 'Unix' ) {
|
||||||
/usr/bin/env sudo "--preserve-env" $(Get-PowerShellPath) "-noprofile" "-EncodedCommand" $(ConvertTo-Base64 $sudo_cmd)
|
if( [bool]$WhatIfPreference.IsPresent ) {
|
||||||
|
Write-Host "What if: passing encoded command to powershell [$sudo_cmd]"
|
||||||
|
} else {
|
||||||
|
if( -not $sudoArgs ) { $sudoArgs = @( "--preserve-env" ) }
|
||||||
|
/usr/bin/env sudo $sudoArgs $(Get-PowerShellPath) "-noprofile" "-EncodedCommand" $(ConvertTo-Base64 $sudo_cmd)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$local:currentIdenity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
|
$local:currentIdenity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
|
||||||
|
@ -224,8 +234,12 @@ function Invoke-ExpressionEx {
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Verbose "Perofrming the following expression in-line:`n{$($expr -join ' ')}"
|
Write-Verbose "Perofrming the following expression in-line:`n{$($expr -join ' ')}"
|
||||||
|
if( [bool]$WhatIfPreference.IsPresent ) {
|
||||||
|
Write-Host "What if: Invoke-ExpressionEx executing [$expr]"
|
||||||
|
} else {
|
||||||
Invoke-Expression "$expr"
|
Invoke-Expression "$expr"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Test-IsAdmin {
|
function Test-IsAdmin {
|
||||||
[CmdletBinding(ConfirmImpact = 'None')]
|
[CmdletBinding(ConfirmImpact = 'None')]
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
[CmdletBinding(SupportsShouldProcess,ConfirmImpact='Medium')]param(
|
||||||
|
[string]$BasePath,
|
||||||
|
[Parameter(Mandatory,Position=1)]
|
||||||
|
[string]$SourcePath,
|
||||||
|
[Parameter(Mandatory,Position=2)]
|
||||||
|
[string]$DestinationPath,
|
||||||
|
$Logic = @(@{ FilterScript = { $flase } }),
|
||||||
|
[ScriptBlock]$SrcTransform,
|
||||||
|
[switch]$NonRecursive,
|
||||||
|
[switch]$NoPassThru,
|
||||||
|
$SubtitutionTable,
|
||||||
|
[int]$Limit,
|
||||||
|
[Alias("Do")]
|
||||||
|
[switch]$NoSimulate
|
||||||
|
)
|
||||||
|
|
||||||
|
$SourcePath = Join-Path $SourcePath '.' | Get-Item | Select-Object -ExpandProperty FullName
|
||||||
|
if( $BasePath ) {
|
||||||
|
$BasePath = Join-Path $BasePath '.' | Get-Item | Select-Object -ExpandProperty FullName
|
||||||
|
} else {
|
||||||
|
$BasePath = $SourcePath
|
||||||
|
}
|
||||||
|
$DestinationPath = Join-Path $DestinationPath '.' | Get-Item | Select-Object -ExpandProperty FullName
|
||||||
|
|
||||||
|
if( -not (Test-Path $BasePath,$SourcePath) ) {
|
||||||
|
throw "Path does not exist"
|
||||||
|
}
|
||||||
|
|
||||||
|
$local:limitParam = @{}
|
||||||
|
if( $Limit ) { $limitParam.First = $Limit }
|
||||||
|
|
||||||
|
Get-ChildItem -LiteralPath $BasePath -File -Recurse | Where-Object {
|
||||||
|
foreach( $local:condition in $Logic ) {
|
||||||
|
if( -not ($_ | Where-Object @condition) ) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$true
|
||||||
|
} | Sort-Object -Property FullName |
|
||||||
|
Select-Object @limitParam | ForEach-Object {
|
||||||
|
$local:srcPath = $_.FullName
|
||||||
|
if( $PSBoundParameters.ContainsKey('SrcTransform') ) { $srcPath = Invoke-Command $SrcTransform -ArgumentList @($_) }
|
||||||
|
$local:path = (Split-Path -Parent $srcPath.Replace($BasePath,'')) -replace '^[/\\]',''
|
||||||
|
$local:dstPath = Join-Path $DestinationPath $path $(Split-Path -Leaf $srcPath)
|
||||||
|
foreach( $local:s in $SubtitutionTable.Keys ) {
|
||||||
|
$dstPath = $dstPath -replace $s, $SubtitutionTable[$s]
|
||||||
|
}
|
||||||
|
if( $srcPath -ceq $dstPath ) { continue }
|
||||||
|
if( $NoSimulate ) {
|
||||||
|
# Create destination path if it doesn't exists
|
||||||
|
$null = New-Item -ItemType Directory -Path $(Join-Path $DestinationPath $path) -Force
|
||||||
|
Move-Item -LiteralPath $srcPath -Destination $dstPath
|
||||||
|
} else {
|
||||||
|
"in $path found: $($_.Name)`nmove : $srcPath`nto +-> $dstPath"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue