functions/public/Save-KlippyLogFile.ps1
|
function Save-KlippyLogFile { <# .SYNOPSIS Downloads a log file from a Klipper printer. .DESCRIPTION Downloads a log file from the printer to local storage. Supports pipeline input from Get-KlippyLogFile. Adds timestamps to filenames by default for log archival. .PARAMETER Id The unique identifier of the printer. .PARAMETER PrinterName The friendly name of the printer. .PARAMETER InputObject A LogFile object from pipeline input (from Get-KlippyLogFile). .PARAMETER Path Path of the log 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 Timestamp Add a timestamp to the filename for archival purposes. Format: filename_YYYYMMDD_HHmmss.ext Enabled by default for log files. .PARAMETER NoTimestamp Disable automatic timestamp addition. .PARAMETER Force Overwrite existing local file without prompting. .PARAMETER PassThru Return the local FileInfo object. .EXAMPLE Save-KlippyLogFile -Path "klippy.log" Downloads klippy.log with timestamp to current directory. .EXAMPLE Save-KlippyLogFile -Path "moonraker.log" -Destination "C:\logs\" -NoTimestamp Downloads without timestamp. .EXAMPLE Get-KlippyLogFile | Save-KlippyLogFile -Destination "./logs/" Downloads all log 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]$Timestamp, [Parameter()] [switch]$NoTimestamp, [Parameter()] [switch]$Force, [Parameter()] [switch]$PassThru ) process { # Handle pipeline input (LogFile 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 # Add timestamp by default for logs (unless -NoTimestamp is specified) $addTimestamp = (-not $NoTimestamp) -or $Timestamp if ($addTimestamp) { $ts = Get-Date -Format "yyyyMMdd_HHmmss" $baseName = [System.IO.Path]::GetFileNameWithoutExtension($sourceFilename) $extension = [System.IO.Path]::GetExtension($sourceFilename) $sourceFilename = "${baseName}_${ts}${extension}" } $resolvedDest = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Destination) if (Test-Path -Path $resolvedDest -PathType Container) { # Destination is a directory $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):logs/$sourcePath -> $localPath", "Download log file")) { try { Write-Verbose "[$($printer.PrinterName)] Downloading log: $sourcePath -> $localPath" # Build URI (URL encode the path) $encodedPath = [System.Uri]::EscapeDataString($sourcePath) $uri = "$($printer.Uri)/server/files/logs/$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 120 Write-Verbose "[$($printer.PrinterName)] Download complete: $localPath" if ($PassThru) { Get-Item -Path $localPath } } catch { Write-Error "[$($printer.PrinterName)] Failed to download log '$sourcePath': $_" } } } } |