From 79e85bb21dce8f50b2749525fd5263e248476c13 Mon Sep 17 00:00:00 2001 From: lksz Date: Mon, 11 Oct 2021 20:41:46 -0400 Subject: [PATCH] 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. --- 7zip/ConvertTo-Zip.ps1 | 36 +++++++++++++------- Setup-ScriptEnv.ps1 | 20 ++++++++++-- {docker => base}/Aliases/cp.ps1 | 0 {docker => base}/Aliases/edc.ps1 | 0 {docker => base}/Aliases/eds.ps1 | 0 {docker => base}/Aliases/mv.ps1 | 0 {docker => base}/Aliases/rm.ps1 | 0 base/Move-3Way.ps1 | 56 ++++++++++++++++++++++++++++++++ 8 files changed, 98 insertions(+), 14 deletions(-) rename {docker => base}/Aliases/cp.ps1 (100%) rename {docker => base}/Aliases/edc.ps1 (100%) rename {docker => base}/Aliases/eds.ps1 (100%) rename {docker => base}/Aliases/mv.ps1 (100%) rename {docker => base}/Aliases/rm.ps1 (100%) create mode 100644 base/Move-3Way.ps1 diff --git a/7zip/ConvertTo-Zip.ps1 b/7zip/ConvertTo-Zip.ps1 index 454eefa..1698043 100644 --- a/7zip/ConvertTo-Zip.ps1 +++ b/7zip/ConvertTo-Zip.ps1 @@ -9,10 +9,11 @@ [string]$MoveProcessedTo="done", [switch]$Flatten, [switch]$MuteSkipped, - [switch]$Force + [switch]$Force, + [ScriptBlock]$GetExtractCmd ) -function Get7zExtractCmd { +$local:Get7zExtractCmd = { param([string]$ArchivePath,[string]$TmpPath) $local:7zCmd = "7z " if( $Flatten ) { @@ -24,6 +25,16 @@ function Get7zExtractCmd { $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 { param([string]$ArchivePath),[string]$CompressOptions @@ -41,12 +52,11 @@ $local:DonePath = [string]::Empty if( $MoveProcessedTo ) { $DonePath = Get-Path $MoveProcessedTo } -Write-Verbose "`n`tTempPath: $TempPath;`n`tDestPathRoot: $DestPathRoot;`n`tDonePath: $DonePath" $local:runTimeSpan = [System.Diagnostics.Stopwatch]::StartNew() $local:lastStatus = $runTimeSpan.Elapsed -$SourcePath = Get-Path "$SourcePath/" +$SourcePath = Get-Path $SourcePath $local:srcSet = Get-ChildItem -Recurse:$Recurse -LiteralPath $SourcePath -Include $SourceSet $local:progress = [ordered]@{ @@ -56,6 +66,8 @@ $local:progress = [ordered]@{ Elapsed = $runTimeSpan.Elapsed } +Write-Verbose "`n`tSourcePath: $SourcePath;`n`tTempPath: $TempPath;`n`tDestPathRoot: $DestPathRoot;`n`tDonePath: $DonePath" + foreach( $local:srcFile in $srcSet ) { Write-Verbose "Processing $($srcFile.Name)..." $progress.ItemProgress++ @@ -66,41 +78,43 @@ foreach( $local:srcFile in $srcSet ) { if( Test-Path -LiteralPath $TempPath ) { 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:destPath = $srcFile.DirectoryName.Replace($SourcePath,$DestPathRoot) $local:destZipPath = $(Join-Path $destPath "$($srcFile.BaseName)$ZipExtension") +# Write-Verbose "relPath = $relPath`ndestPath = $destPath`ndestZipPath = $destZipPath" + $local:ActionStatus = "Failed" Write-Verbose "Dest: $destZipPath" if( -not $Force -and (Test-Path -LiteralPath $destZipPath) ) { Write-Verbose "Skipping, dest already exists: `"$($destZipPath.Replace($DestPathRoot,[string]::Empty))`"" $ActionStatus = "Skipped" } 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 - 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)" $ActionStatus = "Failed" } else { - Push-Location -LiteralPath $TempPath -ErrorAction Stop - $local:destFile = Join-Path $destPath "$([System.io.path]::GetRandomFileName()).zip" $nextCmd = Get7zCompressCmd -ArchivePath $destFile $null = Invoke-ExpressionEx $nextCmd - Pop-Location 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 $ActionStatus = "Processed" } + Pop-Location } if( Test-Path -PathType Container -LiteralPath $TempPath ) { - Remove-Item -Recurse -Force -LiteralPath $TempPath + Remove-Item -Recurse -Force -LiteralPath $TempPath -WhatIf:$false } if( $DonePath ) { diff --git a/Setup-ScriptEnv.ps1 b/Setup-ScriptEnv.ps1 index 64c623b..23ffb1e 100644 --- a/Setup-ScriptEnv.ps1 +++ b/Setup-ScriptEnv.ps1 @@ -134,6 +134,7 @@ function Invoke-ExpressionEx { [switch]$Force, [string]$Function, [switch]$MarshalOutput, + [string[]]$sudoArgs, [Parameter(Position = 1, ValueFromRemainingArguments = $true)] [string[]]$expr ) @@ -157,7 +158,11 @@ function Invoke-ExpressionEx { if ( "$sudo_exec" -match 'not found' ) { $sudo_exec = [string]::Empty } } 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 { Write-Error "Didn't find a known sudo command" @@ -165,7 +170,12 @@ function Invoke-ExpressionEx { } 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 { $local:currentIdenity = [System.Security.Principal.WindowsIdentity]::GetCurrent() @@ -224,7 +234,11 @@ function Invoke-ExpressionEx { } Write-Verbose "Perofrming the following expression in-line:`n{$($expr -join ' ')}" - Invoke-Expression "$expr" + if( [bool]$WhatIfPreference.IsPresent ) { + Write-Host "What if: Invoke-ExpressionEx executing [$expr]" + } else { + Invoke-Expression "$expr" + } } function Test-IsAdmin { diff --git a/docker/Aliases/cp.ps1 b/base/Aliases/cp.ps1 similarity index 100% rename from docker/Aliases/cp.ps1 rename to base/Aliases/cp.ps1 diff --git a/docker/Aliases/edc.ps1 b/base/Aliases/edc.ps1 similarity index 100% rename from docker/Aliases/edc.ps1 rename to base/Aliases/edc.ps1 diff --git a/docker/Aliases/eds.ps1 b/base/Aliases/eds.ps1 similarity index 100% rename from docker/Aliases/eds.ps1 rename to base/Aliases/eds.ps1 diff --git a/docker/Aliases/mv.ps1 b/base/Aliases/mv.ps1 similarity index 100% rename from docker/Aliases/mv.ps1 rename to base/Aliases/mv.ps1 diff --git a/docker/Aliases/rm.ps1 b/base/Aliases/rm.ps1 similarity index 100% rename from docker/Aliases/rm.ps1 rename to base/Aliases/rm.ps1 diff --git a/base/Move-3Way.ps1 b/base/Move-3Way.ps1 new file mode 100644 index 0000000..dffe810 --- /dev/null +++ b/base/Move-3Way.ps1 @@ -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" + } + }