mirror of
https://github.com/kfattic/cupsadmin.git
synced 2026-11-13 19:06:43 -05:00
ppdreport accepts a PPD file path (plain or gzipped) as well as a queue
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -176,3 +176,25 @@ public struct PPD {
|
||||
options.first { $0.keyword == keyword }
|
||||
}
|
||||
}
|
||||
|
||||
extension PPD {
|
||||
/// Reads a PPD file, plain or gzip-compressed (vendors ship `.ppd.gz` / `.gz` under
|
||||
/// /Library/Printers/PPDs). Text that isn't valid UTF-8 is read as ISO Latin-1, the PPD default.
|
||||
public static func text(contentsOfFile path: String) throws -> String {
|
||||
guard var data = FileManager.default.contents(atPath: path) else {
|
||||
throw CupsAdminError.failed("can’t read \(path)")
|
||||
}
|
||||
if data.starts(with: [0x1F, 0x8B]) {
|
||||
let result = try CupsTools.run("/usr/bin/gzip", ["-dc", path])
|
||||
guard result.succeeded else { throw CupsAdminError.failed("can’t decompress \(path): \(result.message)") }
|
||||
data = result.standardOutput
|
||||
}
|
||||
return String(data: data, encoding: .utf8) ?? String(data: data, encoding: .isoLatin1) ?? ""
|
||||
}
|
||||
|
||||
/// True when a `ppdreport` argument names a PPD file rather than a queue. Queue names can't contain "/".
|
||||
public static func looksLikeFile(_ argument: String) -> Bool {
|
||||
argument.contains("/") || [".ppd", ".gz", ".ppd.gz"].contains { argument.lowercased().hasSuffix($0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ enum PPDReportCommand {
|
||||
let source: String
|
||||
var attributes: IPPGroup?
|
||||
if let file {
|
||||
guard let data = FileManager.default.contents(atPath: file) else { throw CupsAdminError.failed("can’t read \(file)") }
|
||||
text = String(decoding: data, as: UTF8.self)
|
||||
text = try PPD.text(contentsOfFile: file)
|
||||
source = file
|
||||
} else if let queue {
|
||||
guard try await client.queueExists(queue) else { throw CupsAdminError.failed("no such queue \(queue)") }
|
||||
|
||||
@@ -42,7 +42,7 @@ let usage = """
|
||||
quick list quick actions (task-named queue defaults)
|
||||
quick <action> <queue> [code | --clear]
|
||||
apply one via lpadmin, then verify
|
||||
ppdreport <queue> | --file <path.ppd>
|
||||
ppdreport <queue | path.ppd[.gz]>
|
||||
every PPD group and option: keyword, label, type, default, choices
|
||||
help show this help
|
||||
"""
|
||||
@@ -130,7 +130,12 @@ func runCommand(_ args: [String]) async throws -> String {
|
||||
}
|
||||
try rejectUnknownFlags()
|
||||
guard (file == nil && rest.count == 1) || (file != nil && rest.isEmpty) else {
|
||||
throw CupsAdminError.usage("ppdreport needs one queue name or --file <path.ppd>")
|
||||
throw CupsAdminError.usage("ppdreport needs one queue name or PPD file path")
|
||||
}
|
||||
// A path (anything with "/", or ending in .ppd / .gz) is a PPD file; queue names can't contain "/".
|
||||
if file == nil, let argument = rest.first, PPD.looksLikeFile(argument) {
|
||||
file = argument
|
||||
rest.removeAll()
|
||||
}
|
||||
return try await PPDReportCommand.run(client: client, queue: rest.first, file: file)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user