Public/Restore-Release.ps1
|
function Restore-Release { <# .SYNOPSIS Scans directories for releases, downloads required files from srrDB, and rebuilds with original names. .DESCRIPTION This is the main automation command for ReScenePS. It performs: - Detection of release names from directory names - Querying srrDB for release metadata - Downloading SRR files and any additional files from srrDB (proof images, samples, etc. that are stored separately on srrDB rather than embedded in the SRR file) - Calling Invoke-SrrRestore to rebuild the release with original names and structure Requires the SrrDBAutomationToolkit module for srrDB API access. .PARAMETER Path Directory to scan for releases. Defaults to current directory. In single mode (default), treats this directory as the release. With -Recurse, treats each subdirectory as a separate release. .PARAMETER Recurse Process each subdirectory as a separate release instead of the root directory. .PARAMETER SourcePath Directory containing source files for reconstruction (e.g., .mkv files). Defaults to the release directory being processed. Use this when source files are stored in a different location than the release folder. .PARAMETER KeepSrr Keep the SRR file after successful restoration. .PARAMETER KeepSources Keep source files (e.g., .mkv) after successful restoration. .PARAMETER SkipValidation Skip CRC validation against embedded SFV. .EXAMPLE Restore-Release Scans current directory, downloads SRR from srrDB, and rebuilds the release. .EXAMPLE Restore-Release -Path "D:\Downloads\Movie.2024.1080p.BluRay-GROUP" Processes a specific release directory. .EXAMPLE Restore-Release -Path "D:\Downloads" -Recurse Processes all subdirectories as separate releases. .EXAMPLE Restore-Release -KeepSrr -KeepSources -WhatIf Preview what would happen without making changes. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Position = 0)] [ValidateScript({ if (-not (Test-Path -Path $_ -PathType Container)) { throw "Directory does not exist: $_" } $true })] [string]$Path = ".", [Parameter()] [switch]$Recurse, [Parameter()] [ValidateScript({ if ([string]::IsNullOrWhiteSpace($_)) { return $true } if (-not (Test-Path -Path $_ -PathType Container)) { throw "SourcePath directory does not exist: $_" } $true })] [string]$SourcePath, [Parameter()] [switch]$KeepSrr, [Parameter()] [switch]$KeepSources, [Parameter()] [switch]$SkipValidation ) begin { # Resolve path $Path = (Resolve-Path -Path $Path).Path # Track results for summary (local variable to avoid accumulation across calls) $results = @{ Processed = 0 Succeeded = 0 Failed = 0 Skipped = 0 Details = [System.Collections.Generic.List[PSCustomObject]]::new() } } process { Write-Host "" Write-Host "===========================================================" -ForegroundColor Cyan Write-Host " Restore-Release Automation" -ForegroundColor Cyan Write-Host "===========================================================" -ForegroundColor Cyan Write-Host "" # Determine directories to process $releaseDirs = @() if ($Recurse) { $releaseDirs = Get-ChildItem -Path $Path -Directory | Select-Object -ExpandProperty FullName Write-Host "Scanning for releases in: $Path" -ForegroundColor Yellow Write-Host "Found $($releaseDirs.Count) subdirectories to process" -ForegroundColor Gray } else { $releaseDirs = @($Path) } if ($releaseDirs.Count -eq 0) { Write-Warning "No directories found to process" return } Write-Host "" foreach ($releaseDir in $releaseDirs) { $results.Processed++ # Get release name from directory, handling edge cases like root dirs or "." $resolvedDir = [System.IO.Path]::GetFullPath($releaseDir) $releaseName = [System.IO.Path]::GetFileName($resolvedDir) if ([string]::IsNullOrEmpty($releaseName)) { # Root directory - use drive letter or path $releaseName = $resolvedDir.TrimEnd([System.IO.Path]::DirectorySeparatorChar) } Write-Host "-----------------------------------------------------------" -ForegroundColor DarkGray Write-Host "Processing: $releaseName" -ForegroundColor Cyan Write-Host "-----------------------------------------------------------" -ForegroundColor DarkGray try { # Step 1: Check if SRR already exists locally $existingSrr = Get-ChildItem -Path $releaseDir -Filter "*.srr" -File -ErrorAction SilentlyContinue | Select-Object -First 1 if ($existingSrr) { Write-Host " [INFO] SRR already exists: $($existingSrr.Name)" -ForegroundColor Yellow $srrPath = $existingSrr.FullName } else { # Step 2: Use Get-SatReleaseFile to download SRR and additional files Write-Host " [1] Downloading release files from srrDB..." -ForegroundColor Yellow if ($PSCmdlet.ShouldProcess($releaseName, "Download release files from srrDB")) { $downloadResult = Get-SatReleaseFile -ReleaseName $releaseName -OutPath $releaseDir -PassThru -ErrorAction Stop if (-not $downloadResult -or -not $downloadResult.SrrFile -or [string]::IsNullOrWhiteSpace($downloadResult.SrrFile.FullName)) { throw "Get-SatReleaseFile did not return an SRR file for: $releaseName" } $srrPath = $downloadResult.SrrFile.FullName Write-Host " [OK] Downloaded: $($downloadResult.SrrFile.Name)" -ForegroundColor Green if ($downloadResult.AdditionalFiles -and $downloadResult.AdditionalFiles.Count -gt 0) { foreach ($file in $downloadResult.AdditionalFiles) { Write-Host " [OK] Downloaded: $($file.Name)" -ForegroundColor Green } } } else { Write-Host " [SKIP] Download (WhatIf)" -ForegroundColor Gray $results.Skipped++ $results.Details.Add([PSCustomObject]@{ Release = $releaseName Status = 'Skipped' Reason = 'WhatIf mode' }) continue } } # Step 3: Run the restoration if ($PSCmdlet.ShouldProcess($releaseName, "Run SRR restoration")) { Write-Host " [2] Running SRR restoration..." -ForegroundColor Yellow $restoreParams = @{ SrrFile = $srrPath SourcePath = if (-not [string]::IsNullOrWhiteSpace($SourcePath)) { $SourcePath } else { $releaseDir } OutputPath = $releaseDir } if ($KeepSrr) { $restoreParams['KeepSrr'] = $true } if ($KeepSources) { $restoreParams['KeepSources'] = $true } if ($SkipValidation) { $restoreParams['SkipValidation'] = $true } Invoke-SrrRestore @restoreParams $results.Succeeded++ $results.Details.Add([PSCustomObject]@{ Release = $releaseName Status = 'Succeeded' Reason = $null }) } else { Write-Host " [SKIP] Restoration (WhatIf)" -ForegroundColor Gray $results.Skipped++ $results.Details.Add([PSCustomObject]@{ Release = $releaseName Status = 'Skipped' Reason = 'WhatIf mode' }) } } catch { Write-Host " [X] Failed: $($_.Exception.Message)" -ForegroundColor Red $results.Failed++ $results.Details.Add([PSCustomObject]@{ Release = $releaseName Status = 'Failed' Reason = $_.Exception.Message }) if (-not $Recurse) { throw } } Write-Host "" } } end { # Summary Write-Host "===========================================================" -ForegroundColor Cyan Write-Host " Summary" -ForegroundColor Cyan Write-Host "===========================================================" -ForegroundColor Cyan Write-Host "" Write-Host " Processed: $($results.Processed)" -ForegroundColor Gray Write-Host " Succeeded: $($results.Succeeded)" -ForegroundColor Green Write-Host " Failed: $($results.Failed)" -ForegroundColor $(if ($results.Failed -gt 0) { 'Red' } else { 'Gray' }) Write-Host " Skipped: $($results.Skipped)" -ForegroundColor $(if ($results.Skipped -gt 0) { 'Yellow' } else { 'Gray' }) Write-Host "" if ($results.Failed -gt 0 -or $results.Skipped -gt 0) { Write-Host "Details:" -ForegroundColor Gray foreach ($detail in $results.Details | Where-Object { $_.Status -ne 'Succeeded' }) { $color = if ($detail.Status -eq 'Failed') { 'Red' } else { 'Yellow' } Write-Host " - $($detail.Release): $($detail.Status) - $($detail.Reason)" -ForegroundColor $color } Write-Host "" } # Return results object for pipeline usage [PSCustomObject]@{ Processed = $results.Processed Succeeded = $results.Succeeded Failed = $results.Failed Skipped = $results.Skipped Details = $results.Details } } } |