mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
Added custom options module for printers by report
corrections for travis tests fix for flake8 errors and travis tests added new sections and rapleced maintainers added USAGE section in readme + bug corection for update of printers changed copyrights updated manifest and fix for case of false ppd
This commit is contained in:
116
printer_custom_options/models/printing_printer.py
Executable file
116
printer_custom_options/models/printing_printer.py
Executable file
@@ -0,0 +1,116 @@
|
||||
# Copyright 2019 Compassion
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import errno
|
||||
import logging
|
||||
import os
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import cups
|
||||
except ImportError:
|
||||
_logger.debug('Cannot `import cups`.')
|
||||
|
||||
|
||||
class PrintingPrinter(models.Model):
|
||||
_inherit = 'printing.printer'
|
||||
|
||||
printer_options = fields.One2many(
|
||||
comodel_name='printer.option',
|
||||
inverse_name='printer_id',
|
||||
readonly=True)
|
||||
printer_option_choices = fields.One2many(
|
||||
comodel_name='printer.option.choice',
|
||||
inverse_name='printer_id',
|
||||
string='Option Choices',
|
||||
readonly=True)
|
||||
|
||||
def _get_cups_ppd(self, cups_connection, cups_printer):
|
||||
""" Returns a PostScript Printer Description (PPD) file for the
|
||||
printer. """
|
||||
printer_uri = cups_printer['printer-uri-supported']
|
||||
printer_system_name = printer_uri[printer_uri.rfind('/') + 1:]
|
||||
ppd_info = cups_connection.getPPD3(printer_system_name)
|
||||
ppd_path = ppd_info[2]
|
||||
if not ppd_path:
|
||||
return False, False
|
||||
return ppd_path, cups.PPD(ppd_path)
|
||||
|
||||
def _cleanup_ppd(self, ppd_path):
|
||||
try:
|
||||
os.unlink(ppd_path)
|
||||
except OSError as err:
|
||||
# ENOENT means No such file or directory
|
||||
# The file has already been deleted, we can continue the update
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
|
||||
@api.multi
|
||||
def _prepare_update_from_cups(self, cups_connection, cups_printer):
|
||||
vals = super()._prepare_update_from_cups(
|
||||
cups_connection, cups_printer)
|
||||
|
||||
current_option_keys = self.printer_option_choices.mapped(
|
||||
'composite_key')
|
||||
ppd_path, ppd = self._get_cups_ppd(cups_connection, cups_printer)
|
||||
if ppd_path and ppd:
|
||||
self._load_printer_option_list(ppd)
|
||||
|
||||
new_option_values = []
|
||||
for printer_option in self.printer_options:
|
||||
option_key = printer_option.option_key
|
||||
new_options = self.discover_values_of_option(ppd,
|
||||
current_option_keys,
|
||||
option_key)
|
||||
new_option_values.extend(new_options)
|
||||
vals['printer_option_choices'] = new_option_values
|
||||
|
||||
self._cleanup_ppd(ppd_path)
|
||||
return vals
|
||||
|
||||
def _load_printer_option_list(self, ppd):
|
||||
if len(self.printer_options) > 0 or not self:
|
||||
# Only fetch options the first time or
|
||||
# if the printer is already in the system.
|
||||
return
|
||||
option_inserts = []
|
||||
for option_group in ppd.optionGroups:
|
||||
for option in option_group.options:
|
||||
option_inserts.append((0, 0, {'option_key': option.keyword}))
|
||||
self.printer_options = option_inserts
|
||||
|
||||
def discover_values_of_option(self, ppd, current_option_keys, option_key):
|
||||
""" Returns all new values for one printer option category. Most
|
||||
probably it will insert all option values the first time we sync with
|
||||
CUPS and then return an empty list."""
|
||||
option = ppd.findOption(option_key)
|
||||
if not option:
|
||||
return []
|
||||
|
||||
printer_option_values = {entry['choice'] for entry in option.choices}
|
||||
option_model = self.env['printer.option.choice']
|
||||
|
||||
# Insertion tuples
|
||||
return [
|
||||
(0, 0,
|
||||
{'option_value': option_value, 'option_key': option_key})
|
||||
for option_value in printer_option_values
|
||||
if option_model.build_composite_key(option_key, option_value)
|
||||
not in current_option_keys
|
||||
]
|
||||
|
||||
@api.multi
|
||||
def print_options(self, report=None, **print_opts):
|
||||
# Use lpoptions to have an exhaustive list of the supported options
|
||||
options = super().print_options(report=report, **print_opts)
|
||||
|
||||
if report is not None:
|
||||
# Some modules pass report_name instead of the report.
|
||||
full_report = self.env['report']._get_report_from_name(report) \
|
||||
if isinstance(report, str) else report
|
||||
for printer_option in full_report.printer_options:
|
||||
options[
|
||||
printer_option.option_key] = printer_option.option_value
|
||||
return options
|
||||
Reference in New Issue
Block a user