mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
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
117 lines
4.3 KiB
Python
Executable File
117 lines
4.3 KiB
Python
Executable File
# 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
|