functions/public/Copy-KlippyGcodeItem.ps1
|
function Copy-KlippyGcodeItem { <# .SYNOPSIS Copies a G-code file or folder on a Klipper printer. .DESCRIPTION Creates a copy of a file or folder within the printer's gcodes storage. Supports pipeline input from Get-KlippyGcodeFile or Get-KlippyGcodeFolder. .PARAMETER Id The unique identifier of the printer. .PARAMETER PrinterName The friendly name of the printer. .PARAMETER InputObject A GcodeFile or GcodeFolder object from pipeline input. .PARAMETER Path Source path of the item to copy. .PARAMETER Destination Destination path for the copy. .PARAMETER PassThru Return the copied item object. .EXAMPLE Copy-KlippyGcodeItem -Path "benchy.gcode" -Destination "benchy_backup.gcode" Creates a copy with a new name. .EXAMPLE Copy-KlippyGcodeItem -Path "model.gcode" -Destination "archive/" Copies a file to a subfolder keeping the same name. .EXAMPLE Get-KlippyGcodeFile -Path "important.gcode" | Copy-KlippyGcodeItem -Destination "backup/" Copies a file via pipeline. .OUTPUTS PSCustomObject with item information (when -PassThru is used). #> [CmdletBinding(DefaultParameterSetName = 'Default', SupportsShouldProcess = $true)] [OutputType([PSCustomObject])] 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(Mandatory = $true, Position = 1)] [ValidateNotNullOrEmpty()] [string]$Destination, [Parameter()] [switch]$PassThru ) process { # Determine source path and printer if ($PSCmdlet.ParameterSetName -eq 'ByObject') { $printer = Resolve-KlippyPrinterTarget -Id $InputObject.PrinterId $sourcePath = $InputObject.Path $isDirectory = $InputObject.PSObject.TypeNames -contains 'KlippyCLI.GcodeFolder' } else { # Resolve printer $resolveParams = @{} switch ($PSCmdlet.ParameterSetName) { 'ById' { $resolveParams['Id'] = $Id } 'ByName' { $resolveParams['PrinterName'] = $PrinterName } } $printer = Resolve-KlippyPrinterTarget @resolveParams $sourcePath = $Path.TrimStart('/') $isDirectory = $false # Will be determined by API } # Clean destination path $destPath = $Destination.TrimStart('/') # If destination ends with /, append source filename if ($destPath.EndsWith('/')) { $destPath = $destPath + (Split-Path $sourcePath -Leaf) } if ($PSCmdlet.ShouldProcess("$($printer.PrinterName):gcodes/$sourcePath -> gcodes/$destPath", "Copy item")) { try { Write-Verbose "[$($printer.PrinterName)] Copying: $sourcePath -> $destPath" $response = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/files/copy" -Method POST -QueryParameters @{ source = "gcodes/$sourcePath" dest = "gcodes/$destPath" } Write-Verbose "[$($printer.PrinterName)] Item copied successfully" if ($PassThru) { # Determine the actual result type $resultItem = $response.Item if ($resultItem.Path) { $actualPath = $resultItem.Path -replace '^gcodes/', '' } else { $actualPath = $destPath } if ($isDirectory -or ($resultItem -and $resultItem.Dirname)) { [PSCustomObject]@{ PSTypeName = 'KlippyCLI.GcodeFolder' PrinterId = $printer.Id PrinterName = $printer.PrinterName Path = $actualPath Name = Split-Path $actualPath -Leaf Modified = Get-Date } } else { [PSCustomObject]@{ PSTypeName = 'KlippyCLI.GcodeFile' PrinterId = $printer.Id PrinterName = $printer.PrinterName Path = $actualPath Name = Split-Path $actualPath -Leaf Size = $resultItem.Size SizeMB = if ($resultItem.Size) { [Math]::Round($resultItem.Size / 1MB, 2) } else { $null } Modified = Get-Date } } } } catch { Write-Error "[$($printer.PrinterName)] Failed to copy '$sourcePath': $_" } } } } |