使用
lp
时,我可以发送 -o raw
作为打印原始文件的选项。但是我该如何使用 pycups 来做到这一点?
从昨天起我一直试图通过稀疏的文档找到这个问题的答案,但没有找到任何东西。
import cups
import subprocess
def print_pwg_raster(file_path, printer_name, page_range=None):
conn = cups.Connection()
printer_info = conn.getPrinters()
if printer_name in printer_info:
options = ["-m", "image/pwg-raster"]
if page_range:
options.extend(["-o", f"page-ranges={page_range}"])
# Convert the file to PWG Raster using cupsfilter
pwg_raster_data = subprocess.check_output(["cupsfilter"] + options + [file_path])
# Get the printer URI
printer_uri = printer_info[printer_name]["device-uri"]
# Send the PWG Raster data as raw print data
print_job = conn.printFile(printer_name, file_path, "Print Job" , options= {???} #options
)
print("Print job ID:", print_job)
else:
print("Printer not found:", printer_name)
file_path = "/home/.../w1.pdf" # Replace with the actual file path
printer_name = "Canon_G5000_series" # Replace with the desired printer name
page_range = "1-2" # Replace with the desired page range, e.g., "1-3" for pages 1 to 3
print_pwg_raster(file_path, printer_name, page_range)
今天我成功地使用了cups.CUPS_FORMAT_RAW常量。由于缺乏正确的示例和清晰的文档,使用 pycups 变得非常困难。但!!!这是我按原样提供的完全可用的 python 代码。它不仅可以用作原始打印的示例,还可以用作直接打印,而无需将临时文件写入磁盘。享受吧!
from bottle import Bottle, request, response
import logging
import hashlib
try:
import cups
print_method = "cups_library"
print("pycups found and imported")
except ModuleNotFoundError:
print_method = "cups_command"
print("pycups not found")
from subprocess import Popen, PIPE, STDOUT
import os
import sys
import time
pid = os.getpid()
logging.basicConfig(level="INFO", format='%(levelname)s | %(asctime)s | %(name)s | %(message)s')
logging.info(f"Printserver.py imported in pid {pid}, name is {__name__}")
last = ""
app = Bottle()
def get_default_printer_name():
return "TLP2824EPL"
@app.get("/")
def index():
return {"status": True}
@app.get("/status")
def status():
return {"status": True}
def check_printer():
c = cups.Connection()
printer_name = get_default_printer_name()
attr = c.getPrinterAttributes(printer_name)
print(f"Default media is {attr['media-default']}")
@app.post("/print/ps")
def print_ps():
global print_method, last
# 63840a510dc0ce60f3f06edaf94a1053 *sticker-mod-box-4242.ps
files = list(request.files.values())
data = dict(request.forms.items())
if len(files) == 0:
logging.error("No files in request")
response.status = 400
return {}
elif len(files) > 1:
logging.error("Only 1 file at a time supported")
response.status = 413
return {}
file = files.pop(0)
file_bytes = file.file.read()
last = file_bytes
file_name = file.filename
hash_algo = hashlib.sha512()
hash_algo.update(file_bytes)
file_hash = hash_algo.hexdigest()
if "hash" in data:
if data["hash"] != file_hash:
logging.error("Hash sum mismatch")
response.status = 417
return {}
copies = 1
if "copies" in data:
copies = int(data["copies"])
print(f"{file_name}: {file_hash}")
if print_method == "cups_library":
conn = cups.Connection()
default_printer = conn.getDefault()
timestamp = round(time.time())
# jobname = f"{bytes(file_name).decode('ascii', 'ignore').strip()}-{timestamp}"
job_name = f"{file_name.strip()}-{timestamp}"
# job_id = conn.createJob(default_printer, job_name, {'document-format': cups.CUPS_FORMAT_AUTO, "copies": f"{str(copies)}"})
job_id = conn.createJob(default_printer, job_name, {
'document-format': cups.CUPS_FORMAT_AUTO,
"scaling": "no",
"media": "Custom.30x10mm",
"page-bottom": "0",
"page-top": "0",
"page-left": "0",
"page-right": "0",
"zePrintRate": "1.5",
"Darkness": "15",
# PageSize/Media Size: w90h18 w90h162 w108h18 w108h36 w108h72 w108h144 w144h26 w144h3
# 6 w144h72 w144h90 w144h288 w144h396 w162h36 w162h90 w162h288 w162h396 w171h396 w180
# h72 w180h144 w198h90 w216h72 w216h90 w216h144 w216h216 w216h360 w234h144 w234h360 w
# 234h396 w234h419 w234h563 w252h72 w288h72 w288h144 w288h180 w288h216 w288h288 w288h
# 360 w288h432 w288h468 w288h936 *Custom.WIDTHxHEIGHT
# Resolution/Resolution: *203dpi 300dpi 600dpi
# MediaType/Media Type: Saved *Thermal Direct
# Darkness/Darkness: -1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 *18 19 20 21 22 23 24 25 26 27 28 29 30
# zePrintRate/Print Rate: Default *1 1.5 2 2.5 3 4 5 6
})
print(f"Job-ID: {job_id}")
for n in range(copies):
document_id = job_name + '_' + str(n)
startdocument = conn.startDocument(default_printer, job_id, document_id, cups.CUPS_FORMAT_AUTO, 1 if n + 1 == copies else 0)
print("startdocument")
print(startdocument)
print("startdocument type")
print(type(startdocument))
result = conn.writeRequestData(file_bytes, len(file_bytes))
print("requestresult")
print(result)
print("requestresult type")
print(type(result))
finish = conn.finishDocument(document_id)
print(finish)
return {"status": True}
elif print_method == "cups_command":
try:
for c in range(copies):
# process = Popen(["lp", "-d", get_default_printer_name(), "-o", "scaling=0", "-n", f"{str(copies)}", "--", "-"], stdout=PIPE, stdin=PIPE)
# Some printers like mine does not recognize copies parameter so here is a workaround
process = Popen(["lp", "-d", get_default_printer_name(), "-o", "scaling=0", "--", "-"], stdout=PIPE, stdin=PIPE)
result = process.communicate(input=file_bytes)[0]
decoded_result = result.decode('utf-8')
print(f"Result is {decoded_result}")
response.content_type = "application/json"
return {"status": True}
except FileNotFoundError:
response.status = 500
response.content_type = "application/json"
return {"status": False, "error": "commandnotfound"}
else:
raise Exception("Not implemented")
@app.post("/print/raw")
def print_ps():
global print_method, last
# 63840a510dc0ce60f3f06edaf94a1053 *sticker-mod-box-4242.ps
files = list(request.files.values())
data = dict(request.forms.items())
if len(files) == 0:
logging.error("No files in request")
response.status = 400
return {}
elif len(files) > 1:
logging.error("Only 1 file at a time supported")
response.status = 413
return {}
file = files.pop(0)
file_bytes = file.file.read()
last = file_bytes
file_name = file.filename
hash_algo = hashlib.sha512()
hash_algo.update(file_bytes)
file_hash = hash_algo.hexdigest()
if "hash" in data:
if data["hash"] != file_hash:
logging.error("Hash sum mismatch")
response.status = 417
return {}
copies = 1
if "copies" in data:
copies = int(data["copies"])
print(f"{file_name}: {file_hash}")
if print_method == "cups_library":
conn = cups.Connection()
default_printer = conn.getDefault()
timestamp = round(time.time())
# jobname = f"{bytes(file_name).decode('ascii', 'ignore').strip()}-{timestamp}"
job_name = f"{file_name.strip()}-{timestamp}"
# job_id = conn.createJob(default_printer, job_name, {'document-format': cups.CUPS_FORMAT_AUTO, "copies": f"{str(copies)}"})
job_id = conn.createJob(default_printer, job_name, {
'document-format': cups.CUPS_FORMAT_RAW,
"raw": "1"
})
print(f"Job-ID: {job_id}")
for n in range(copies):
document_id = job_name + '_' + str(n)
startdocument = conn.startDocument(default_printer, job_id, document_id, cups.CUPS_FORMAT_RAW, 1 if n + 1 == copies else 0)
print("startdocument")
print(startdocument)
print("startdocument type")
print(type(startdocument))
result = conn.writeRequestData(file_bytes, len(file_bytes))
print("requestresult")
print(result)
print("requestresult type")
print(type(result))
finish = conn.finishDocument(document_id)
print(finish)
return {"status": True}
elif print_method == "cups_command":
try:
for c in range(copies):
# process = Popen(["lp", "-d", get_default_printer_name(), "-o", "scaling=0", "-n", f"{str(copies)}", "--", "-"], stdout=PIPE, stdin=PIPE)
process = Popen(["lp", "-d", get_default_printer_name(), "-o", "raw", "--", "-"], stdout=PIPE, stdin=PIPE)
result = process.communicate(input=file_bytes)[0]
decoded_result = result.decode('utf-8')
print(f"Result is {decoded_result}")
response.content_type = "application/json"
return {"status": True}
except FileNotFoundError:
response.status = 500
response.content_type = "application/json"
return {"status": False, "error": "commandnotfound"}
else:
raise Exception("Not implemented")
@app.get("/reload")
def reload():
print("Reloading")
# sys.exit(0)
sys.stderr.close()
if __name__ == "__main__":
print("Starting printserver")
app.run(debug=True, host="0.0.0.0", port=44777)