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/changelog.rst b/doc/changelog.rst index c85bf64273f..59c4a6bced5 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -6,6 +6,9 @@ Changelog `trunk` ------- +- Almost removed ``LocalService()``. For reports, + ``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. - Added :ref:`orm-workflows` to the ORM. 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. + diff --git a/openerp/__init__.py b/openerp/__init__.py index b9f4f71d76a..960890de0b6 100644 --- a/openerp/__init__.py +++ b/openerp/__init__.py @@ -53,5 +53,12 @@ multi_process = False # Is the server running with gevent. evented = False +def registry(database_name): + """ + Return the model registry for the given database. If the registry does not + exist yet, it is created on the fly. + """ + return modules.registry.RegistryManager.get(database_name) + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 3e29a0a9b97..cde6f6f9a91 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -20,19 +20,22 @@ ############################################################################## 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 import tools from openerp.osv import fields, osv import openerp.report.interface from openerp.report.report_sxw import report_sxw, report_rml from openerp.tools.config import config from openerp.tools.safe_eval import safe_eval as eval from openerp.tools.translate import _ +import openerp.workflow _logger = logging.getLogger(__name__) @@ -85,26 +88,45 @@ 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. + def _lookup_report(self, cr, name): + """ + Look up a report definition. """ 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'])) + + # 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: + 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 + + 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' _inherit = 'ir.actions.actions' @@ -140,6 +162,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', @@ -645,12 +668,11 @@ class actions_server(osv.osv): _logger.warning('Failed to send email to: %s', addresses) if action.state == 'trigger': - wf_service = netsvc.LocalService("workflow") model = action.wkf_model_id.model m2o_field_name = action.trigger_obj_id.name target_id = obj_pool.read(cr, uid, context.get('active_id'), [m2o_field_name])[m2o_field_name] target_id = target_id[0] if isinstance(target_id,tuple) else target_id - wf_service.trg_validate(uid, model, int(target_id), action.trigger_name, cr) + openerp.workflow.trg_validate(uid, model, int(target_id), action.trigger_name, cr) if action.state == 'sms': #TODO: set the user and password from the system 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/addons/base/ir/ir_cron.py b/openerp/addons/base/ir/ir_cron.py index d86eb10f3d8..c3f7ccc7dd2 100644 --- a/openerp/addons/base/ir/ir_cron.py +++ b/openerp/addons/base/ir/ir_cron.py @@ -123,7 +123,7 @@ class ir_cron(osv.osv): try: args = str2tuple(args) openerp.modules.registry.RegistryManager.check_registry_signaling(cr.dbname) - registry = openerp.pooler.get_pool(cr.dbname) + registry = openerp.registry(cr.dbname) model = registry.get(model_name) if model and hasattr(model, method_name): method = getattr(model, method_name) @@ -223,7 +223,7 @@ class ir_cron(osv.osv): _logger.debug('Starting job `%s`.', job['name']) job_cr = db.cursor() try: - registry = openerp.pooler.get_pool(db_name) + registry = openerp.registry(db_name) registry[cls._name]._process_job(job_cr, job, lock_cr) except Exception: _logger.exception('Unexpected exception while processing cron job %r', job) diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py index 5a3c40552f0..10fc5f82187 100644 --- a/openerp/addons/base/ir/ir_mail_server.py +++ b/openerp/addons/base/ir/ir_mail_server.py @@ -41,6 +41,8 @@ import openerp.tools as tools from openerp.loglevels import ustr _logger = logging.getLogger(__name__) +_test_logger = logging.getLogger('openerp.tests') + class MailDeliveryException(osv.except_osv): """Specific exception subclass for mail delivery errors""" @@ -411,7 +413,7 @@ class ir_mail_server(osv.osv): # Do not actually send emails in testing mode! if getattr(threading.currentThread(), 'testing', False): - _logger.log(logging.TEST, "skip sending email in test mode") + _test_logger.info("skip sending email in test mode") return message['Message-Id'] # Get SMTP Server Details from Mail Server diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index b6bb0c5e227..f0bacc1cd32 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -26,7 +26,7 @@ import types import openerp from openerp import SUPERUSER_ID -from openerp import netsvc, pooler, tools +from openerp import tools from openerp.osv import fields,osv from openerp.osv.orm import Model from openerp.tools.safe_eval import safe_eval as eval @@ -50,7 +50,7 @@ def _get_fields_type(self, cr, uid, context=None): def _in_modules(self, cr, uid, ids, field_name, arg, context=None): #pseudo-method used by fields.function in ir.model/ir.model.fields - module_pool = self.pool.get("ir.module.module") + module_pool = self.pool["ir.module.module"] installed_module_ids = module_pool.search(cr, uid, [('state','=','installed')]) installed_module_names = module_pool.read(cr, uid, installed_module_ids, ['name'], context=context) installed_modules = set(x['name'] for x in installed_module_names) @@ -71,7 +71,7 @@ class ir_model(osv.osv): res = dict.fromkeys(ids) for model in models: if self.pool.get(model.model): - res[model.id] = self.pool.get(model.model).is_transient() + res[model.id] = self.pool[model.model].is_transient() else: _logger.error('Missing model %s' % (model.model, )) return res @@ -91,7 +91,7 @@ class ir_model(osv.osv): models = self.browse(cr, uid, ids) res = {} for model in models: - res[model.id] = self.pool.get("ir.ui.view").search(cr, uid, [('model', '=', model.model)]) + res[model.id] = self.pool["ir.ui.view"].search(cr, uid, [('model', '=', model.model)]) return res _columns = { @@ -144,7 +144,7 @@ class ir_model(osv.osv): def _drop_table(self, cr, uid, ids, context=None): for model in self.browse(cr, uid, ids, context): - model_pool = self.pool.get(model.model) + model_pool = self.pool[model.model] cr.execute('select relkind from pg_class where relname=%s', (model_pool._table,)) result = cr.fetchone() if result and result[0] == 'v': @@ -168,7 +168,7 @@ class ir_model(osv.osv): if not context.get(MODULE_UNINSTALL_FLAG): # only reload pool for normal unlink. For module uninstall the # reload is done independently in openerp.modules.loading - pooler.restart_pool(cr.dbname) + openerp.modules.registry.RegistryManager.new(cr.dbname) return res @@ -193,8 +193,7 @@ class ir_model(osv.osv): field_name=vals['name'], field_state='manual', select=vals.get('select_level', '0')) - self.pool.get(vals['model'])._auto_init(cr, ctx) - #pooler.restart_pool(cr.dbname) + self.pool[vals['model']]._auto_init(cr, ctx) return res def instanciate(self, cr, user, model, context=None): @@ -298,7 +297,7 @@ class ir_model_fields(osv.osv): def _drop_column(self, cr, uid, ids, context=None): for field in self.browse(cr, uid, ids, context): - model = self.pool.get(field.model) + model = self.pool[field.model] cr.execute('select relkind from pg_class where relname=%s', (model._table,)) result = cr.fetchone() cr.execute("SELECT column_name FROM information_schema.columns WHERE table_name ='%s' and column_name='%s'" %(model._table, field.name)) @@ -323,7 +322,7 @@ class ir_model_fields(osv.osv): def create(self, cr, user, vals, context=None): if 'model_id' in vals: - model_data = self.pool.get('ir.model').browse(cr, user, vals['model_id']) + model_data = self.pool['ir.model'].browse(cr, user, vals['model_id']) vals['model'] = model_data.model if context is None: context = {} @@ -338,18 +337,18 @@ class ir_model_fields(osv.osv): if not vals['name'].startswith('x_'): raise except_orm(_('Error'), _("Custom fields must have a name that starts with 'x_' !")) - if vals.get('relation',False) and not self.pool.get('ir.model').search(cr, user, [('model','=',vals['relation'])]): + if vals.get('relation',False) and not self.pool['ir.model'].search(cr, user, [('model','=',vals['relation'])]): raise except_orm(_('Error'), _("Model %s does not exist!") % vals['relation']) if self.pool.get(vals['model']): - self.pool.get(vals['model']).__init__(self.pool, cr) + self.pool[vals['model']].__init__(self.pool, cr) #Added context to _auto_init for special treatment to custom field for select_level ctx = dict(context, field_name=vals['name'], field_state='manual', select=vals.get('select_level', '0'), update_custom_fields=True) - self.pool.get(vals['model'])._auto_init(cr, ctx) + self.pool[vals['model']]._auto_init(cr, ctx) return res @@ -498,7 +497,7 @@ class ir_model_constraint(Model): Delete PostgreSQL foreign keys and constraints tracked by this model. """ - if uid != SUPERUSER_ID and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"): + if uid != SUPERUSER_ID and not self.pool['ir.model.access'].check_groups(cr, uid, "base.group_system"): raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module'))) context = dict(context or {}) @@ -559,7 +558,7 @@ class ir_model_relation(Model): Delete PostgreSQL many2many relations tracked by this model. """ - if uid != SUPERUSER_ID and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"): + if uid != SUPERUSER_ID and not self.pool['ir.model.access'].check_groups(cr, uid, "base.group_system"): raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module'))) ids_set = set(ids) @@ -685,7 +684,7 @@ class ir_model_access(osv.osv): # TransientModel records have no access rights, only an implicit access rule if not self.pool.get(model_name): _logger.error('Missing model %s' % (model_name, )) - elif self.pool.get(model_name).is_transient(): + elif self.pool[model_name].is_transient(): return True # We check if a specific rule exists @@ -793,7 +792,7 @@ class ir_model_data(osv.osv): for model in result: try: - r = dict(self.pool.get(model).name_get(cr, uid, result[model].keys(), context=context)) + r = dict(self.pool[model].name_get(cr, uid, result[model].keys(), context=context)) for key,val in result[model].items(): result2[val] = r.get(key, False) except: @@ -867,7 +866,7 @@ class ir_model_data(osv.osv): def get_object(self, cr, uid, module, xml_id, context=None): """Returns a browsable record for the given module name and xml_id or raise ValueError if not found""" res_model, res_id = self.get_object_reference(cr, uid, module, xml_id) - result = self.pool.get(res_model).browse(cr, uid, res_id, context=context) + result = self.pool[res_model].browse(cr, uid, res_id, context=context) if not result.exists(): raise ValueError('No record found for unique ID %s.%s. It may have been deleted.' % (module, xml_id)) return result @@ -1001,7 +1000,7 @@ class ir_model_data(osv.osv): cr.execute('select * from ir_values where model=%s and key=%s and name=%s'+where,(model, key, name)) res = cr.fetchone() if not res: - ir_values_obj = pooler.get_pool(cr.dbname).get('ir.values') + ir_values_obj = openerp.registry(cr.dbname)['ir.values'] ir_values_obj.set(cr, uid, key, key2, name, models, value, replace, isobject, meta) elif xml_id: cr.execute('UPDATE ir_values set value=%s WHERE model=%s and key=%s and name=%s'+where,(value, model, key, name)) @@ -1020,7 +1019,7 @@ class ir_model_data(osv.osv): ids = self.search(cr, uid, [('module', 'in', modules_to_remove)]) - if uid != 1 and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"): + if uid != 1 and not self.pool['ir.model.access'].check_groups(cr, uid, "base.group_system"): raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module'))) context = dict(context or {}) @@ -1047,10 +1046,9 @@ class ir_model_data(osv.osv): wkf_todo.extend(cr.fetchall()) cr.execute("update wkf_transition set condition='True', group_id=NULL, signal=NULL,act_to=act_from,act_from=%s where act_to=%s", (res_id,res_id)) - wf_service = netsvc.LocalService("workflow") for model,res_id in wkf_todo: try: - wf_service.trg_write(uid, model, res_id, cr) + openerp.workflow.trg_write(uid, model, res_id, cr) except Exception: _logger.info('Unable to force processing of workflow for item %s@%s in order to leave activity to be deleted', res_id, model, exc_info=True) @@ -1063,7 +1061,7 @@ class ir_model_data(osv.osv): if model == 'ir.model.fields': # Don't remove the LOG_ACCESS_COLUMNS unless _log_access # has been turned off on the model. - field = self.pool.get(model).browse(cr, uid, [res_id], context=context)[0] + field = self.pool[model].browse(cr, uid, [res_id], context=context)[0] if field.name in openerp.osv.orm.LOG_ACCESS_COLUMNS and self.pool[field.model]._log_access: continue if field.name == 'id': @@ -1071,7 +1069,7 @@ class ir_model_data(osv.osv): _logger.info('Deleting %s@%s', res_id, model) try: cr.execute('SAVEPOINT record_unlink_save') - self.pool.get(model).unlink(cr, uid, [res_id], context=context) + self.pool[model].unlink(cr, uid, [res_id], context=context) except Exception: _logger.info('Unable to delete %s@%s', res_id, model, exc_info=True) cr.execute('ROLLBACK TO SAVEPOINT record_unlink_save') @@ -1084,8 +1082,8 @@ class ir_model_data(osv.osv): unlink_if_refcount((model, res_id) for model, res_id in to_unlink if model == 'ir.model.fields') - ir_model_relation = self.pool.get('ir.model.relation') - ir_module_module = self.pool.get('ir.module.module') + ir_model_relation = self.pool['ir.model.relation'] + ir_module_module = self.pool['ir.module.module'] modules_to_remove_ids = ir_module_module.search(cr, uid, [('name', 'in', modules_to_remove)]) relation_ids = ir_model_relation.search(cr, uid, [('module', 'in', modules_to_remove_ids)]) ir_model_relation._module_data_uninstall(cr, uid, relation_ids, context) @@ -1118,6 +1116,6 @@ class ir_model_data(osv.osv): for (model, res_id) in to_unlink: if self.pool.get(model): _logger.info('Deleting %s@%s', res_id, model) - self.pool.get(model).unlink(cr, uid, [res_id]) + self.pool[model].unlink(cr, uid, [res_id]) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/ir/workflow/workflow.py b/openerp/addons/base/ir/workflow/workflow.py index 46884c5035b..0ce951940a9 100644 --- a/openerp/addons/base/ir/workflow/workflow.py +++ b/openerp/addons/base/ir/workflow/workflow.py @@ -21,7 +21,7 @@ from openerp.osv import fields, osv from openerp.tools.translate import _ -from openerp import netsvc +import openerp.workflow class workflow(osv.osv): _name = "workflow" @@ -40,8 +40,7 @@ class workflow(osv.osv): def write(self, cr, user, ids, vals, context=None): if not context: context={} - wf_service = netsvc.LocalService("workflow") - wf_service.clear_cache(cr, user) + openerp.workflow.clear_cache(cr, user) return super(workflow, self).write(cr, user, ids, vals, context=context) def get_active_workitems(self, cr, uid, res, res_id, context=None): @@ -62,8 +61,7 @@ class workflow(osv.osv): def create(self, cr, user, vals, context=None): if not context: context={} - wf_service = netsvc.LocalService("workflow") - wf_service.clear_cache(cr, user) + openerp.workflow.clear_cache(cr, user) return super(workflow, self).create(cr, user, vals, context=context) workflow() diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index a0d1eedef2b..7e370e86f0e 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -39,7 +39,7 @@ except ImportError: from StringIO import StringIO # NOQA import openerp -from openerp import modules, pooler, tools, addons +from openerp import modules, tools, addons from openerp.modules.db import create_categories from openerp.tools.parse_version import parse_version from openerp.tools.translate import _ @@ -473,14 +473,14 @@ class module(osv.osv): function(cr, uid, ids, context=context) cr.commit() - _, pool = pooler.restart_pool(cr.dbname, update_module=True) + registry = openerp.modules.registry.RegistryManager.new(cr.dbname, update_module=True) - config = pool.get('res.config').next(cr, uid, [], context=context) or {} + config = registry['res.config'].next(cr, uid, [], context=context) or {} if config.get('type') not in ('ir.actions.act_window_close',): return config # reload the client; open the first available root menu - menu_obj = self.pool.get('ir.ui.menu') + menu_obj = registry['ir.ui.menu'] menu_ids = menu_obj.search(cr, uid, [('parent_id', '=', False)], context=context) return { 'type': 'ir.actions.client', diff --git a/openerp/addons/base/module/wizard/base_module_upgrade.py b/openerp/addons/base/module/wizard/base_module_upgrade.py index bd6b9b7640d..c081663d8ed 100644 --- a/openerp/addons/base/module/wizard/base_module_upgrade.py +++ b/openerp/addons/base/module/wizard/base_module_upgrade.py @@ -19,7 +19,7 @@ # ############################################################################## -from openerp import pooler +import openerp from openerp.osv import osv, fields from openerp.tools.translate import _ @@ -87,7 +87,7 @@ class base_module_upgrade(osv.osv_memory): ir_module.download(cr, uid, ids, context=context) cr.commit() # save before re-creating cursor below - pooler.restart_pool(cr.dbname, update_module=True) + openerp.modules.registry.RegistryManager.new(cr.dbname, update_module=True) ir_model_data = self.pool.get('ir.model.data') __, res_id = ir_model_data.get_object_reference(cr, uid, 'base', 'view_base_module_upgrade_install') diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index bfa9abe5607..1a5806ad93b 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -23,7 +23,7 @@ from operator import attrgetter import re import openerp -from openerp import pooler, SUPERUSER_ID +from openerp import SUPERUSER_ID from openerp.osv import osv, fields from openerp.tools import ustr from openerp.tools.translate import _ @@ -72,7 +72,7 @@ class res_config_configurable(osv.osv_memory): res['nodestroy'] = False return res # reload the client; open the first available root menu - menu_obj = self.pool.get('ir.ui.menu') + menu_obj = self.pool['ir.ui.menu'] menu_ids = menu_obj.search(cr, uid, [('parent_id', '=', False)], context=context) return { 'type': 'ir.actions.client', @@ -271,7 +271,7 @@ class res_config_installer(osv.osv_memory): :returns: a list of all installed modules in this installer :rtype: [browse_record] """ - modules = self.pool.get('ir.module.module') + modules = self.pool['ir.module.module'] selectable = [field for field in self._columns if type(self._columns[field]) is fields.boolean] @@ -353,7 +353,7 @@ class res_config_installer(osv.osv_memory): return fields def execute(self, cr, uid, ids, context=None): - modules = self.pool.get('ir.module.module') + modules = self.pool['ir.module.module'] to_install = list(self.modules_to_install( cr, uid, ids, context=context)) _logger.info('Selecting addons %s to install', to_install) @@ -363,7 +363,7 @@ class res_config_installer(osv.osv_memory): 'to install', ['uninstalled'], context=context) cr.commit() openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname) - new_db, self.pool = pooler.restart_pool(cr.dbname, update_module=True) + openerp.modules.registry.RegistryManager.new(cr.dbname, update_module=True) res_config_installer() @@ -455,8 +455,8 @@ class res_config_settings(osv.osv_memory): 'other': ['other_field', ...], } """ - ir_model_data = self.pool.get('ir.model.data') - ir_module = self.pool.get('ir.module.module') + ir_model_data = self.pool['ir.model.data'] + ir_module = self.pool['ir.module.module'] def ref(xml_id): mod, xml = xml_id.split('.', 1) return ir_model_data.get_object(cr, uid, mod, xml, context) @@ -478,7 +478,7 @@ class res_config_settings(osv.osv_memory): return {'default': defaults, 'group': groups, 'module': modules, 'other': others} def default_get(self, cr, uid, fields, context=None): - ir_values = self.pool.get('ir.values') + ir_values = self.pool['ir.values'] classified = self._get_classified_fields(cr, uid, context) res = super(res_config_settings, self).default_get(cr, uid, fields, context) @@ -505,8 +505,8 @@ class res_config_settings(osv.osv_memory): return res def execute(self, cr, uid, ids, context=None): - ir_values = self.pool.get('ir.values') - ir_module = self.pool.get('ir.module.module') + ir_values = self.pool['ir.values'] + ir_module = self.pool['ir.module.module'] classified = self._get_classified_fields(cr, uid, context) config = self.browse(cr, uid, ids[0], context) @@ -572,7 +572,7 @@ class res_config_settings(osv.osv_memory): def cancel(self, cr, uid, ids, context=None): # ignore the current record, and send the action to reopen the view - act_window = self.pool.get('ir.actions.act_window') + act_window = self.pool['ir.actions.act_window'] action_ids = act_window.search(cr, uid, [('res_model', '=', self._name)]) if action_ids: return act_window.read(cr, uid, action_ids[0], [], context=context) @@ -588,7 +588,7 @@ class res_config_settings(osv.osv_memory): if isinstance(ids, (int, long)): ids = [ids] - act_window = self.pool.get('ir.actions.act_window') + act_window = self.pool['ir.actions.act_window'] action_ids = act_window.search(cr, uid, [('res_model', '=', self._name)], context=context) name = self._name if action_ids: @@ -606,8 +606,8 @@ class res_config_settings(osv.osv_memory): - t[1]: long: id of the menuitem's action """ module_name, menu_xml_id = menu_xml_id.split('.') - dummy, menu_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, module_name, menu_xml_id) - ir_ui_menu = self.pool.get('ir.ui.menu').browse(cr, uid, menu_id, context=context) + dummy, menu_id = self.pool['ir.model.data'].get_object_reference(cr, uid, module_name, menu_xml_id) + ir_ui_menu = self.pool['ir.ui.menu'].browse(cr, uid, menu_id, context=context) return (ir_ui_menu.complete_name, ir_ui_menu.action.id) @@ -621,7 +621,7 @@ class res_config_settings(osv.osv_memory): """ model_name, field_name = full_field_name.rsplit('.', 1) - return self.pool.get(model_name).fields_get(cr, uid, allfields=[field_name], context=context)[field_name]['string'] + return self.pool[model_name].fields_get(cr, uid, allfields=[field_name], context=context)[field_name]['string'] def get_config_warning(self, cr, msg, context=None): """ @@ -652,7 +652,7 @@ class res_config_settings(osv.osv_memory): Cannot find any account journal of %s type for this company.\n\nYou can create one in the %%(menu:account.menu_account_config)s. """ - res_config_obj = pooler.get_pool(cr.dbname).get('res.config.settings') + res_config_obj = openerp.registry(cr.dbname)['res.config.settings'] regex_path = r'%\(((?:menu|field):[a-z_\.]*)\)s' # Process the message diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index d6e554b598d..aef2af80d5f 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -27,13 +27,13 @@ import re import openerp from openerp import SUPERUSER_ID -from openerp import pooler, tools +from openerp import tools from openerp.osv import osv, fields from openerp.tools.translate import _ class format_address(object): def fields_view_get_address(self, cr, uid, arch, context={}): - user_obj = self.pool.get('res.users') + user_obj = self.pool['res.users'] fmt = user_obj.browse(cr, SUPERUSER_ID, uid, context).company_id.country_id fmt = fmt and fmt.address_format layouts = { @@ -154,7 +154,7 @@ class res_partner_title(osv.osv): } def _lang_get(self, cr, uid, context=None): - lang_pool = self.pool.get('res.lang') + lang_pool = self.pool['res.lang'] ids = lang_pool.search(cr, uid, [], context=context) res = lang_pool.read(cr, uid, ids, ['code', 'name'], context) return [(r['code'], r['name']) for r in res] @@ -287,7 +287,7 @@ class res_partner(osv.osv, format_address): def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): if (not view_id) and (view_type=='form') and context and context.get('force_email', False): - view_id = self.pool.get('ir.model.data').get_object_reference(cr, user, 'base', 'view_partner_simple_form')[1] + view_id = self.pool['ir.model.data'].get_object_reference(cr, user, 'base', 'view_partner_simple_form')[1] res = super(res_partner,self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu) if view_type == 'form': res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context) @@ -299,7 +299,7 @@ class res_partner(osv.osv, format_address): 'tz': lambda self, cr, uid, ctx: ctx.get('tz', False), 'customer': True, 'category_id': _default_category, - 'company_id': lambda self, cr, uid, ctx: self.pool.get('res.company')._company_default_get(cr, uid, 'res.partner', context=ctx), + 'company_id': lambda self, cr, uid, ctx: self.pool['res.company']._company_default_get(cr, uid, 'res.partner', context=ctx), 'color': 0, 'is_company': False, 'type': 'default', @@ -336,12 +336,12 @@ class res_partner(osv.osv, format_address): def onchange_state(self, cr, uid, ids, state_id, context=None): if state_id: - country_id = self.pool.get('res.country.state').browse(cr, uid, state_id, context).country_id.id + country_id = self.pool['res.country.state'].browse(cr, uid, state_id, context).country_id.id return {'value':{'country_id':country_id}} return {} def _check_ean_key(self, cr, uid, ids, context=None): - for partner_o in pooler.get_pool(cr.dbname).get('res.partner').read(cr, uid, ids, ['ean13',]): + for partner_o in self.pool['res.partner'].read(cr, uid, ids, ['ean13',]): thisean=partner_o['ean13'] if thisean and thisean!='': if len(thisean)!=13: @@ -487,7 +487,7 @@ class res_partner(osv.osv, format_address): def email_send(self, cr, uid, ids, email_from, subject, body, on_error=''): while len(ids): - self.pool.get('ir.cron').create(cr, uid, { + self.pool['ir.cron'].create(cr, uid, { 'name': 'Send Partner Emails', 'user_id': uid, 'model': 'res.partner', @@ -523,12 +523,12 @@ class res_partner(osv.osv, format_address): if res: return res if not context.get('category_id', False): return False - return _('Partners: ')+self.pool.get('res.partner.category').browse(cr, uid, context['category_id'], context).name + return _('Partners: ')+self.pool['res.partner.category'].browse(cr, uid, context['category_id'], context).name def main_partner(self, cr, uid): ''' Return the id of the main partner ''' - model_data = self.pool.get('ir.model.data') + model_data = self.pool['ir.model.data'] return model_data.browse(cr, uid, model_data.search(cr, uid, [('module','=','base'), ('name','=','main_partner')])[0], diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index 4c1d1317e07..063996bec72 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -26,7 +26,7 @@ from lxml.builder import E import openerp from openerp import SUPERUSER_ID -from openerp import pooler, tools +from openerp import tools import openerp.exceptions from openerp.osv import fields,osv from openerp.osv.orm import browse_record @@ -98,7 +98,7 @@ class groups(osv.osv): raise osv.except_osv(_('Error'), _('The name of the group can not start with "-"')) res = super(groups, self).write(cr, uid, ids, vals, context=context) - self.pool.get('ir.model.access').call_cache_clearing_methods(cr) + self.pool['ir.model.access'].call_cache_clearing_methods(cr) return res groups() @@ -178,7 +178,7 @@ class res_users(osv.osv): partner.onchange_type method, but applied to the user object. """ partner_ids = [user.partner_id.id for user in self.browse(cr, uid, ids, context=context)] - return self.pool.get('res.partner').onchange_type(cr, uid, partner_ids, is_company, context=context) + return self.pool['res.partner'].onchange_type(cr, uid, partner_ids, is_company, context=context) def onchange_address(self, cr, uid, ids, use_parent_address, parent_id, context=None): """ Wrapper on the user.partner onchange_address, because some calls to the @@ -186,7 +186,7 @@ class res_users(osv.osv): partner.onchange_type method, but applied to the user object. """ partner_ids = [user.partner_id.id for user in self.browse(cr, uid, ids, context=context)] - return self.pool.get('res.partner').onchange_address(cr, uid, partner_ids, use_parent_address, parent_id, context=context) + return self.pool['res.partner'].onchange_address(cr, uid, partner_ids, use_parent_address, parent_id, context=context) def _check_company(self, cr, uid, ids, context=None): return all(((this.company_id in this.company_ids) or not this.company_ids) for this in self.browse(cr, uid, ids, context)) @@ -202,7 +202,7 @@ class res_users(osv.osv): def _get_company(self,cr, uid, context=None, uid2=False): if not uid2: uid2 = uid - user = self.pool.get('res.users').read(cr, uid, uid2, ['company_id'], context) + user = self.pool['res.users'].read(cr, uid, uid2, ['company_id'], context) company_id = user.get('company_id', False) return company_id and company_id[0] or False @@ -243,7 +243,7 @@ class res_users(osv.osv): 'company_id': _get_company, 'company_ids': _get_companies, 'groups_id': _get_group, - 'image': lambda self, cr, uid, ctx={}: self.pool.get('res.partner')._get_default_image(cr, uid, False, ctx, colorize=True), + 'image': lambda self, cr, uid, ctx={}: self.pool['res.partner']._get_default_image(cr, uid, False, ctx, colorize=True), } # User can write on a few of his own fields (but not his groups for example) @@ -266,7 +266,7 @@ class res_users(osv.osv): uid = SUPERUSER_ID result = super(res_users, self).read(cr, uid, ids, fields=fields, context=context, load=load) - canwrite = self.pool.get('ir.model.access').check(cr, uid, 'res.users', 'write', False) + canwrite = self.pool['ir.model.access'].check(cr, uid, 'res.users', 'write', False) if not canwrite: if isinstance(ids, (int, long)): result = override_password(result) @@ -291,8 +291,8 @@ class res_users(osv.osv): res = super(res_users, self).write(cr, uid, ids, values, context=context) # clear caches linked to the users - self.pool.get('ir.model.access').call_cache_clearing_methods(cr) - clear = partial(self.pool.get('ir.rule').clear_cache, cr) + self.pool['ir.model.access'].call_cache_clearing_methods(cr) + clear = partial(self.pool['ir.rule'].clear_cache, cr) map(clear, ids) db = cr.dbname if db in self._uid_cache: @@ -352,7 +352,7 @@ class res_users(osv.osv): return result def action_get(self, cr, uid, context=None): - dataobj = self.pool.get('ir.model.data') + dataobj = self.pool['ir.model.data'] data_id = dataobj._get_id(cr, SUPERUSER_ID, 'base', 'action_res_users_my') return dataobj.browse(cr, uid, data_id, context=context).res_id @@ -372,7 +372,7 @@ class res_users(osv.osv): if not password: return False user_id = False - cr = pooler.get_db(db).cursor() + cr = self.pool.db.cursor() try: # autocommit: our single update request will be performed atomically. # (In this way, there is no opportunity to have two transactions @@ -423,10 +423,10 @@ class res_users(osv.osv): # Successfully logged in as admin! # Attempt to guess the web base url... if user_agent_env and user_agent_env.get('base_location'): - cr = pooler.get_db(db).cursor() + cr = self.pool.db.cursor() try: base = user_agent_env['base_location'] - self.pool.get('ir.config_parameter').set_param(cr, uid, 'web.base.url', base) + self.pool['ir.config_parameter'].set_param(cr, uid, 'web.base.url', base) cr.commit() except Exception: _logger.exception("Failed to update web.base.url configuration parameter") @@ -442,7 +442,7 @@ class res_users(osv.osv): raise openerp.exceptions.AccessDenied() if self._uid_cache.get(db, {}).get(uid) == passwd: return - cr = pooler.get_db(db).cursor() + cr = self.pool.db.cursor() try: self.check_credentials(cr, uid, passwd) if self._uid_cache.has_key(db): @@ -690,7 +690,7 @@ class groups_view(osv.osv): def get_user_groups_view(self, cr, uid, context=None): try: - view = self.pool.get('ir.model.data').get_object(cr, SUPERUSER_ID, 'base', 'user_groups_view', context) + view = self.pool['ir.model.data'].get_object(cr, SUPERUSER_ID, 'base', 'user_groups_view', context) assert view and view._table_name == 'ir.ui.view' except Exception: view = False @@ -826,7 +826,7 @@ class users_view(osv.osv): def fields_get(self, cr, uid, allfields=None, context=None, write_access=True): res = super(users_view, self).fields_get(cr, uid, allfields, context, write_access) # add reified groups fields - for app, kind, gs in self.pool.get('res.groups').get_groups_by_application(cr, uid, context): + for app, kind, gs in self.pool['res.groups'].get_groups_by_application(cr, uid, context): if kind == 'selection': # selection group field tips = ['%s: %s' % (g.name, g.comment) for g in gs if g.comment] diff --git a/openerp/cli/server.py b/openerp/cli/server.py index dbb77d72ca6..9339e590b7c 100644 --- a/openerp/cli/server.py +++ b/openerp/cli/server.py @@ -95,7 +95,7 @@ def preload_registry(dbname): """ Preload a registry, and start the cron.""" try: update_module = True if openerp.tools.config['init'] or openerp.tools.config['update'] else False - db, registry = openerp.pooler.get_db_and_pool(dbname,update_module=update_module) + openerp.modules.registry.RegistryManager.new(dbname, update_module=update_module) except Exception: _logger.exception('Failed to initialize database `%s`.', dbname) @@ -103,8 +103,8 @@ def run_test_file(dbname, test_file): """ Preload a registry, possibly run a test file, and start the cron.""" try: config = openerp.tools.config - db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update']) - cr = db.cursor() + registry = openerp.modules.registry.RegistryManager.new(dbname, update_module=config['init'] or config['update']) + cr = registry.db.cursor() _logger.info('loading test file %s', test_file) openerp.tools.convert_yaml_import(cr, 'base', file(test_file), 'test', {}, 'test', True) cr.rollback() @@ -125,7 +125,8 @@ def export_translation(): fileformat = os.path.splitext(config["translate_out"])[-1][1:].lower() buf = file(config["translate_out"], "w") - cr = openerp.pooler.get_db(dbname).cursor() + registry = openerp.modules.registry.RegistryManager.new(dbname) + cr = registry.db.cursor() openerp.tools.trans_export(config["language"], config["translate_modules"] or ["all"], buf, fileformat, cr) cr.close() @@ -138,7 +139,8 @@ def import_translation(): context = {'overwrite': config["overwrite_existing_translations"]} dbname = config['db_name'] - cr = openerp.pooler.get_db(dbname).cursor() + registry = openerp.modules.registry.RegistryManager.new(dbname) + cr = registry.db.cursor() openerp.tools.trans_load( cr, config["translate_in"], config["language"], context=context) cr.commit() diff --git a/openerp/conf/deprecation.py b/openerp/conf/deprecation.py index 11399bef4fb..6064b52e9c5 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,25 @@ 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.interface.report_int (and in its +# - auto column in ir.actions.report.xml. +# 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 + +# If True, the functions in openerp.pooler can be used. +# Introduced around 2013.03 (actually they are deprecated since much longer +# but no warning was dispayed in the logs). +openerp_pooler = True + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: 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/loglevels.py b/openerp/loglevels.py index 3172a2b2042..fdb32d8d2f0 100644 --- a/openerp/loglevels.py +++ b/openerp/loglevels.py @@ -20,80 +20,14 @@ ############################################################################## import sys -import logging LOG_NOTSET = 'notset' LOG_DEBUG = 'debug' -LOG_TEST = 'test' LOG_INFO = 'info' LOG_WARNING = 'warn' LOG_ERROR = 'error' LOG_CRITICAL = 'critical' -logging.TEST = logging.INFO - 5 -logging.addLevelName(logging.TEST, 'TEST') - -_logger = logging.getLogger(__name__) - -class Logger(object): - def __init__(self): - _logger.warning( - "The netsvc.Logger API shouldn't be used anymore, please " - "use the standard `logging.getLogger` API instead.") - super(Logger, self).__init__() - - def notifyChannel(self, name, level, msg): - _logger.warning( - "notifyChannel API shouldn't be used anymore, please use " - "the standard `logging` module instead.") - from service import common - - log = logging.getLogger(__name__ + '.deprecated.' + ustr(name)) - - if level in [LOG_TEST] and not hasattr(log, level): - fct = lambda msg, *args, **kwargs: log.log(getattr(logging, level.upper()), msg, *args, **kwargs) - setattr(log, level, fct) - - - level_method = getattr(log, level) - - if isinstance(msg, Exception): - msg = exception_to_unicode(msg) - - try: - msg = ustr(msg).strip() - if level in (LOG_ERROR, LOG_CRITICAL): # and tools.config.get_misc('debug','env_info',False): - msg = common.exp_get_server_environment() + "\n" + msg - - result = msg.split('\n') - except UnicodeDecodeError: - result = msg.strip().split('\n') - try: - if len(result)>1: - for idx, s in enumerate(result): - level_method('[%02d]: %s' % (idx+1, s,)) - elif result: - level_method(result[0]) - except IOError: - # TODO: perhaps reset the logger streams? - #if logrotate closes our files, we end up here.. - pass - except Exception: - # better ignore the exception and carry on.. - pass - - def set_loglevel(self, level, logger=None): - if logger is not None: - log = logging.getLogger(str(logger)) - else: - log = logging.getLogger() - log.setLevel(logging.INFO) # make sure next msg is printed - log.info("Log level changed to %s" % logging.getLevelName(level)) - log.setLevel(level) - - def shutdown(self): - logging.shutdown() - # TODO get_encodings, ustr and exception_to_unicode were originally from tools.misc. # There are here until we refactor tools so that this module doesn't depends on tools. diff --git a/openerp/modules/graph.py b/openerp/modules/graph.py index 56b17e3239a..74f4e0db9ce 100644 --- a/openerp/modules/graph.py +++ b/openerp/modules/graph.py @@ -33,11 +33,8 @@ import openerp.osv as osv import openerp.tools as tools import openerp.tools.osutil as osutil 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/loading.py b/openerp/modules/loading.py index 07e5c28a925..73709055755 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -35,7 +35,6 @@ import openerp.modules.db import openerp.modules.graph import openerp.modules.migration import openerp.osv as osv -import openerp.pooler as pooler import openerp.tools as tools from openerp import SUPERUSER_ID @@ -44,6 +43,7 @@ from openerp.modules.module import initialize_sys_path, \ load_openerp_module, init_module_models, adapt_version _logger = logging.getLogger(__name__) +_test_logger = logging.getLogger('openerp.tests') def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=None, report=None): @@ -75,7 +75,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= _load_data(cr, module_name, idref, mode, 'test') return True except Exception: - _logger.exception( + _test_logger.exception( 'module %s: an exception occurred in a test', module_name) return False finally: @@ -96,7 +96,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= """ for filename in package.data[kind]: if kind == 'test': - _logger.log(logging.TEST, "module %s: loading %s", module_name, filename) + _test_logger.info("module %s: loading %s", module_name, filename) else: _logger.info("module %s: loading %s", module_name, filename) _, ext = os.path.splitext(filename) @@ -129,17 +129,17 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= processed_modules = [] loaded_modules = [] - pool = pooler.get_pool(cr.dbname) + registry = openerp.registry(cr.dbname) migrations = openerp.modules.migration.MigrationManager(cr, graph) _logger.debug('loading %d packages...', len(graph)) # Query manual fields for all models at once and save them on the registry # so the initialization code for each model does not have to do it # one model at a time. - pool.fields_by_model = {} + registry.fields_by_model = {} cr.execute('SELECT * FROM ir_model_fields WHERE state=%s', ('manual',)) for field in cr.dictfetchall(): - pool.fields_by_model.setdefault(field['model'], []).append(field) + registry.fields_by_model.setdefault(field['model'], []).append(field) # register, instantiate and initialize models for each modules for index, package in enumerate(graph): @@ -153,17 +153,17 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= migrations.migrate_module(package, 'pre') load_openerp_module(package.name) - models = pool.load(cr, package) + models = registry.load(cr, package) loaded_modules.append(package.name) if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'): init_module_models(cr, package.name, models) - pool._init_modules.add(package.name) + registry._init_modules.add(package.name) status['progress'] = float(index) / len(graph) # Can't put this line out of the loop: ir.module.module will be # registered by init_module_models() above. - modobj = pool.get('ir.module.module') + modobj = registry['ir.module.module'] if perform_checks: modobj.check(cr, SUPERUSER_ID, [module_id]) @@ -219,7 +219,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= # The query won't be valid for models created later (i.e. custom model # created after the registry has been loaded), so empty its result. - pool.fields_by_model = None + registry.fields_by_model = None cr.commit() @@ -258,7 +258,7 @@ def load_marked_modules(cr, graph, states, force, progressdict, report, loaded_m def load_modules(db, force_demo=False, status=None, update_module=False): # TODO status['progress'] reporting is broken: used twice (and reset each # time to zero) in load_module_graph, not fine-grained enough. - # It should be a method exposed by the pool. + # It should be a method exposed by the registry. initialize_sys_path() force = [] @@ -275,8 +275,9 @@ def load_modules(db, force_demo=False, status=None, update_module=False): if not tools.config['without_demo']: tools.config["demo"]['all'] = 1 - # This is a brand new pool, just created in pooler.get_db_and_pool() - pool = pooler.get_pool(cr.dbname) + # This is a brand new registry, just created in + # openerp.modules.registry.RegistryManger.new(). + registry = openerp.registry(cr.dbname) if 'base' in tools.config['update'] or 'all' in tools.config['update']: cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed')) @@ -290,7 +291,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): # processed_modules: for cleanup step after install # loaded_modules: to avoid double loading - report = pool._assertion_report + report = registry._assertion_report loaded_modules, processed_modules = load_module_graph(cr, graph, status, perform_checks=update_module, report=report) if tools.config['load_language']: @@ -299,7 +300,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): # STEP 2: Mark other modules to be loaded/updated if update_module: - modobj = pool.get('ir.module.module') + modobj = registry['ir.module.module'] if ('base' in tools.config['init']) or ('base' in tools.config['update']): _logger.info('updating modules list') modobj.update_list(cr, SUPERUSER_ID) @@ -341,13 +342,13 @@ def load_modules(db, force_demo=False, status=None, update_module=False): # load custom models cr.execute('select model from ir_model where state=%s', ('manual',)) for model in cr.dictfetchall(): - pool.get('ir.model').instanciate(cr, SUPERUSER_ID, model['model'], {}) + registry['ir.model'].instanciate(cr, SUPERUSER_ID, model['model'], {}) # STEP 4: Finish and cleanup installations if processed_modules: cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""") for (model, name) in cr.fetchall(): - model_obj = pool.get(model) + model_obj = registry.get(model) if model_obj and not model_obj.is_transient(): _logger.warning('The model %s has no access rules, consider adding one. E.g. access_%s,access_%s,model_%s,,1,1,1,1', model, model.replace('.', '_'), model.replace('.', '_'), model.replace('.', '_')) @@ -356,20 +357,20 @@ def load_modules(db, force_demo=False, status=None, update_module=False): # been replaced by owner-only access rights cr.execute("""select distinct mod.model, mod.name from ir_model_access acc, ir_model mod where acc.model_id = mod.id""") for (model, name) in cr.fetchall(): - model_obj = pool.get(model) + model_obj = registry.get(model) if model_obj and model_obj.is_transient(): _logger.warning('The transient model %s (%s) should not have explicit access rules!', model, name) cr.execute("SELECT model from ir_model") for (model,) in cr.fetchall(): - obj = pool.get(model) + obj = registry.get(model) if obj: obj._check_removed_columns(cr, log=True) else: _logger.warning("Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model) # Cleanup orphan records - pool.get('ir.model.data')._process_end(cr, SUPERUSER_ID, processed_modules) + registry['ir.model.data']._process_end(cr, SUPERUSER_ID, processed_modules) for kind in ('init', 'demo', 'update'): tools.config[kind] = {} @@ -403,12 +404,12 @@ def load_modules(db, force_demo=False, status=None, update_module=False): cr.execute("SELECT id FROM ir_module_module WHERE state=%s", ('to remove',)) mod_ids_to_remove = [x[0] for x in cr.fetchall()] if mod_ids_to_remove: - pool.get('ir.module.module').module_uninstall(cr, SUPERUSER_ID, mod_ids_to_remove) + registry['ir.module.module'].module_uninstall(cr, SUPERUSER_ID, mod_ids_to_remove) # Recursive reload, should only happen once, because there should be no # modules to remove next time cr.commit() _logger.info('Reloading registry once more after uninstalling modules') - return pooler.restart_pool(cr.dbname, force_demo, status, update_module) + return openerp.modules.registry.RegistryManger.new(cr.dbname, force_demo, status, update_module) if report.failures: _logger.error('At least one test failed when loading the modules.') @@ -416,7 +417,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): _logger.info('Modules loaded.') # STEP 7: call _register_hook on every model - for model in pool.models.values(): + for model in registry.models.values(): model._register_hook(cr) finally: diff --git a/openerp/modules/migration.py b/openerp/modules/migration.py index e0faa77c3a4..3dbc725109b 100644 --- a/openerp/modules/migration.py +++ b/openerp/modules/migration.py @@ -33,11 +33,8 @@ import openerp.osv as osv import openerp.tools as tools import openerp.tools.osutil as osutil 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/module.py b/openerp/modules/module.py index e71c1f1c519..cc7b5904c73 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -43,6 +43,7 @@ from cStringIO import StringIO import logging _logger = logging.getLogger(__name__) +_test_logger = logging.getLogger('openerp.tests') _ad = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'addons') # default addons path (base) ad_paths = [] @@ -503,7 +504,7 @@ def run_unit_tests(module_name): for m in ms: suite.addTests(unittest2.TestLoader().loadTestsFromModule(m)) if ms: - _logger.log(logging.TEST, 'module %s: executing %s `fast_suite` and/or `checks` sub-modules', module_name, len(ms)) + _test_logger.info('module %s: executing %s `fast_suite` and/or `checks` sub-modules', module_name, len(ms)) # Use a custom stream object to log the test executions. class MyStream(object): def __init__(self): @@ -518,7 +519,7 @@ def run_unit_tests(module_name): if not first: c = '` ' + c first = False - _logger.log(logging.TEST, c) + _test_logger.info(c) result = unittest2.TextTestRunner(verbosity=2, stream=MyStream()).run(suite) if result.wasSuccessful(): return True 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() diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 6b66830b75e..6929b7a9289 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -21,11 +21,9 @@ ############################################################################## -import errno import logging import logging.handlers import os -import platform import release import sys import threading @@ -38,20 +36,36 @@ try: except ImportError: psutil = None -# TODO modules that import netsvc only for things from loglevels must be changed to use loglevels. -from loglevels import * import tools import openerp _logger = logging.getLogger(__name__) def LocalService(name): - # Special case for addons support, will be removed in a few days when addons - # are updated to directly use openerp.osv.osv.service. + """ + 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, + openerp.report.render_report() should be used (methods on the Model should + be provided too in the future). + """ + 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 - return openerp.report.interface.report_int._reports[name] + if name.startswith('report.'): + 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 @@ -63,7 +77,6 @@ COLOR_PATTERN = "%s%s%%s%s" % (COLOR_SEQ, COLOR_SEQ, RESET_SEQ) LEVEL_COLOR_MAPPING = { logging.DEBUG: (BLUE, DEFAULT), logging.INFO: (GREEN, DEFAULT), - logging.TEST: (WHITE, BLUE), logging.WARNING: (YELLOW, DEFAULT), logging.ERROR: (RED, DEFAULT), logging.CRITICAL: (WHITE, RED), @@ -161,7 +174,6 @@ PSEUDOCONFIG_MAPPER = { 'debug_rpc': ['openerp:DEBUG','openerp.netsvc.rpc.request:DEBUG'], 'debug': ['openerp:DEBUG'], 'debug_sql': ['openerp.sql_db:DEBUG'], - 'test': ['openerp:TEST'], 'info': [], 'warn': ['openerp:WARNING'], 'error': ['openerp:ERROR'], 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. diff --git a/openerp/pooler.py b/openerp/pooler.py index 58cf4936b27..0df6f88c819 100644 --- a/openerp/pooler.py +++ b/openerp/pooler.py @@ -25,27 +25,36 @@ """ +import logging +import openerp.conf.deprecation from openerp.modules.registry import RegistryManager +_logger = logging.getLogger(__name__) def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False): """Create and return a database connection and a newly initialized registry.""" + assert openerp.conf.deprecation.openerp_pooler + _logger.warning('openerp.pooler.get_db_and_pool() is deprecated.') registry = RegistryManager.get(db_name, force_demo, status, update_module) return registry.db, registry def restart_pool(db_name, force_demo=False, status=None, update_module=False): """Delete an existing registry and return a database connection and a newly initialized registry.""" + _logger.warning('openerp.pooler.restart_pool() is deprecated.') + assert openerp.conf.deprecation.openerp_pooler registry = RegistryManager.new(db_name, force_demo, status, update_module) return registry.db, registry def get_db(db_name): """Return a database connection. The corresponding registry is initialized.""" + assert openerp.conf.deprecation.openerp_pooler return get_db_and_pool(db_name)[0] def get_pool(db_name, force_demo=False, status=None, update_module=False): """Return a model registry.""" + assert openerp.conf.deprecation.openerp_pooler return get_db_and_pool(db_name, force_demo, status, update_module)[1] # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/report/__init__.py b/openerp/report/__init__.py index 6b56f15b6b5..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,6 +32,13 @@ import report_sxw import printscreen +def render_report(cr, uid, ids, name, data, context=None): + """ + Helper to call ``ir.actions.report.xml.render_report()``. + """ + 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/report/custom.py b/openerp/report/custom.py index c3d0ff810b7..84634d1dc25 100644 --- a/openerp/report/custom.py +++ b/openerp/report/custom.py @@ -22,6 +22,7 @@ import os import time +import openerp import openerp.tools as tools from openerp.tools.safe_eval import safe_eval as eval import print_xml @@ -31,7 +32,6 @@ import common from openerp.osv.osv import except_osv from openerp.osv.orm import browse_null from openerp.osv.orm import browse_record_list -import openerp.pooler as pooler from pychart import * import misc import cStringIO @@ -127,22 +127,22 @@ class report_custom(report_int): def create(self, cr, uid, ids, datas, context=None): if not context: context={} - self.pool = pooler.get_pool(cr.dbname) - report = self.pool.get('ir.report.custom').browse(cr, uid, [datas['report_id']])[0] + self.pool = openerp.registry(cr.dbname) + report = self.pool['ir.report.custom'].browse(cr, uid, [datas['report_id']])[0] datas['model'] = report.model_id.model if report.menu_id: - ids = self.pool.get(report.model_id.model).search(cr, uid, []) + ids = self.pool[report.model_id.model].search(cr, uid, []) datas['ids'] = ids report_id = datas['report_id'] - report = self.pool.get('ir.report.custom').read(cr, uid, [report_id], context=context)[0] - fields = self.pool.get('ir.report.custom.fields').read(cr, uid, report['fields_child0'], context=context) + report = self.pool['ir.report.custom'].read(cr, uid, [report_id], context=context)[0] + fields = self.pool['ir.report.custom.fields'].read(cr, uid, report['fields_child0'], context=context) fields.sort(lambda x,y : x['sequence'] - y['sequence']) if report['field_parent']: - parent_field = self.pool.get('ir.model.fields').read(cr, uid, [report['field_parent'][0]], ['model']) - model_name = self.pool.get('ir.model').read(cr, uid, [report['model_id'][0]], ['model'], context=context)[0]['model'] + parent_field = self.pool['ir.model.fields'].read(cr, uid, [report['field_parent'][0]], ['model']) + model_name = self.pool['ir.model'].read(cr, uid, [report['model_id'][0]], ['model'], context=context)[0]['model'] fct = { 'id': lambda x: x, @@ -158,7 +158,7 @@ class report_custom(report_int): field_child = f['field_child'+str(i)] if field_child: row.append( - self.pool.get('ir.model.fields').read(cr, uid, [field_child[0]], ['name'], context=context)[0]['name'] + self.pool['ir.model.fields'].read(cr, uid, [field_child[0]], ['name'], context=context)[0]['name'] ) if f['fc'+str(i)+'_operande']: fct_name = 'id' @@ -171,7 +171,7 @@ class report_custom(report_int): cond.append(None) new_fields.append(row) new_cond.append(cond) - objs = self.pool.get(model_name).browse(cr, uid, ids) + objs = self.pool[model_name].browse(cr, uid, ids) # Group by groupby = None @@ -340,7 +340,7 @@ class report_custom(report_int): def _create_lines(self, cr, uid, ids, report, fields, results, context): - pool = pooler.get_pool(cr.dbname) + pool = openerp.registry(cr.dbname) pdf_string = cStringIO.StringIO() can = canvas.init(fname=pdf_string, format='pdf') @@ -371,7 +371,7 @@ class report_custom(report_int): for f in fields: field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0]) if field_id: - type = pool.get('ir.model.fields').read(cr, uid, [field_id],['ttype']) + type = pool['ir.model.fields'].read(cr, uid, [field_id],['ttype']) if type[0]['ttype'] == 'date': date_idx = idx fct[idx] = process_date[report['frequency']] @@ -444,7 +444,7 @@ class report_custom(report_int): def _create_bars(self, cr, uid, ids, report, fields, results, context): - pool = pooler.get_pool(cr.dbname) + pool = openerp.registry(cr.dbname) pdf_string = cStringIO.StringIO() can = canvas.init(fname=pdf_string, format='pdf') @@ -472,7 +472,7 @@ class report_custom(report_int): for f in fields: field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0]) if field_id: - type = pool.get('ir.model.fields').read(cr, uid, [field_id],['ttype']) + type = pool['ir.model.fields'].read(cr, uid, [field_id],['ttype']) if type[0]['ttype'] == 'date': date_idx = idx fct[idx] = process_date[report['frequency']] diff --git a/openerp/report/interface.py b/openerp/report/interface.py index f0de9631800..846172ef773 100644 --- a/openerp/report/interface.py +++ b/openerp/report/interface.py @@ -23,8 +23,10 @@ import os import re from lxml import etree -import openerp.pooler as pooler +import openerp + +import openerp import openerp.tools as tools import openerp.modules import print_xml @@ -43,11 +45,16 @@ 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: + 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 + else: + # The report is instanciated at each use site, which is ok. + pass + self.__name = name self.name = name @@ -65,8 +72,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 @@ -90,8 +97,8 @@ class report_rml(report_int): if report_type == 'raw': return xml, report_type rml = self.create_rml(cr, xml, uid, context) - pool = pooler.get_pool(cr.dbname) - ir_actions_report_xml_obj = pool.get('ir.actions.report.xml') + registry = openerp.registry(cr.dbname) + ir_actions_report_xml_obj = registry['ir.actions.report.xml'] report_xml_ids = ir_actions_report_xml_obj.search(cr, uid, [('report_name', '=', self.name[7:])], context=context) self.title = report_xml_ids and ir_actions_report_xml_obj.browse(cr,uid,report_xml_ids)[0].name or 'OpenERP Report' create_doc = self.generators[report_type] @@ -140,8 +147,8 @@ class report_rml(report_int): self.internal_header=True if not context: context={} - pool = pooler.get_pool(cr.dbname) - ir_translation_obj = pool.get('ir.translation') + registry = openerp.registry(cr.dbname) + ir_translation_obj = registry['ir.translation'] # In some case we might not use xsl ... if not self.xsl: diff --git a/openerp/report/print_xml.py b/openerp/report/print_xml.py index c2af0984c2e..f4191498aa8 100644 --- a/openerp/report/print_xml.py +++ b/openerp/report/print_xml.py @@ -20,11 +20,11 @@ ############################################################################## from lxml import etree +import openerp import openerp.tools as tools from openerp.tools.safe_eval import safe_eval import print_fnc from openerp.osv.orm import browse_null, browse_record -import openerp.pooler as pooler class InheritDict(dict): # Might be usefull when we're doing name lookup for call or eval. @@ -54,7 +54,7 @@ class document(object): def __init__(self, cr, uid, datas, func=False): # create a new document self.cr = cr - self.pool = pooler.get_pool(cr.dbname) + self.pool = openerp.registry(cr.dbname) self.func = func or {} self.datas = datas self.uid = uid @@ -134,8 +134,8 @@ class document(object): value = self.get_value(browser, attrs['name']) - ids = self.pool.get('ir.attachment').search(self.cr, self.uid, [('res_model','=',model),('res_id','=',int(value))]) - datas = self.pool.get('ir.attachment').read(self.cr, self.uid, ids) + ids = self.pool['ir.attachment'].search(self.cr, self.uid, [('res_model','=',model),('res_id','=',int(value))]) + datas = self.pool['ir.attachment'].read(self.cr, self.uid, ids) if len(datas): # if there are several, pick first @@ -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/printscreen/ps_form.py b/openerp/report/printscreen/ps_form.py index e585176d515..b3934457e2f 100644 --- a/openerp/report/printscreen/ps_form.py +++ b/openerp/report/printscreen/ps_form.py @@ -19,8 +19,8 @@ # ############################################################################## +import openerp from openerp.report.interface import report_int -import openerp.pooler as pooler import openerp.tools as tools from openerp.report import render @@ -55,8 +55,8 @@ class report_printscreen_list(report_int): if not context: context={} datas['ids'] = ids - pool = pooler.get_pool(cr.dbname) - model = pool.get(datas['model']) + registry = openerp.registry(cr.dbname) + model = registry[datas['model']] # title come from description of model which are specified in py file. self.title = model._description result = model.fields_view_get(cr, uid, view_type='form', context=context) diff --git a/openerp/report/printscreen/ps_list.py b/openerp/report/printscreen/ps_list.py index c26597c8cdf..fa6bd29a6a6 100644 --- a/openerp/report/printscreen/ps_list.py +++ b/openerp/report/printscreen/ps_list.py @@ -19,8 +19,8 @@ # ############################################################################## +import openerp from openerp.report.interface import report_int -import openerp.pooler as pooler import openerp.tools as tools from openerp.tools.safe_eval import safe_eval as eval from lxml import etree @@ -66,12 +66,12 @@ class report_printscreen_list(report_int): self.context = context self.groupby = context.get('group_by',[]) self.groupby_no_leaf = context.get('group_by_no_leaf',False) - pool = pooler.get_pool(cr.dbname) - model = pool.get(datas['model']) - model_id = pool.get('ir.model').search(cr, uid, [('model','=',model._name)]) + registry = openerp.registry(cr.dbname) + model = registry[datas['model']] + model_id = registry['ir.model'].search(cr, uid, [('model','=',model._name)]) model_desc = model._description if model_id: - model_desc = pool.get('ir.model').browse(cr, uid, model_id[0], context).name + model_desc = registry['ir.model'].browse(cr, uid, model_id[0], context).name self.title = model_desc datas['ids'] = ids result = model.fields_view_get(cr, uid, view_type='tree', context=context) @@ -134,8 +134,9 @@ class report_printscreen_list(report_int): _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,)) _append_node('report-header', title) - _append_node('company', pooler.get_pool(self.cr.dbname).get('res.users').browse(self.cr,uid,uid).company_id.name) - rpt_obj = pooler.get_pool(self.cr.dbname).get('res.users') + registry = openerp.registry(self.cr.dbname) + _append_node('company', registry['res.users'].browse(self.cr,uid,uid).company_id.name) + rpt_obj = registry['res.users'] rml_obj=report_sxw.rml_parse(self.cr, uid, rpt_obj._name,context) _append_node('header-date', str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M"))) l = [] diff --git a/openerp/report/render/rml2pdf/utils.py b/openerp/report/render/rml2pdf/utils.py index 273d5815609..75923e64081 100644 --- a/openerp/report/render/rml2pdf/utils.py +++ b/openerp/report/render/rml2pdf/utils.py @@ -131,14 +131,11 @@ def _process_text(self, txt): to_translate = tools.ustr(sps.pop(0)) result += tools.ustr(self.localcontext.get('translate', lambda x:x)(to_translate)) if sps: - try: - txt = None - expr = sps.pop(0) - txt = eval(expr, self.localcontext) - if txt and isinstance(txt, basestring): - txt = tools.ustr(txt) - except Exception: - pass + txt = None + expr = sps.pop(0) + txt = eval(expr, self.localcontext) + if txt and isinstance(txt, basestring): + txt = tools.ustr(txt) if isinstance(txt, basestring): result += txt elif txt and (txt is not None) and (txt is not False): diff --git a/openerp/report/report_sxw.py b/openerp/report/report_sxw.py index 325690205ef..fceb318401b 100644 --- a/openerp/report/report_sxw.py +++ b/openerp/report/report_sxw.py @@ -29,10 +29,11 @@ import time from interface import report_rml import preprocess import logging -import openerp.pooler as pooler import openerp.tools as tools import zipfile import common + +import openerp from openerp.osv.fields import float as float_field, function as function_field, datetime as datetime_field from openerp.tools.translate import _ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT @@ -152,8 +153,8 @@ class rml_parse(object): context={} self.cr = cr self.uid = uid - self.pool = pooler.get_pool(cr.dbname) - user = self.pool.get('res.users').browse(cr, uid, uid, context=context) + self.pool = openerp.registry(cr.dbname) + user = self.pool['res.users'].browse(cr, uid, uid, context=context) self.localcontext = { 'user': user, 'setCompany': self.setCompany, @@ -220,7 +221,7 @@ class rml_parse(object): model = 'ir.attachment' try : id = int(id) - res = self.pool.get(model).read(self.cr,self.uid,id) + res = self.pool[model].read(self.cr,self.uid,id) if field : return res[field] elif model =='ir.attachment' : @@ -237,7 +238,7 @@ class rml_parse(object): obj._context['lang'] = lang def _get_lang_dict(self): - pool_lang = self.pool.get('res.lang') + pool_lang = self.pool['res.lang'] lang = self.localcontext.get('lang', 'en_US') or 'en_US' lang_ids = pool_lang.search(self.cr,self.uid,[('code','=',lang)])[0] lang_obj = pool_lang.browse(self.cr,self.uid,lang_ids) @@ -252,7 +253,7 @@ class rml_parse(object): def get_digits(self, obj=None, f=None, dp=None): d = DEFAULT_DIGITS = 2 if dp: - decimal_precision_obj = self.pool.get('decimal.precision') + decimal_precision_obj = self.pool['decimal.precision'] ids = decimal_precision_obj.search(self.cr, self.uid, [('name', '=', dp)]) if ids: d = decimal_precision_obj.browse(self.cr, self.uid, ids)[0].digits @@ -323,7 +324,7 @@ class rml_parse(object): return res def display_address(self, address_browse_record): - return self.pool.get('res.partner')._display_address(self.cr, self.uid, address_browse_record) + return self.pool['res.partner']._display_address(self.cr, self.uid, address_browse_record) def repeatIn(self, lst, name,nodes_parent=False): ret_lst = [] @@ -334,7 +335,7 @@ class rml_parse(object): def _translate(self,text): lang = self.localcontext['lang'] if lang and text and not text.isspace(): - transl_obj = self.pool.get('ir.translation') + transl_obj = self.pool['ir.translation'] piece_list = self._transl_regex.split(text) for pn in range(len(piece_list)): if not self._transl_regex.match(piece_list[pn]): @@ -388,8 +389,19 @@ 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, '') + """ + 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 self.parser = parser self.header = header @@ -399,7 +411,7 @@ class report_sxw(report_rml, preprocess.report): self.internal_header=True def getObjects(self, cr, uid, ids, context): - table_obj = pooler.get_pool(cr.dbname).get(self.table) + table_obj = openerp.registry(cr.dbname)[self.table] return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context, fields_process=_fields_process) def create(self, cr, uid, ids, data, context=None): @@ -409,8 +421,8 @@ class report_sxw(report_rml, preprocess.report): context.update(internal_header=self.internal_header) # skip osv.fields.sanitize_binary_value() because we want the raw bytes in all cases context.update(bin_raw=True) - pool = pooler.get_pool(cr.dbname) - ir_obj = pool.get('ir.actions.report.xml') + registry = openerp.registry(cr.dbname) + ir_obj = registry['ir.actions.report.xml'] report_xml_ids = ir_obj.search(cr, uid, [('report_name', '=', self.name[7:])], context=context) if report_xml_ids: @@ -458,7 +470,7 @@ class report_sxw(report_rml, preprocess.report): def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None): if not context: context={} - pool = pooler.get_pool(cr.dbname) + registry = openerp.registry(cr.dbname) attach = report_xml.attachment if attach: objs = self.getObjects(cr, uid, ids, context) @@ -467,9 +479,9 @@ class report_sxw(report_rml, preprocess.report): aname = eval(attach, {'object':obj, 'time':time}) result = False if report_xml.attachment_use and aname and context.get('attachment_use', True): - aids = pool.get('ir.attachment').search(cr, uid, [('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)]) + aids = registry['ir.attachment'].search(cr, uid, [('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)]) if aids: - brow_rec = pool.get('ir.attachment').browse(cr, uid, aids[0]) + brow_rec = registry['ir.attachment'].browse(cr, uid, aids[0]) if not brow_rec.datas: continue d = base64.decodestring(brow_rec.datas) @@ -487,7 +499,7 @@ class report_sxw(report_rml, preprocess.report): # field. ctx = dict(context) ctx.pop('default_type', None) - pool.get('ir.attachment').create(cr, uid, { + registry['ir.attachment'].create(cr, uid, { 'name': aname, 'datas': base64.encodestring(result[0]), 'datas_fname': name, diff --git a/openerp/service/common.py b/openerp/service/common.py index 9b326fd07ca..d7d58c2850f 100644 --- a/openerp/service/common.py +++ b/openerp/service/common.py @@ -2,7 +2,6 @@ import logging -import openerp.pooler import openerp.release import openerp.tools @@ -40,7 +39,7 @@ def exp_login(db, login, password): return res or False def exp_authenticate(db, login, password, user_agent_env): - res_users = openerp.pooler.get_pool(db).get('res.users') + res_users = openerp.registry(db)['res.users'] return res_users.authenticate(db, login, password, user_agent_env) def exp_version(): diff --git a/openerp/service/db.py b/openerp/service/db.py index 7293e17c3c5..c440720b6fc 100644 --- a/openerp/service/db.py +++ b/openerp/service/db.py @@ -7,8 +7,8 @@ import os import threading import traceback +import openerp from openerp import SUPERUSER_ID -import openerp.pooler import openerp.release import openerp.sql_db import openerp.tools @@ -28,7 +28,7 @@ def _initialize_db(id, db_name, demo, lang, user_password): try: self_actions[id]['progress'] = 0 cr = openerp.sql_db.db_connect(db_name).cursor() - openerp.modules.db.initialize(cr) # TODO this should be removed as it is done by pooler.restart_pool. + openerp.modules.db.initialize(cr) # TODO this should be removed as it is done by RegistryManager.new(). openerp.tools.config['lang'] = lang cr.commit() finally: @@ -36,20 +36,20 @@ def _initialize_db(id, db_name, demo, lang, user_password): cr.close() cr = None - pool = openerp.pooler.restart_pool(db_name, demo, self_actions[id], - update_module=True)[1] + registry = openerp.modules.registry.RegistryManager.new( + db_name, demo, self_actions[id], update_module=True)[1] try: cr = openerp.sql_db.db_connect(db_name).cursor() if lang: - modobj = pool.get('ir.module.module') + modobj = registry['ir.module.module'] mids = modobj.search(cr, SUPERUSER_ID, [('state', '=', 'installed')]) modobj.update_translations(cr, SUPERUSER_ID, mids, lang) # update admin's password and lang values = {'password': user_password, 'lang': lang} - pool.get('res.users').write(cr, SUPERUSER_ID, [SUPERUSER_ID], values) + registry['res.users'].write(cr, SUPERUSER_ID, [SUPERUSER_ID], values) cr.execute('SELECT login, password FROM res_users ORDER BY login') self_actions[id].update(users=cr.dictfetchall(), clean=True) @@ -351,7 +351,7 @@ def exp_migrate_databases(databases): for db in databases: _logger.info('migrate database %s', db) openerp.tools.config['update']['base'] = True - openerp.pooler.restart_pool(db, force_demo=False, update_module=True) + openerp.modules.registry.RegistryManager.new(db, force_demo=False, update_module=True) return True # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/service/model.py b/openerp/service/model.py index 976af76bc93..79f0ace4f2b 100644 --- a/openerp/service/model.py +++ b/openerp/service/model.py @@ -61,7 +61,7 @@ def check(f): # callable. We need to find the right parameters to call # the orm._sql_message(self, cr, uid, ids, context) function, # or we skip.. - # our signature is f(osv_pool, dbname [,uid, obj, method, args]) + # our signature is f(registry, dbname [,uid, obj, method, args]) try: if args and len(args) > 1: # TODO self doesn't exist, but was already wrong before (it was not a registry but just the object_service. @@ -95,14 +95,14 @@ def check(f): return tr(src, 'code') try: - if openerp.pooler.get_pool(dbname)._init: + if openerp.registry(dbname)._init: raise openerp.exceptions.Warning('Currently, this database is not fully loaded and can not be used.') return f(dbname, *args, **kwargs) except IntegrityError, inst: - osv_pool = openerp.pooler.get_pool(dbname) - for key in osv_pool._sql_error.keys(): + registry = openerp.registry(dbname) + for key in registry._sql_error.keys(): if key in inst[0]: - raise openerp.osv.orm.except_orm(_('Constraint Error'), tr(osv_pool._sql_error[key], 'sql_constraint') or inst[0]) + raise openerp.osv.orm.except_orm(_('Constraint Error'), tr(registry._sql_error[key], 'sql_constraint') or inst[0]) if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION): msg = _('The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set') _logger.debug("IntegrityError", exc_info=True) @@ -116,7 +116,7 @@ def check(f): last_quote_begin = errortxt.rfind('"', 0, last_quote_end) model_name = table = errortxt[last_quote_begin+1:last_quote_end].strip() model = table.replace("_",".") - model_obj = osv_pool.get(model) + model_obj = registry.get(model) if model_obj: model_name = model_obj._description or model_obj._name msg += _('\n\n[object with reference: %s - %s]') % (model_name, model) @@ -129,7 +129,7 @@ def check(f): return wrapper def execute_cr(cr, uid, obj, method, *args, **kw): - object = openerp.pooler.get_pool(cr.dbname).get(obj) + object = openerp.registry(cr.dbname).get(obj) if not object: raise except_orm('Object Error', 'Object %s doesn\'t exist' % str(obj)) return getattr(object, method)(cr, uid, *args, **kw) @@ -140,7 +140,7 @@ def execute_kw(db, uid, obj, method, args, kw=None): @check def execute(db, uid, obj, method, *args, **kw): threading.currentThread().dbname = db - cr = openerp.pooler.get_db(db).cursor() + cr = openerp.registry(db).db.cursor() try: try: if method.startswith('_'): @@ -157,7 +157,7 @@ def execute(db, uid, obj, method, *args, **kw): return res def exec_workflow_cr(cr, uid, obj, signal, *args): - object = openerp.pooler.get_pool(cr.dbname).get(obj) + object = openerp.registry(cr.dbname).get(obj) if not object: raise except_orm('Object Error', 'Object %s doesn\'t exist' % str(obj)) res_id = args[0] @@ -165,7 +165,7 @@ def exec_workflow_cr(cr, uid, obj, signal, *args): @check def exec_workflow(db, uid, obj, signal, *args): - cr = openerp.pooler.get_db(db).cursor() + cr = openerp.registry(db).db.cursor() try: try: res = exec_workflow_cr(cr, uid, obj, signal, *args) diff --git a/openerp/service/report.py b/openerp/service/report.py index c20c7f0d7ec..370b11fc199 100644 --- a/openerp/service/report.py +++ b/openerp/service/report.py @@ -5,8 +5,8 @@ import logging import sys import threading -import openerp.netsvc -import openerp.pooler +import openerp +import openerp.report from openerp import tools import security @@ -49,10 +49,9 @@ def exp_render_report(db, uid, object, ids, datas=None, context=None): self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None} - cr = openerp.pooler.get_db(db).cursor() + cr = openerp.registry(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) @@ -88,10 +87,9 @@ def exp_report(db, uid, object, ids, datas=None, context=None): self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None} def go(id, uid, ids, datas, context): - cr = openerp.pooler.get_db(db).cursor() + cr = openerp.registry(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) diff --git a/openerp/service/security.py b/openerp/service/security.py index 849796da8bf..6f115b8030a 100644 --- a/openerp/service/security.py +++ b/openerp/service/security.py @@ -19,25 +19,20 @@ # ############################################################################## -import openerp.exceptions -import openerp.pooler as pooler -import openerp.tools as tools - +import openerp def login(db, login, password): - pool = pooler.get_pool(db) - user_obj = pool.get('res.users') - return user_obj.login(db, login, password) + res_users = openerp.registry(db)['res.users'] + return res_users.login(db, login, password) def check_super(passwd): - if passwd == tools.config['admin_passwd']: + if passwd == openerp.tools.config['admin_passwd']: return True else: raise openerp.exceptions.AccessDenied() def check(db, uid, passwd): - pool = pooler.get_pool(db) - user_obj = pool.get('res.users') - return user_obj.check(db, uid, passwd) + res_users = openerp.registry(db)['res.users'] + return res_users.check(db, uid, passwd) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/sql_db.py b/openerp/sql_db.py index 77c873b3482..c27784433c0 100644 --- a/openerp/sql_db.py +++ b/openerp/sql_db.py @@ -25,8 +25,6 @@ The PostgreSQL connector is a connectivity layer between the OpenERP code and the database, *not* a database abstraction toolkit. Database abstraction is what the ORM does, in fact. - -See also: the `pooler` module """ diff --git a/openerp/tools/config.py b/openerp/tools/config.py index fd2b46f325e..cc3c187c775 100644 --- a/openerp/tools/config.py +++ b/openerp/tools/config.py @@ -83,7 +83,7 @@ class configmanager(object): self.config_file = fname self.has_ssl = check_ssl() - self._LOGLEVELS = dict([(getattr(loglevels, 'LOG_%s' % x), getattr(logging, x)) for x in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'TEST', 'DEBUG', 'NOTSET')]) + self._LOGLEVELS = dict([(getattr(loglevels, 'LOG_%s' % x), getattr(logging, x)) for x in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET')]) version = "%s %s" % (release.description, release.version) self.parser = parser = optparse.OptionParser(version=version, option_class=MyOption) diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index 55ca1c1ce9c..cdcaff35b9e 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -29,7 +29,10 @@ import sys # for eval context: import time -import openerp.release as release + +import openerp +import openerp.release +import openerp.workflow import assertion_report @@ -47,7 +50,6 @@ except: from datetime import datetime, timedelta from lxml import etree import misc -import openerp.pooler as pooler from config import config from translate import _ @@ -77,7 +79,7 @@ def _ref(self, cr): return lambda x: self.id_get(cr, x) def _obj(pool, cr, uid, model_str, context=None): - model = pool.get(model_str) + model = pool[model_str] return lambda x: model.browse(cr, uid, x, context=context) def _get_idref(self, cr, uid, model_str, context, idref): @@ -85,7 +87,7 @@ def _get_idref(self, cr, uid, model_str, context, idref): time=time, DateTime=datetime, timedelta=timedelta, - version=release.major_version, + version=openerp.release.major_version, ref=_ref(self, cr), pytz=pytz) if len(model_str): @@ -124,10 +126,10 @@ def _eval_xml(self, node, pool, cr, uid, idref, context=None): if f_search: idref2 = _get_idref(self, cr, uid, f_model, context, idref) q = unsafe_eval(f_search, idref2) - ids = pool.get(f_model).search(cr, uid, q) + ids = pool[f_model].search(cr, uid, q) if f_use != 'id': - ids = map(lambda x: x[f_use], pool.get(f_model).read(cr, uid, ids, [f_use])) - _cols = pool.get(f_model)._columns + ids = map(lambda x: x[f_use], pool[f_model].read(cr, uid, ids, [f_use])) + _cols = pool[f_model]._columns if (f_name in _cols) and _cols[f_name]._type=='many2many': return ids f_val = False @@ -196,7 +198,7 @@ def _eval_xml(self, node, pool, cr, uid, idref, context=None): return_val = _eval_xml(self,n, pool, cr, uid, idref, context) if return_val is not None: args.append(return_val) - model = pool.get(node.get('model','')) + model = pool[node.get('model','')] method = node.get('name','') res = getattr(model, method)(cr, uid, *args) return res @@ -256,7 +258,7 @@ class xml_import(object): maximum one dot. They are used to refer to other modules ID, in the form: module.record_id""" % (xml_id,) if module != self.module: - modcnt = self.pool.get('ir.module.module').search_count(self.cr, self.uid, ['&', ('name', '=', module), ('state', 'in', ['installed'])]) + modcnt = self.pool['ir.module.module'].search_count(self.cr, self.uid, ['&', ('name', '=', module), ('state', 'in', ['installed'])]) assert modcnt == 1, """The ID "%s" refers to an uninstalled module""" % (xml_id,) if len(id) > 64: @@ -270,7 +272,7 @@ form: module.record_id""" % (xml_id,) if d_search: idref = _get_idref(self, cr, self.uid, d_model, context={}, idref={}) - ids = self.pool.get(d_model).search(cr, self.uid, unsafe_eval(d_search, idref)) + ids = self.pool[d_model].search(cr, self.uid, unsafe_eval(d_search, idref)) if d_id: try: ids.append(self.id_get(cr, d_id)) @@ -278,10 +280,10 @@ form: module.record_id""" % (xml_id,) # d_id cannot be found. doesn't matter in this case pass if ids: - self.pool.get(d_model).unlink(cr, self.uid, ids) + self.pool[d_model].unlink(cr, self.uid, ids) def _remove_ir_values(self, cr, name, value, model): - ir_values_obj = self.pool.get('ir.values') + ir_values_obj = self.pool['ir.values'] ir_value_ids = ir_values_obj.search(cr, self.uid, [('name','=',name),('value','=',value),('model','=',model)]) if ir_value_ids: ir_values_obj.unlink(cr, self.uid, ir_value_ids) @@ -294,7 +296,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,8 +307,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') res['multi'] = rec.get('multi') and eval(rec.get('multi','False')) @@ -324,14 +325,14 @@ form: module.record_id""" % (xml_id,) groups_value.append((4, group_id)) res['groups_id'] = groups_value - id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) + id = self.pool['ir.model.data']._update(cr, self.uid, "ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) self.idref[xml_id] = int(id) if not rec.get('menu') or eval(rec.get('menu','False')): keyword = str(rec.get('keyword', 'client_print_multi')) value = 'ir.actions.report.xml,'+str(id) replace = rec.get('replace', True) - self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, res['name'], [res['model']], value, replace=replace, isobject=True, xml_id=xml_id) + self.pool['ir.model.data'].ir_set(cr, self.uid, 'action', keyword, res['name'], [res['model']], value, replace=replace, isobject=True, xml_id=xml_id) elif self.mode=='update' and eval(rec.get('menu','False'))==False: # Special check for report having attribute menu=False on update value = 'ir.actions.report.xml,'+str(id) @@ -367,14 +368,14 @@ form: module.record_id""" % (xml_id,) groups_value.append((4, group_id)) res['groups_id'] = groups_value - id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.wizard", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) + id = self.pool['ir.model.data']._update(cr, self.uid, "ir.actions.wizard", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) self.idref[xml_id] = int(id) # ir_set if (not rec.get('menu') or eval(rec.get('menu','False'))) and id: keyword = str(rec.get('keyword','') or 'client_action_multi') value = 'ir.actions.wizard,'+str(id) replace = rec.get("replace",'') or True - self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, string, [model], value, replace=replace, isobject=True, xml_id=xml_id) + self.pool['ir.model.data'].ir_set(cr, self.uid, 'action', keyword, string, [model], value, replace=replace, isobject=True, xml_id=xml_id) elif self.mode=='update' and (rec.get('menu') and eval(rec.get('menu','False'))==False): # Special check for wizard having attribute menu=False on update value = 'ir.actions.wizard,'+str(id) @@ -389,7 +390,7 @@ form: module.record_id""" % (xml_id,) res = {'name': name, 'url': url, 'target':target} - id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.act_url", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) + id = self.pool['ir.model.data']._update(cr, self.uid, "ir.actions.act_url", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) self.idref[xml_id] = int(id) def _tag_act_window(self, cr, rec, data_node=None): @@ -489,7 +490,7 @@ form: module.record_id""" % (xml_id,) res['target'] = rec.get('target','') if rec.get('multi'): res['multi'] = rec.get('multi', False) - id = self.pool.get('ir.model.data')._update(cr, self.uid, 'ir.actions.act_window', self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) + id = self.pool['ir.model.data']._update(cr, self.uid, 'ir.actions.act_window', self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode) self.idref[xml_id] = int(id) if src_model: @@ -497,7 +498,7 @@ form: module.record_id""" % (xml_id,) keyword = rec.get('key2','').encode('utf-8') or 'client_action_relate' value = 'ir.actions.act_window,'+str(id) replace = rec.get('replace','') or True - self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, xml_id, [src_model], value, replace=replace, isobject=True, xml_id=xml_id) + self.pool['ir.model.data'].ir_set(cr, self.uid, 'action', keyword, xml_id, [src_model], value, replace=replace, isobject=True, xml_id=xml_id) # TODO add remove ir.model.data def _tag_ir_set(self, cr, rec, data_node=None): @@ -508,7 +509,7 @@ form: module.record_id""" % (xml_id,) f_name = field.get("name",'').encode('utf-8') f_val = _eval_xml(self,field,self.pool, cr, self.uid, self.idref) res[f_name] = f_val - self.pool.get('ir.model.data').ir_set(cr, self.uid, res['key'], res['key2'], res['name'], res['models'], res['value'], replace=res.get('replace',True), isobject=res.get('isobject', False), meta=res.get('meta',None)) + self.pool['ir.model.data'].ir_set(cr, self.uid, res['key'], res['key2'], res['name'], res['models'], res['value'], replace=res.get('replace',True), isobject=res.get('isobject', False), meta=res.get('meta',None)) def _tag_workflow(self, cr, rec, data_node=None): if self.isnoupdate(data_node) and self.mode != 'init': @@ -526,9 +527,7 @@ form: module.record_id""" % (xml_id,) id = _eval_xml(self, rec[0], self.pool, cr, self.uid, self.idref) uid = self.get_uid(cr, self.uid, data_node, rec) - import openerp.netsvc as netsvc - wf_service = netsvc.LocalService("workflow") - wf_service.trg_validate(uid, model, + openerp.workflow.trg_validate(uid, model, id, str(rec.get('action','')), cr) @@ -563,7 +562,7 @@ form: module.record_id""" % (xml_id,) else: # the menuitem does't exist but we are in branch (not a leaf) _logger.warning('Warning no ID for submenu %s of menu %s !', menu_elem, str(m_l)) - pid = self.pool.get('ir.ui.menu').create(cr, self.uid, {'parent_id' : pid, 'name' : menu_elem}) + pid = self.pool['ir.ui.menu'].create(cr, self.uid, {'parent_id' : pid, 'name' : menu_elem}) values['parent_id'] = pid else: # The parent attribute was specified, if non-empty determine its ID, otherwise @@ -657,14 +656,14 @@ form: module.record_id""" % (xml_id,) groups_value.append((4, group_id)) values['groups_id'] = groups_value - pid = self.pool.get('ir.model.data')._update(cr, self.uid, 'ir.ui.menu', self.module, values, rec_id, noupdate=self.isnoupdate(data_node), mode=self.mode, res_id=res and res[0] or False) + pid = self.pool['ir.model.data']._update(cr, self.uid, 'ir.ui.menu', self.module, values, rec_id, noupdate=self.isnoupdate(data_node), mode=self.mode, res_id=res and res[0] or False) if rec_id and pid: self.idref[rec_id] = int(pid) if rec.get('action') and pid: action = "ir.actions.%s,%d" % (a_type, a_id) - self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(pid))], action, True, True, xml_id=rec_id) + self.pool['ir.model.data'].ir_set(cr, self.uid, 'action', 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(pid))], action, True, True, xml_id=rec_id) return 'ir.ui.menu', pid def _assert_equals(self, f1, f2, prec=4): @@ -675,8 +674,7 @@ form: module.record_id""" % (xml_id,) return rec_model = rec.get("model",'').encode('ascii') - model = self.pool.get(rec_model) - assert model, "The model %s does not exist !" % (rec_model,) + model = self.pool[rec_model] rec_id = rec.get("id",'').encode('ascii') self._test_xml_id(rec_id) rec_src = rec.get("search",'').encode('utf8') @@ -692,7 +690,7 @@ form: module.record_id""" % (xml_id,) ids = [self.id_get(cr, rec_id)] elif rec_src: q = unsafe_eval(rec_src, eval_dict) - ids = self.pool.get(rec_model).search(cr, uid, q, context=context) + ids = self.pool[rec_model].search(cr, uid, q, context=context) if rec_src_count: count = int(rec_src_count) if len(ids) != count: @@ -737,8 +735,7 @@ form: module.record_id""" % (xml_id,) def _tag_record(self, cr, rec, data_node=None): rec_model = rec.get("model").encode('ascii') - model = self.pool.get(rec_model) - assert model, "The model %s does not exist !" % (rec_model,) + model = self.pool[rec_model] rec_id = rec.get("id",'').encode('ascii') rec_context = rec.get("context", None) if rec_context: @@ -752,7 +749,7 @@ form: module.record_id""" % (xml_id,) else: module = self.module rec_id2 = rec_id - id = self.pool.get('ir.model.data')._update_dummy(cr, self.uid, rec_model, module, rec_id2) + id = self.pool['ir.model.data']._update_dummy(cr, self.uid, rec_model, module, rec_id2) # check if the resource already existed at the last update if id: # if it existed, we don't update the data, but we need to @@ -785,11 +782,11 @@ form: module.record_id""" % (xml_id,) q = unsafe_eval(f_search, self.idref) field = [] assert f_model, 'Define an attribute model="..." in your .XML file !' - f_obj = self.pool.get(f_model) + f_obj = self.pool[f_model] # browse the objects searched s = f_obj.browse(cr, self.uid, f_obj.search(cr, self.uid, q)) # column definitions of the "local" object - _cols = self.pool.get(rec_model)._columns + _cols = self.pool[rec_model]._columns # if the current field is many2many if (f_name in _cols) and _cols[f_name]._type=='many2many': f_val = [(6, 0, map(lambda x: x[f_use], s))] @@ -815,7 +812,7 @@ form: module.record_id""" % (xml_id,) f_val = int(f_val) res[f_name] = f_val - id = self.pool.get('ir.model.data')._update(cr, self.uid, rec_model, self.module, res, rec_id or False, not self.isnoupdate(data_node), noupdate=self.isnoupdate(data_node), mode=self.mode, context=rec_context ) + id = self.pool['ir.model.data']._update(cr, self.uid, rec_model, self.module, res, rec_id or False, not self.isnoupdate(data_node), noupdate=self.isnoupdate(data_node), mode=self.mode, context=rec_context ) if rec_id: self.idref[rec_id] = int(id) if config.get('import_partial', False): @@ -830,7 +827,7 @@ form: module.record_id""" % (xml_id,) return res def model_id_get(self, cr, id_str): - model_data_obj = self.pool.get('ir.model.data') + model_data_obj = self.pool['ir.model.data'] mod = self.module if '.' in id_str: mod,id_str = id_str.split('.') @@ -857,7 +854,7 @@ form: module.record_id""" % (xml_id,) self.module = module self.cr = cr self.idref = idref - self.pool = pooler.get_pool(cr.dbname) + self.pool = openerp.registry(cr.dbname) self.uid = 1 if report is None: report = assertion_report.assertion_report() @@ -889,8 +886,6 @@ def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init', #remove folder path from model head, model = os.path.split(model) - pool = pooler.get_pool(cr.dbname) - input = cStringIO.StringIO(csvcontent) #FIXME reader = csv.reader(input, quotechar='"', delimiter=',') fields = reader.next() @@ -921,7 +916,9 @@ def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init', datas.append(map(misc.ustr, line)) except: _logger.error("Cannot import the line: %s", line) - result, rows, warning_msg, dummy = pool.get(model).import_data(cr, uid, fields, datas,mode, module, noupdate, filename=fname_partial) + + registry = openerp.registry(cr.dbname) + result, rows, warning_msg, dummy = registry[model].import_data(cr, uid, fields, datas,mode, module, noupdate, filename=fname_partial) if result < 0: # Report failed import and abort module install raise Exception(_('Module loading failed: file %s/%s could not be processed:\n %s') % (module, fname, warning_msg)) diff --git a/openerp/tools/mail.py b/openerp/tools/mail.py index 574d8c94f05..1fe22094831 100644 --- a/openerp/tools/mail.py +++ b/openerp/tools/mail.py @@ -24,13 +24,13 @@ import cgi import logging import lxml.html import lxml.html.clean as clean -import openerp.pooler as pooler import random import re import socket import threading import time +import openerp from openerp.loglevels import ustr _logger = logging.getLogger(__name__) @@ -325,13 +325,13 @@ def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=Non if not cr: db_name = getattr(threading.currentThread(), 'dbname', None) if db_name: - local_cr = cr = pooler.get_db(db_name).cursor() + local_cr = cr = openerp.registry(db_name).db.cursor() else: raise Exception("No database cursor found, please pass one explicitly") # Send Email try: - mail_server_pool = pooler.get_pool(cr.dbname).get('ir.mail_server') + mail_server_pool = openerp.registry(cr.dbname)['ir.mail_server'] res = False # Pack Message into MIME Object email_msg = mail_server_pool.build_email(email_from, email_to, subject, body, email_cc, email_bcc, reply_to, diff --git a/openerp/tools/test_reports.py b/openerp/tools/test_reports.py index 9ec4dab6cc3..874a8cced61 100644 --- a/openerp/tools/test_reports.py +++ b/openerp/tools/test_reports.py @@ -25,16 +25,18 @@ through the code of yaml tests. """ -import openerp.netsvc as netsvc +import openerp +import openerp.report import openerp.tools as tools import logging -import openerp.pooler as pooler from openerp.tools.safe_eval import safe_eval from subprocess import Popen, PIPE import os import tempfile _logger = logging.getLogger(__name__) +_test_logger = logging.getLogger('openerp.tests') + def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None): """ Try to render a report with contents of ids @@ -49,8 +51,8 @@ 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) - res = netsvc.LocalService(rname).create(cr, uid, ids, data, context) + _test_logger.info(" - 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" % \ (rname, type(res))) @@ -92,7 +94,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) + _test_logger.info(" + Report %s produced correctly.", rname) return True def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, @@ -123,10 +125,10 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, context = context.copy() # keep it local # TODO context fill-up - pool = pooler.get_pool(cr.dbname) + registry = openerp.registry(cr.dbname) def log_test(msg, *args): - _logger.log(netsvc.logging.TEST, " - " + msg, *args) + _test_logger.info(" - " + msg, *args) datas = {} if active_model: @@ -145,7 +147,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, raise ValueError('You cannot only specify action_id "%s" without a module name' % action_id) act_module = our_module act_xmlid = action_id - act_model, act_id = pool.get('ir.model.data').get_object_reference(cr, uid, act_module, act_xmlid) + act_model, act_id = registry['ir.model.data'].get_object_reference(cr, uid, act_module, act_xmlid) else: assert isinstance(action_id, (long, int)) act_model = 'ir.action.act_window' # assume that @@ -181,11 +183,11 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, log_test("will emulate a %s view: %s#%s", action['view_type'], datas['res_model'], view_id or '?') - view_res = pool.get(datas['res_model']).fields_view_get(cr, uid, view_id, action['view_type'], context) + view_res = registry[datas['res_model']].fields_view_get(cr, uid, view_id, action['view_type'], context) assert view_res and view_res.get('arch'), "Did not return any arch for the view" view_data = {} if view_res.get('fields',{}).keys(): - view_data = pool.get(datas['res_model']).default_get(cr, uid, view_res['fields'].keys(), context) + view_data = registry[datas['res_model']].default_get(cr, uid, view_res['fields'].keys(), context) if datas.get('form'): view_data.update(datas.get('form')) if wiz_data: @@ -238,7 +240,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, if not datas['res_id']: # it is probably an orm_memory object, we need to create # an instance - datas['res_id'] = pool.get(datas['res_model']).create(cr, uid, view_data, context) + datas['res_id'] = registry[datas['res_model']].create(cr, uid, view_data, context) if not buttons: raise AssertionError("view form doesn't have any buttons to press!") @@ -255,7 +257,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, continue if b['type'] == 'object': #there we are! press the button! - fn = getattr(pool.get(datas['res_model']), b['name']) + fn = getattr(registry[datas['res_model']], b['name']) if not fn: _logger.error("The %s model doesn't have a %s attribute!", datas['res_model'], b['name']) continue @@ -281,7 +283,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, raise Exception("Cannot handle action of type %s" % act_model) log_test("will be using %s action %s #%d", act_model, act_xmlid, act_id) - action = pool.get(act_model).read(cr, uid, act_id, context=context) + action = registry[act_model].read(cr, uid, act_id, context=context) assert action, "Could not read action %s[%s]" %(act_model, act_id) loop = 0 while action: diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 45688ae76e0..207d2f2992c 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -25,7 +25,6 @@ import fnmatch import inspect import locale import os -import openerp.pooler as pooler import openerp.sql_db as sql_db import re import logging @@ -43,6 +42,7 @@ import misc from misc import UpdateableStr from misc import SKIPPED_ELEMENT_TYPES import osutil +import openerp from openerp import SUPERUSER_ID _logger = logging.getLogger(__name__) @@ -208,7 +208,7 @@ class GettextAlias(object): (cr, dummy) = self._get_cr(frame, allow_create=False) uid = self._get_uid(frame) if pool and cr and uid: - lang = pool.get('res.users').context_get(cr, uid)['lang'] + lang = pool['res.users'].context_get(cr, uid)['lang'] return lang def __call__(self, source): @@ -227,8 +227,8 @@ class GettextAlias(object): cr, is_new_cr = self._get_cr(frame) if cr: # Try to use ir.translation to benefit from global cache if possible - pool = pooler.get_pool(cr.dbname) - res = pool.get('ir.translation')._get_source(cr, SUPERUSER_ID, None, ('code','sql_constraint'), lang, source) + registry = openerp.registry(cr.dbname) + res = registry['ir.translation']._get_source(cr, SUPERUSER_ID, None, ('code','sql_constraint'), lang, source) else: _logger.debug('no context cursor detected, skipping translation for "%r"', source) else: @@ -611,11 +611,11 @@ def babel_extract_qweb(fileobj, keywords, comment_tags, options): def trans_generate(lang, modules, cr): dbname = cr.dbname - pool = pooler.get_pool(dbname) - trans_obj = pool.get('ir.translation') - model_data_obj = pool.get('ir.model.data') + registry = openerp.registry(dbname) + trans_obj = registry.get('ir.translation') + model_data_obj = registry.get('ir.model.data') uid = 1 - l = pool.models.items() + l = registry.models.items() l.sort() query = 'SELECT name, model, res_id, module' \ @@ -659,15 +659,15 @@ def trans_generate(lang, modules, cr): model = encode(model) xml_name = "%s.%s" % (module, encode(xml_name)) - if not pool.get(model): + if not registry.get(model): _logger.error("Unable to find object %r", model) continue - exists = pool.get(model).exists(cr, uid, res_id) + exists = registry[model].exists(cr, uid, res_id) if not exists: _logger.warning("Unable to find object %r with id %d", model, res_id) continue - obj = pool.get(model).browse(cr, uid, res_id) + obj = registry[model].browse(cr, uid, res_id) if model=='ir.ui.view': d = etree.XML(encode(obj.arch)) @@ -682,7 +682,7 @@ def trans_generate(lang, modules, cr): except AttributeError, exc: _logger.error("name error in %s: %s", xml_name, str(exc)) continue - objmodel = pool.get(obj.model) + objmodel = registry[obj.model] if not objmodel or not field_name in objmodel._columns: continue field_def = objmodel._columns[field_name] @@ -764,7 +764,7 @@ def trans_generate(lang, modules, cr): push_constraint_msg(module, term_type, model._name, constraint[msg_pos]) for (_, model, module) in cr.fetchall(): - model_obj = pool.get(model) + model_obj = registry.get(model) if not model_obj: _logger.error("Unable to find object %r", model) @@ -794,7 +794,7 @@ def trans_generate(lang, modules, cr): return path.split(os.path.sep)[0] return 'base' # files that are not in a module are considered as being in 'base' module - modobj = pool.get('ir.module.module') + modobj = registry['ir.module.module'] installed_modids = modobj.search(cr, uid, [('state', '=', 'installed')]) installed_modules = map(lambda m: m['name'], modobj.read(cr, uid, installed_modids, ['name'])) @@ -887,9 +887,9 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, if context is None: context = {} db_name = cr.dbname - pool = pooler.get_pool(db_name) - lang_obj = pool.get('res.lang') - trans_obj = pool.get('ir.translation') + registry = openerp.registry(db_name) + lang_obj = registry.get('res.lang') + trans_obj = registry.get('ir.translation') iso_lang = misc.get_iso_codes(lang) try: ids = lang_obj.search(cr, SUPERUSER_ID, [('code','=', lang)]) @@ -1009,11 +1009,10 @@ def load_language(cr, lang): :param lang: language ISO code with optional _underscore_ and l10n flavor (ex: 'fr', 'fr_BE', but not 'fr-BE') :type lang: str """ - pool = pooler.get_pool(cr.dbname) - language_installer = pool.get('base.language.install') - uid = 1 - oid = language_installer.create(cr, uid, {'lang': lang}) - language_installer.lang_install(cr, uid, [oid], context=None) + registry = openerp.registry(cr.dbname) + language_installer = registry['base.language.install'] + oid = language_installer.create(cr, SUPERUSER_ID, {'lang': lang}) + language_installer.lang_install(cr, SUPERUSER_ID, [oid], context=None) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index 3172caac1f4..6c2d459d6a8 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -5,8 +5,9 @@ import time # used to eval time.strftime expressions from datetime import datetime, timedelta import logging -import openerp.pooler as pooler +import openerp import openerp.sql_db as sql_db +import openerp.workflow import misc from config import config import yaml_tag @@ -112,7 +113,7 @@ class YamlInterpreter(object): self.assertion_report = report self.noupdate = noupdate self.loglevel = loglevel - self.pool = pooler.get_pool(cr.dbname) + self.pool = openerp.registry(cr.dbname) self.uid = 1 self.context = {} # opererp context self.eval_context = {'ref': self._ref(), @@ -128,9 +129,7 @@ class YamlInterpreter(object): return lambda xml_id: self.get_id(xml_id) def get_model(self, model_name): - model = self.pool.get(model_name) - assert model, "The model %s does not exist." % (model_name,) - return model + return self.pool[model_name] def validate_xml_id(self, xml_id): id = xml_id @@ -140,7 +139,7 @@ class YamlInterpreter(object): "It is used to refer to other modules ID, in the form: module.record_id" \ % (xml_id,) if module != self.module: - module_count = self.pool.get('ir.module.module').search_count(self.cr, self.uid, \ + module_count = self.pool['ir.module.module'].search_count(self.cr, self.uid, \ ['&', ('name', '=', module), ('state', 'in', ['installed'])]) assert module_count == 1, 'The ID "%s" refers to an uninstalled module.' % (xml_id,) if len(id) > 64: # TODO where does 64 come from (DB is 128)? should be a constant or loaded form DB @@ -162,7 +161,7 @@ class YamlInterpreter(object): module = self.module checked_xml_id = xml_id try: - _, id = self.pool.get('ir.model.data').get_object_reference(self.cr, self.uid, module, checked_xml_id) + _, id = self.pool['ir.model.data'].get_object_reference(self.cr, self.uid, module, checked_xml_id) self.id_map[xml_id] = id except ValueError: raise ValueError("""%s not found when processing %s. @@ -201,7 +200,7 @@ class YamlInterpreter(object): ids = [self.get_id(assertion.id)] elif assertion.search: q = eval(assertion.search, self.eval_context) - ids = self.pool.get(assertion.model).search(self.cr, self.uid, q, context=assertion.context) + ids = self.pool[assertion.model].search(self.cr, self.uid, q, context=assertion.context) else: raise YamlImportException('Nothing to assert: you must give either an id or a search criteria.') return ids @@ -281,7 +280,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) @@ -290,20 +288,20 @@ class YamlInterpreter(object): module = self.module if '.' in view_id: module, view_id = view_id.split('.',1) - view_id = self.pool.get('ir.model.data').get_object_reference(self.cr, SUPERUSER_ID, module, view_id)[1] + view_id = self.pool['ir.model.data'].get_object_reference(self.cr, SUPERUSER_ID, module, view_id)[1] if model.is_transient(): record_dict=self.create_osv_memory_record(record, fields) else: self.validate_xml_id(record.id) try: - self.pool.get('ir.model.data')._get_id(self.cr, SUPERUSER_ID, self.module, record.id) + self.pool['ir.model.data']._get_id(self.cr, SUPERUSER_ID, self.module, record.id) default = False except ValueError: default = True if self.isnoupdate(record) and self.mode != 'init': - id = self.pool.get('ir.model.data')._update_dummy(self.cr, SUPERUSER_ID, record.model, self.module, record.id) + id = self.pool['ir.model.data']._update_dummy(self.cr, SUPERUSER_ID, record.model, self.module, record.id) # check if the resource already existed at the last update if id: self.id_map[record] = int(id) @@ -324,7 +322,7 @@ class YamlInterpreter(object): record_dict = self._create_record(model, fields, view_info, default=default) _logger.debug("RECORD_DICT %s" % record_dict) - id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, record.model, \ + id = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, record.model, \ self.module, record_dict, record.id, noupdate=self.isnoupdate(record), mode=self.mode, context=context) self.id_map[record.id] = int(id) if config.get('import_partial'): @@ -346,7 +344,7 @@ class YamlInterpreter(object): one2many_view = fg[field_name]['views'].get(view_type) # if the view is not defined inline, we call fields_view_get() if not one2many_view: - one2many_view = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, SUPERUSER_ID, False, view_type, self.context) + one2many_view = self.pool[fg[field_name]['relation']].fields_view_get(self.cr, SUPERUSER_ID, False, view_type, self.context) return one2many_view def process_val(key, val): @@ -543,7 +541,14 @@ class YamlInterpreter(object): 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') @@ -584,9 +589,7 @@ class YamlInterpreter(object): signals=[x['signal'] for x in self.cr.dictfetchall()] if workflow.action not in signals: raise YamlImportException('Incorrect action %s. No such action defined' % workflow.action) - import openerp.netsvc as netsvc - wf_service = netsvc.LocalService("workflow") - wf_service.trg_validate(uid, workflow.model, id, workflow.action, self.cr) + openerp.workflow.trg_validate(uid, workflow.model, id, workflow.action, self.cr) def _eval_params(self, model, params): args = [] @@ -707,7 +710,7 @@ class YamlInterpreter(object): self._set_group_values(node, values) - pid = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, \ + pid = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, \ 'ir.ui.menu', self.module, values, node.id, mode=self.mode, \ noupdate=self.isnoupdate(node), res_id=res and res[0] or False) @@ -718,7 +721,7 @@ class YamlInterpreter(object): action_type = node.type or 'act_window' action_id = self.get_id(node.action) action = "ir.actions.%s,%d" % (action_type, action_id) - self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \ + self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, 'action', \ 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(parent_id))], action, True, True, xml_id=node.id) def process_act_window(self, node): @@ -752,7 +755,7 @@ class YamlInterpreter(object): if node.target: values['target'] = node.target - id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, \ + id = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, \ 'ir.actions.act_window', self.module, values, node.id, mode=self.mode) self.id_map[node.id] = int(id) @@ -760,7 +763,7 @@ class YamlInterpreter(object): keyword = 'client_action_relate' value = 'ir.actions.act_window,%s' % id replace = node.replace or True - self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', keyword, \ + self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, 'action', keyword, \ node.id, [node.src_model], value, replace=replace, noupdate=self.isnoupdate(node), isobject=True, xml_id=node.id) # TODO add remove ir.model.data @@ -768,11 +771,11 @@ class YamlInterpreter(object): assert getattr(node, 'model'), "Attribute %s of delete tag is empty !" % ('model',) if self.pool.get(node.model): if node.search: - ids = self.pool.get(node.model).search(self.cr, self.uid, eval(node.search, self.eval_context)) + ids = self.pool[node.model].search(self.cr, self.uid, eval(node.search, self.eval_context)) else: ids = [self.get_id(node.id)] if len(ids): - self.pool.get(node.model).unlink(self.cr, self.uid, ids) + self.pool[node.model].unlink(self.cr, self.uid, ids) else: self._log("Record not deleted.") @@ -781,7 +784,7 @@ class YamlInterpreter(object): res = {'name': node.name, 'url': node.url, 'target': node.target} - id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, \ + id = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, \ "ir.actions.act_url", self.module, res, node.id, mode=self.mode) self.id_map[node.id] = int(id) # ir_set @@ -789,7 +792,7 @@ class YamlInterpreter(object): keyword = node.keyword or 'client_action_multi' value = 'ir.actions.act_url,%s' % id replace = node.replace or True - self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \ + self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, 'action', \ keyword, node.url, ["ir.actions.act_url"], value, replace=replace, \ noupdate=self.isnoupdate(node), isobject=True, xml_id=node.id) @@ -804,7 +807,7 @@ class YamlInterpreter(object): else: value = expression res[fieldname] = value - self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, res['key'], res['key2'], \ + self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, res['key'], res['key2'], \ res['name'], res['models'], res['value'], replace=res.get('replace',True), \ isobject=res.get('isobject', False), meta=res.get('meta',None)) @@ -833,7 +836,7 @@ class YamlInterpreter(object): self._set_group_values(node, values) - id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, "ir.actions.report.xml", \ + id = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, "ir.actions.report.xml", \ self.module, values, xml_id, noupdate=self.isnoupdate(node), mode=self.mode) self.id_map[xml_id] = int(id) @@ -841,7 +844,7 @@ class YamlInterpreter(object): keyword = node.keyword or 'client_print_multi' value = 'ir.actions.report.xml,%s' % id replace = node.replace or True - self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \ + self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, 'action', \ keyword, values['name'], [values['model']], value, replace=replace, isobject=True, xml_id=xml_id) def process_none(self): @@ -922,7 +925,7 @@ class YamlInterpreter(object): def yaml_import(cr, module, yamlfile, kind, idref=None, mode='init', noupdate=False, report=None): if idref is None: idref = {} - loglevel = logging.TEST if kind == 'test' else logging.DEBUG + loglevel = logging.INFO if kind == 'test' else logging.DEBUG yaml_string = yamlfile.read() yaml_interpreter = YamlInterpreter(cr, module, idref, mode, filename=yamlfile.name, report=report, noupdate=noupdate, loglevel=loglevel) yaml_interpreter.process(yaml_string) diff --git a/openerp/workflow/wkf_expr.py b/openerp/workflow/wkf_expr.py index 8e93a99f038..b43fa83e3de 100644 --- a/openerp/workflow/wkf_expr.py +++ b/openerp/workflow/wkf_expr.py @@ -19,7 +19,7 @@ # ############################################################################## -import openerp.pooler as pooler +import openerp from openerp.tools.safe_eval import safe_eval as eval class Env(dict): @@ -28,7 +28,7 @@ class Env(dict): self.uid = uid self.model = model self.ids = ids - self.obj = pooler.get_pool(cr.dbname).get(model) + self.obj = openerp.registry(cr.dbname)[model] self.columns = self.obj._columns.keys() + self.obj._inherit_fields.keys() def __getitem__(self, key): @@ -58,7 +58,7 @@ def _eval_expr(cr, ident, workitem, action): return ret def execute_action(cr, ident, workitem, activity): - obj = pooler.get_pool(cr.dbname).get('ir.actions.server') + obj = openerp.registry(cr.dbname)['ir.actions.server'] ctx = {'active_model':ident[1], 'active_id':ident[2], 'active_ids':[ident[2]]} result = obj.run(cr, ident[0], [activity['action_id']], ctx) return result @@ -72,8 +72,8 @@ def check(cr, workitem, ident, transition, signal): uid = ident[0] if transition['group_id'] and uid != 1: - pool = pooler.get_pool(cr.dbname) - user_groups = pool.get('res.users').read(cr, uid, [uid], ['groups_id'])[0]['groups_id'] + registry = openerp.registry(cr.dbname) + user_groups = registry['res.users'].read(cr, uid, [uid], ['groups_id'])[0]['groups_id'] if not transition['group_id'] in user_groups: return False diff --git a/openerpcommand/initialize.py b/openerpcommand/initialize.py index 44fb084bd1e..9822dd5f5b2 100644 --- a/openerpcommand/initialize.py +++ b/openerpcommand/initialize.py @@ -47,7 +47,7 @@ def run(args): config = openerp.tools.config if args.tests: - config['log_handler'] = [':TEST'] + config['log_handler'] = [':INFO'] config['test_enable'] = True config['without_demo'] = False else: