From f48a70ed616ca5c82179e9bbe50fb34dbb7837db Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Thu, 4 Feb 2021 13:54:13 +0100 Subject: [PATCH] [IMP] base_report_to_printer: 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. --- base_report_to_printer/__manifest__.py | 2 +- .../models/printing_printer.py | 18 +++++-- .../models/printing_server.py | 50 +++++++++++-------- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/base_report_to_printer/__manifest__.py b/base_report_to_printer/__manifest__.py index 5f521f5..4e969e9 100644 --- a/base_report_to_printer/__manifest__.py +++ b/base_report_to_printer/__manifest__.py @@ -7,7 +7,7 @@ { "name": "Report to printer", - "version": "14.0.1.0.0", + "version": "14.0.1.0.1", "category": "Generic Modules/Base", "author": "Agile Business Group & Domsense, Pegueroles SCP, NaN," " LasLabs, Camptocamp, Odoo Community Association (OCA)," diff --git a/base_report_to_printer/models/printing_printer.py b/base_report_to_printer/models/printing_printer.py index e16bbc3..d29813c 100644 --- a/base_report_to_printer/models/printing_printer.py +++ b/base_report_to_printer/models/printing_printer.py @@ -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): diff --git a/base_report_to_printer/models/printing_server.py b/base_report_to_printer/models/printing_server.py index ad84029..6ae2c6c 100644 --- a/base_report_to_printer/models/printing_server.py +++ b/base_report_to_printer/models/printing_server.py @@ -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: