From 0cb53890df64672f436b45762427b28b74bb8392 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 10:34:28 +0100 Subject: [PATCH 01/24] [IMP] report: reports with custom parsers can be declared in XML files. bzr revid: vmt@openerp.com-20130222093428-f1isxxqlbaj7uhuo --- openerp/addons/base/ir/ir_actions.py | 4 ++++ openerp/import_xml.rng | 1 + openerp/netsvc.py | 29 ++++++++++++++++++++++++++-- openerp/report/interface.py | 20 ++++++++++++------- openerp/report/print_xml.py | 2 +- openerp/report/report_sxw.py | 4 ++-- openerp/service/report.py | 2 +- openerp/tools/convert.py | 2 ++ openerp/tools/test_reports.py | 2 +- 9 files changed, 52 insertions(+), 14 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index beb4e27200a..4f3ed8b0387 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -96,8 +96,11 @@ class report_xml(osv.osv): result = cr.dictfetchall() reports = openerp.report.interface.report_int._reports for r in result: + print ">>> Registering:", r['report_name'], "...", if reports.has_key('report.'+r['report_name']): + print " Already present." continue + print " Done." if r['report_rml'] or r['report_rml_content_data']: report_sxw('report.'+r['report_name'], r['model'], opj('addons',r['report_rml'] or '/'), header=r['header']) @@ -140,6 +143,7 @@ class report_xml(osv.osv): 'report_sxw_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='SXW Content',), 'report_rml_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='RML Content'), + 'parser': fields.char('Parser Class'), } _defaults = { 'type': 'ir.actions.report.xml', diff --git a/openerp/import_xml.rng b/openerp/import_xml.rng index 97b2c4a13c0..5f4c40b65d3 100644 --- a/openerp/import_xml.rng +++ b/openerp/import_xml.rng @@ -107,6 +107,7 @@ + diff --git a/openerp/netsvc.py b/openerp/netsvc.py index a5e33ff22b1..33d7a222884 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -24,6 +24,7 @@ import errno import logging import logging.handlers +import operator import os import platform import release @@ -45,13 +46,37 @@ import openerp _logger = logging.getLogger(__name__) -def LocalService(name): +def LocalService(name, cursor=None): # Special case for addons support, will be removed in a few days when addons # are updated to directly use openerp.osv.osv.service. if name == 'workflow': return openerp.workflow - return openerp.report.interface.report_int._reports[name] + if cursor is None: # TODO temporary, while refactoring + registered_report = openerp.report.interface.report_int._reports[name] + print ">>> Oh noes no cursor." + return registered_report + else: + from openerp.report.report_sxw import report_sxw, report_rml + cr = cursor + opj = os.path.join + cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name[len('report.'):],)) + result = cr.dictfetchall() + for r in result: + if r['report_rml'] or r['report_rml_content_data']: + if r['parser']: + kwargs = { 'parser': operator.attrgetter(r['parser'])(openerp.addons) } + else: + kwargs = {} + new_report = report_sxw('report.'+r['report_name'], r['model'], + opj('addons',r['report_rml'] or '/'), header=r['header'], register=False, **kwargs) + elif r['report_xsl']: + new_report = report_rml('report.'+r['report_name'], r['model'], + opj('addons',r['report_xml']), + r['report_xsl'] and opj('addons',r['report_xsl']), register=False) + else: + raise Exception, "Unhandled report type: %s" % r + return new_report BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10) #The background is set with 40 plus the number of the color, and the foreground with 30 diff --git a/openerp/report/interface.py b/openerp/report/interface.py index f0de9631800..6c5fc24b559 100644 --- a/openerp/report/interface.py +++ b/openerp/report/interface.py @@ -43,11 +43,17 @@ class report_int(object): _reports = {} - def __init__(self, name): - if not name.startswith('report.'): - raise Exception('ConceptionError, bad report name, should start with "report."') - assert name not in self._reports, 'The report "%s" already exists!' % name - self._reports[name] = self + def __init__(self, name, register=True): + if register: + print "*** Registering report `%s` but it should be registered trough data declaration instead. ***" % name + if not name.startswith('report.'): + raise Exception('ConceptionError, bad report name, should start with "report."') + assert name not in self._reports, 'The report "%s" already exists!' % name + self._reports[name] = self + else: + # The report is instanciated at each use site, which is ok. + pass + self.__name = name self.name = name @@ -65,8 +71,8 @@ class report_rml(report_int): XML -> DATAS -> RML -> PDF -> HTML using a XSL:RML transformation """ - def __init__(self, name, table, tmpl, xsl): - super(report_rml, self).__init__(name) + def __init__(self, name, table, tmpl, xsl, register=True): + super(report_rml, self).__init__(name, register=register) self.table = table self.internal_header=False self.tmpl = tmpl diff --git a/openerp/report/print_xml.py b/openerp/report/print_xml.py index c2af0984c2e..558f7dd3bd0 100644 --- a/openerp/report/print_xml.py +++ b/openerp/report/print_xml.py @@ -264,7 +264,7 @@ class document(object): def parse_tree(self, ids, model, context=None): if not context: context={} - browser = self.pool.get(model).browse(self.cr, self.uid, ids, context) + browser = self.pool[model].browse(self.cr, self.uid, ids, context) self.parse_node(self.dom, self.doc, browser) def parse_string(self, xml, ids, model, context=None): diff --git a/openerp/report/report_sxw.py b/openerp/report/report_sxw.py index 325690205ef..0e2a7e18edd 100644 --- a/openerp/report/report_sxw.py +++ b/openerp/report/report_sxw.py @@ -388,8 +388,8 @@ class rml_parse(object): self.setCompany(objects[0].company_id) class report_sxw(report_rml, preprocess.report): - def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False): - report_rml.__init__(self, name, table, rml, '') + def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False, register=True): + report_rml.__init__(self, name, table, rml, '', register=register) self.name = name self.parser = parser self.header = header diff --git a/openerp/service/report.py b/openerp/service/report.py index c20c7f0d7ec..d7832dfb40b 100644 --- a/openerp/service/report.py +++ b/openerp/service/report.py @@ -90,7 +90,7 @@ def exp_report(db, uid, object, ids, datas=None, context=None): def go(id, uid, ids, datas, context): cr = openerp.pooler.get_db(db).cursor() try: - obj = openerp.netsvc.LocalService('report.'+object) + obj = openerp.netsvc.LocalService('report.'+object, cursor=cr) (result, format) = obj.create(cr, uid, ids, datas, context) if not result: tb = sys.exc_info() diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index 00b8bf96340..a8ba37e29d5 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -302,6 +302,8 @@ form: module.record_id""" % (xml_id,) res['header'] = eval(rec.get('header','False')) if rec.get('report_type'): res['report_type'] = rec.get('report_type') + if rec.get('parser'): + res['parser'] = rec.get('parser') res['multi'] = rec.get('multi') and eval(rec.get('multi','False')) diff --git a/openerp/tools/test_reports.py b/openerp/tools/test_reports.py index 9ec4dab6cc3..71cedc1a98d 100644 --- a/openerp/tools/test_reports.py +++ b/openerp/tools/test_reports.py @@ -50,7 +50,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None): else: rname_s = rname _logger.log(netsvc.logging.TEST, " - Trying %s.create(%r)", rname, ids) - res = netsvc.LocalService(rname).create(cr, uid, ids, data, context) + res = netsvc.LocalService(rname, cursor=cr).create(cr, uid, ids, data, context) if not isinstance(res, tuple): raise RuntimeError("Result of %s.create() should be a (data,format) tuple, now it is a %s" % \ (rname, type(res))) From 729d969fd9b0dcc7c7d25cc50acfbd45fc612f30 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 13:48:01 +0100 Subject: [PATCH 02/24] [IMP] report: use openerp.report.render_report() instead of LocalService().create(). bzr revid: vmt@openerp.com-20130222124801-zhhbw2bgghhf6rg6 --- doc/changelog.rst | 2 ++ openerp/addons/base/ir/ir_actions.py | 33 +++++++++++++++++++++++++++ openerp/addons/base/ir/ir_actions.xml | 1 + openerp/netsvc.py | 33 +++------------------------ openerp/report/__init__.py | 9 ++++++++ openerp/service/report.py | 7 +++--- openerp/tools/test_reports.py | 3 ++- 7 files changed, 53 insertions(+), 35 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index a80e8dc6c8d..ec75fadfe6b 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -6,6 +6,8 @@ Changelog `trunk` ------- +- Almost removed ``LocalService()``. For reports, + ``openerp.report.render_report()`` can be used. - Added the :ref:`Long polling ` worker type. - Added :ref:`orm-workflows` to the ORM. - Added :ref:`routing-decorators` to the RPC and WSGI stack. diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 4f3ed8b0387..71170f42e91 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -109,6 +109,39 @@ class report_xml(osv.osv): opj('addons',r['report_xml']), r['report_xsl'] and opj('addons',r['report_xsl'])) + def render_report(self, cr, uid, ids, name, data, context=None): + """ + Look up a report definition and render the report for the provided IDs. + """ + import openerp + import operator + import os + opj = os.path.join + + cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name,)) + new_report = None + for r in cr.dictfetchall(): + if r['report_rml'] or r['report_rml_content_data']: + if r['parser']: + kwargs = { 'parser': operator.attrgetter(r['parser'])(openerp.addons) } + else: + kwargs = {} + new_report = report_sxw('report.'+r['report_name'], r['model'], + opj('addons',r['report_rml'] or '/'), header=r['header'], register=False, **kwargs) + elif r['report_xsl']: + new_report = report_rml('report.'+r['report_name'], r['model'], + opj('addons',r['report_xml']), + r['report_xsl'] and opj('addons',r['report_xsl']), register=False) + else: + # TODO: + # Temporarily, we look reports up the _reports dict. + # raise Exception, "Unhandled report type: %s" % r + pass + if new_report is None: + new_report = interface.report_int._reports['report.' + name] + + return new_report.create(cr, uid, ids, data, context) + _name = 'ir.actions.report.xml' _inherit = 'ir.actions.actions' _table = 'ir_act_report_xml' diff --git a/openerp/addons/base/ir/ir_actions.xml b/openerp/addons/base/ir/ir_actions.xml index da118129932..82514692c06 100644 --- a/openerp/addons/base/ir/ir_actions.xml +++ b/openerp/addons/base/ir/ir_actions.xml @@ -82,6 +82,7 @@ + diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 33d7a222884..aab166ab4c2 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -46,37 +46,10 @@ import openerp _logger = logging.getLogger(__name__) +# TODO LocalService is deprecated. def LocalService(name, cursor=None): - # Special case for addons support, will be removed in a few days when addons - # are updated to directly use openerp.osv.osv.service. - if name == 'workflow': - return openerp.workflow - - if cursor is None: # TODO temporary, while refactoring - registered_report = openerp.report.interface.report_int._reports[name] - print ">>> Oh noes no cursor." - return registered_report - else: - from openerp.report.report_sxw import report_sxw, report_rml - cr = cursor - opj = os.path.join - cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name[len('report.'):],)) - result = cr.dictfetchall() - for r in result: - if r['report_rml'] or r['report_rml_content_data']: - if r['parser']: - kwargs = { 'parser': operator.attrgetter(r['parser'])(openerp.addons) } - else: - kwargs = {} - new_report = report_sxw('report.'+r['report_name'], r['model'], - opj('addons',r['report_rml'] or '/'), header=r['header'], register=False, **kwargs) - elif r['report_xsl']: - new_report = report_rml('report.'+r['report_name'], r['model'], - opj('addons',r['report_xml']), - r['report_xsl'] and opj('addons',r['report_xsl']), register=False) - else: - raise Exception, "Unhandled report type: %s" % r - return new_report + assert name == 'workflow' + return openerp.workflow BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10) #The background is set with 40 plus the number of the color, and the foreground with 30 diff --git a/openerp/report/__init__.py b/openerp/report/__init__.py index 6b56f15b6b5..647e6ba93a6 100644 --- a/openerp/report/__init__.py +++ b/openerp/report/__init__.py @@ -31,5 +31,14 @@ import report_sxw import printscreen +def render_report(cr, uid, ids, name, data, context=None): + """ + Helper to call ``ir.actions.report.xml.render_report()``. + """ + import openerp + registry = openerp.modules.registry.RegistryManager.get(cr.dbname) + return registry['ir.actions.report.xml'].render_report(cr, uid, ids, name, data, context) + + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/service/report.py b/openerp/service/report.py index d7832dfb40b..5144a064b1e 100644 --- a/openerp/service/report.py +++ b/openerp/service/report.py @@ -7,6 +7,7 @@ import threading import openerp.netsvc import openerp.pooler +import openerp.report from openerp import tools import security @@ -51,8 +52,7 @@ def exp_render_report(db, uid, object, ids, datas=None, context=None): cr = openerp.pooler.get_db(db).cursor() try: - obj = openerp.netsvc.LocalService('report.'+object) - (result, format) = obj.create(cr, uid, ids, datas, context) + result, format = openerp.report.render_report(cr, uid, ids, object, datas, context) if not result: tb = sys.exc_info() self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb) @@ -90,8 +90,7 @@ def exp_report(db, uid, object, ids, datas=None, context=None): def go(id, uid, ids, datas, context): cr = openerp.pooler.get_db(db).cursor() try: - obj = openerp.netsvc.LocalService('report.'+object, cursor=cr) - (result, format) = obj.create(cr, uid, ids, datas, context) + result, format = openerp.report.render_report(cr, uid, ids, object, datas, context) if not result: tb = sys.exc_info() self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb) diff --git a/openerp/tools/test_reports.py b/openerp/tools/test_reports.py index 71cedc1a98d..ccb9c839dc9 100644 --- a/openerp/tools/test_reports.py +++ b/openerp/tools/test_reports.py @@ -26,6 +26,7 @@ """ import openerp.netsvc as netsvc +import openerp.report import openerp.tools as tools import logging import openerp.pooler as pooler @@ -50,7 +51,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None): else: rname_s = rname _logger.log(netsvc.logging.TEST, " - Trying %s.create(%r)", rname, ids) - res = netsvc.LocalService(rname, cursor=cr).create(cr, uid, ids, data, context) + res = openerp.report.render_report(cr, uid, ids, rname_s, data, context) if not isinstance(res, tuple): raise RuntimeError("Result of %s.create() should be a (data,format) tuple, now it is a %s" % \ (rname, type(res))) From 575771f6519aba14b8073a79408731d3faadbecb Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 14:36:37 +0100 Subject: [PATCH 03/24] [FIX] ir_actions: wrong namespace. bzr revid: vmt@openerp.com-20130222133637-14d903ci0hvwej5j --- openerp/addons/base/ir/ir_actions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 71170f42e91..8929c13489c 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -138,7 +138,7 @@ class report_xml(osv.osv): # raise Exception, "Unhandled report type: %s" % r pass if new_report is None: - new_report = interface.report_int._reports['report.' + name] + new_report = openerp.report.interface.report_int._reports['report.' + name] return new_report.create(cr, uid, ids, data, context) From 1ce0db171dbb3c383d300dc705a607e1705fdc96 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 14:40:12 +0100 Subject: [PATCH 04/24] [DOC] changelog: give a better hint at how LocalService() can be replaced. bzr revid: vmt@openerp.com-20130222134012-n8zg5s3jud08me18 --- doc/changelog.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index ec75fadfe6b..bb18944b514 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -7,7 +7,8 @@ Changelog ------- - Almost removed ``LocalService()``. For reports, - ``openerp.report.render_report()`` can be used. + ``openerp.report.render_report()`` can be used. For workflows, see + :ref:`orm-workflows`. - Added the :ref:`Long polling ` worker type. - Added :ref:`orm-workflows` to the ORM. - Added :ref:`routing-decorators` to the RPC and WSGI stack. From 460cc6f755899ef45c09c17dc6e66cfea04e4eaf Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 15:24:00 +0100 Subject: [PATCH 05/24] [IMP] ir.actions.report.xml: allow for a smoother transition for reports still declared the old way (in Python). bzr revid: vmt@openerp.com-20130222142400-qoomw17s2u8a73kh --- openerp/addons/base/ir/ir_actions.py | 42 +++++++++++++++------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 8929c13489c..5bb70ed4cf1 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -118,27 +118,29 @@ class report_xml(osv.osv): import os opj = os.path.join - cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name,)) - new_report = None - for r in cr.dictfetchall(): - if r['report_rml'] or r['report_rml_content_data']: - if r['parser']: - kwargs = { 'parser': operator.attrgetter(r['parser'])(openerp.addons) } - else: - kwargs = {} - new_report = report_sxw('report.'+r['report_name'], r['model'], - opj('addons',r['report_rml'] or '/'), header=r['header'], register=False, **kwargs) - elif r['report_xsl']: - new_report = report_rml('report.'+r['report_name'], r['model'], - opj('addons',r['report_xml']), - r['report_xsl'] and opj('addons',r['report_xsl']), register=False) - else: - # TODO: - # Temporarily, we look reports up the _reports dict. - # raise Exception, "Unhandled report type: %s" % r - pass - if new_report is None: + # First lookup in the deprecated place, because if the report definition + # has not been updated, it is more likely the correct definition is there. + if 'report.' + name in openerp.report.interface.report_int._reports: new_report = openerp.report.interface.report_int._reports['report.' + name] + else: + cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name,)) + r = cr.dictfetchone() + if r: + if r['report_rml'] or r['report_rml_content_data']: + if r['parser']: + kwargs = { 'parser': operator.attrgetter(r['parser'])(openerp.addons) } + else: + kwargs = {} + new_report = report_sxw('report.'+r['report_name'], r['model'], + opj('addons',r['report_rml'] or '/'), header=r['header'], register=False, **kwargs) + elif r['report_xsl']: + new_report = report_rml('report.'+r['report_name'], r['model'], + opj('addons',r['report_xml']), + r['report_xsl'] and opj('addons',r['report_xsl']), register=False) + else: + raise Exception, "Unhandled report type: %s" % r + else: + raise Exception, "Required report does not exist: %s" % r return new_report.create(cr, uid, ids, data, context) From efb97705f571e74e61084fe6c3afc5c8d6697db1 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 15:52:26 +0100 Subject: [PATCH 06/24] [IMP] LocalService(): re-allow for a few moment (so addons can be updated a bit later). bzr revid: vmt@openerp.com-20130222145226-dqu6e612oi3yalow --- openerp/netsvc.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/openerp/netsvc.py b/openerp/netsvc.py index aab166ab4c2..3620cbd0525 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -46,10 +46,14 @@ import openerp _logger = logging.getLogger(__name__) -# TODO LocalService is deprecated. -def LocalService(name, cursor=None): - assert name == 'workflow' - return openerp.workflow +def LocalService(name): + _logger.warning("LocalService() is deprecated.") + + if name == 'workflow': + return openerp.workflow + + if name.startswith('report.'): + return openerp.report.interface.report_int._reports[name] BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10) #The background is set with 40 plus the number of the color, and the foreground with 30 From ef127fddc7676e616cd6a256c448382fc7861cb3 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 15:52:50 +0100 Subject: [PATCH 07/24] [IMP] netsvc: removed unused import. bzr revid: vmt@openerp.com-20130222145250-qd9v52tu2xt8jyb2 --- openerp/modules/graph.py | 2 -- openerp/modules/migration.py | 2 -- openerp/osv/orm.py | 1 - openerp/service/report.py | 1 - openerp/tools/test_reports.py | 7 +++---- 5 files changed, 3 insertions(+), 10 deletions(-) diff --git a/openerp/modules/graph.py b/openerp/modules/graph.py index 56b17e3239a..0e14480d8ac 100644 --- a/openerp/modules/graph.py +++ b/openerp/modules/graph.py @@ -36,8 +36,6 @@ from openerp.tools.safe_eval import safe_eval as eval import openerp.pooler as pooler from openerp.tools.translate import _ -import openerp.netsvc as netsvc - import zipfile import openerp.release as release diff --git a/openerp/modules/migration.py b/openerp/modules/migration.py index e0faa77c3a4..16de56879b9 100644 --- a/openerp/modules/migration.py +++ b/openerp/modules/migration.py @@ -36,8 +36,6 @@ from openerp.tools.safe_eval import safe_eval as eval import openerp.pooler as pooler from openerp.tools.translate import _ -import openerp.netsvc as netsvc - import zipfile import openerp.release as release diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index e4a5a5435fd..d23663fb700 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -59,7 +59,6 @@ from lxml import etree import fields import openerp -import openerp.netsvc as netsvc import openerp.tools as tools from openerp.tools.config import config from openerp.tools.misc import CountingStream diff --git a/openerp/service/report.py b/openerp/service/report.py index 5144a064b1e..73d8d6a7e3d 100644 --- a/openerp/service/report.py +++ b/openerp/service/report.py @@ -5,7 +5,6 @@ import logging import sys import threading -import openerp.netsvc import openerp.pooler import openerp.report from openerp import tools diff --git a/openerp/tools/test_reports.py b/openerp/tools/test_reports.py index ccb9c839dc9..3fd1ba2fed4 100644 --- a/openerp/tools/test_reports.py +++ b/openerp/tools/test_reports.py @@ -25,7 +25,6 @@ through the code of yaml tests. """ -import openerp.netsvc as netsvc import openerp.report import openerp.tools as tools import logging @@ -50,7 +49,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None): rname_s = rname[7:] else: rname_s = rname - _logger.log(netsvc.logging.TEST, " - Trying %s.create(%r)", rname, ids) + _logger.log(logging.TEST, " - Trying %s.create(%r)", rname, ids) res = openerp.report.render_report(cr, uid, ids, rname_s, data, context) if not isinstance(res, tuple): raise RuntimeError("Result of %s.create() should be a (data,format) tuple, now it is a %s" % \ @@ -93,7 +92,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None): _logger.warning("Report %s produced a \"%s\" chunk, cannot examine it", rname, res_format) return False - _logger.log(netsvc.logging.TEST, " + Report %s produced correctly.", rname) + _logger.log(logging.TEST, " + Report %s produced correctly.", rname) return True def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, @@ -127,7 +126,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, pool = pooler.get_pool(cr.dbname) def log_test(msg, *args): - _logger.log(netsvc.logging.TEST, " - " + msg, *args) + _logger.log(logging.TEST, " - " + msg, *args) datas = {} if active_model: From 48d1bce6ec4fd77a98923b7132e718b33cafadd8 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 16:13:11 +0100 Subject: [PATCH 08/24] [IMP] report: remove the print statement upon report registration. bzr revid: vmt@openerp.com-20130222151311-xz609m3o5jazo7ld --- openerp/report/interface.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openerp/report/interface.py b/openerp/report/interface.py index 6c5fc24b559..d6d90b17d42 100644 --- a/openerp/report/interface.py +++ b/openerp/report/interface.py @@ -45,10 +45,8 @@ class report_int(object): def __init__(self, name, register=True): if register: - print "*** Registering report `%s` but it should be registered trough data declaration instead. ***" % name - if not name.startswith('report.'): - raise Exception('ConceptionError, bad report name, should start with "report."') - assert name not in self._reports, 'The report "%s" already exists!' % name + assert name.startswith('report.'), 'Report names should start with "report.".' + assert name not in self._reports, 'The report "%s" already exists.' % name self._reports[name] = self else: # The report is instanciated at each use site, which is ok. From a2f5e9d201f94938d432174d869b1a662f6b1093 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 16:17:02 +0100 Subject: [PATCH 09/24] [IMP] ir_actions: removed forgotten print statements. bzr revid: vmt@openerp.com-20130222151702-d73geh539mb99m5b --- openerp/addons/base/ir/ir_actions.py | 3 --- openerp/netsvc.py | 3 --- 2 files changed, 6 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 5bb70ed4cf1..bfef042ef57 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -96,11 +96,8 @@ class report_xml(osv.osv): result = cr.dictfetchall() reports = openerp.report.interface.report_int._reports for r in result: - print ">>> Registering:", r['report_name'], "...", if reports.has_key('report.'+r['report_name']): - print " Already present." continue - print " Done." if r['report_rml'] or r['report_rml_content_data']: report_sxw('report.'+r['report_name'], r['model'], opj('addons',r['report_rml'] or '/'), header=r['header']) diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 3620cbd0525..94e1664c852 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -21,12 +21,9 @@ ############################################################################## -import errno import logging import logging.handlers -import operator import os -import platform import release import sys import threading From 687fc9afac3cab2d765f3bae65772430588d9abd Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Feb 2013 16:36:49 +0100 Subject: [PATCH 10/24] [DOC] report. bzr revid: vmt@openerp.com-20130222153649-h4quh4r8ptz465s1 --- doc/03_module_dev.rst | 1 + doc/report-declaration.rst | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 doc/report-declaration.rst diff --git a/doc/03_module_dev.rst b/doc/03_module_dev.rst index 72f035be4d0..c5f965e4b93 100644 --- a/doc/03_module_dev.rst +++ b/doc/03_module_dev.rst @@ -13,3 +13,4 @@ Modules 03_module_dev_04 03_module_dev_05 03_module_dev_06 + report-declaration diff --git a/doc/report-declaration.rst b/doc/report-declaration.rst new file mode 100644 index 00000000000..2a40c96ec61 --- /dev/null +++ b/doc/report-declaration.rst @@ -0,0 +1,23 @@ +.. _report-declaration: + +Report declaration +================== + +.. versionadded:: 7.1 + +Before version 7.1, report declaration could be done in two different ways: +either via a ```` tag in XML, or via such a tag and a class +instanciation in a Python module. Instanciating a class in a Python module was +necessary when a custom parser was used. + +In version 7.1, the recommended way to register a report is to use only the +```` XML tag. The tag can now support an additional ``parser`` +attribute. The value for that attibute must be a fully-qualified class name, +without the leading ``openerp.addons.`` namespace. + +.. note:: + The rational to deprecate the manual class instanciation is to make all + reports visible in the database, have a unique way to declare reports + instead of two, and remove the need to maintain a registry of reports in + memory. + From 5c9b5e4ac352a59674ff7686d0c9cbc7163907ba Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 25 Feb 2013 14:35:32 +0100 Subject: [PATCH 11/24] [IMP] netsvc: slightly more explicit warning when using LocalService(). bzr revid: vmt@openerp.com-20130225133532-o3m2e6vvzcmdeziv --- openerp/netsvc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 94e1664c852..3b5ee2c835c 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -44,7 +44,7 @@ import openerp _logger = logging.getLogger(__name__) def LocalService(name): - _logger.warning("LocalService() is deprecated.") + _logger.warning("LocalService('%s') is deprecated." % name) if name == 'workflow': return openerp.workflow From b08d7ef6bd0f1b8a36d82e238d563a37c7fa9057 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Mar 2013 16:39:55 +0100 Subject: [PATCH 12/24] [REF] ir.actions.report.xml: register_all do not make sense any more: auto=True reports are looked up in the database for each rendering, so they do no have to be in the report registry any longer. auto=False reports will register themselves but at this point they can be updated to use the new `parser` XML attribute. bzr revid: vmt@openerp.com-20130322153955-s6nyux2pyez6c01w --- openerp/addons/base/ir/ir_actions.py | 22 +--------------------- openerp/modules/registry.py | 1 - 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 9a76d5c28fc..b32617d0134 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -85,27 +85,6 @@ class report_xml(osv.osv): res[report.id] = False return res - def register_all(self, cr): - """Report registration handler that may be overridden by subclasses to - add their own kinds of report services. - Loads all reports with no manual loaders (auto==True) and - registers the appropriate services to implement them. - """ - opj = os.path.join - cr.execute("SELECT * FROM ir_act_report_xml WHERE auto=%s ORDER BY id", (True,)) - result = cr.dictfetchall() - reports = openerp.report.interface.report_int._reports - for r in result: - if reports.has_key('report.'+r['report_name']): - continue - if r['report_rml'] or r['report_rml_content_data']: - report_sxw('report.'+r['report_name'], r['model'], - opj('addons',r['report_rml'] or '/'), header=r['header']) - if r['report_xsl']: - report_rml('report.'+r['report_name'], r['model'], - opj('addons',r['report_xml']), - r['report_xsl'] and opj('addons',r['report_xsl'])) - def render_report(self, cr, uid, ids, name, data, context=None): """ Look up a report definition and render the report for the provided IDs. @@ -117,6 +96,7 @@ class report_xml(osv.osv): # First lookup in the deprecated place, because if the report definition # has not been updated, it is more likely the correct definition is there. + # Only reports with custom parser sepcified in Python are still there. if 'report.' + name in openerp.report.interface.report_int._reports: new_report = openerp.report.interface.report_int._reports['report.' + name] else: diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py index b06c500a24c..89cb6143a59 100644 --- a/openerp/modules/registry.py +++ b/openerp/modules/registry.py @@ -225,7 +225,6 @@ class RegistryManager(object): try: Registry.setup_multi_process_signaling(cr) registry.do_parent_store(cr) - registry.get('ir.actions.report.xml').register_all(cr) cr.commit() finally: cr.close() From 010d8044fe40d3ed402dff0cf8b1c7306a92b00a Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Fri, 22 Mar 2013 17:22:51 +0100 Subject: [PATCH 13/24] [REF] ir.actions.report.xml: renamed ids to res_ids because those are not the self model IDs. bzr revid: vmt@openerp.com-20130322162251-j0f3eobpc6oh4il1 --- openerp/addons/base/ir/ir_actions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index b32617d0134..4b4ed6fe799 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -85,7 +85,7 @@ class report_xml(osv.osv): res[report.id] = False return res - def render_report(self, cr, uid, ids, name, data, context=None): + def render_report(self, cr, uid, res_ids, name, data, context=None): """ Look up a report definition and render the report for the provided IDs. """ @@ -119,7 +119,7 @@ class report_xml(osv.osv): else: raise Exception, "Required report does not exist: %s" % r - return new_report.create(cr, uid, ids, data, context) + return new_report.create(cr, uid, res_ids, data, context) _name = 'ir.actions.report.xml' _inherit = 'ir.actions.actions' From 6e43e6c4e1cc8da4b2cd1f6919ea43c79295686c Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 25 Mar 2013 13:33:59 +0100 Subject: [PATCH 14/24] [FIX] reports: now that _register_all() has been removed, LocalService() must be modified to do the lookup in the database too. bzr revid: vmt@openerp.com-20130325123359-szxx6a0n06tha70p --- openerp/addons/base/ir/ir_actions.py | 11 +++++++++-- openerp/netsvc.py | 18 +++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 4b4ed6fe799..1d717048b3f 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -85,9 +85,9 @@ class report_xml(osv.osv): res[report.id] = False return res - def render_report(self, cr, uid, res_ids, name, data, context=None): + def _lookup_report(self, cr, name): """ - Look up a report definition and render the report for the provided IDs. + Look up a report definition. """ import openerp import operator @@ -119,6 +119,13 @@ class report_xml(osv.osv): else: raise Exception, "Required report does not exist: %s" % r + return new_report + + def render_report(self, cr, uid, res_ids, name, data, context=None): + """ + Look up a report definition and render the report for the provided IDs. + """ + new_report = self._lookup_report(cr, name) return new_report.create(cr, uid, res_ids, data, context) _name = 'ir.actions.report.xml' diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 1e1cd887d1a..4ad2d24ddb2 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -44,13 +44,29 @@ import openerp _logger = logging.getLogger(__name__) def LocalService(name): + """ + The openerp.netsvc.LocalService() fucntion is deprecated. It still works + in two cases: workflows and reports. For workflows, instead of using + LocalService('workflow'), openerp.workflow should be used (better yet, + methods on openerp.osv.orm.Model should be used). For reports, + openerp.report.render_report() should be used (methods on the Model should + be provided too in the future). + """ _logger.warning("LocalService('%s') is deprecated." % name) if name == 'workflow': return openerp.workflow if name.startswith('report.'): - return openerp.report.interface.report_int._reports[name] + report = openerp.report.interface.report_int._reports.get(name) + if report: + return report + else: + dbname = getattr(threading.currentThread(), 'dbname', None) + if dbname: + registry = openerp.modules.registry.RegistryManager.get(dbname) + with registry.cursor() as cr: + return registry['ir.actions.report.xml']._lookup_report(cr, name[len('report.'):]) BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10) #The background is set with 40 plus the number of the color, and the foreground with 30 From 464af881bf9915514f21cbc03f0537ab7355a0e6 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 25 Mar 2013 14:12:45 +0100 Subject: [PATCH 15/24] [IMP] netsvc: LocalService deprecation now guarded via openerp.conf.deprecation. bzr revid: vmt@openerp.com-20130325131245-9o5uizn6v4r8irc3 --- openerp/conf/deprecation.py | 12 ++++++++++++ openerp/netsvc.py | 3 ++- openerp/report/report_sxw.py | 11 +++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/openerp/conf/deprecation.py b/openerp/conf/deprecation.py index 11399bef4fb..fec2fbbf224 100644 --- a/openerp/conf/deprecation.py +++ b/openerp/conf/deprecation.py @@ -26,6 +26,8 @@ additional code is needed throughout the core library. This module keeps track of those specific measures by providing variables that can be unset by the user to check if her code is future proof. +In a perfect world, all these variables are set to False, the corresponding +code removed, and thus these variables made unnecessary. """ # If True, the Python modules inside the openerp namespace are made available @@ -35,4 +37,14 @@ by the user to check if her code is future proof. # Change to False around 2013.02. open_openerp_namespace = False +# If True, openerp.netsvc.LocalService() can be used to lookup reports or to +# access openerp.workflow. +# Introduced around 2013.03. +# Among the related code: +# - The openerp.netsvc.LocalService() function. +# - The openerp.report.interface.report_int._reports dictionary. +# - The register attribute in openerp.report.report_sxw (and in its inheriting +# classes). +allow_local_service = True + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 4ad2d24ddb2..799fd74158b 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -52,7 +52,8 @@ def LocalService(name): openerp.report.render_report() should be used (methods on the Model should be provided too in the future). """ - _logger.warning("LocalService('%s') is deprecated." % name) + assert openerp.conf.deprecation.allow_local_service + _logger.warning("LocalService() is deprecated since march 2013 (it was called with '%s')." % name) if name == 'workflow': return openerp.workflow diff --git a/openerp/report/report_sxw.py b/openerp/report/report_sxw.py index 0e2a7e18edd..b0fb70513bb 100644 --- a/openerp/report/report_sxw.py +++ b/openerp/report/report_sxw.py @@ -388,6 +388,17 @@ class rml_parse(object): self.setCompany(objects[0].company_id) class report_sxw(report_rml, preprocess.report): + """ + The register=True kwarg has been added to help remove the + openerp.netsvc.LocalService() indirection and the related + openerp.report.interface.report_int._reports dictionary: + report_sxw registered in XML with auto=False are also registered in Python. + In that case, they are registered in the above dictionary. Since + registration is automatically done upon instanciation, and that + instanciation is needed before rendering, a way was needed to + instanciate-without-register a report. In the future, no report + should be registered in the above dictionary and it will be dropped. + """ def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False, register=True): report_rml.__init__(self, name, table, rml, '', register=register) self.name = name From 1ea66164f30437a176e72cdc453c307e7c66b3f5 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 25 Mar 2013 14:17:56 +0100 Subject: [PATCH 16/24] [IMP] report: registration deprecation now guarded via openerp.conf.deprecation. bzr revid: vmt@openerp.com-20130325131756-5bns19n20nar9ogs --- openerp/conf/deprecation.py | 9 +++++++-- openerp/report/interface.py | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/openerp/conf/deprecation.py b/openerp/conf/deprecation.py index fec2fbbf224..66ddfc441d4 100644 --- a/openerp/conf/deprecation.py +++ b/openerp/conf/deprecation.py @@ -43,8 +43,13 @@ open_openerp_namespace = False # Among the related code: # - The openerp.netsvc.LocalService() function. # - The openerp.report.interface.report_int._reports dictionary. -# - The register attribute in openerp.report.report_sxw (and in its inheriting -# classes). +# - The register attribute in openerp.report.interface.report_int (and in its +# inheriting classes). allow_local_service = True +# Applies for the register attribute in openerp.report.interface.report_int. +# See comments for allow_local_service above. +# Introduced around 2013.03. +allow_report_int_registration = True + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/report/interface.py b/openerp/report/interface.py index d6d90b17d42..2f3a89a913b 100644 --- a/openerp/report/interface.py +++ b/openerp/report/interface.py @@ -45,6 +45,8 @@ class report_int(object): def __init__(self, name, register=True): if register: + import openerp + assert openerp.conf.deprecation.allow_report_int_registration assert name.startswith('report.'), 'Report names should start with "report.".' assert name not in self._reports, 'The report "%s" already exists.' % name self._reports[name] = self From cea4c4ff8c10985cb8ba3aa2c915d305a97cb0dc Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 25 Mar 2013 14:48:36 +0100 Subject: [PATCH 17/24] [IMP] conf.deprecation: comment. bzr revid: vmt@openerp.com-20130325134836-0mlduchmvw8ken2o --- openerp/conf/deprecation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openerp/conf/deprecation.py b/openerp/conf/deprecation.py index 66ddfc441d4..41bd4f971d9 100644 --- a/openerp/conf/deprecation.py +++ b/openerp/conf/deprecation.py @@ -44,6 +44,7 @@ open_openerp_namespace = False # - The openerp.netsvc.LocalService() function. # - The openerp.report.interface.report_int._reports dictionary. # - The register attribute in openerp.report.interface.report_int (and in its +# - auto column in ir.actions.report.xml. # inheriting classes). allow_local_service = True From 2829882389f08ae3ea0e449ca1b5d835bbdc6144 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 25 Mar 2013 15:32:56 +0100 Subject: [PATCH 18/24] [IMP] orm: added a print_report() method. bzr revid: vmt@openerp.com-20130325143256-f8hw66j09310cgjo --- openerp/osv/orm.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index c6609592e00..69c7498c6b9 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -5155,6 +5155,15 @@ class BaseModel(object): get_xml_id = get_external_id _get_xml_ids = _get_external_ids + def print_report(self, cr, uid, ids, name, data, context=None): + """ + Render the report `name` for the given IDs. The report must be defined + for this model, not another. + """ + report = self.pool['ir.actions.report.xml']._lookup_report(cr, name) + assert self._name == report.table + return report.create(cr, uid, ids, data, context) + # Transience def is_transient(self): """ Return whether the model is transient. From 63222e389e75834e3986fd30ec9bb69f6ff9703d Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 25 Mar 2013 15:40:55 +0100 Subject: [PATCH 19/24] [DOC] changelog updated to mention the new print_report(). bzr revid: vmt@openerp.com-20130325144055-kmoixbn2e40vr3vu --- doc/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index 0080a66c176..59c4a6bced5 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -7,7 +7,7 @@ Changelog ------- - Almost removed ``LocalService()``. For reports, - ``openerp.report.render_report()`` can be used. For workflows, see + ``openerp.osv.orm.Model.print_report()`` can be used. For workflows, see :ref:`orm-workflows`. - Removed support for the ``NET-RPC`` protocol. - Added the :ref:`Long polling ` worker type. From 385491f46e990936b039c8749b18b8f8a9bcbc86 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 25 Mar 2013 15:48:33 +0100 Subject: [PATCH 20/24] [IMP] yaml_import: add openerp in the evaluation context. bzr revid: vmt@openerp.com-20130325144833-aos5t6x5bc8vi0ss --- openerp/tools/yaml_import.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index 3172caac1f4..2ce7fc0a99a 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -540,10 +540,18 @@ class YamlInterpreter(object): self.noupdate = node.noupdate def process_python(self, node): + import openerp python, statements = node.items()[0] model = self.get_model(python.model) statements = statements.replace("\r\n", "\n") - code_context = { 'model': model, 'cr': self.cr, 'uid': self.uid, 'log': self._log, 'context': self.context } + code_context = { + 'model': model, + 'cr': self.cr, + 'uid': self.uid, + 'log': self._log, + 'context': self.context, + 'openerp': openerp, + } code_context.update({'self': model}) # remove me when no !python block test uses 'self' anymore try: code_obj = compile(statements, self.filename, 'exec') From ce58e16138ab29d02ae972171b779c4fca5c82fd Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 27 Mar 2013 16:44:25 +0100 Subject: [PATCH 21/24] [REF] yaml_import: removed nested import openerp. bzr revid: vmt@openerp.com-20130327154425-uu1fa01tdhrjt8kn --- openerp/tools/yaml_import.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index 2ce7fc0a99a..662229541ad 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -5,6 +5,7 @@ import time # used to eval time.strftime expressions from datetime import datetime, timedelta import logging +import openerp import openerp.pooler as pooler import openerp.sql_db as sql_db import misc @@ -281,7 +282,6 @@ class YamlInterpreter(object): return record_dict def process_record(self, node): - import openerp.osv as osv record, fields = node.items()[0] model = self.get_model(record.model) @@ -540,7 +540,6 @@ class YamlInterpreter(object): self.noupdate = node.noupdate def process_python(self, node): - import openerp python, statements = node.items()[0] model = self.get_model(python.model) statements = statements.replace("\r\n", "\n") From de5c84c0e1a4d3a0ed2165e05b09c5354090ffdb Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 27 Mar 2013 16:47:14 +0100 Subject: [PATCH 22/24] [REF] removed nested import openerp. bzr revid: vmt@openerp.com-20130327154714-fa3k6gqtsmlt3vx6 --- openerp/addons/base/ir/ir_actions.py | 5 ++--- openerp/report/__init__.py | 4 ++-- openerp/report/interface.py | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 1d717048b3f..cbdddb4401c 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -20,11 +20,13 @@ ############################################################################## import logging +import operator import os import re from socket import gethostname import time +import openerp from openerp import SUPERUSER_ID from openerp import netsvc, tools from openerp.osv import fields, osv @@ -89,9 +91,6 @@ class report_xml(osv.osv): """ Look up a report definition. """ - import openerp - import operator - import os opj = os.path.join # First lookup in the deprecated place, because if the report definition diff --git a/openerp/report/__init__.py b/openerp/report/__init__.py index 647e6ba93a6..2cf01636806 100644 --- a/openerp/report/__init__.py +++ b/openerp/report/__init__.py @@ -19,6 +19,8 @@ # ############################################################################## +import openerp + import interface import print_xml import print_fnc @@ -30,12 +32,10 @@ import report_sxw import printscreen - def render_report(cr, uid, ids, name, data, context=None): """ Helper to call ``ir.actions.report.xml.render_report()``. """ - import openerp registry = openerp.modules.registry.RegistryManager.get(cr.dbname) return registry['ir.actions.report.xml'].render_report(cr, uid, ids, name, data, context) diff --git a/openerp/report/interface.py b/openerp/report/interface.py index 2f3a89a913b..39de2fc7a31 100644 --- a/openerp/report/interface.py +++ b/openerp/report/interface.py @@ -25,6 +25,7 @@ import re from lxml import etree import openerp.pooler as pooler +import openerp import openerp.tools as tools import openerp.modules import print_xml @@ -45,7 +46,6 @@ class report_int(object): def __init__(self, name, register=True): if register: - import openerp assert openerp.conf.deprecation.allow_report_int_registration assert name.startswith('report.'), 'Report names should start with "report.".' assert name not in self._reports, 'The report "%s" already exists.' % name From 92aace0c1340bdacd669c691bdba0dd50af0d46e Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 27 Mar 2013 16:53:53 +0100 Subject: [PATCH 23/24] [DOC] netsvc: typo in docstring. bzr revid: vmt@openerp.com-20130327155353-5eo7r95e7gbw9c4l --- openerp/netsvc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 799fd74158b..52984ccf29f 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -45,7 +45,7 @@ _logger = logging.getLogger(__name__) def LocalService(name): """ - The openerp.netsvc.LocalService() fucntion is deprecated. It still works + The openerp.netsvc.LocalService() function is deprecated. It still works in two cases: workflows and reports. For workflows, instead of using LocalService('workflow'), openerp.workflow should be used (better yet, methods on openerp.osv.orm.Model should be used). For reports, From 4613a97c0101cc906b4c75d10015d88bac7c72c5 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 27 Mar 2013 16:59:17 +0100 Subject: [PATCH 24/24] [REF] trolls.convert: missed an opportunity to reuse a beautiful association list. bzr revid: vmt@openerp.com-20130327155917-xaepclhoazgw51ef --- openerp/tools/convert.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index cf8633f7a82..aaa29f2f9d3 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -294,7 +294,8 @@ form: module.record_id""" % (xml_id,) res[dest] = rec.get(f,'').encode('utf8') assert res[dest], "Attribute %s of report is empty !" % (f,) for field,dest in (('rml','report_rml'),('file','report_rml'),('xml','report_xml'),('xsl','report_xsl'), - ('attachment','attachment'),('attachment_use','attachment_use'), ('usage','usage')): + ('attachment','attachment'),('attachment_use','attachment_use'), ('usage','usage'), + ('report_type', 'report_type'), ('parser', 'parser')): if rec.get(field): res[dest] = rec.get(field).encode('utf8') if rec.get('auto'): @@ -304,10 +305,6 @@ form: module.record_id""" % (xml_id,) res['report_sxw_content'] = sxw_content if rec.get('header'): res['header'] = eval(rec.get('header','False')) - if rec.get('report_type'): - res['report_type'] = rec.get('report_type') - if rec.get('parser'): - res['parser'] = rec.get('parser') res['multi'] = rec.get('multi') and eval(rec.get('multi','False'))