diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 3484b40cee9..42b57b7c661 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -20,7 +20,10 @@ ############################################################################## import base64 +from docutils import io, nodes from docutils.core import publish_string +from docutils.transforms import Transform, writer_aux +from docutils.writers.html4css1 import Writer import imp import logging import re @@ -80,6 +83,32 @@ class module_category(osv.osv): 'visible' : 1, } +class MyFilterMessages(Transform): + """ + Custom docutils transform to remove `system message` for a document and + generate warnings. + + (The standard filter removes them based on some `report_level` passed in + the `settings_override` dictionary, but if we use it, we can't see them + and generate warnings.) + """ + + default_priority = 870 + + def apply(self): + for node in self.document.traverse(nodes.system_message): + _logger.warning("docutils' system message present: %s", str(node)) + node.parent.remove(node) + +class MyWriter(Writer): + """ + Custom docutils html4ccs1 writer that doesn't add the warnings to the + output document. + """ + + def get_transforms(self): + return [MyFilterMessages, writer_aux.Admonitions] + class module(osv.osv): _name = "ir.module.module" _rec_name = "shortdesc" @@ -100,7 +129,7 @@ class module(osv.osv): res = dict.fromkeys(ids, '') for module in self.browse(cr, uid, ids, context=context): overrides = dict(embed_stylesheet=False, doctitle_xform=False, output_encoding='unicode') - output = publish_string(source=module.description, writer_name='html', settings_overrides=overrides) + output = publish_string(source=module.description, settings_overrides=overrides, writer=MyWriter()) res[module.id] = output return res diff --git a/openerp/cli/server.py b/openerp/cli/server.py index f030f801967..9352ad37ef0 100644 --- a/openerp/cli/server.py +++ b/openerp/cli/server.py @@ -94,7 +94,11 @@ def setup_pid_file(): def preload_registry(dbname): """ Preload a registry, and start the cron.""" try: - db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=openerp.tools.config['init'] or openerp.tools.config['update'], pooljobs=False) + config = openerp.tools.config + update_module = True if config['init'] or config['update'] else False + db, registry = openerp.pooler.get_db_and_pool( + dbname, update_module=update_module, pooljobs=False, + force_demo=not config['without_demo']) # jobs will start to be processed later, when openerp.cron.start_master_thread() is called by openerp.service.start_services() registry.schedule_cron_jobs() @@ -105,7 +109,9 @@ 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'], pooljobs=False) + update_module = True if config['init'] or config['update'] else False + db, registry = openerp.pooler.get_db_and_pool( + dbname, update_module=update_module, pooljobs=False, force_demo=not config['without_demo']) cr = db.cursor() _logger.info('loading test file %s', test_file) openerp.tools.convert_yaml_import(cr, 'base', file(test_file), 'test', {}, 'test', True) diff --git a/openerp/modules/graph.py b/openerp/modules/graph.py index 56b17e3239a..f7e9bc7c77a 100644 --- a/openerp/modules/graph.py +++ b/openerp/modules/graph.py @@ -87,15 +87,19 @@ class Graph(dict): for k, v in additional_data[package.name].items(): setattr(package, k, v) - def add_module(self, cr, module, force=None): - self.add_modules(cr, [module], force) + def add_module(self, cr, module, force_demo=False): + self.add_modules(cr, [module], force_demo) - def add_modules(self, cr, module_list, force=None): - if force is None: - force = [] + def add_modules(self, cr, module_list, force_demo=False): packages = [] len_graph = len(self) for module in module_list: + if force_demo: + cr.execute(""" + UPDATE ir_module_module + SET demo='t' + WHERE name = %s""", + (module,)) # This will raise an exception if no/unreadable descriptor file. # NOTE The call to load_information_from_description_file is already # done by db.initialize, so it is possible to not do it again here. @@ -121,9 +125,6 @@ class Graph(dict): current.remove(package) node = self.add_node(package, info) node.data = info - for kind in ('init', 'demo', 'update'): - if package in tools.config[kind] or 'all' in tools.config[kind] or kind in force: - setattr(node, kind, True) else: later.add(package) packages.append((package, info)) @@ -185,18 +186,11 @@ class Node(Singleton): node.depth = self.depth + 1 if node not in self.children: self.children.append(node) - for attr in ('init', 'update', 'demo'): - if hasattr(self, attr): - setattr(node, attr, True) self.children.sort(lambda x, y: cmp(x.name, y.name)) return node def __setattr__(self, name, value): super(Singleton, self).__setattr__(name, value) - if name in ('init', 'update', 'demo'): - tools.config[name][self.name] = 1 - for child in self.children: - setattr(child, name, value) if name == 'depth': for child in self.children: setattr(child, name, value + 1) diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py index bcda1690c91..13b02bd7a6e 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -42,6 +42,7 @@ from openerp import SUPERUSER_ID from openerp import SUPERUSER_ID from openerp.tools.translate import _ +from openerp.tools import assertion_report from openerp.modules.module import initialize_sys_path, \ load_openerp_module, init_module_models @@ -157,7 +158,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= models = pool.load(cr, package) loaded_modules.append(package.name) - if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'): + if package.state in ('to install', 'to upgrade'): init_module_models(cr, package.name, models) pool._init_modules.add(package.name) status['progress'] = float(index) / len(graph) @@ -171,18 +172,19 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= idref = {} - mode = 'update' - if hasattr(package, 'init') or package.state == 'to install': + if package.state == 'to install': mode = 'init' + else: + mode = 'update' - if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'): + if package.state in ('to install', 'to upgrade'): if package.state=='to upgrade': # upgrading the module information modobj.write(cr, SUPERUSER_ID, [module_id], modobj.get_values_from_terp(package.data)) load_init_xml(module_name, idref, mode) load_update_xml(module_name, idref, mode) load_data(module_name, idref, mode) - if hasattr(package, 'demo') or (package.dbdemo and package.state != 'installed'): + if package.dbdemo and package.state != 'installed': status['progress'] = (index + 0.75) / len(graph) load_demo_xml(module_name, idref, mode) load_demo(module_name, idref, mode) @@ -212,9 +214,6 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= modobj.update_translations(cr, SUPERUSER_ID, [module_id], None) package.state = 'installed' - for kind in ('init', 'demo', 'update'): - if hasattr(package, kind): - delattr(package, kind) cr.commit() @@ -269,10 +268,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): if not openerp.modules.db.is_initialized(cr): _logger.info("init db") openerp.modules.db.initialize(cr) - tools.config["init"]["all"] = 1 - tools.config['update']['all'] = 1 - if not tools.config['without_demo']: - tools.config["demo"]['all'] = 1 + update_module = True # This is a brand new pool, just created in pooler.get_db_and_pool() pool = pooler.get_pool(cr.dbname) @@ -282,43 +278,51 @@ def load_modules(db, force_demo=False, status=None, update_module=False): # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps) graph = openerp.modules.graph.Graph() - graph.add_module(cr, 'base', force) + graph.add_module(cr, 'base', force_demo) if not graph: _logger.critical('module base cannot be loaded! (hint: verify addons-path)') raise osv.osv.except_osv(_('Could not load base module'), _('module base cannot be loaded! (hint: verify addons-path)')) # processed_modules: for cleanup step after install # loaded_modules: to avoid double loading - report = pool._assertion_report - loaded_modules, processed_modules = load_module_graph(cr, graph, status, perform_checks=(not update_module), report=report) + # After load_module_graph(), 'base' has been installed or updated and its state is 'installed'. + report = assertion_report.assertion_report() + loaded_modules, processed_modules = load_module_graph(cr, graph, status, report=report) if tools.config['load_language']: for lang in tools.config['load_language'].split(','): tools.load_language(cr, lang) # STEP 2: Mark other modules to be loaded/updated + # This is a one-shot use of tools.config[init|update] from the command line + # arguments. It is directly cleared to not interfer with later create/update + # issued via RPC. if update_module: modobj = pool.get('ir.module.module') - if ('base' in tools.config['init']) or ('base' in tools.config['update']): + if ('base' in tools.config['init']) or ('base' in tools.config['update']) \ + or ('all' in tools.config['init']) or ('all' in tools.config['update']): _logger.info('updating modules list') modobj.update_list(cr, SUPERUSER_ID) + if 'all' in tools.config['init']: + ids = modobj.search(cr, 1, []) + tools.config['init'] = dict.fromkeys([m['name'] for m in modobj.read(cr, 1, ids, ['name'])], 1) + _check_module_names(cr, itertools.chain(tools.config['init'].keys(), tools.config['update'].keys())) - mods = [k for k in tools.config['init'] if tools.config['init'][k]] - if mods: - ids = modobj.search(cr, SUPERUSER_ID, ['&', ('state', '=', 'uninstalled'), ('name', 'in', mods)]) - if ids: - modobj.button_install(cr, SUPERUSER_ID, ids) + mods = [k for k in tools.config['init'] if tools.config['init'][k] and k not in ('base', 'all')] + ids = modobj.search(cr, SUPERUSER_ID, ['&', ('state', '=', 'uninstalled'), ('name', 'in', mods)]) + if ids: + modobj.button_install(cr, SUPERUSER_ID, ids) # goes from 'uninstalled' to 'to install' - mods = [k for k in tools.config['update'] if tools.config['update'][k]] - if mods: - ids = modobj.search(cr, SUPERUSER_ID, ['&', ('state', '=', 'installed'), ('name', 'in', mods)]) - if ids: - modobj.button_upgrade(cr, SUPERUSER_ID, ids) - - cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base')) + mods = [k for k in tools.config['update'] if tools.config['update'][k] and k not in ('base', 'all')] + ids = modobj.search(cr, SUPERUSER_ID, ['&', ('state', '=', 'installed'), ('name', 'in', mods)]) + if ids: + modobj.button_upgrade(cr, SUPERUSER_ID, ids) # goes from 'installed' to 'to upgrade' + # Remove that funky global one-shot thingy. + for kind in ('init', 'demo', 'update'): + tools.config[kind] = {} # STEP 3: Load marked modules (skipping base which was done in STEP 1) # IMPORTANT: this is done in two parts, first loading all installed or @@ -370,9 +374,6 @@ def load_modules(db, force_demo=False, status=None, update_module=False): # Cleanup orphan records pool.get('ir.model.data')._process_end(cr, SUPERUSER_ID, processed_modules) - for kind in ('init', 'demo', 'update'): - tools.config[kind] = {} - cr.commit() # STEP 5: Cleanup menus diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 731ccbe757e..4824cea84e4 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -196,10 +196,15 @@ class db(netsvc.ExportService): # Try to terminate all other connections that might prevent # dropping the database try: - cr.execute("""SELECT pg_terminate_backend(procpid) + + # PostgreSQL 9.2 renamed pg_stat_activity.procpid to pid: + # http://www.postgresql.org/docs/9.2/static/release-9-2.html#AEN110389 + pid_col = 'pid' if cr._cnx.server_version >= 90200 else 'procpid' + + cr.execute("""SELECT pg_terminate_backend(%(pid_col)s) FROM pg_stat_activity - WHERE datname = %s AND - procpid != pg_backend_pid()""", + WHERE datname = %%s AND + %(pid_col)s != pg_backend_pid()""" % {'pid_col': pid_col}, (db_name,)) except Exception: pass diff --git a/openerp/workflow/wkf_expr.py b/openerp/workflow/wkf_expr.py index 608af34d118..b4d6c5b9ccc 100644 --- a/openerp/workflow/wkf_expr.py +++ b/openerp/workflow/wkf_expr.py @@ -46,6 +46,8 @@ def _eval_expr(cr, ident, workitem, action): assert action, 'You used a NULL action in a workflow, use dummy node instead.' for line in action.split('\n'): line = line.strip() + if not line: + continue uid=ident[0] model=ident[1] ids=[ident[2]]