From ef01166fdf3bce931c4e914eff0af2fbbda07059 Mon Sep 17 00:00:00 2001 From: Florent Aide Date: Tue, 2 Jun 2015 09:51:15 +0200 Subject: [PATCH] Adding a fallback system so that you own implementer module can define its default template --HG-- branch : odoo8 --- models/ir_report.py | 12 ++++++++ py3o_parser.py | 68 ++++++++++++++++++++++++++++++++++++++++++--- views/ir_report.xml | 2 ++ 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/models/ir_report.py b/models/ir_report.py index d0feb2af..eb43ebe9 100644 --- a/models/ir_report.py +++ b/models/ir_report.py @@ -23,6 +23,18 @@ class report_xml(osv.Model): 'py3o.template', u"Template", ), + 'module': fields.char( + u"Module", + size=64, + help=u"The implementer module that provides this report", + ), + 'py3o_template_fallback': fields.char( + u"Fallback", + size=128, + help=(u"If the user does not provide a template this will be used " + u"it should be a relattive path to root of YOUR module", + ), + ), 'report_type': fields.selection( [ ('qweb-pdf', u"PDF"), diff --git a/py3o_parser.py b/py3o_parser.py index 6414071b..06dafc98 100644 --- a/py3o_parser.py +++ b/py3o_parser.py @@ -1,14 +1,25 @@ +# -*- encoding: utf-8 -*- +import pkg_resources +import os +import sys from base64 import b64decode import requests from tempfile import NamedTemporaryFile +from openerp import _ from openerp.report.report_sxw import report_sxw, rml_parse from openerp import registry +from openerp.exceptions import DeferredException + from py3o.template import Template _extender_functions = {} +class TemplateNotFound(DeferredException): + pass + + def py3o_report_extender(report_name): """ A decorator to define function to extend the context sent to a template. @@ -23,7 +34,7 @@ def py3o_report_extender(report_name): Method copied from CampToCamp report_webkit module. :param report_name: xml id of the report - :return: + :return: a decorated class """ def fct1(fct): lst = _extender_functions.get(report_name) @@ -47,6 +58,55 @@ class Py3oParser(report_sxw): header=header, store=store, register=register ) + def get_template(self, report_obj): + """private helper to fetch the template data either from the database + or from the default template file provided by the implementer. + + ATM this method takes a report definition recordset + to try and fetch the report template from database. If not found it will + fallback to the template file referenced in the report definition. + + @param report_obj: a recordset representing the report defintion + @type report_obj: openerp.model.recordset instance + + @returns: string or buffer containing the template data + + @raises: TemplateNotFound which is a subclass of + openerp.exceptions.DeferredException + """ + + tmpl_data = None + + if report_obj.py3o_template_id and report_obj.py3o_template_id.id: + # if a user gave a report template + tmpl_data = b64decode( + report_obj.py3o_template_id.py3o_template_data + ) + + elif report_obj.py3o_template_fallback and report_obj.module: + # if the default is defined + flbk_filename = pkg_resources.resource_filename( + "openerp.addons.%s" % report_obj.module, + report_obj.py3o_template_fallback, + ) + if os.path.exists(flbk_filename): + # and it exists on the fileystem + with open(flbk_filename, 'r') as tmpl: + tmpl_data = tmpl.read() + + if tmpl_data is None: + # if for any reason the template is not found + print("*"*35) + print("Template filename: %s" % flbk_filename) + print("*"*35) + + raise TemplateNotFound( + _(u'No template found. Aborting.'), + sys.exc_info(), + ) + + return tmpl_data + def create_single_pdf(self, cr, uid, ids, data, report_xml, context=None): """ Overide this function to generate our py3o report """ @@ -83,6 +143,8 @@ class Py3oParser(report_sxw): template = report_xml.py3o_template_id filetype = report_xml.py3o_fusion_filetype + tmpl_data = self.get_template(report_xml) + # py3o.template operates on filenames so create temporary files. with NamedTemporaryFile( suffix='.odt', @@ -90,12 +152,10 @@ class Py3oParser(report_sxw): suffix='.odt', prefix='py3o-report-') as out_temp: - in_temp.write(b64decode(template.py3o_template_data)) + in_temp.write(tmpl_data) in_temp.flush() template = Template(in_temp.name, out_temp.name) - - print parser_instance.localcontext template.render(parser_instance.localcontext) out_temp.seek(0) diff --git a/views/ir_report.xml b/views/ir_report.xml index d4521c76..a5586aa4 100644 --- a/views/ir_report.xml +++ b/views/ir_report.xml @@ -16,6 +16,8 @@ + +