From feae5dba249f0a934e6dc751c1d9656f3df34d75 Mon Sep 17 00:00:00 2001 From: Lorenzo Battistini Date: Thu, 22 Nov 2012 22:22:52 +0100 Subject: [PATCH 001/180] [ADD] base_report_to_printer --- base_report_to_printer/AUTHORS.txt | 4 + base_report_to_printer/__init__.py | 25 ++ base_report_to_printer/__openerp__.py | 45 +++ .../i18n/base_report_to_printer.pot | 246 ++++++++++++ base_report_to_printer/i18n/it.po | 246 ++++++++++++ base_report_to_printer/printing.py | 363 ++++++++++++++++++ base_report_to_printer/printing_data.xml | 20 + base_report_to_printer/printing_view.xml | 113 ++++++ base_report_to_printer/security/security.xml | 52 +++ base_report_to_printer/wizard/__init__.py | 23 ++ .../wizard/update_printers.py | 76 ++++ .../wizard/update_printers.xml | 26 ++ 12 files changed, 1239 insertions(+) create mode 100644 base_report_to_printer/AUTHORS.txt create mode 100644 base_report_to_printer/__init__.py create mode 100644 base_report_to_printer/__openerp__.py create mode 100644 base_report_to_printer/i18n/base_report_to_printer.pot create mode 100644 base_report_to_printer/i18n/it.po create mode 100755 base_report_to_printer/printing.py create mode 100755 base_report_to_printer/printing_data.xml create mode 100755 base_report_to_printer/printing_view.xml create mode 100755 base_report_to_printer/security/security.xml create mode 100644 base_report_to_printer/wizard/__init__.py create mode 100755 base_report_to_printer/wizard/update_printers.py create mode 100644 base_report_to_printer/wizard/update_printers.xml diff --git a/base_report_to_printer/AUTHORS.txt b/base_report_to_printer/AUTHORS.txt new file mode 100644 index 00000000000..6cc912bc20c --- /dev/null +++ b/base_report_to_printer/AUTHORS.txt @@ -0,0 +1,4 @@ +Ferran Pegueroles +Albert Cervera i Areny +Davide Corio +Lorenzo Battistini diff --git a/base_report_to_printer/__init__.py b/base_report_to_printer/__init__.py new file mode 100644 index 00000000000..456cc25c494 --- /dev/null +++ b/base_report_to_printer/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2007 Ferran Pegueroles +# Copyright (c) 2009 Albert Cervera i Areny +# Copyright (C) 2011 Agile Business Group sagl () +# Copyright (C) 2011 Domsense srl () +# All Rights Reserved +# +# 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 . +# +############################################################################## +import printing +import wizard diff --git a/base_report_to_printer/__openerp__.py b/base_report_to_printer/__openerp__.py new file mode 100644 index 00000000000..d1765f080f0 --- /dev/null +++ b/base_report_to_printer/__openerp__.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2007 Ferran Pegueroles +# Copyright (c) 2009 Albert Cervera i Areny +# Copyright (C) 2011 Agile Business Group sagl () +# Copyright (C) 2011 Domsense srl () +# All Rights Reserved +# +# 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 . +# +############################################################################## +{ + 'name': "Report to printer", + 'version': '0.1', + 'category': 'Generic Modules/Base', + 'description': """Extracted from printjob ( http://apps.openerp.com/addon/1727 ), this module allows to send reports to a printer attached to the server. Settings can be configured globaly, per user, per report and per user and report. + + For more info: http://planet.domsense.com/en/2011/10/linking-openerp-to-cups-printers-base_report_to_printer/""", + 'author': 'Agile Business Group & Domsense, Pegueroles SCP, NaN', + 'website': 'http://www.agilebg.com', + 'license': 'AGPL-3', + "depends" : ['base', 'base_calendar'], + "init_xml" : [], + "update_xml" : [ + 'printing_data.xml', + 'printing_view.xml', + 'wizard/update_printers.xml', + 'security/security.xml', + ], + "demo_xml" : [], + "active": False, + "installable": True +} diff --git a/base_report_to_printer/i18n/base_report_to_printer.pot b/base_report_to_printer/i18n/base_report_to_printer.pot new file mode 100644 index 00000000000..6991398f45d --- /dev/null +++ b/base_report_to_printer/i18n/base_report_to_printer.pot @@ -0,0 +1,246 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * base_report_to_printer +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 6.0.3\n" +"Report-Msgid-Bugs-To: support@openerp.com\n" +"POT-Creation-Date: 2011-09-26 09:06+0000\n" +"PO-Revision-Date: 2011-09-26 09:06+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: base_report_to_printer +#: sql_constraint:res.users:0 +msgid "You can not have two users with the same login !" +msgstr "" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Unavailable" +msgstr "" + +#. module: base_report_to_printer +#: view:printing.printer.update.wizard:0 +msgid "This process will create all missing printers from the current CUPS server." +msgstr "" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Unknown" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.printer,status:0 +msgid "Status" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.printer,system_name:0 +msgid "System Name" +msgstr "" + +#. module: base_report_to_printer +#: constraint:res.users:0 +msgid "The chosen company is not in the allowed companies for this user" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.printer,location:0 +msgid "Location" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.actions.act_window,name:base_report_to_printer.action_printing_printer_form +#: model:ir.ui.menu,name:base_report_to_printer.menu_printing_printer_form +#: view:printing.printer:0 +msgid "Printers" +msgstr "" + +#. module: base_report_to_printer +#: field:res.users,printing_action:0 +msgid "Printing Action" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.module.module,description:base_report_to_printer.module_meta_information +msgid "Extracted from printjob ( http://apps.openerp.com/addon/1727 ), this module allows to send reports to a printer attached to the server. Settings can be configured globaly, per user, per report and per user and report." +msgstr "" + +#. module: base_report_to_printer +#: field:printing.action,type:0 +msgid "Type" +msgstr "" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Available" +msgstr "" + +#. module: base_report_to_printer +#: field:ir.actions.report.xml,printing_printer_id:0 +#: model:ir.model,name:base_report_to_printer.model_printing_printer +#: field:printing.report.xml.action,printer_id:0 +msgid "Printer" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_printing_report_xml_action +#: view:printing.report.xml.action:0 +msgid "Report Printing Actions" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_printing_action +msgid "Print Job Action" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.report.xml.action,user_id:0 +msgid "User" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.report.xml.action,report_id:0 +msgid "Report" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.ui.menu,name:base_report_to_printer.menu_printing_config +msgid "Configuration" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.module.module,shortdesc:base_report_to_printer.module_meta_information +msgid "Report to printer" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_printjob_printer_update_wizard +msgid "printjob.printer.update.wizard" +msgstr "" + +#. module: base_report_to_printer +#: view:printing.printer.update.wizard:0 +msgid "Ok" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.action,name:0 +#: field:printing.printer,name:0 +msgid "Name" +msgstr "" + +#. module: base_report_to_printer +#: view:printing.printer:0 +msgid "Set Default" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.printer,default:0 +#: field:res.users,printing_printer_id:0 +msgid "Default Printer" +msgstr "" + +#. module: base_report_to_printer +#: code:addons/base_report_to_printer/printing.py:189 +#, python-format +msgid "Send to Client" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.printer,uri:0 +msgid "URI" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_printing_printer_update_wizard +msgid "printing.printer.update.wizard" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.actions.act_window,name:base_report_to_printer.action_printer_update_wizard +#: model:ir.ui.menu,name:base_report_to_printer.menu_printer_update_wizard +#: view:printing.printer.update.wizard:0 +msgid "Update Printers from CUPS" +msgstr "" + +#. module: base_report_to_printer +#: code:addons/base_report_to_printer/printing.py:188 +#, python-format +msgid "Send to Printer" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.ui.menu,name:base_report_to_printer.menu_printing_main +#: selection:printing.printer,status:0 +msgid "Printing" +msgstr "" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Error" +msgstr "" + +#. module: base_report_to_printer +#: field:ir.actions.report.xml,property_printing_action:0 +#: field:printing.report.xml.action,action:0 +msgid "Action" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.printer,model:0 +msgid "Model" +msgstr "" + +#. module: base_report_to_printer +#: field:printing.printer,status_message:0 +msgid "Status Message" +msgstr "" + +#. module: base_report_to_printer +#: help:ir.actions.report.xml,printing_action_ids:0 +msgid "This field allows configuring action and printer on a per user basis" +msgstr "" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Server Error" +msgstr "" + +#. module: base_report_to_printer +#: field:ir.actions.report.xml,printing_action_ids:0 +msgid "Actions" +msgstr "" + +#. module: base_report_to_printer +#: view:printing.job:0 +msgid "Print Jobs" +msgstr "" + +#. module: base_report_to_printer +#: view:printing.printer.update.wizard:0 +msgid "Cancel" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_res_users +msgid "res.users" +msgstr "" + +#. module: base_report_to_printer +#: code:addons/base_report_to_printer/printing.py:190 +#, python-format +msgid "Use user's defaults" +msgstr "" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_ir_actions_report_xml +msgid "ir.actions.report.xml" +msgstr "" + diff --git a/base_report_to_printer/i18n/it.po b/base_report_to_printer/i18n/it.po new file mode 100644 index 00000000000..da0596edd3e --- /dev/null +++ b/base_report_to_printer/i18n/it.po @@ -0,0 +1,246 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * base_report_to_printer +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 6.0.3\n" +"Report-Msgid-Bugs-To: support@openerp.com\n" +"POT-Creation-Date: 2011-09-26 09:06+0000\n" +"PO-Revision-Date: 2011-09-26 11:14+0100\n" +"Last-Translator: Lorenzo Battistini \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" + +#. module: base_report_to_printer +#: sql_constraint:res.users:0 +msgid "You can not have two users with the same login !" +msgstr "Non è possibile inserire due utenti con lo stesso nome di login!" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Unavailable" +msgstr "Non disponibile" + +#. module: base_report_to_printer +#: view:printing.printer.update.wizard:0 +msgid "This process will create all missing printers from the current CUPS server." +msgstr "Questo processo creerà tutte le stampante mancanti dal server CUPS corrente" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Unknown" +msgstr "Sconosciuto" + +#. module: base_report_to_printer +#: field:printing.printer,status:0 +msgid "Status" +msgstr "Stato" + +#. module: base_report_to_printer +#: field:printing.printer,system_name:0 +msgid "System Name" +msgstr "Nome di sistema" + +#. module: base_report_to_printer +#: constraint:res.users:0 +msgid "The chosen company is not in the allowed companies for this user" +msgstr "L'azienda selezionata non è tra quelle a cui è permesso l'accesso a questo utente" + +#. module: base_report_to_printer +#: field:printing.printer,location:0 +msgid "Location" +msgstr "Locazione" + +#. module: base_report_to_printer +#: model:ir.actions.act_window,name:base_report_to_printer.action_printing_printer_form +#: model:ir.ui.menu,name:base_report_to_printer.menu_printing_printer_form +#: view:printing.printer:0 +msgid "Printers" +msgstr "Stampanti" + +#. module: base_report_to_printer +#: field:res.users,printing_action:0 +msgid "Printing Action" +msgstr "Azione di stampa" + +#. module: base_report_to_printer +#: model:ir.module.module,description:base_report_to_printer.module_meta_information +msgid "Extracted from printjob ( http://apps.openerp.com/addon/1727 ), this module allows to send reports to a printer attached to the server. Settings can be configured globaly, per user, per report and per user and report." +msgstr "Estratto da printjob ( http://apps.openerp.com/addon/1727 ), questo modulo permetto di inviare i report alle stampanti collegate al server. Le impostazioni possono essere configurate globalmente, per utente, per report e per utente e report." + +#. module: base_report_to_printer +#: field:printing.action,type:0 +msgid "Type" +msgstr "Tipo" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Available" +msgstr "Disponibile" + +#. module: base_report_to_printer +#: field:ir.actions.report.xml,printing_printer_id:0 +#: model:ir.model,name:base_report_to_printer.model_printing_printer +#: field:printing.report.xml.action,printer_id:0 +msgid "Printer" +msgstr "Stampante" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_printing_report_xml_action +#: view:printing.report.xml.action:0 +msgid "Report Printing Actions" +msgstr "Azioni di stampa report" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_printing_action +msgid "Print Job Action" +msgstr "Azione di stampa" + +#. module: base_report_to_printer +#: field:printing.report.xml.action,user_id:0 +msgid "User" +msgstr "Utente" + +#. module: base_report_to_printer +#: field:printing.report.xml.action,report_id:0 +msgid "Report" +msgstr "Report" + +#. module: base_report_to_printer +#: model:ir.ui.menu,name:base_report_to_printer.menu_printing_config +msgid "Configuration" +msgstr "Configurazione" + +#. module: base_report_to_printer +#: model:ir.module.module,shortdesc:base_report_to_printer.module_meta_information +msgid "Report to printer" +msgstr "Report alla stampante" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_printjob_printer_update_wizard +msgid "printjob.printer.update.wizard" +msgstr "printjob.printer.update.wizard" + +#. module: base_report_to_printer +#: view:printing.printer.update.wizard:0 +msgid "Ok" +msgstr "Ok" + +#. module: base_report_to_printer +#: field:printing.action,name:0 +#: field:printing.printer,name:0 +msgid "Name" +msgstr "Nome" + +#. module: base_report_to_printer +#: view:printing.printer:0 +msgid "Set Default" +msgstr "Imposta default" + +#. module: base_report_to_printer +#: field:printing.printer,default:0 +#: field:res.users,printing_printer_id:0 +msgid "Default Printer" +msgstr "Stampante di default" + +#. module: base_report_to_printer +#: code:addons/base_report_to_printer/printing.py:189 +#, python-format +msgid "Send to Client" +msgstr "Invia al client" + +#. module: base_report_to_printer +#: field:printing.printer,uri:0 +msgid "URI" +msgstr "URI" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_printing_printer_update_wizard +msgid "printing.printer.update.wizard" +msgstr "printing.printer.update.wizard" + +#. module: base_report_to_printer +#: model:ir.actions.act_window,name:base_report_to_printer.action_printer_update_wizard +#: model:ir.ui.menu,name:base_report_to_printer.menu_printer_update_wizard +#: view:printing.printer.update.wizard:0 +msgid "Update Printers from CUPS" +msgstr "Aggiorna stampanti da CUPS" + +#. module: base_report_to_printer +#: code:addons/base_report_to_printer/printing.py:188 +#, python-format +msgid "Send to Printer" +msgstr "Invia alla stampante" + +#. module: base_report_to_printer +#: model:ir.ui.menu,name:base_report_to_printer.menu_printing_main +#: selection:printing.printer,status:0 +msgid "Printing" +msgstr "Stampa" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Error" +msgstr "Errore" + +#. module: base_report_to_printer +#: field:ir.actions.report.xml,property_printing_action:0 +#: field:printing.report.xml.action,action:0 +msgid "Action" +msgstr "Azione" + +#. module: base_report_to_printer +#: field:printing.printer,model:0 +msgid "Model" +msgstr "Model" + +#. module: base_report_to_printer +#: field:printing.printer,status_message:0 +msgid "Status Message" +msgstr "Messaggio di stato" + +#. module: base_report_to_printer +#: help:ir.actions.report.xml,printing_action_ids:0 +msgid "This field allows configuring action and printer on a per user basis" +msgstr "Questo campo permette di configurare azioni e stampanti sulla base degli utenti" + +#. module: base_report_to_printer +#: selection:printing.printer,status:0 +msgid "Server Error" +msgstr "Errore server" + +#. module: base_report_to_printer +#: field:ir.actions.report.xml,printing_action_ids:0 +msgid "Actions" +msgstr "Azioni" + +#. module: base_report_to_printer +#: view:printing.job:0 +msgid "Print Jobs" +msgstr "Stampe" + +#. module: base_report_to_printer +#: view:printing.printer.update.wizard:0 +msgid "Cancel" +msgstr "Annulla" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_res_users +msgid "res.users" +msgstr "res.users" + +#. module: base_report_to_printer +#: code:addons/base_report_to_printer/printing.py:190 +#, python-format +msgid "Use user's defaults" +msgstr "Utilizza i default dell'utente" + +#. module: base_report_to_printer +#: model:ir.model,name:base_report_to_printer.model_ir_actions_report_xml +msgid "ir.actions.report.xml" +msgstr "ir.actions.report.xml" + diff --git a/base_report_to_printer/printing.py b/base_report_to_printer/printing.py new file mode 100755 index 00000000000..1d929c00e46 --- /dev/null +++ b/base_report_to_printer/printing.py @@ -0,0 +1,363 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2007 Ferran Pegueroles +# Copyright (c) 2009 Albert Cervera i Areny +# Copyright (C) 2011 Agile Business Group sagl () +# Copyright (C) 2011 Domsense srl () +# All Rights Reserved +# +# 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 . +# +############################################################################## + +import os +import base64 +import threading +from tempfile import mkstemp + +import cups +import thread +from threading import Thread +from threading import Lock + +import netsvc +import tools +import time +from osv import fields +from osv import osv +import pooler +import tools +from tools.translate import _ +from base_calendar import base_calendar + + +# +# Printers +# +class printing_printer(osv.osv): + _name = "printing.printer" + _description = "Printer" + + _columns = { + 'name' : fields.char('Name',size=64,required=True,select="1"), + 'system_name': fields.char('System Name',size=64,required=True,select="1"), + 'default':fields.boolean('Default Printer',required=True,readonly=True), + 'status': fields.selection([('unavailable','Unavailable'),('printing','Printing'),('unknown','Unknown'),('available','Available'),('error','Error'),('server-error','Server Error')], 'Status', required=True, readonly=True), + 'status_message': fields.char('Status Message', size=500, readonly=True), + 'model': fields.char('Model', size=500, readonly=True), + 'location': fields.char('Location', size=500, readonly=True), + 'uri': fields.char('URI', size=500, readonly=True), + } + _order = "name" + + _defaults = { + 'default': lambda *a: False, + 'status': lambda *a: 'unknown', + } + + def __init__(self, pool, cr): + super(printing_printer, self).__init__(pool, cr) + self.lock = Lock() + self.last_update = None + self.updating = False + + def update_printers_status(self, db_name, uid, context): + db, pool = pooler.get_db_and_pool(db_name) + cr = db.cursor() + + try: + connection = cups.Connection() + printers = connection.getPrinters() + server_error = False + except: + server_error = True + + mapping = { + 3 : 'available', + 4 : 'printing', + 5 : 'error' + } + + # Skip update to avoid the thread being created again + ctx = context.copy() + ctx['skip_update'] = True + ids = self.pool.get('printing.printer').search(cr, uid, [], context=ctx) + for printer in self.pool.get('printing.printer').browse(cr, uid, ids, context=ctx): + vals = {} + if server_error: + status = 'server-error' + elif printer.system_name in printers: + info = printers[printer.system_name] + status = mapping.get( info['printer-state'], 'unknown' ) + vals = { + 'model': info.get('printer-make-and-model', False), + 'location': info.get('printer-location', False), + 'uri': info.get('device-uri', False), + } + else: + status = 'unavailable' + + vals['status'] = status + self.pool.get('printing.printer').write(cr, uid, [printer.id], vals, context) + + cr.commit() + cr.close() + self.lock.acquire() + self.updating = False + self.last_update = time.time() + self.lock.release() + + + def start_printer_update(self, cr, uid, context): + self.lock.acquire() + if self.updating: + self.lock.release() + return + self.updating = True + self.lock.release() + thread = Thread(target=self.update_printers_status, args=(cr.dbname, uid, context.copy())) + thread.start() + + def update(self, cr, uid, context=None): + if not context or context.get('skip_update'): + return + self.lock.acquire() + last_update = self.last_update + updating = self.updating + self.lock.release() + now = time.time() + # Only update printer status if current status is more than 10 seconds old. + if not last_update or now - last_update > 10: + self.start_printer_update(cr, uid, context) + # Wait up to five seconds for printer status update + for x in range(0,5): + time.sleep(1) + self.lock.acquire() + updating = self.updating + self.lock.release() + if not updating: + break + + def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): + self.update(cr, uid, context) + return super(printing_printer,self).search(cr, uid, args, offset, limit, order, context, count) + + def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): + self.update(cr, uid, context) + return super(printing_printer,self).read(cr, uid, ids, fields, context, load) + + def browse(self, cr, uid, ids, context=None): + self.update(cr, uid, context) + return super(printing_printer,self).browse(cr, uid, ids, context) + + def set_default(self, cr, uid, ids, context): + if not ids: + return + default_ids= self.search(cr, uid,[('default','=',True)]) + self.write(cr, uid, default_ids, {'default':False}, context) + self.write(cr, uid, ids[0], {'default':True}, context) + return True + + def get_default(self,cr,uid,context): + printer_ids = self.search(cr, uid,[('default','=',True)]) + if printer_ids: + return printer_ids[0] + return None + +printing_printer() + + + +# +# Actions +# + +def _available_action_types(self, cr, uid, context={}): + return [ + ('server',_('Send to Printer')), + ('client',_('Send to Client')), + ('user_default',_("Use user's defaults")), + ] + +class printing_action(osv.osv): + _name = 'printing.action' + _description = 'Print Job Action' + + _columns = { + 'name': fields.char('Name', size=256, required=True), + 'type': fields.selection(_available_action_types, 'Type', required=True), + } +printing_action() + +# +# Users +# + +class res_users(osv.osv): + _name = "res.users" + _inherit = "res.users" + + def _user_available_action_types(self, cr, uid, context={}): + return [x for x in _available_action_types(self, cr, uid, context) if x[0] != 'user_default'] + + _columns = { + 'printing_action': fields.selection(_user_available_action_types, 'Printing Action'), + 'printing_printer_id': fields.many2one('printing.printer', 'Default Printer'), + } + +res_users() + +# +# Reports +# + +class report_xml(osv.osv): + + def print_direct(self, cr, uid, result, format, printer): + logger = netsvc.Logger() + fd, file_name = mkstemp() + try: + os.write(fd, base64.decodestring(result)) + finally: + os.close(fd) + printer_system_name = '' + if printer: + if isinstance(printer, (str,unicode)): + printer_system_name = printer + else: + printer_system_name = printer.system_name + if format == 'raw': + # -l is the same as -o raw + cmd = "lpr -l -P %s %s" % (printer_system_name,file_name) + else: + cmd = "lpr -P %s %s" % (printer_system_name,file_name) + logger.notifyChannel("report", netsvc.LOG_INFO,"Printing job : '%s'" % cmd) + os.system(cmd) + + _inherit = 'ir.actions.report.xml' + _columns = { + 'property_printing_action': fields.property( + #'ir.actions.report.xml', + 'printing.action', + type='many2one', + relation='printing.action', + string='Action', + view_load=True, + method=True, + ), + 'printing_printer_id': fields.many2one('printing.printer', 'Printer'), + 'printing_action_ids': fields.one2many('printing.report.xml.action', 'report_id', 'Actions', help='This field allows configuring action and printer on a per user basis'), + } + + def behaviour(self, cr, uid, ids, context={}): + result = {} + + # Set hardcoded default action + default_action = 'client' + # Retrieve system wide printer + default_printer = self.pool.get('printing.printer').get_default(cr,uid,context) + if default_printer: + default_printer = self.pool.get('printing.printer').browse(cr,uid,default_printer,context).system_name + + + # Retrieve user default values + user = self.pool.get('res.users').browse(cr, uid, context) + if user.printing_action: + default_action = user.printing_action + if user.printing_printer_id: + default_printer = user.printing_printer_id.system_name + + for report in self.browse(cr, uid, ids, context): + action = default_action + printer = default_printer + + # Retrieve report default values + if report.property_printing_action and report.property_printing_action.type != 'user_default': + action = report.property_printing_action.type + if report.printing_printer_id: + printer = report.printing_printer_id + + # Retrieve report-user specific values + user_action = self.pool.get('printing.report.xml.action').behaviour(cr, uid, report.id, context) + if user_action and user_action['action'] != 'user_default': + action = user_action['action'] + if user_action['printer']: + printer = user_action['printer'] + + result[report.id] = { + 'action': action, + 'printer': printer, + } + return result + + +report_xml() + +class report_xml_action(osv.osv): + _name = 'printing.report.xml.action' + _description = 'Report Printing Actions' + _columns = { + 'report_id': fields.many2one('ir.actions.report.xml', 'Report', required=True, ondelete='cascade'), + 'user_id': fields.many2one('res.users', 'User', required=True, ondelete='cascade'), + 'action': fields.selection(_available_action_types, 'Action', required=True), + 'printer_id': fields.many2one('printing.printer', 'Printer'), + } + + def behaviour(self, cr, uid, report_id, context={}): + result = {} + ids = self.search(cr, uid, [('report_id','=',report_id),('user_id','=',uid)], context=context) + if not ids: + return False + action = self.browse(cr, uid, ids[0], context) + return { + 'action': action.action, + 'printer': action.printer_id.system_name, + } +report_xml_action() + +class virtual_report_spool(base_calendar.virtual_report_spool): + + def exp_report(self, db, uid, object, ids, datas=None, context=None): + res = super(virtual_report_spool, self).exp_report(db, uid, object, ids, datas, context) + self._reports[res]['report_name'] = object + return res + + def exp_report_get(self, db, uid, report_id): + + cr = pooler.get_db(db).cursor() + pool = pooler.get_pool(cr.dbname) + + # First of all load report defaults: name, action and printer + report_obj = pool.get('ir.actions.report.xml') + report = report_obj.search(cr,uid,[('report_name','=',self._reports[report_id]['report_name'])]) + if report: + report = report_obj.browse(cr,uid,report[0]) + name = report.name + data = report.behaviour()[report.id] + action = data['action'] + printer = data['printer'] + if action != 'client': + if (self._reports and self._reports.get(report_id, False) and self._reports[report_id].get('result', False) + and self._reports[report_id].get('format', False)): + report_obj.print_direct(cr, uid, base64.encodestring(self._reports[report_id]['result']), + self._reports[report_id]['format'], printer) + cr.close() + + res = super(virtual_report_spool, self).exp_report_get(db, uid, report_id) + return res + +virtual_report_spool() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/base_report_to_printer/printing_data.xml b/base_report_to_printer/printing_data.xml new file mode 100755 index 00000000000..6e81db157e7 --- /dev/null +++ b/base_report_to_printer/printing_data.xml @@ -0,0 +1,20 @@ + + + + + + Send to Printer + server + + + Send to Client + client + + + + property_printing_action + + + + + diff --git a/base_report_to_printer/printing_view.xml b/base_report_to_printer/printing_view.xml new file mode 100755 index 00000000000..6735d419fa7 --- /dev/null +++ b/base_report_to_printer/printing_view.xml @@ -0,0 +1,113 @@ + + + + + + + + + + printing.printer.form + printing.printer + form + +
+ + + + +