2021-01-29 23:26:39 +00:00
|
|
|
[CmdletBinding(SupportsShouldProcess)]param(
|
|
|
|
[string]$SourcePath=".",
|
|
|
|
[string]$SourceSet="*.rar",
|
|
|
|
[switch]$Recurse,
|
2021-06-24 13:43:37 +00:00
|
|
|
# The extension of the output zip file, don't forget to include the dot, default is ".zip"
|
2021-01-29 23:26:39 +00:00
|
|
|
[string]$ZipExtension=".zip",
|
|
|
|
[string]$ZipDestPath="./zipped",
|
|
|
|
[string]$ZipOptions="-mm=Deflate -mfb=258 -mpass=15",
|
|
|
|
[string]$MoveProcessedTo="done",
|
|
|
|
[switch]$Flatten,
|
2021-02-04 00:43:12 +00:00
|
|
|
[switch]$MuteSkipped,
|
2021-10-12 00:41:46 +00:00
|
|
|
[switch]$Force,
|
|
|
|
[ScriptBlock]$GetExtractCmd
|
2021-01-29 23:26:39 +00:00
|
|
|
)
|
|
|
|
|
2021-10-12 00:41:46 +00:00
|
|
|
$local:Get7zExtractCmd = {
|
2021-01-29 23:26:39 +00:00
|
|
|
param([string]$ArchivePath,[string]$TmpPath)
|
|
|
|
$local:7zCmd = "7z "
|
|
|
|
if( $Flatten ) {
|
|
|
|
$7zCmd += "e "
|
|
|
|
} else {
|
|
|
|
$7zCmd += "x "
|
|
|
|
}
|
|
|
|
$7zCmd += "-o$(Get-ShellSafePath $TmpPath) $(Get-ShellSafePath $ArchivePath)"
|
|
|
|
|
|
|
|
$7zCmd
|
|
|
|
}
|
2021-10-12 00:41:46 +00:00
|
|
|
$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
|
|
|
|
}
|
|
|
|
}
|
2021-01-29 23:26:39 +00:00
|
|
|
|
|
|
|
function Get7zCompressCmd {
|
|
|
|
param([string]$ArchivePath),[string]$CompressOptions
|
|
|
|
$local:7zCmd = "7z a -sdel "
|
|
|
|
if( -not $Flatten ) { $7zCmd += "-r " }
|
|
|
|
$7zCmd += "$CompressOptions $(Get-ShellSafePath $ArchivePath)"
|
|
|
|
|
|
|
|
$7zCmd
|
|
|
|
}
|
|
|
|
|
|
|
|
# Create a new temporary dir
|
|
|
|
$local:DestPathRoot = Get-Path "$ZipDestPath/"
|
|
|
|
$local:TempPath = Join-Path $DestPathRoot ([System.IO.Path]::GetRandomFileName())
|
|
|
|
$local:DonePath = [string]::Empty
|
|
|
|
if( $MoveProcessedTo ) {
|
|
|
|
$DonePath = Get-Path $MoveProcessedTo
|
|
|
|
}
|
|
|
|
|
|
|
|
$local:runTimeSpan = [System.Diagnostics.Stopwatch]::StartNew()
|
|
|
|
$local:lastStatus = $runTimeSpan.Elapsed
|
|
|
|
|
2021-10-12 00:41:46 +00:00
|
|
|
$SourcePath = Get-Path $SourcePath
|
2021-01-29 23:26:39 +00:00
|
|
|
$local:srcSet = Get-ChildItem -Recurse:$Recurse -LiteralPath $SourcePath -Include $SourceSet
|
|
|
|
|
|
|
|
$local:progress = [ordered]@{
|
|
|
|
Activity = "ConvertTo-Zip $SourcePath"
|
|
|
|
ItemCount = $srcSet.Count
|
|
|
|
ItemProgress = 0
|
|
|
|
Elapsed = $runTimeSpan.Elapsed
|
|
|
|
}
|
|
|
|
|
2021-10-12 00:41:46 +00:00
|
|
|
Write-Verbose "`n`tSourcePath: $SourcePath;`n`tTempPath: $TempPath;`n`tDestPathRoot: $DestPathRoot;`n`tDonePath: $DonePath"
|
|
|
|
|
2021-01-29 23:26:39 +00:00
|
|
|
foreach( $local:srcFile in $srcSet ) {
|
|
|
|
Write-Verbose "Processing $($srcFile.Name)..."
|
|
|
|
$progress.ItemProgress++
|
|
|
|
$progress.Elapsed = $runTimeSpan.Elapsed
|
|
|
|
if( ($runTimeSpan.Elapsed - $lastStatus).TotalSeconds -gt 3 ) {
|
|
|
|
Show-Progress @progress -Status "Processing $($srcFile.Name)..."
|
|
|
|
}
|
|
|
|
if( Test-Path -LiteralPath $TempPath ) {
|
|
|
|
Remove-Item -Recurse -Force -LiteralPath $TempPath -ErrorAction Stop
|
|
|
|
}
|
2021-10-12 00:41:46 +00:00
|
|
|
$null = New-Item -ItemType Directory -Force -Path $TempPath -ErrorAction Stop -WhatIf:$false
|
2021-01-29 23:26:39 +00:00
|
|
|
|
|
|
|
$local:relPath = $srcFile.DirectoryName.Replace($SourcePath,[string]::Empty)
|
|
|
|
$local:destPath = $srcFile.DirectoryName.Replace($SourcePath,$DestPathRoot)
|
|
|
|
$local:destZipPath = $(Join-Path $destPath "$($srcFile.BaseName)$ZipExtension")
|
|
|
|
|
2021-10-12 00:41:46 +00:00
|
|
|
# Write-Verbose "relPath = $relPath`ndestPath = $destPath`ndestZipPath = $destZipPath"
|
|
|
|
|
2021-01-29 23:26:39 +00:00
|
|
|
$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 {
|
2021-10-12 00:41:46 +00:00
|
|
|
Push-Location -LiteralPath $TempPath -ErrorAction Stop
|
|
|
|
$local:nextCmd = Invoke-Command $GetExtractCmd -ArgumentList @( $srcFile.FullName, $TempPath )
|
2021-01-29 23:26:39 +00:00
|
|
|
$null = Invoke-ExpressionEx $nextCmd
|
2021-10-12 00:41:46 +00:00
|
|
|
if( -not (Get-ChildItem -Recurse -File -LiteralPath $TempPath).Length ) {
|
2021-01-29 23:26:39 +00:00
|
|
|
Write-Warning "Failed to convert file:`n`t$($srcFile.FullName)"
|
|
|
|
$ActionStatus = "Failed"
|
|
|
|
} else {
|
|
|
|
$local:destFile = Join-Path $destPath "$([System.io.path]::GetRandomFileName()).zip"
|
|
|
|
$nextCmd = Get7zCompressCmd -ArchivePath $destFile
|
|
|
|
$null = Invoke-ExpressionEx $nextCmd
|
|
|
|
|
|
|
|
if( -not (Test-Path -LiteralPath $destPath ) ) {
|
2021-10-12 00:41:46 +00:00
|
|
|
$null = New-Item -Type Directory -Path $destPath
|
2021-01-29 23:26:39 +00:00
|
|
|
}
|
|
|
|
$null = Move-Item -Force:$Force -LiteralPath $destFile $destZipPath
|
|
|
|
|
|
|
|
$ActionStatus = "Processed"
|
|
|
|
}
|
2021-10-12 00:41:46 +00:00
|
|
|
Pop-Location
|
2021-01-29 23:26:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( Test-Path -PathType Container -LiteralPath $TempPath ) {
|
2021-10-12 00:41:46 +00:00
|
|
|
Remove-Item -Recurse -Force -LiteralPath $TempPath -WhatIf:$false
|
2021-01-29 23:26:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( $DonePath ) {
|
|
|
|
$local:doneFinalPath = Join-Path $DonePath $relPath
|
|
|
|
if( -not (Test-Path -LiteralPath $doneFinalPath) ) { $null = New-Item -Type Directory $doneFinalPath }
|
|
|
|
$local:moveParams = [ordered]@{
|
|
|
|
LiteralPath=$srcFile.FullName
|
|
|
|
Destination=$doneFinalPath
|
|
|
|
}
|
|
|
|
if( Test-Path (Join-Path $doneFinalPath $($srcFile.Name))) {
|
|
|
|
$moveParams.Confirm = $true
|
|
|
|
$moveParams.Force = $true
|
|
|
|
}
|
|
|
|
Move-Item @moveParams
|
|
|
|
}
|
|
|
|
|
2021-02-04 00:43:12 +00:00
|
|
|
if( $ActionStatus -eq 'Skipped' -and $MuteSkipped ) { continue }
|
2021-01-29 23:26:39 +00:00
|
|
|
[PSCustomObject]([ordered]@{
|
|
|
|
Action = $ActionStatus
|
|
|
|
SrcMoved = $(if($DonePath){ $true } else {$false})
|
|
|
|
Path = $relPath
|
|
|
|
File = $srcFile.BaseName
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|