Skip to content
Snippets Groups Projects
Verified Commit a36b40f7 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Write logic to get and execute print jobs with CUPS

parent 115dc165
No related branches found
No related tags found
No related merge requests found
...@@ -22,6 +22,8 @@ class KortAPI: ...@@ -22,6 +22,8 @@ class KortAPI:
"token": "oauth/token/", "token": "oauth/token/",
"status": "app/kort/api/v1/printers/{}/status/", "status": "app/kort/api/v1/printers/{}/status/",
"printer": "app/kort/api/v1/printers/", "printer": "app/kort/api/v1/printers/",
"next_job": "app/kort/api/v1/printers/{}/jobs/next/",
"job_status": "app/kort/api/v1/jobs/{}/status/",
} }
def __init__(self): def __init__(self):
...@@ -36,6 +38,22 @@ class KortAPI: ...@@ -36,6 +38,22 @@ class KortAPI:
r = self.get_printer() r = self.get_printer()
return r["id"] return r["id"]
def get_next_job(self, printer_id: int) -> Optional[dict[str, Any]]:
r = self._do_request("GET", "next_job", [printer_id])
print(r)
if r.get("status") == "no_job":
return None
return r
def set_job_status(
self, job_id: int, status: str, status_text: str = None
) -> dict[str, Any]:
data = {"status": status}
if status_text is not None:
data["status_text"] = status_text
r = self._do_request("PUT", "job_status", [job_id], data=data)
return r
def set_printer_status( def set_printer_status(
self, printer_id: int, status: str, status_text: str = None self, printer_id: int, status: str, status_text: str = None
) -> dict[str, Any]: ) -> dict[str, Any]:
...@@ -84,7 +102,7 @@ class KortAPI: ...@@ -84,7 +102,7 @@ class KortAPI:
url = urljoin(settings.base_url, url) url = urljoin(settings.base_url, url)
try: try:
r = self.oauth.request(method, url, **kwargs) r = self.oauth.request(method, url, **kwargs)
if r.status_code != 200: if not r.ok:
click.secho("Error {}: {}".format(r.status_code, r.text), fg="red") click.secho("Error {}: {}".format(r.status_code, r.text), fg="red")
raise KortAPIException("Error {}: {}".format(r.status_code, r.text)) raise KortAPIException("Error {}: {}".format(r.status_code, r.text))
return r.json() return r.json()
......
import tempfile
import time import time
from urllib.parse import urljoin
import click import click
import cups import cups
import requests
from kort_client.api import KortAPIException from kort_client.api import KortAPIException
...@@ -10,6 +13,9 @@ class KortClientException(Exception): ...@@ -10,6 +13,9 @@ class KortClientException(Exception):
pass pass
IPP_CODES = {y: x for x, y in cups.__dict__.items() if x.startswith("IPP_JOB")}
class PrintClient: class PrintClient:
def __init__(self, settings, api): def __init__(self, settings, api):
self.settings = settings self.settings = settings
...@@ -70,3 +76,65 @@ class PrintClient: ...@@ -70,3 +76,65 @@ class PrintClient:
self.printer_id = self.printer_config["id"] self.printer_id = self.printer_config["id"]
self._validate_printer() self._validate_printer()
next_job = self.api.get_next_job(self.printer_id)
print(next_job)
if next_job:
job_id = next_job["id"]
click.secho("Got new print job {}".format(next_job), fg="green")
if not self.printer_config.get("generate_number_on_server"):
# Now do something to set the number, but irrelevant for this example
pass
if next_job["card"]["chip_number"]:
# Download PDF file
with tempfile.NamedTemporaryFile("wb") as f:
r = requests.get(
urljoin(self.settings.base_url, next_job["card"]["pdf_file"])
)
f.write(r.content)
f.flush()
cups_job_id = self.conn.printFile(
self.printer_config["cups_printer"],
f.name,
f"AlekSIS: #{job_id}",
{},
)
last_job_state = None
while True:
a = self.conn.getJobAttributes(cups_job_id)
current_job_state = a["job-state"]
status = "in_progress"
if current_job_state in (
cups.IPP_JOB_STOPPED,
cups.IPP_JOB_CANCELED,
cups.IPP_JOB_ABORTED,
cups.IPP_JOB_HELD,
):
status = "failed"
elif current_job_state == cups.IPP_JOB_COMPLETED:
status = "finished"
if last_job_state != current_job_state:
click.echo(
click.style(
f"Print job is in state {status}: {current_job_state}",
fg="yellow",
)
)
last_job_state = current_job_state
self.api.set_job_status(
job_id,
status,
IPP_CODES.get(current_job_state, str(current_job_state)),
)
if status in ("failed", "finished"):
break
time.sleep(0.5)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment