Avoid writing on printing printers/jobs if no change

The cron (by default) every minute, updates the printing.printer and
printing.job records from the cups server. The field values rarely
change, so we can prevent many updates in database.

Also, writing on `printing_printer.server_id` triggers another update
on the printing.job records as the model has a stored related field.
This commit is contained in:
Guewen Baconnier
2021-02-04 13:54:13 +01:00
parent 2160eedf36
commit 001c637be2
2 changed files with 43 additions and 25 deletions

View File

@@ -69,7 +69,7 @@ class PrintingPrinter(models.Model):
def _prepare_update_from_cups(self, cups_connection, cups_printer):
mapping = {3: "available", 4: "printing", 5: "error"}
vals = {
cups_vals = {
"name": cups_printer["printer-info"],
"model": cups_printer.get("printer-make-and-model", False),
"location": cups_printer.get("printer-location", False),
@@ -77,6 +77,14 @@ class PrintingPrinter(models.Model):
"status": mapping.get(cups_printer.get("printer-state"), "unknown"),
"status_message": cups_printer.get("printer-state-message", ""),
}
# prevent write if the field didn't change
vals = {
fieldname: value
for fieldname, value in cups_vals.items()
if not self or value != self[fieldname]
}
printer_uri = cups_printer["printer-uri-supported"]
printer_system_name = printer_uri[printer_uri.rfind("/") + 1 :]
ppd_info = cups_connection.getPPD3(printer_system_name)
@@ -96,13 +104,13 @@ class PrintingPrinter(models.Model):
if not option:
return vals
vals["tray_ids"] = []
tray_commands = []
cups_trays = {
tray_option["choice"]: tray_option["text"] for tray_option in option.choices
}
# Add new trays
vals["tray_ids"].extend(
tray_commands.extend(
[
(0, 0, {"name": text, "system_name": choice})
for choice, text in cups_trays.items()
@@ -111,7 +119,7 @@ class PrintingPrinter(models.Model):
)
# Remove deleted trays
vals["tray_ids"].extend(
tray_commands.extend(
[
(2, tray.id)
for tray in self.tray_ids.filtered(
@@ -119,6 +127,8 @@ class PrintingPrinter(models.Model):
)
]
)
if tray_commands:
vals["tray_ids"] = tray_commands
return vals
def print_document(self, report, content, **print_opts):

View File

@@ -82,11 +82,14 @@ class PrintingServer(models.Model):
printer_values = printer._prepare_update_from_cups(
connection, printer_info
)
printer_values.update(system_name=name, server_id=server.id)
if server != printer.server_id:
printer_values["server_id"] = server.id
updated_printers.append(name)
if not printer:
printer_values["system_name"] = name
printer.create(printer_values)
else:
elif printer_values:
printer.write(printer_values)
# Set printers not found as unavailable
@@ -172,27 +175,30 @@ class PrintingServer(models.Model):
jobs = job_obj.with_context(active_test=False).search(
[("job_id_cups", "=", cups_job_id), ("server_id", "=", server.id)]
)
job_values = {
cups_job_values = {
"name": job_data.get("job-name", ""),
"active": True,
"job_id_cups": cups_job_id,
"job_media_progress": job_data.get("job-media-progress", False),
"job_media_progress": job_data.get("job-media-progress", 0),
"job_state": mapping.get(job_data.get("job-state"), "unknown"),
"job_state_reason": job_data.get("job-state-reasons", ""),
"time_at_creation": fields.Datetime.to_string(
datetime.fromtimestamp(job_data.get("time-at-creation", False))
),
"time_at_processing": job_data.get("time-at-processing", False)
and fields.Datetime.to_string(
datetime.fromtimestamp(
job_data.get("time-at-processing", False)
)
),
"time_at_completed": job_data.get("time-at-completed", False)
and fields.Datetime.to_string(
datetime.fromtimestamp(job_data.get("time-at-completed", False))
"time_at_creation": datetime.fromtimestamp(
job_data.get("time-at-creation", 0)
),
}
if job_data.get("time-at-processing"):
cups_job_values["time_at_processing"] = datetime.fromtimestamp(
job_data["time-at-processing"]
)
if job_data.get("time-at-completed"):
cups_job_values["time_at_completed"] = datetime.fromtimestamp(
job_data["time-at-completed"]
)
job_values = {
fieldname: value
for fieldname, value in cups_job_values.items()
if not jobs or value != jobs[fieldname]
}
# Search for the printer in Odoo
printer_uri = job_data["printer-uri"]
@@ -209,12 +215,14 @@ class PrintingServer(models.Model):
# discard here if not printer found
if not printer:
continue
job_values["printer_id"] = printer.id
if jobs.printer_id != printer:
job_values["printer_id"] = printer.id
if jobs:
jobs.write(job_values)
else:
if not jobs:
job_values["job_id_cups"] = cups_job_id
job_obj.create(job_values)
elif job_values:
jobs.write(job_values)
# Deactive purged jobs
if which == "all" and first_job_id == -1: