functions/public/Save-KlippyGcodeFile.ps1
|
function Save-KlippyGcodeFile { <# .SYNOPSIS Downloads a G-code file from a Klipper printer to local storage. .DESCRIPTION Downloads a G-code file from the printer's gcodes storage to a local path. Supports pipeline input from Get-KlippyGcodeFile. .PARAMETER Id The unique identifier of the printer. .PARAMETER PrinterName The friendly name of the printer. .PARAMETER InputObject A GcodeFile object from pipeline input (from Get-KlippyGcodeFile). .PARAMETER Path Path of the file on the printer to download. .PARAMETER Destination Local destination path. Can be a directory or full file path. If a directory, the original filename is preserved. Defaults to current directory. .PARAMETER Force Overwrite existing local file without prompting. .PARAMETER PassThru Return the local FileInfo object. .EXAMPLE Save-KlippyGcodeFile -Path "benchy.gcode" Downloads to current directory. .EXAMPLE Save-KlippyGcodeFile -Path "model.gcode" -Destination "C:\Downloads\" Downloads to specified folder. .EXAMPLE Save-KlippyGcodeFile -Path "print.gcode" -Destination "C:\backup\renamed.gcode" Downloads with a new name. .EXAMPLE Get-KlippyGcodeFile -Path "*.gcode" | Save-KlippyGcodeFile -Destination "./backup/" Downloads multiple files via pipeline. .OUTPUTS System.IO.FileInfo (when -PassThru is used). #> [CmdletBinding(DefaultParameterSetName = 'Default', SupportsShouldProcess = $true)] [OutputType([System.IO.FileInfo])] param( [Parameter(Mandatory = $true, ParameterSetName = 'ById')] [ValidateNotNullOrEmpty()] [string]$Id, [Parameter(Mandatory = $true, ParameterSetName = 'ByName')] [ValidateNotNullOrEmpty()] [string]$PrinterName, [Parameter(Mandatory = $true, ParameterSetName = 'ByObject', ValueFromPipeline = $true)] [PSCustomObject]$InputObject, [Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'Default')] [Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'ById')] [Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'ByName')] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Position = 1)] [string]$Destination = ".", [Parameter()] [switch]$Force, [Parameter()] [switch]$PassThru ) process { # Handle pipeline input (GcodeFile object) if ($PSCmdlet.ParameterSetName -eq 'ByObject') { $printer = Resolve-KlippyPrinterTarget -Id $InputObject.PrinterId $sourcePath = $InputObject.Path } else { # Resolve printer $resolveParams = @{} switch ($PSCmdlet.ParameterSetName) { 'ById' { $resolveParams['Id'] = $Id } 'ByName' { $resolveParams['PrinterName'] = $PrinterName } } $printer = Resolve-KlippyPrinterTarget @resolveParams $sourcePath = $Path.TrimStart('/') } # Determine local destination $sourceFilename = Split-Path $sourcePath -Leaf $resolvedDest = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Destination) if (Test-Path -Path $resolvedDest -PathType Container) { # Destination is a directory, append filename $localPath = Join-Path $resolvedDest $sourceFilename } elseif ($Destination.EndsWith([System.IO.Path]::DirectorySeparatorChar) -or $Destination.EndsWith('/')) { # Destination looks like a directory that doesn't exist yet $null = New-Item -Path $resolvedDest -ItemType Directory -Force $localPath = Join-Path $resolvedDest $sourceFilename } else { # Destination is a file path $localPath = $resolvedDest $parentDir = Split-Path $localPath -Parent if ($parentDir -and -not (Test-Path $parentDir)) { $null = New-Item -Path $parentDir -ItemType Directory -Force } } # Check if file exists if ((Test-Path $localPath) -and -not $Force) { if (-not $PSCmdlet.ShouldProcess($localPath, "Overwrite existing file")) { Write-Warning "File '$localPath' already exists. Use -Force to overwrite." return } } if ($PSCmdlet.ShouldProcess("$($printer.PrinterName):gcodes/$sourcePath -> $localPath", "Download file")) { try { Write-Verbose "[$($printer.PrinterName)] Downloading: $sourcePath -> $localPath" # Build URI (URL encode the path) $encodedPath = [System.Uri]::EscapeDataString($sourcePath) $uri = "$($printer.Uri)/server/files/gcodes/$encodedPath" # Build headers $headers = @{} if ($printer.ApiKey) { $headers['X-Api-Key'] = $printer.ApiKey } # Download file Invoke-WebRequest -Uri $uri -Method GET -Headers $headers -OutFile $localPath -TimeoutSec 300 Write-Verbose "[$($printer.PrinterName)] Download complete: $localPath" if ($PassThru) { Get-Item -Path $localPath } } catch { Write-Error "[$($printer.PrinterName)] Failed to download '$sourcePath': $_" } } } } |