mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
Migrate ir_report.py to new API Migrate printing.py to new API Migrate res_users.py to new API Migrate report_xml_action.py to new API Migrate wizard/update_printers.py to new API Better view for wizard Recursion when calling a method with old-style api signature from browse Remove the Lock because it is useless on multiprocess Replace it by a database lock so the different processes are all aware of the lock and the last update timestamp. browse is called often enough to call the update routine (even too much) Implements the print on the new 'report' model Restore the print capability on deprecated reports Update copyrights Improve form view, add search view for printers Update translations, add a string to URI so it is uppercased missing api decorator We need the report in print_document and print options (needed in printer_tray) Move the 'skip_update' right in the browse, it prevents a loop See https://github.com/odoo/odoo/issues/3644 Also, it helps to have the value set/read in context close to each other. Avoid to hits the database too many times to check if the list of printers needs to be refreshed. Keep the last update datetime in cache and invalidate this datetime if is is older than POLL_INTERVAL. Thus, one process won't hit the DB more than 1 time every POLL_INTERVAL (10 seconds currently) to check if it needs to update the list. Refresh the list of printers every 15 seconds instead of 10 Extract a method so it will be easier to override in printer_tray Error on installation of the module Invalidate the cache when the table is created so the table_exists() method returns a fresh value after creation of the table Use a cron instead of threads to update printers status The implementation with threads was blocking the loading of the server in multiprocess. Using a cron will lower the frequency of the updates but at least it is simple and reliable. Fixes #14 Do not write the printer status if it has not changed Avoid unnecessary UPDATE every minute Clean the XML file (remove eval, reindent) Give access to models to all users for reading So they are able to print
173 lines
5.6 KiB
Python
173 lines
5.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
##############################################################################
|
|
#
|
|
# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
|
|
# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
|
|
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
|
|
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
|
|
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
##############################################################################
|
|
import logging
|
|
import os
|
|
|
|
from tempfile import mkstemp
|
|
|
|
import cups
|
|
|
|
from openerp import models, fields, api
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class PrintingPrinter(models.Model):
|
|
"""
|
|
Printers
|
|
"""
|
|
|
|
_name = 'printing.printer'
|
|
_description = 'Printer'
|
|
_order = 'name'
|
|
|
|
name = fields.Char(required=True, select=True)
|
|
system_name = fields.Char(required=True, select=True)
|
|
default = fields.Boolean(readonly=True)
|
|
status = fields.Selection([('unavailable', 'Unavailable'),
|
|
('printing', 'Printing'),
|
|
('unknown', 'Unknown'),
|
|
('available', 'Available'),
|
|
('error', 'Error'),
|
|
('server-error', 'Server Error')],
|
|
required=True,
|
|
readonly=True,
|
|
default='unknown')
|
|
status_message = fields.Char(readonly=True)
|
|
model = fields.Char(readonly=True)
|
|
location = fields.Char(readonly=True)
|
|
uri = fields.Char(string='URI', readonly=True)
|
|
|
|
@api.model
|
|
def update_printers_status(self):
|
|
printer_recs = self.search([])
|
|
try:
|
|
connection = cups.Connection()
|
|
printers = connection.getPrinters()
|
|
except:
|
|
printer_recs.write({'status': 'server-error'})
|
|
else:
|
|
for printer in printer_recs:
|
|
cups_printer = printers.get(printer.system_name)
|
|
if cups_printer:
|
|
printer.update_from_cups(connection, cups_printer)
|
|
else:
|
|
# not in cups list
|
|
printer.status = 'unavailable'
|
|
return True
|
|
|
|
@api.multi
|
|
def _prepare_update_from_cups(self, cups_connection, cups_printer):
|
|
mapping = {
|
|
3: 'available',
|
|
4: 'printing',
|
|
5: 'error'
|
|
}
|
|
vals = {
|
|
'model': cups_printer.get('printer-make-and-model', False),
|
|
'location': cups_printer.get('printer-location', False),
|
|
'uri': cups_printer.get('device-uri', False),
|
|
'status': mapping.get(cups_printer['printer-state'], 'unknown'),
|
|
}
|
|
return vals
|
|
|
|
@api.multi
|
|
def update_from_cups(self, cups_connection, cups_printer):
|
|
""" Update a printer from the information returned by cups.
|
|
|
|
:param cups_connection: connection to CUPS, may be used when the
|
|
method is overriden (e.g. in printer_tray)
|
|
:param cups_printer: dict of information returned by CUPS for the
|
|
current printer
|
|
"""
|
|
self.ensure_one()
|
|
vals = self._prepare_update_from_cups(cups_connection, cups_printer)
|
|
if any(self[name] != value for name, value in vals.iteritems()):
|
|
self.write(vals)
|
|
|
|
@api.multi
|
|
def print_options(self, report, format):
|
|
""" Hook to set print options """
|
|
options = {}
|
|
if format == 'raw':
|
|
options['raw'] = True
|
|
return options
|
|
|
|
@api.multi
|
|
def print_document(self, report, content, format):
|
|
""" Print a file
|
|
|
|
Format could be pdf, qweb-pdf, raw, ...
|
|
|
|
"""
|
|
self.ensure_one()
|
|
fd, file_name = mkstemp()
|
|
try:
|
|
os.write(fd, content)
|
|
finally:
|
|
os.close(fd)
|
|
connection = cups.Connection()
|
|
|
|
options = self.print_options(report, format)
|
|
|
|
connection.printFile(self.system_name,
|
|
file_name,
|
|
file_name,
|
|
options=options)
|
|
_logger.info("Printing job: '%s'" % file_name)
|
|
return True
|
|
|
|
@api.multi
|
|
def set_default(self):
|
|
if not self:
|
|
return
|
|
self.ensure_one()
|
|
default_printers = self.search([('default', '=', True)])
|
|
default_printers.write({'default': False})
|
|
self.write({'default': True})
|
|
return True
|
|
|
|
@api.multi
|
|
def get_default(self):
|
|
return self.search([('default', '=', True)], limit=1)
|
|
|
|
#
|
|
# Actions
|
|
#
|
|
|
|
|
|
def _available_action_types(self):
|
|
return [('server', 'Send to Printer'),
|
|
('client', 'Send to Client'),
|
|
('user_default', "Use user's defaults"),
|
|
]
|
|
|
|
|
|
class PrintingAction(models.Model):
|
|
_name = 'printing.action'
|
|
_description = 'Print Job Action'
|
|
|
|
name = fields.Char(required=True)
|
|
type = fields.Selection(_available_action_types, required=True)
|