From 8736e1102aa681362377767d885b1e56826f1647 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 22 Aug 2012 19:44:13 +0200 Subject: [PATCH 01/64] [IMP] remove apps bzr revid: chs@openerp.com-20120822174413-dln0k2refi86g0lj --- openerp/addons/base/__openerp__.py | 5 +- openerp/addons/base/module/module.py | 68 ++++++++++++++++++++ openerp/addons/base/module/module_view.xml | 10 ++- openerp/addons/base/static/src/js/apps.js | 73 ++++++++++++++++++++++ 4 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 openerp/addons/base/static/src/js/apps.js diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index 5b65bff4bd7..8d051a17127 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -3,7 +3,7 @@ # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). -# Copyright (C) 2010 OpenERP s.a. (). +# Copyright (C) 2010-2012 OpenERP s.a. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -99,5 +99,8 @@ 'auto_install': True, 'certificate': '0076807797149', 'css': ['static/src/css/modules.css'], + 'js': [ + 'static/src/js/apps.js', + ], } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 5751ed678eb..cc0b05af97f 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -18,13 +18,25 @@ # along with this program. If not, see . # ############################################################################## +from collections import defaultdict import imp import logging +import os import re +import shutil +import tempfile import urllib +import zipfile import zipimport import base64 +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO # NOQA + +import requests + from openerp import modules, pooler, release, tools, addons from openerp.tools.parse_version import parse_version from openerp.tools.translate import _ @@ -41,6 +53,21 @@ ACTION_DICT = { 'nodestroy':True, } +def backup(path, raise_exception=True): + path = os.path.normpath(path) + if not os.path.exists(path): + if not raise_exception: + return None + raise OSError('path does not exists') + cnt = 1 + while True: + bck = '%s~%d' % (path, cnt) + if not os.path.exists(bck): + shutil.move(path, bck) + return bck + cnt += 1 + + class module_category(osv.osv): _name = "ir.module.category" _description = "Application" @@ -584,6 +611,47 @@ class module(osv.osv): zimp.load_module(mod.name) return res + def install_from_urls(self, cr, uid, urls, context=None): + tmp = tempfile.mkdtemp() + try: + for module_name in urls: + try: + r = requests.get(urls[module_name]) + r.raise_for_status() + except requests.HTTPError, e: + _logger.exception('ggr') + raise osv.except_osv('grrr', e) + else: + zipfile.ZipFile(StringIO(r.content)).extractall(tmp) + assert os.path.isdir(os.path.join(tmp, module_name)) + + for module_name in urls: + module_path = modules.get_module_path(module_name, downloaded=True, display_warning=False) + bck = backup(module_path, False) + shutil.move(os.path.join(tmp, module_name), module_path) + if bck: + shutil.rmtree(bck) + + self.update_list(cr, uid, context=context) + + # FIXME restart server if ugrade... + + ids = self.search(cr, uid, [('name', 'in', urls.keys())], context=context) + + def install_or_upgrade(cr, uid, ids, context=None): + bystate = defaultdict(list) + names = [] + for m in self.read(cr, uid, ids, ['state', 'name'], context=context): + bystate[m['state']].append(m['id']) + names.append(m['name']) + + self.button_install(cr, uid, bystate['uninstalled'], context=context) + self.button_upgrade(cr, uid, bystate['installed'], context=context) + + return self._button_immediate_function(cr, uid, ids, install_or_upgrade, context=context) + finally: + shutil.rmtree(tmp) + def _update_dependencies(self, cr, uid, mod_browse, depends=None): if depends is None: depends = [] diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index 19f9dbdaa44..8aca2546f4f 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -2,6 +2,12 @@ + + Modules + apps + + + @@ -187,8 +193,8 @@

You should try others search criteria.

- +
diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js new file mode 100644 index 00000000000..651ce6d0708 --- /dev/null +++ b/openerp/addons/base/static/src/js/apps.js @@ -0,0 +1,73 @@ +openerp.base = function(instance) { + + instance.base = {}; + instance.base.Apps = instance.web.Widget.extend({ + template: 'EmptyComponent', + init: function(parent, options) { + this._super(parent); + // create a new instance + this.remote_instance = new openerp.init(); + + }, + + destroy: function() { + if (this.client) { + this.client.destroy(); + } + delete this.remote_instance; + }, + + _get_options: function() { + //var DEFAULT_SERVER = 'http://apps.openerp.com/loempia'; // PROD + //var DEFAULT_SERVER = 'http://apps.openerp.com:9069/loempia7'; // TEST + var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7'; // DEV + var ICP = new instance.web.Model('ir.config_parameter'); + return ICP.call('get_param', ['loempia.server', DEFAULT_SERVER]).pipe(function(u) { + var link = $(_.str.sprintf('', u))[0]; + var host = _.str.sprintf('%s//%s', link.protocol, link.host); + var dbname = link.pathname.substr(1); + + var login = (sessionStorage ? sessionStorage.getItem('loempia.login') : null) || 'anonymous'; + var passwd = (sessionStorage ? sessionStorage.getItem('loempia.passwd') : null) || 'anonymous'; + + return { + url: host, + dbname: dbname, + login: login, + password: passwd, + action_id: 'loempia.action_embed' + }; + }); + }, + + start: function() { + return this._get_options().then(this.proxy('_connect')); + }, + _connect: function(options) { + this.options = options; + + var client = this.client = new this.remote_instance.web.EmbeddedClient(null, this.options.url, + this.options.dbname, this.options.login, this.options.password, + this.options.action_id, this.action_flags); + client.on('connection_failed', this, this.action_fallback); + this.client = client; + + client.replace(this.$element). + done(function() { + client.$element.removeClass('openerp'); + }). + fail(function() { + console.log('fail', this); + alert('fail'); + }); + }, + + action_fallback: function() { + // TODO show flash message + this.do_warn(this.options.url + ' unreachable'); + this.do_action('base.action_modules'); + } + }); + + instance.web.client_actions.add("apps", "instance.base.Apps"); +}; From d73d78d4c89bb90226d879010f6ce221124eedf3 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 23 Aug 2012 17:52:34 +0200 Subject: [PATCH 02/64] [IMP] connect to test server bzr revid: chs@openerp.com-20120823155234-welcel8i5odi6hh8 --- openerp/addons/base/static/src/js/apps.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 651ce6d0708..ad2079677ff 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -19,8 +19,8 @@ openerp.base = function(instance) { _get_options: function() { //var DEFAULT_SERVER = 'http://apps.openerp.com/loempia'; // PROD - //var DEFAULT_SERVER = 'http://apps.openerp.com:9069/loempia7'; // TEST - var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7'; // DEV + var DEFAULT_SERVER = 'http://apps.openerp.com:9069/loempia7'; // TEST + //var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7'; // DEV var ICP = new instance.web.Model('ir.config_parameter'); return ICP.call('get_param', ['loempia.server', DEFAULT_SERVER]).pipe(function(u) { var link = $(_.str.sprintf('', u))[0]; From ca4c2b8c49840febc34ebbfbf94078b05e96bbf2 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 23 Aug 2012 18:03:08 +0200 Subject: [PATCH 03/64] [FIX] correct module menu bzr revid: chs@openerp.com-20120823160308-23iwttphu7l3xan9 --- openerp/addons/base/module/module_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index bca4645b818..d18403cb5df 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -7,7 +7,7 @@ apps - + From 9f9de9914a96b462ce0ea62fdda14e397a331f02 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 24 Aug 2012 16:23:23 +0200 Subject: [PATCH 04/64] [FIX] automatically adapt version numbers of modules bzr revid: chs@openerp.com-20120824142323-m503lc6tfj4vntop --- openerp/addons/base/module/module.py | 16 +++++++++------- openerp/modules/__init__.py | 5 +++-- openerp/modules/module.py | 18 +++++++++++++----- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 368ac9fbe8f..b1f402d4ef6 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -116,7 +116,6 @@ class module(osv.osv): info = {} try: info = modules.load_information_from_description_file(name) - info['version'] = release.major_version + '.' + info['version'] except Exception: _logger.debug('Error when trying to fetch informations for ' 'module %s', name, exc_info=True) @@ -132,9 +131,10 @@ class module(osv.osv): return res def _get_latest_version(self, cr, uid, ids, field_name=None, arg=None, context=None): - res = dict.fromkeys(ids, '') + default_version = modules.adapt_version('1.0') + res = dict.fromkeys(ids, default_version) for m in self.browse(cr, uid, ids): - res[m.id] = self.get_module_info(m.name).get('version', '') + res[m.id] = self.get_module_info(m.name).get('version', default_version) return res def _get_views(self, cr, uid, ids, field_name=None, arg=None, context=None): @@ -546,8 +546,9 @@ class module(osv.osv): # update the list of available packages def update_list(self, cr, uid, context=None): - res = [0, 0] # [update, add] + res = [0, 0] # [update, add] + default_version = modules.adapt_version('1.0') known_mods = self.browse(cr, uid, self.search(cr, uid, [])) known_mods_names = dict([(m.name, m) for m in known_mods]) @@ -566,7 +567,7 @@ class module(osv.osv): updated_values[key] = values[key] if terp.get('installable', True) and mod.state == 'uninstallable': updated_values['state'] = 'uninstalled' - if parse_version(terp.get('version', '')) > parse_version(mod.latest_version or ''): + if parse_version(terp.get('version', default_version)) > parse_version(mod.latest_version or default_version): res[0] += 1 if updated_values: self.write(cr, uid, mod.id, updated_values) @@ -587,14 +588,15 @@ class module(osv.osv): def download(self, cr, uid, ids, download=True, context=None): res = [] + default_version = modules.adapt_version('1.0') for mod in self.browse(cr, uid, ids, context=context): if not mod.url: continue match = re.search('-([a-zA-Z0-9\._-]+)(\.zip)', mod.url, re.I) - version = '0' + version = default_version if match: version = match.group(1) - if parse_version(mod.installed_version or '0') >= parse_version(version): + if parse_version(mod.installed_version) >= parse_version(version): continue res.append(mod.url) if not download: diff --git a/openerp/modules/__init__.py b/openerp/modules/__init__.py index 56265e353a2..feaf014f568 100644 --- a/openerp/modules/__init__.py +++ b/openerp/modules/__init__.py @@ -3,7 +3,7 @@ # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). -# Copyright (C) 2010-2011 OpenERP s.a. (). +# Copyright (C) 2010-2012 OpenERP s.a. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -32,7 +32,8 @@ from openerp.modules.module import \ load_information_from_description_file, \ get_module_resource, zip_directory, \ get_module_path, initialize_sys_path, \ - load_openerp_module, init_module_models + load_openerp_module, init_module_models, \ + adapt_version from openerp.modules.loading import load_modules diff --git a/openerp/modules/module.py b/openerp/modules/module.py index b1d4de31bce..1f11ad21b37 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -3,7 +3,7 @@ # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). -# Copyright (C) 2010-2011 OpenERP s.a. (). +# Copyright (C) 2010-2012 OpenERP s.a. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -337,7 +337,7 @@ def load_information_from_description_file(module): 'license': 'AGPL-3', 'name': False, 'post_load': None, - 'version': '0.0.0', + 'version': '1.0', 'web': False, 'website': '', 'sequence': 100, @@ -357,6 +357,7 @@ def load_information_from_description_file(module): # 'active' has been renamed 'auto_install' info['auto_install'] = info['active'] + info['version'] = adapt_version(info['version']) return info #TODO: refactor the logger in this file to follow the logging guidelines @@ -454,15 +455,22 @@ def get_modules(): def get_modules_with_version(): modules = get_modules() - res = {} + res = dict.fromkeys(modules, adapt_version('1.0')) for module in modules: try: info = load_information_from_description_file(module) - res[module] = "%s.%s" % (release.major_version, info['version']) - except Exception, e: + res[module] = info['version'] + except Exception: continue return res +def adapt_version(version): + serie = release.major_version + if version == serie or not version.startswith(serie + '.'): + version = '%s.%s' % (serie, version) + return version + + def get_test_modules(module, submodule, explode): """ Return a list of submodules containing tests. From 5dbbe6eabe0db02b5ddef91886211fa972b14435 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 5 Sep 2012 15:21:39 +0200 Subject: [PATCH 05/64] [IMP] apps: restart server when updated needed bzr revid: chs@openerp.com-20120905132139-lkk0uue7hmkw9k9n --- openerp/addons/base/module/module.py | 30 +++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index b1f402d4ef6..0f58fa9d950 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -26,6 +26,7 @@ import logging import os import re import shutil +import sys import tempfile import urllib import zipfile @@ -646,24 +647,25 @@ class module(osv.osv): self.update_list(cr, uid, context=context) - # FIXME restart server if ugrade... - ids = self.search(cr, uid, [('name', 'in', urls.keys())], context=context) - - def install_or_upgrade(cr, uid, ids, context=None): - bystate = defaultdict(list) - names = [] - for m in self.read(cr, uid, ids, ['state', 'name'], context=context): - bystate[m['state']].append(m['id']) - names.append(m['name']) - - self.button_install(cr, uid, bystate['uninstalled'], context=context) - self.button_upgrade(cr, uid, bystate['installed'], context=context) - - return self._button_immediate_function(cr, uid, ids, install_or_upgrade, context=context) + if self.search_count(cr, uid, [('id', 'in', ids), ('state', '=', 'installed')], context=context): + # if any to update + return self.restart_server(cr, uid, context) # in fact will never return... + return self.button_immediate_install(cr, uid, ids, context=context) finally: shutil.rmtree(tmp) + def restart_server(self, cr, uid, context=None): + raise NotImplementedError('# FIXME') + # TODO send a signal to will wait all threads (include us) like ctrl-c + # catch the case of gunicorn and force all workers to die... + + strip_args = ['-d', '-u'] + a = sys.argv[:] + args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] + + os.execv(sys.executable, [sys.executable] + args) + def _update_dependencies(self, cr, uid, mod_browse, depends=None): if depends is None: depends = [] From b28f42d2b5a3a29603b663c8d5d94d72ea654b40 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 5 Sep 2012 16:04:04 +0200 Subject: [PATCH 06/64] [FIX] %s/\$element/\$el/g bzr revid: chs@openerp.com-20120905140404-cv1oi88uncy2vpr1 --- openerp/addons/base/static/src/js/apps.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index ad2079677ff..c3abd399ca8 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -52,9 +52,9 @@ openerp.base = function(instance) { client.on('connection_failed', this, this.action_fallback); this.client = client; - client.replace(this.$element). + client.replace(this.$el). done(function() { - client.$element.removeClass('openerp'); + client.$el.removeClass('openerp'); }). fail(function() { console.log('fail', this); From f633c116e21106eb2f978aaa85b0bff777976c89 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 5 Sep 2012 16:30:29 +0200 Subject: [PATCH 07/64] [IMP] base: reorganise modules menus bzr revid: chs@openerp.com-20120905143029-ajbcwxwoevyu6a93 --- openerp/addons/base/module/wizard/base_module_import_view.xml | 2 +- openerp/addons/base/module/wizard/base_module_update_view.xml | 2 +- openerp/addons/base/module/wizard/base_module_upgrade_view.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/module/wizard/base_module_import_view.xml b/openerp/addons/base/module/wizard/base_module_import_view.xml index 192bf6c2a92..938998506f0 100644 --- a/openerp/addons/base/module/wizard/base_module_import_view.xml +++ b/openerp/addons/base/module/wizard/base_module_import_view.xml @@ -41,7 +41,7 @@ name="Import Module" action="action_view_base_module_import" id="menu_view_base_module_import" - parent="menu_management" + parent="menu_module_tree" groups="base.group_no_one" sequence="1"/> --> diff --git a/openerp/addons/base/module/wizard/base_module_update_view.xml b/openerp/addons/base/module/wizard/base_module_update_view.xml index 75d2b1316a6..fb1c5a980f6 100644 --- a/openerp/addons/base/module/wizard/base_module_update_view.xml +++ b/openerp/addons/base/module/wizard/base_module_update_view.xml @@ -44,7 +44,7 @@ action="action_view_base_module_update" id="menu_view_base_module_update" groups="base.group_no_one" - parent="menu_management" + parent="menu_module_tree" sequence="2" icon="STOCK_CONVERT"/> diff --git a/openerp/addons/base/module/wizard/base_module_upgrade_view.xml b/openerp/addons/base/module/wizard/base_module_upgrade_view.xml index afd3a2e17b1..210cdccd5be 100644 --- a/openerp/addons/base/module/wizard/base_module_upgrade_view.xml +++ b/openerp/addons/base/module/wizard/base_module_upgrade_view.xml @@ -34,7 +34,7 @@ action="action_view_base_module_upgrade" groups="base.group_no_one" id="menu_view_base_module_upgrade" - parent="menu_management" + parent="menu_module_tree" sequence="3"/> From 8b68252da4383020fda612ab17fae64d9583c59e Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 7 Sep 2012 16:41:02 +0200 Subject: [PATCH 08/64] [WIP] restart server + update of server via apps bzr revid: chs@openerp.com-20120907144102-qi35brwee3wh9fwb --- openerp-server | 16 +++++++++--- openerp/addons/base/module/module.py | 38 ++++++++++++++++++---------- openerp/service/__init__.py | 34 ++++++++++++++++++++----- 3 files changed, 66 insertions(+), 22 deletions(-) diff --git a/openerp-server b/openerp-server index be0710cbce9..bff23d4c4e0 100755 --- a/openerp-server +++ b/openerp-server @@ -203,13 +203,23 @@ def quit_on_signals(): try: while quit_signals_received == 0: time.sleep(60) - except KeyboardInterrupt, e: + except KeyboardInterrupt: pass + openerp.service.stop_services() + + if getattr(openerp, 'phoenix', False): + # like the phoenix, reborn from ashes... + strip_args = ['-d', '-u'] + a = sys.argv[:] + args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] + + time.sleep(0.5) # wait end of sockets... + os.execv(sys.executable, [sys.executable] + args) + return + if config['pidfile']: os.unlink(config['pidfile']) - - openerp.service.stop_services() sys.exit(0) def configure_babel_localedata_path(): diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 79fbac8eb7f..93ad9cef4a2 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -26,7 +26,6 @@ import logging import os import re import shutil -import sys import tempfile import urllib import zipfile @@ -39,6 +38,7 @@ except ImportError: import requests +import openerp from openerp import modules, pooler, release, tools, addons from openerp.tools.parse_version import parse_version from openerp.tools.translate import _ @@ -640,33 +640,45 @@ class module(osv.osv): assert os.path.isdir(os.path.join(tmp, module_name)) for module_name in urls: + if module_name == 'base': + continue # special case. handled below module_path = modules.get_module_path(module_name, downloaded=True, display_warning=False) bck = backup(module_path, False) shutil.move(os.path.join(tmp, module_name), module_path) if bck: shutil.rmtree(bck) + if urls.get('base', None): + # base is a special case. it containt the server and the base module. + # extract path is not the same + + # TODO copy all modules in the SERVER/openerp/addons directory to the new "base" module (exceptbase itself) + # then replace the server by the new "base" module + base_path = os.path.dirname(modules.get_module_path('base')) + + for d in os.listdir(base_path): + if d != 'base' and os.path.isdir(os.path.join(base_path, d)): + destdir = os.path.join(tmp, 'base', 'addons', d) # XXX 'openerp' + shutil.copytree(os.path.join(base_path, d), destdir) + + server_dir = openerp.tools.config['root_path'] # XXX or dirname() + bck = backup(server_dir) + shutil.move(os.path.join(tmp, 'base'), server_dir) + #if bck: + # shutil.rmtree(bck) + self.update_list(cr, uid, context=context) ids = self.search(cr, uid, [('name', 'in', urls.keys())], context=context) if self.search_count(cr, uid, [('id', 'in', ids), ('state', '=', 'installed')], context=context): # if any to update - return self.restart_server(cr, uid, context) # in fact will never return... + cr.commit() + openerp.service.restart_server() + return False return self.button_immediate_install(cr, uid, ids, context=context) finally: shutil.rmtree(tmp) - def restart_server(self, cr, uid, context=None): - raise NotImplementedError('# FIXME') - # TODO send a signal to will wait all threads (include us) like ctrl-c - # catch the case of gunicorn and force all workers to die... - - strip_args = ['-d', '-u'] - a = sys.argv[:] - args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] - - os.execv(sys.executable, [sys.executable] + args) - def _update_dependencies(self, cr, uid, mod_browse, depends=None): if depends is None: depends = [] diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index 511d62c5862..72f807a5d69 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). # @@ -15,11 +15,14 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## import logging +import os +import signal +import sys import threading import time @@ -83,24 +86,43 @@ def stop_services(): openerp.netsvc.Server.quitAll() openerp.wsgi.core.stop_server() - config = openerp.tools.config _logger.info("Initiating shutdown") _logger.info("Hit CTRL-C again or send a second signal to force the shutdown.") - logging.shutdown() # Manually join() all threads before calling sys.exit() to allow a second signal # to trigger _force_quit() in case some non-daemon threads won't exit cleanly. # threading.Thread.join() should not mask signals (at least in python 2.5). + me = threading.currentThread() + _logger.debug('current thread: %r', me) for thread in threading.enumerate(): - if thread != threading.currentThread() and not thread.isDaemon(): + _logger.debug('process %r (%r)', thread, thread.isDaemon()) + if thread != me and not thread.isDaemon(): while thread.isAlive(): + _logger.debug('join and sleep') # Need a busyloop here as thread.join() masks signals # and would prevent the forced shutdown. thread.join(0.05) time.sleep(0.05) + _logger.debug('--') openerp.modules.registry.RegistryManager.delete_all() + logging.shutdown() +def restart_server(): + pid = openerp.wsgi.core.arbiter_pid + if pid: + os.kill(pid, signal.SIGHUP) + else: + openerp.phoenix = True + signame = 'CTRL_C_EVENT' if os.name == 'nt' else 'SIGINT' + sig = getattr(signal, signame) + os.kill(os.getpid(), sig) + + #strip_args = ['-d', '-u'] + #a = sys.argv[:] + #args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] + + #stop_services() + #os.execv(sys.executable, [sys.executable] + args) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - From 89fb9bc09067b442b216195ce55e54da6a99d17d Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Tue, 11 Sep 2012 12:30:02 +0200 Subject: [PATCH 09/64] [FIX] remove depenency on requests 4 insertions(+), 6 deletions(-) bzr revid: al@openerp.com-20120911103002-xdztbyonwfsfjgjk --- openerp/addons/base/module/module.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 79fbac8eb7f..c21f74f5ba2 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -29,6 +29,7 @@ import shutil import sys import tempfile import urllib +import urllib2 import zipfile import zipimport @@ -37,8 +38,6 @@ try: except ImportError: from StringIO import StringIO # NOQA -import requests - from openerp import modules, pooler, release, tools, addons from openerp.tools.parse_version import parse_version from openerp.tools.translate import _ @@ -630,13 +629,12 @@ class module(osv.osv): try: for module_name in urls: try: - r = requests.get(urls[module_name]) - r.raise_for_status() - except requests.HTTPError, e: + content = urllib2.urlopen(urls[module_name]).read() + except Exception, e: _logger.exception('ggr') raise osv.except_osv('grrr', e) else: - zipfile.ZipFile(StringIO(r.content)).extractall(tmp) + zipfile.ZipFile(StringIO(content).extractall(tmp) assert os.path.isdir(os.path.join(tmp, module_name)) for module_name in urls: From 60d217e4a6dcc954aee68f98023307ee3f10d214 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 11 Sep 2012 12:38:53 +0200 Subject: [PATCH 10/64] [FIX] Fix al fix bzr revid: fme@openerp.com-20120911103853-dcx4u5gmsjzorny3 --- openerp/addons/base/module/module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index c21f74f5ba2..ae1268a565e 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -634,7 +634,7 @@ class module(osv.osv): _logger.exception('ggr') raise osv.except_osv('grrr', e) else: - zipfile.ZipFile(StringIO(content).extractall(tmp) + zipfile.ZipFile(StringIO(content)).extractall(tmp) assert os.path.isdir(os.path.join(tmp, module_name)) for module_name in urls: From a37175f85a2d4205f1327735593ddad903de4518 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 11 Sep 2012 13:50:03 +0200 Subject: [PATCH 11/64] [FIX] correct config wizard to not crash if a module is not found bzr revid: chs@openerp.com-20120911115003-8a9a0f8dsoirkx9i --- openerp-server | 2 +- openerp/addons/base/module/module.py | 3 +++ openerp/addons/base/res/res_config.py | 23 ++++++++++++----------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/openerp-server b/openerp-server index bff23d4c4e0..1348d5a6315 100755 --- a/openerp-server +++ b/openerp-server @@ -214,7 +214,7 @@ def quit_on_signals(): a = sys.argv[:] args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] - time.sleep(0.5) # wait end of sockets... + # FIXME http socket cannot be rebind ?!? socket seems to not be freed, even shutdown() is called os.execv(sys.executable, [sys.executable] + args) return diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 93ad9cef4a2..7aabf8091f5 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -625,6 +625,9 @@ class module(osv.osv): zimp.load_module(mod.name) return res + def install_by_names(self, cr, uid, names, context=None): + raise NotImplementedError('# TODO') + def install_from_urls(self, cr, uid, urls, context=None): tmp = tempfile.mkdtemp() try: diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index 3f4a052a36b..7556af500d9 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -467,7 +467,8 @@ class res_config_settings(osv.osv_memory): groups.append((name, ref(field_group), ref(field.implied_group))) elif name.startswith('module_') and isinstance(field, fields.boolean): mod_ids = ir_module.search(cr, uid, [('name', '=', name[7:])]) - modules.append((name, ir_module.browse(cr, uid, mod_ids[0], context))) + record = ir_module.browse(cr, uid, mod_ids[0], context) if mod_ids else None + modules.append((name, record)) else: others.append(name) @@ -491,7 +492,7 @@ class res_config_settings(osv.osv_memory): # modules: which modules are installed/to install for name, module in classified['module']: - res[name] = module.state in ('installed', 'to install', 'to upgrade') + res[name] = module and module.state in ('installed', 'to install', 'to upgrade') # other fields: call all methods that start with 'get_default_' for method in dir(self): @@ -502,9 +503,7 @@ class res_config_settings(osv.osv_memory): def execute(self, cr, uid, ids, context=None): ir_values = self.pool.get('ir.values') - ir_model_data = self.pool.get('ir.model.data') ir_module = self.pool.get('ir.module.module') - res_groups = self.pool.get('res.groups') classified = self._get_classified_fields(cr, uid, context) config = self.browse(cr, uid, ids[0], context) @@ -527,17 +526,19 @@ class res_config_settings(osv.osv_memory): getattr(self, method)(cr, uid, ids, context) # module fields: install/uninstall the selected modules - to_install_ids = [] + to_install_names = [] to_uninstall_ids = [] for name, module in classified['module']: - if config[name]: - if module.state == 'uninstalled': to_install_ids.append(module.id) + if module and module.state in ('installed', 'to upgrade'): + to_uninstall_ids.append(module.id) else: - if module.state in ('installed','upgrade'): to_uninstall_ids.append(module.id) + to_install_names.append(name) - if to_install_ids or to_uninstall_ids: - ir_module.button_uninstall(cr, uid, to_uninstall_ids, context=context) - ir_module.button_immediate_install(cr, uid, to_install_ids, context=context) + if to_uninstall_ids: + ir_module.button_immediate_uninstall(cr, uid, to_uninstall_ids, context=context) + + if to_install_names: + return ir_module.install_by_names(cr, uid, to_install_names, context=context) # force client-side reload (update user menu and current view) return { From 8458885ff1ebe572546a98817cfbb021080411d4 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 11 Sep 2012 14:02:57 +0200 Subject: [PATCH 12/64] [WIP] bzr revid: chs@openerp.com-20120911120257-zm1ho30fpb6vln59 --- openerp/addons/base/module/module.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 7aabf8091f5..77f305b28be 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -625,9 +625,6 @@ class module(osv.osv): zimp.load_module(mod.name) return res - def install_by_names(self, cr, uid, names, context=None): - raise NotImplementedError('# TODO') - def install_from_urls(self, cr, uid, urls, context=None): tmp = tempfile.mkdtemp() try: @@ -682,6 +679,9 @@ class module(osv.osv): finally: shutil.rmtree(tmp) + def install_by_names(self, cr, uid, names, context=None): + raise NotImplementedError('# TODO') + def _update_dependencies(self, cr, uid, mod_browse, depends=None): if depends is None: depends = [] From 2b00459e1ee20c80aeb63dd6202670a7734bf5a6 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 11 Sep 2012 15:00:37 +0200 Subject: [PATCH 13/64] [IMP] flake8 openerp/addons/base/module/module.py bzr revid: chs@openerp.com-20120911130037-vmi1s1b92ihqwutj --- openerp/addons/base/module/module.py | 158 +++++++++++++-------------- 1 file changed, 75 insertions(+), 83 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index fc13d3affc3..455d68c5371 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -18,8 +18,6 @@ # along with this program. If not, see . # ############################################################################## -from collections import defaultdict -import base64 from docutils.core import publish_string import imp import logging @@ -38,7 +36,7 @@ except ImportError: from StringIO import StringIO # NOQA import openerp -from openerp import modules, pooler, release, tools, addons +from openerp import modules, pooler, tools, addons from openerp.tools.parse_version import parse_version from openerp.tools.translate import _ from openerp.osv import fields, osv, orm @@ -51,7 +49,7 @@ ACTION_DICT = { 'res_model': 'base.module.upgrade', 'target': 'new', 'type': 'ir.actions.act_window', - 'nodestroy':True, + 'nodestroy': True, } def backup(path, raise_exception=True): @@ -73,7 +71,7 @@ class module_category(osv.osv): _name = "ir.module.category" _description = "Application" - def _module_nbr(self,cr,uid, ids, prop, unknow_none, context): + def _module_nbr(self, cr, uid, ids, prop, unknow_none, context): cr.execute('SELECT category_id, COUNT(*) \ FROM ir_module_module \ WHERE category_id IN %(ids)s \ @@ -81,7 +79,7 @@ class module_category(osv.osv): FROM ir_module_category \ WHERE parent_id IN %(ids)s) \ GROUP BY category_id', {'ids': tuple(ids)} - ) + ) result = dict(cr.fetchall()) for id in ids: cr.execute('select id from ir_module_category where parent_id=%s', (id,)) @@ -94,16 +92,16 @@ class module_category(osv.osv): 'parent_id': fields.many2one('ir.module.category', 'Parent Application', select=True), 'child_ids': fields.one2many('ir.module.category', 'parent_id', 'Child Applications'), 'module_nr': fields.function(_module_nbr, string='Number of Modules', type='integer'), - 'module_ids' : fields.one2many('ir.module.module', 'category_id', 'Modules'), - 'description' : fields.text("Description", translate=True), - 'sequence' : fields.integer('Sequence'), - 'visible' : fields.boolean('Visible'), + 'module_ids': fields.one2many('ir.module.module', 'category_id', 'Modules'), + 'description': fields.text("Description", translate=True), + 'sequence': fields.integer('Sequence'), + 'visible': fields.boolean('Visible'), 'xml_id': fields.function(osv.osv.get_external_id, type='char', size=128, string="External ID"), } _order = 'name' _defaults = { - 'visible' : 1, + 'visible': 1, } class module(osv.osv): @@ -164,9 +162,11 @@ class module(osv.osv): continue # then, search and group ir.model.data records - imd_models = dict( [(m,[]) for m in dmodels]) - imd_ids = model_data_obj.search(cr,uid,[('module','=', module_rec.name), - ('model','in',tuple(dmodels))]) + imd_models = dict([(m, []) for m in dmodels]) + imd_ids = model_data_obj.search(cr, uid, [ + ('module', '=', module_rec.name), + ('model', 'in', tuple(dmodels)) + ]) for imd_res in model_data_obj.read(cr, uid, imd_ids, ['model', 'res_id'], context=context): imd_models[imd_res['model']].append(imd_res['res_id']) @@ -178,7 +178,7 @@ class module(osv.osv): view_ids = imd_models.get('ir.ui.view', []) for v in view_obj.browse(cr, uid, view_ids, context=context): aa = v.inherit_id and '* INHERIT ' or '' - res_mod_dic['views_by_module'].append(aa + v.name + '('+v.type+')') + res_mod_dic['views_by_module'].append('%s%s (%s)' % (aa, v.name, v.type)) report_ids = imd_models.get('ir.actions.report.xml', []) for rx in report_obj.browse(cr, uid, report_ids, context=context): @@ -188,15 +188,13 @@ class module(osv.osv): for um in menu_obj.browse(cr, uid, menu_ids, context=context): res_mod_dic['menus_by_module'].append(um.complete_name) except KeyError, e: - _logger.warning( - 'Data not found for items of %s', module_rec.name) + _logger.warning('Data not found for items of %s', module_rec.name) except AttributeError, e: - _logger.warning( - 'Data not found for items of %s %s', module_rec.name, str(e)) + _logger.warning('Data not found for items of %s %s', module_rec.name, str(e)) except Exception, e: - _logger.warning('Unknown error while fetching data of %s', - module_rec.name, exc_info=True) - for key, _ in res.iteritems(): + _logger.warning('Unknown error while fetching data of %s', module_rec.name, exc_info=True) + + for key in res.iterkeys(): for k, v in res[key].iteritems(): res[key][k] = "\n".join(sorted(v)) return res @@ -229,41 +227,39 @@ class module(osv.osv): # installed_version refer the latest version (the one on disk) # latest_version refer the installed version (the one in database) # published_version refer the version available on the repository - 'installed_version': fields.function(_get_latest_version, - string='Latest Version', type='char'), + 'installed_version': fields.function(_get_latest_version, string='Latest Version', type='char'), 'latest_version': fields.char('Installed Version', size=64, readonly=True), 'published_version': fields.char('Published Version', size=64, readonly=True), 'url': fields.char('URL', size=128, readonly=True), 'sequence': fields.integer('Sequence'), - 'dependencies_id': fields.one2many('ir.module.module.dependency', - 'module_id', 'Dependencies', readonly=True), + 'dependencies_id': fields.one2many('ir.module.module.dependency', 'module_id', 'Dependencies', readonly=True), 'auto_install': fields.boolean('Automatic Installation', - help='An auto-installable module is automatically installed by the ' - 'system when all its dependencies are satisfied. ' - 'If the module has no dependency, it is always installed.'), + help='An auto-installable module is automatically installed by the ' + 'system when all its dependencies are satisfied. ' + 'If the module has no dependency, it is always installed.'), 'state': fields.selection([ - ('uninstallable','Not Installable'), - ('uninstalled','Not Installed'), - ('installed','Installed'), - ('to upgrade','To be upgraded'), - ('to remove','To be removed'), - ('to install','To be installed') + ('uninstallable', 'Not Installable'), + ('uninstalled', 'Not Installed'), + ('installed', 'Installed'), + ('to upgrade', 'To be upgraded'), + ('to remove', 'To be removed'), + ('to install', 'To be installed') ], string='State', readonly=True, select=True), 'demo': fields.boolean('Demo Data', readonly=True), 'license': fields.selection([ - ('GPL-2', 'GPL Version 2'), - ('GPL-2 or any later version', 'GPL-2 or later version'), - ('GPL-3', 'GPL Version 3'), - ('GPL-3 or any later version', 'GPL-3 or later version'), - ('AGPL-3', 'Affero GPL-3'), - ('Other OSI approved licence', 'Other OSI Approved Licence'), - ('Other proprietary', 'Other Proprietary') + ('GPL-2', 'GPL Version 2'), + ('GPL-2 or any later version', 'GPL-2 or later version'), + ('GPL-3', 'GPL Version 3'), + ('GPL-3 or any later version', 'GPL-3 or later version'), + ('AGPL-3', 'Affero GPL-3'), + ('Other OSI approved licence', 'Other OSI Approved Licence'), + ('Other proprietary', 'Other Proprietary') ], string='License', readonly=True), 'menus_by_module': fields.function(_get_views, string='Menus', type='text', multi="meta", store=True), 'reports_by_module': fields.function(_get_views, string='Reports', type='text', multi="meta", store=True), 'views_by_module': fields.function(_get_views, string='Views', type='text', multi="meta", store=True), - 'certificate' : fields.char('Quality Certificate', size=64, readonly=True), + 'certificate': fields.char('Quality Certificate', size=64, readonly=True), 'application': fields.boolean('Application', readonly=True), 'icon': fields.char('Icon URL', size=128), 'icon_image': fields.function(_get_icon_image, string='Icon', type="binary"), @@ -283,8 +279,8 @@ class module(osv.osv): return _('The certificate ID of the module must be unique !') _sql_constraints = [ - ('name_uniq', 'UNIQUE (name)',_name_uniq_msg ), - ('certificate_uniq', 'UNIQUE (certificate)',_certificate_uniq_msg ) + ('name_uniq', 'UNIQUE (name)', _name_uniq_msg), + ('certificate_uniq', 'UNIQUE (certificate)', _certificate_uniq_msg) ] def unlink(self, cr, uid, ids, context=None): @@ -293,10 +289,9 @@ class module(osv.osv): if isinstance(ids, (int, long)): ids = [ids] mod_names = [] - for mod in self.read(cr, uid, ids, ['state','name'], context): + for mod in self.read(cr, uid, ids, ['state', 'name'], context): if mod['state'] in ('installed', 'to upgrade', 'to remove', 'to install'): - raise orm.except_orm(_('Error'), - _('You try to remove a module that is installed or will be installed')) + raise orm.except_orm(_('Error'), _('You try to remove a module that is installed or will be installed')) mod_names.append(mod['name']) #Removing the entry from ir_model_data #ids_meta = self.pool.get('ir.model.data').search(cr, uid, [('name', '=', 'module_meta_information'), ('module', 'in', mod_names)]) @@ -341,7 +336,7 @@ class module(osv.osv): raise orm.except_orm(_('Error'), msg % (module_name, e.args[0])) def state_update(self, cr, uid, ids, newstate, states_to_update, context=None, level=100): - if level<1: + if level < 1: raise orm.except_orm(_('Error'), _('Recursion error in modules dependencies !')) demo = False for module in self.browse(cr, uid, ids, context=context): @@ -349,9 +344,9 @@ class module(osv.osv): for dep in module.dependencies_id: if dep.state == 'unknown': raise orm.except_orm(_('Error'), _("You try to install module '%s' that depends on module '%s'.\nBut the latter module is not available in your system.") % (module.name, dep.name,)) - ids2 = self.search(cr, uid, [('name','=',dep.name)]) + ids2 = self.search(cr, uid, [('name', '=', dep.name)]) if dep.state != newstate: - mdemo = self.state_update(cr, uid, ids2, newstate, states_to_update, context, level-1,) or mdemo + mdemo = self.state_update(cr, uid, ids2, newstate, states_to_update, context, level - 1) or mdemo else: od = self.browse(cr, uid, ids2)[0] mdemo = od.demo or mdemo @@ -360,7 +355,7 @@ class module(osv.osv): if not module.dependencies_id: mdemo = module.demo if module.state in states_to_update: - self.write(cr, uid, [module.id], {'state': newstate, 'demo':mdemo}) + self.write(cr, uid, [module.id], {'state': newstate, 'demo': mdemo}) demo = demo or mdemo return demo @@ -372,7 +367,7 @@ class module(osv.osv): # Mark (recursively) the newly satisfied modules to also be installed: # Select all auto-installable (but not yet installed) modules. - domain = [('state', '=', 'uninstalled'), ('auto_install', '=', True),] + domain = [('state', '=', 'uninstalled'), ('auto_install', '=', True)] uninstalled_ids = self.search(cr, uid, domain, context=context) uninstalled_modules = self.browse(cr, uid, uninstalled_ids, context=context) @@ -398,7 +393,7 @@ class module(osv.osv): return self._button_immediate_function(cr, uid, ids, self.button_install, context=context) def button_install_cancel(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, {'state': 'uninstalled', 'demo':False}) + self.write(cr, uid, ids, {'state': 'uninstalled', 'demo': False}) return True def module_uninstall(self, cr, uid, ids, context=None): @@ -416,12 +411,13 @@ class module(osv.osv): return True def downstream_dependencies(self, cr, uid, ids, known_dep_ids=None, - exclude_states=['uninstalled','uninstallable','to remove'], + exclude_states=['uninstalled', 'uninstallable', 'to remove'], context=None): """Return the ids of all modules that directly or indirectly depend on the given module `ids`, and that satisfy the `exclude_states` filter""" - if not ids: return [] + if not ids: + return [] known_dep_ids = set(known_dep_ids or []) cr.execute('''SELECT DISTINCT m.id FROM @@ -432,13 +428,13 @@ class module(osv.osv): d.name IN (SELECT name from ir_module_module where id in %s) AND m.state NOT IN %s AND m.id NOT IN %s ''', - (tuple(ids),tuple(exclude_states), tuple(known_dep_ids or ids))) + (tuple(ids), tuple(exclude_states), tuple(known_dep_ids or ids))) new_dep_ids = set([m[0] for m in cr.fetchall()]) missing_mod_ids = new_dep_ids - known_dep_ids known_dep_ids |= new_dep_ids if missing_mod_ids: known_dep_ids |= set(self.downstream_dependencies(cr, uid, list(missing_mod_ids), - known_dep_ids, exclude_states,context)) + known_dep_ids, exclude_states, context)) return list(known_dep_ids) def _button_immediate_function(self, cr, uid, ids, function, context=None): @@ -456,9 +452,9 @@ class module(osv.osv): menu_ids = menu_obj.search(cr, uid, [('parent_id', '=', False)], context=context) return { - 'type' : 'ir.actions.client', - 'tag' : 'reload', - 'params' : {'menu_id' : menu_ids and menu_ids[0] or False} + 'type': 'ir.actions.client', + 'tag': 'reload', + 'params': {'menu_id': menu_ids and menu_ids[0] or False} } def button_immediate_uninstall(self, cr, uid, ids, context=None): @@ -492,20 +488,19 @@ class module(osv.osv): self.update_list(cr, uid) i = 0 - while i Date: Fri, 21 Sep 2012 15:29:11 +0200 Subject: [PATCH 14/64] [IMP] res_config: return correct action for installing modules from apps bzr revid: chs@openerp.com-20120921132911-n6mb58gxlo9aqflm --- openerp/addons/base/res/res_config.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index bd75d280e7c..0ff4b5104d8 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -528,17 +528,24 @@ class res_config_settings(osv.osv_memory): # module fields: install/uninstall the selected modules to_install_names = [] to_uninstall_ids = [] + lm = len('module_') for name, module in classified['module']: if module and module.state in ('installed', 'to upgrade'): to_uninstall_ids.append(module.id) else: - to_install_names.append(name) + to_install_names.append(name[lm:]) if to_uninstall_ids: ir_module.button_immediate_uninstall(cr, uid, to_uninstall_ids, context=context) if to_install_names: - return ir_module.install_by_names(cr, uid, to_install_names, context=context) + return { + 'type': 'ir.actions.client', + 'tag': 'apps', + 'params': {'modules': to_install_names}, + } + + #return ir_module.install_by_names(cr, uid, to_install_names, context=context) # force client-side reload (update user menu and current view) return { From 28cddd0d7dabe399a143e7168b9ca263e12448bf Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 21 Sep 2012 15:57:06 +0200 Subject: [PATCH 15/64] [FIX] wsgi: close explicitly the socket bzr revid: chs@openerp.com-20120921135706-3124bcqt5pbac7ir --- openerp/wsgi/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openerp/wsgi/core.py b/openerp/wsgi/core.py index 0aff7172480..e94236d0509 100644 --- a/openerp/wsgi/core.py +++ b/openerp/wsgi/core.py @@ -456,6 +456,7 @@ def stop_server(): """ if httpd: httpd.shutdown() + openerp.netsvc.close_socket(httpd.socket) # Master process id, can be used for signaling. arbiter_pid = None From 3fe032242ed6375bdadcc46979daf281bd7f5d0f Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 21 Sep 2012 16:30:57 +0200 Subject: [PATCH 16/64] [FIX] apps: store params bzr revid: chs@openerp.com-20120921143057-s2dq1821j0y7fgml --- openerp/addons/base/static/src/js/apps.js | 27 ++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index c3abd399ca8..92c9c700ec7 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -5,19 +5,26 @@ openerp.base = function(instance) { template: 'EmptyComponent', init: function(parent, options) { this._super(parent); + this.params = options; + this.clean(); // create a new instance this.remote_instance = new openerp.init(); - }, - destroy: function() { + clean: function() { if (this.client) { this.client.destroy(); } - delete this.remote_instance; }, - + + destroy: function() { + this.clean(); + //delete this.remote_instance; + this._super(); + }, + _get_options: function() { + var self = this; //var DEFAULT_SERVER = 'http://apps.openerp.com/loempia'; // PROD var DEFAULT_SERVER = 'http://apps.openerp.com:9069/loempia7'; // TEST //var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7'; // DEV @@ -47,11 +54,11 @@ openerp.base = function(instance) { this.options = options; var client = this.client = new this.remote_instance.web.EmbeddedClient(null, this.options.url, - this.options.dbname, this.options.login, this.options.password, - this.options.action_id, this.action_flags); + this.options.dbname, this.options.login, this.options.password, + this.options.action_id); client.on('connection_failed', this, this.action_fallback); - this.client = client; - + //this.client = client; + client.replace(this.$el). done(function() { client.$el.removeClass('openerp'); @@ -61,11 +68,11 @@ openerp.base = function(instance) { alert('fail'); }); }, - + action_fallback: function() { // TODO show flash message this.do_warn(this.options.url + ' unreachable'); - this.do_action('base.action_modules'); + this.do_action('base.action_modules'); } }); From 8ad77552a421fec63d9f2cbc8f354d8bb39ca49f Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 24 Sep 2012 16:27:25 +0200 Subject: [PATCH 17/64] [FIX] apps: fallback to local module list when apps server is not available bzr revid: chs@openerp.com-20120924142725-lkzlpzv57ssrng8s --- openerp/addons/base/static/src/js/apps.js | 41 +++++++++++------------ 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 92c9c700ec7..829d08881b1 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -5,7 +5,7 @@ openerp.base = function(instance) { template: 'EmptyComponent', init: function(parent, options) { this._super(parent); - this.params = options; + this.params = options; // NOTE read by embeded client action this.clean(); // create a new instance this.remote_instance = new openerp.init(); @@ -20,7 +20,7 @@ openerp.base = function(instance) { destroy: function() { this.clean(); //delete this.remote_instance; - this._super(); + return this._super(); }, _get_options: function() { @@ -51,28 +51,25 @@ openerp.base = function(instance) { return this._get_options().then(this.proxy('_connect')); }, _connect: function(options) { - this.options = options; + var self = this; + // before creating the client, check the connectivity... + var i = new Image(); + i.onerror = function() { + self.do_warn(_.str.sprintf('Apps Server %s not available.', options.url), 'Showing local modules.', true); + self.do_action('base.open_module_tree'); + }; + i.onload = function() { - var client = this.client = new this.remote_instance.web.EmbeddedClient(null, this.options.url, - this.options.dbname, this.options.login, this.options.password, - this.options.action_id); - client.on('connection_failed', this, this.action_fallback); - //this.client = client; + var client = self.client = new self.remote_instance.web.EmbeddedClient(null, options.url, + options.dbname, options.login, options.password, + options.action_id); - client.replace(this.$el). - done(function() { - client.$el.removeClass('openerp'); - }). - fail(function() { - console.log('fail', this); - alert('fail'); - }); - }, - - action_fallback: function() { - // TODO show flash message - this.do_warn(this.options.url + ' unreachable'); - this.do_action('base.action_modules'); + client.replace(self.$el). + done(function() { + client.$el.removeClass('openerp'); + }); + }; + i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif', options.url); } }); From 3c8381c299e02be83fa0a5ea3409d68206ef9561 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 24 Sep 2012 17:08:21 +0200 Subject: [PATCH 18/64] [IMP] rearrange local modules menus bzr revid: chs@openerp.com-20120924150821-de4sckxujgyhaoeq --- openerp/addons/base/module/module_view.xml | 7 ++++--- .../addons/base/module/wizard/base_module_import_view.xml | 2 +- .../addons/base/module/wizard/base_module_update_view.xml | 2 +- .../addons/base/module/wizard/base_module_upgrade_view.xml | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index 2f4ded8830e..d525d10987b 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -182,7 +182,7 @@ - Install a Module + Modules ir.module.module form kanban,tree,form @@ -193,8 +193,9 @@

You should try others search criteria.

- + + diff --git a/openerp/addons/base/module/wizard/base_module_import_view.xml b/openerp/addons/base/module/wizard/base_module_import_view.xml index 938998506f0..59c781c5aad 100644 --- a/openerp/addons/base/module/wizard/base_module_import_view.xml +++ b/openerp/addons/base/module/wizard/base_module_import_view.xml @@ -41,7 +41,7 @@ name="Import Module" action="action_view_base_module_import" id="menu_view_base_module_import" - parent="menu_module_tree" + parent="menu_local_modules" groups="base.group_no_one" sequence="1"/> --> diff --git a/openerp/addons/base/module/wizard/base_module_update_view.xml b/openerp/addons/base/module/wizard/base_module_update_view.xml index fb1c5a980f6..841f773fc8d 100644 --- a/openerp/addons/base/module/wizard/base_module_update_view.xml +++ b/openerp/addons/base/module/wizard/base_module_update_view.xml @@ -44,7 +44,7 @@ action="action_view_base_module_update" id="menu_view_base_module_update" groups="base.group_no_one" - parent="menu_module_tree" + parent="menu_local_modules" sequence="2" icon="STOCK_CONVERT"/> diff --git a/openerp/addons/base/module/wizard/base_module_upgrade_view.xml b/openerp/addons/base/module/wizard/base_module_upgrade_view.xml index 210cdccd5be..9e785d7f993 100644 --- a/openerp/addons/base/module/wizard/base_module_upgrade_view.xml +++ b/openerp/addons/base/module/wizard/base_module_upgrade_view.xml @@ -34,7 +34,7 @@ action="action_view_base_module_upgrade" groups="base.group_no_one" id="menu_view_base_module_upgrade" - parent="menu_module_tree" + parent="menu_local_modules" sequence="3"/> From 180582656674fb2effb615fc1c8fb8a6131651c0 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 25 Sep 2012 17:19:44 +0200 Subject: [PATCH 19/64] [FIX] res_config: only install selected modules bzr revid: chs@openerp.com-20120925151944-84a93rm1yvza79js --- openerp/addons/base/res/res_config.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index 0ff4b5104d8..bba206294bf 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -530,10 +530,12 @@ class res_config_settings(osv.osv_memory): to_uninstall_ids = [] lm = len('module_') for name, module in classified['module']: - if module and module.state in ('installed', 'to upgrade'): - to_uninstall_ids.append(module.id) + if config[name]: + if not module or module.state == 'uninstalled': + to_install_names.append(name[lm:]) else: - to_install_names.append(name[lm:]) + if module and module.state in ('installed', 'to upgrade'): + to_uninstall_ids.append(module.id) if to_uninstall_ids: ir_module.button_immediate_uninstall(cr, uid, to_uninstall_ids, context=context) @@ -545,8 +547,6 @@ class res_config_settings(osv.osv_memory): 'params': {'modules': to_install_names}, } - #return ir_module.install_by_names(cr, uid, to_install_names, context=context) - # force client-side reload (update user menu and current view) return { 'type': 'ir.actions.client', From b4aa241adeba3bc4df846c4b80bd1ecce97ab6a1 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 28 Sep 2012 11:49:59 +0200 Subject: [PATCH 20/64] [REF] apps: change the way the remote client is created. Show an error when the remote host is not reachable bzr revid: chs@openerp.com-20120928094959-0hp3aaiw8bfcm2sw --- openerp/addons/base/static/src/js/apps.js | 120 ++++++++++++---------- 1 file changed, 68 insertions(+), 52 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 829d08881b1..e1bf2365ca8 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -1,30 +1,27 @@ openerp.base = function(instance) { - instance.base = {}; - instance.base.Apps = instance.web.Widget.extend({ - template: 'EmptyComponent', - init: function(parent, options) { - this._super(parent); - this.params = options; // NOTE read by embeded client action - this.clean(); - // create a new instance - this.remote_instance = new openerp.init(); - }, + instance.base = {apps:{}}; - clean: function() { - if (this.client) { - this.client.destroy(); - } - }, + instance.base.apps.remote_instance = null; - destroy: function() { - this.clean(); - //delete this.remote_instance; - return this._super(); - }, - - _get_options: function() { - var self = this; + instance.base.apps.get_client = function() { + // return the client via a deferred, resolved or rejected depending if the remote host is available or not. + var check_client_available = function(client) { + var d = $.Deferred(); + var i = new Image(); + i.onerror = function() { + d.reject(client); + }; + i.onload = function() { + console.log('client is available', client); + d.resolve(client); + }; + i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif', client.origin); + return d.promise(); + }; + if (instance.base.apps._client) { + return check_client_available(instance.base.apps._client); + } else { //var DEFAULT_SERVER = 'http://apps.openerp.com/loempia'; // PROD var DEFAULT_SERVER = 'http://apps.openerp.com:9069/loempia7'; // TEST //var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7'; // DEV @@ -37,41 +34,60 @@ openerp.base = function(instance) { var login = (sessionStorage ? sessionStorage.getItem('loempia.login') : null) || 'anonymous'; var passwd = (sessionStorage ? sessionStorage.getItem('loempia.passwd') : null) || 'anonymous'; - return { - url: host, - dbname: dbname, - login: login, - password: passwd, - action_id: 'loempia.action_embed' - }; + if (_.isNull(instance.base.apps.remote_instance)) { + instance.base.apps.remote_instance = new openerp.init(); + } + var client = new instance.base.apps.remote_instance.web.EmbeddedClient(null, host, + dbname, login, passwd); + + console.log('new client', client); + instance.base.apps._client = client; + return check_client_available(client); }); + } + + }; + + instance.base.apps.Apps = instance.web.Widget.extend({ + template: 'EmptyComponent', + init: function(parent, options) { + this._super(parent); + this.params = options; // NOTE read by embeded client action + }, + + clean: function() { + instance.base.apps.get_client().always(function(client) { client.destroy(); }); + }, + + destroy: function() { + this.clean(); + return this._super(); }, start: function() { - return this._get_options().then(this.proxy('_connect')); - }, - _connect: function(options) { var self = this; - // before creating the client, check the connectivity... - var i = new Image(); - i.onerror = function() { - self.do_warn(_.str.sprintf('Apps Server %s not available.', options.url), 'Showing local modules.', true); - self.do_action('base.open_module_tree'); - }; - i.onload = function() { + console.time('apps'); + console.time('client'); + console.log('Apps.start()'); + return instance.base.apps.get_client(). + done(function(client) { + console.timeEnd('client'); + client.replace(self.$el). + done(function() { + client.$el.removeClass('openerp'); + console.timeEnd('apps'); + client.do_action('loempia.action_embed'); + }); + }). + fail(function(client) { + self.do_warn('Apps Server not reachable.', 'Showing local modules.', true); + self.do_action('base.open_module_tree'); + }); + }, - var client = self.client = new self.remote_instance.web.EmbeddedClient(null, options.url, - options.dbname, options.login, options.password, - options.action_id); - - client.replace(self.$el). - done(function() { - client.$el.removeClass('openerp'); - }); - }; - i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif', options.url); - } + 0:0 }); - instance.web.client_actions.add("apps", "instance.base.Apps"); + instance.web.client_actions.add("apps", "instance.base.apps.Apps"); + }; From 86b91826a343f26597fdd45ecebd412255eaab69 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 28 Sep 2012 13:31:43 +0200 Subject: [PATCH 21/64] [FIX] apps: reload client when updating a module bzr revid: chs@openerp.com-20120928113143-drizsnkiev35r8y1 --- openerp/addons/base/module/module.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 455d68c5371..72f48e15d34 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -664,7 +664,10 @@ class module(osv.osv): # if any to update cr.commit() openerp.service.restart_server() - return False + return { + 'type': 'ir.actions.client', + 'tag': 'reload' + } return self.button_immediate_install(cr, uid, ids, context=context) finally: shutil.rmtree(tmp) From 6d00f4e900c9cb5841b882b12487ea3cf8bf1f5c Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 28 Sep 2012 13:33:29 +0200 Subject: [PATCH 22/64] [IMP] modules: reorder menus bzr revid: chs@openerp.com-20120928113329-26sip23spkkv01wm --- openerp/addons/base/module/module_view.xml | 23 +++++++++++++------ .../module/wizard/base_module_import_view.xml | 4 ++-- .../module/wizard/base_module_update_view.xml | 10 ++++---- .../wizard/base_module_upgrade_view.xml | 4 ++-- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index d525d10987b..15a2673c910 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -3,11 +3,20 @@ - Modules + Modules apps + + + Updates Available + apps + {'updates': 1} + + + + @@ -49,7 +58,7 @@ - + @@ -181,21 +190,21 @@ + - Modules + Installed Modules ir.module.module form kanban,tree,form - {'search_default_app':1} + {'search_default_installed':1}

No module found!

You should try others search criteria.

- - +
diff --git a/openerp/addons/base/module/wizard/base_module_import_view.xml b/openerp/addons/base/module/wizard/base_module_import_view.xml index 59c781c5aad..d9d6bb6ee78 100644 --- a/openerp/addons/base/module/wizard/base_module_import_view.xml +++ b/openerp/addons/base/module/wizard/base_module_import_view.xml @@ -41,9 +41,9 @@ name="Import Module" action="action_view_base_module_import" id="menu_view_base_module_import" - parent="menu_local_modules" + parent="menu_management" groups="base.group_no_one" - sequence="1"/> + sequence="6"/> --> diff --git a/openerp/addons/base/module/wizard/base_module_update_view.xml b/openerp/addons/base/module/wizard/base_module_update_view.xml index 841f773fc8d..64461e12707 100644 --- a/openerp/addons/base/module/wizard/base_module_update_view.xml +++ b/openerp/addons/base/module/wizard/base_module_update_view.xml @@ -18,17 +18,17 @@
-
-
-
+
Module Update @@ -44,8 +44,8 @@ action="action_view_base_module_update" id="menu_view_base_module_update" groups="base.group_no_one" - parent="menu_local_modules" - sequence="2" + parent="menu_management" + sequence="4" icon="STOCK_CONVERT"/> diff --git a/openerp/addons/base/module/wizard/base_module_upgrade_view.xml b/openerp/addons/base/module/wizard/base_module_upgrade_view.xml index 9e785d7f993..9b45c4915b2 100644 --- a/openerp/addons/base/module/wizard/base_module_upgrade_view.xml +++ b/openerp/addons/base/module/wizard/base_module_upgrade_view.xml @@ -34,8 +34,8 @@ action="action_view_base_module_upgrade" groups="base.group_no_one" id="menu_view_base_module_upgrade" - parent="menu_local_modules" - sequence="3"/> + parent="menu_management" + sequence="5"/> Module Upgrade Install From 0f47c550ec8db2a6d724d433608601bff07020cb Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 28 Sep 2012 14:58:40 +0200 Subject: [PATCH 23/64] [IMP] apps: add new client action to show updates availables bzr revid: chs@openerp.com-20120928125840-or2eql38s9mku6ab --- openerp/addons/base/module/module_view.xml | 4 ++-- openerp/addons/base/static/src/js/apps.js | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index 15a2673c910..4702473183c 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -11,8 +11,8 @@ Updates Available - apps - {'updates': 1} + apps.updates + {} diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index e1bf2365ca8..5d60a824382 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -50,9 +50,13 @@ openerp.base = function(instance) { instance.base.apps.Apps = instance.web.Widget.extend({ template: 'EmptyComponent', + + remote_action_id: 'loempia.action_embed', + failback_action_id: 'base.open_module_tree', + init: function(parent, options) { this._super(parent); - this.params = options; // NOTE read by embeded client action + this.params = options; // NOTE read by embedded client action }, clean: function() { @@ -76,18 +80,23 @@ openerp.base = function(instance) { done(function() { client.$el.removeClass('openerp'); console.timeEnd('apps'); - client.do_action('loempia.action_embed'); + client.do_action(self.remote_action_id); }); }). fail(function(client) { self.do_warn('Apps Server not reachable.', 'Showing local modules.', true); - self.do_action('base.open_module_tree'); + self.do_action(self.failback_action_id); }); }, 0:0 }); + instance.base.apps.UpdatesAvailable = instance.base.apps.Apps.extend({ + remote_action_id: 'loempia.action_embed_updates' + }) + instance.web.client_actions.add("apps", "instance.base.apps.Apps"); + instance.web.client_actions.add("apps.updates", "instance.base.apps.UpdatesAvailable"); }; From bfd0ffb694f1cbc817d190509ac674e6ea5890c6 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 1 Oct 2012 18:44:32 +0200 Subject: [PATCH 24/64] [IMP] rpc: common/version return more info bzr revid: chs@openerp.com-20121001164432-z5cqm6ffmgoocnec --- openerp/service/web_services.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 1eebac9a7a0..5e01ad56105 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -54,7 +54,16 @@ from openerp import SUPERUSER_ID _logger = logging.getLogger(__name__) -RPC_VERSION_1 = {'server_version': '6.1', 'protocol_version': 1} +RPC_VERSION_1 = { + 'openerp': { + 'version': release.version, + 'version_info': release.version_info, + 'serie': release.serie, + }, + 'protocol': { + 'version': 1 + }, +} # This should be moved to openerp.modules.db, along side initialize(). def _initialize_db(serv, id, db_name, demo, lang, user_password): From bbf705dbcfb0ecbc127ac09b9b6eae11e0ac9598 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 2 Oct 2012 12:06:39 +0200 Subject: [PATCH 25/64] [FIX] modules: correct "openerp" update bzr revid: chs@openerp.com-20121002100639-lx61srh0v119avj0 --- openerp/addons/base/module/module.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 72f48e15d34..f8f06502f21 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -629,8 +629,10 @@ class module(osv.osv): zipfile.ZipFile(StringIO(content)).extractall(tmp) assert os.path.isdir(os.path.join(tmp, module_name)) + OPENERP = 'openerp' + for module_name in urls: - if module_name == 'base': + if module_name == OPENERP: continue # special case. handled below module_path = modules.get_module_path(module_name, downloaded=True, display_warning=False) bck = backup(module_path, False) @@ -638,22 +640,22 @@ class module(osv.osv): if bck: shutil.rmtree(bck) - if urls.get('base', None): - # base is a special case. it containt the server and the base module. + if urls.get(OPENERP, None): + # special case. it containt the server and the base module. # extract path is not the same - # TODO copy all modules in the SERVER/openerp/addons directory to the new "base" module (exceptbase itself) - # then replace the server by the new "base" module base_path = os.path.dirname(modules.get_module_path('base')) + # copy all modules in the SERVER/openerp/addons directory to the new "openerp" module (except base itself) for d in os.listdir(base_path): if d != 'base' and os.path.isdir(os.path.join(base_path, d)): - destdir = os.path.join(tmp, 'base', 'addons', d) # XXX 'openerp' + destdir = os.path.join(tmp, OPENERP, 'addons', d) # XXX 'openerp' subdirectory ? shutil.copytree(os.path.join(base_path, d), destdir) + # then replace the server by the new "base" module server_dir = openerp.tools.config['root_path'] # XXX or dirname() bck = backup(server_dir) - shutil.move(os.path.join(tmp, 'base'), server_dir) + shutil.move(os.path.join(tmp, OPENERP), server_dir) #if bck: # shutil.rmtree(bck) From 5eccc931771043854682a4d122de6035fdc97f71 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 2 Oct 2012 15:25:35 +0200 Subject: [PATCH 26/64] [FIX] base: modules: install_from_urls: an empty url mean nothing to download bzr revid: chs@openerp.com-20121002132535-l0tajxiqydn7ahcv --- openerp/addons/base/module/module.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index f8f06502f21..804f8f3e5b7 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -617,11 +617,14 @@ class module(osv.osv): return res def install_from_urls(self, cr, uid, urls, context=None): + OPENERP = 'openerp' tmp = tempfile.mkdtemp() try: - for module_name in urls: + for module_name, url in urls.items(): + if not url: + continue # nothing to download, local version is already the last one try: - content = urllib2.urlopen(urls[module_name]).read() + content = urllib2.urlopen(url).read() except Exception, e: _logger.exception('ggr') raise osv.except_osv('grrr', e) @@ -629,8 +632,6 @@ class module(osv.osv): zipfile.ZipFile(StringIO(content)).extractall(tmp) assert os.path.isdir(os.path.join(tmp, module_name)) - OPENERP = 'openerp' - for module_name in urls: if module_name == OPENERP: continue # special case. handled below From 897a5afbdfa6d1e5f801104795efb4e368b3a2fe Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 2 Oct 2012 18:26:11 +0200 Subject: [PATCH 27/64] [IMP] modules: rename xmlid bzr revid: chs@openerp.com-20121002162611-uf3hkas78epif0l2 --- openerp/addons/base/module/module_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index 4702473183c..88d9313a5f7 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -15,7 +15,7 @@ {} - + From 70f2f8bc8ecd4f2109cad9d61085d42db2c1fd96 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 11 Oct 2012 11:22:49 +0200 Subject: [PATCH 28/64] [FIX] apps: log user in bzr revid: chs@openerp.com-20121011092249-m6anmzie9oxv6nnw --- openerp/addons/base/static/src/js/apps.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 5d60a824382..125b8a54fad 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -31,8 +31,8 @@ openerp.base = function(instance) { var host = _.str.sprintf('%s//%s', link.protocol, link.host); var dbname = link.pathname.substr(1); - var login = (sessionStorage ? sessionStorage.getItem('loempia.login') : null) || 'anonymous'; - var passwd = (sessionStorage ? sessionStorage.getItem('loempia.passwd') : null) || 'anonymous'; + var login = (sessionStorage ? sessionStorage.getItem('apps.login') : null) || 'anonymous'; + var passwd = (sessionStorage ? sessionStorage.getItem('apps.access_token') : null) || 'anonymous'; if (_.isNull(instance.base.apps.remote_instance)) { instance.base.apps.remote_instance = new openerp.init(); @@ -56,6 +56,14 @@ openerp.base = function(instance) { init: function(parent, options) { this._super(parent); + + if (options.apps_user) { + sessionStorage.setItem('apps.login', options.apps_user); + } + if (options.apps_access_token) { + sessionStorage.setItem('apps.access_token', options.apps_access_token); + } + this.params = options; // NOTE read by embedded client action }, From 9373587e5a93dd69d2bce33d4de64afb4c358a92 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 15 Oct 2012 18:26:26 +0200 Subject: [PATCH 29/64] [FIX] apps: test if client can connect. failback and connect as anonymous bzr revid: chs@openerp.com-20121015162626-ea5hrrfxqkdqafo7 --- openerp/addons/base/static/src/js/apps.js | 26 ++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 125b8a54fad..1f3566f7b2d 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -14,7 +14,27 @@ openerp.base = function(instance) { }; i.onload = function() { console.log('client is available', client); - d.resolve(client); + + client.session.session_bind(client.origin).then(function() { + // check if client can authenticate + client.authenticate().done(function() { + d.resolve(client); + }).fail(function() { + if (client.login === 'anonymous') { + d.reject(client); + } else { + sessionStorage.removeItem('apps.login'); + sessionStorage.removeItem('apps.access_token'); + client.bind(client.dbname, 'anonymous', 'anonymous'); + client.authenticate().done(function() { + d.resolve(client); + }).fail(function() { + d.reject(client); + }); + } + }); + }); + }; i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif', client.origin); return d.promise(); @@ -56,7 +76,7 @@ openerp.base = function(instance) { init: function(parent, options) { this._super(parent); - + if (options.apps_user) { sessionStorage.setItem('apps.login', options.apps_user); } @@ -102,7 +122,7 @@ openerp.base = function(instance) { instance.base.apps.UpdatesAvailable = instance.base.apps.Apps.extend({ remote_action_id: 'loempia.action_embed_updates' - }) + }); instance.web.client_actions.add("apps", "instance.base.apps.Apps"); instance.web.client_actions.add("apps.updates", "instance.base.apps.UpdatesAvailable"); From c1d67819ee9235566d0778db97edc96839072167 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 19 Oct 2012 14:29:06 +0200 Subject: [PATCH 30/64] [FIX] apps: change test server bzr revid: chs@openerp.com-20121019122906-8vpwgycr0mqcfvsj --- openerp/addons/base/static/src/js/apps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 1f3566f7b2d..38c8b4f334b 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -43,7 +43,7 @@ openerp.base = function(instance) { return check_client_available(instance.base.apps._client); } else { //var DEFAULT_SERVER = 'http://apps.openerp.com/loempia'; // PROD - var DEFAULT_SERVER = 'http://apps.openerp.com:9069/loempia7'; // TEST + var DEFAULT_SERVER = 'http://apps.v7.openerp.com:8069/apps'; // TEST //var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7'; // DEV var ICP = new instance.web.Model('ir.config_parameter'); return ICP.call('get_param', ['loempia.server', DEFAULT_SERVER]).pipe(function(u) { From 0499ba78af67ac1816aad8a1f92ab097201d93f6 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 30 Oct 2012 11:59:10 +0100 Subject: [PATCH 31/64] [FIX] correct restart of openerp bzr revid: chs@openerp.com-20121030105910-r3bol2cvs6a1mbxd --- openerp/service/__init__.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index baabb17c5ab..acf4161f563 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -22,14 +22,11 @@ import logging import os import signal -import sys import threading import time -import http_server import netrpc_server import web_services -import websrv_lib import openerp.cron import openerp.modules @@ -126,13 +123,13 @@ def stop_services(): logging.shutdown() def start_services_workers(): - openerp.multi_process = True # Nah! - + openerp.multi_process = True openerp.service.workers.Multicorn(openerp.service.wsgi_server.application).run() def restart_server(): - pid = openerp.wsgi.core.arbiter_pid - if pid: + if openerp.multi_process: + raise NotImplementedError("Multicorn is not supported (but gunicorn was)") + pid = openerp.wsgi.core.arbiter_pid os.kill(pid, signal.SIGHUP) else: openerp.phoenix = True @@ -140,11 +137,4 @@ def restart_server(): sig = getattr(signal, signame) os.kill(os.getpid(), sig) - #strip_args = ['-d', '-u'] - #a = sys.argv[:] - #args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] - - #stop_services() - #os.execv(sys.executable, [sys.executable] + args) - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 9cdc77b6ea22a9ccafde9ce6e7e65c9d08d75353 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 31 Oct 2012 13:03:01 +0100 Subject: [PATCH 32/64] [IMP] modules: go home after restart of server bzr revid: chs@openerp.com-20121031120301-b6680zyxq7u1wxq4 --- openerp/addons/base/module/module.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 5e3698f6867..c6da65c7c2c 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -663,7 +663,8 @@ class module(osv.osv): openerp.service.restart_server() return { 'type': 'ir.actions.client', - 'tag': 'reload' + 'tag': 'home', + 'params': {'wait': True}, } return self.button_immediate_install(cr, uid, ids, context=context) finally: From 35975001d2b05f37ccb1e867a2fb569ac642413e Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 6 Nov 2012 18:06:57 +0100 Subject: [PATCH 33/64] [FIX] client actions take action in params bzr revid: chs@openerp.com-20121106170657-328uq20n0bawjjbf --- openerp/addons/base/static/src/js/apps.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 38c8b4f334b..7c5090567f7 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -74,8 +74,9 @@ openerp.base = function(instance) { remote_action_id: 'loempia.action_embed', failback_action_id: 'base.open_module_tree', - init: function(parent, options) { - this._super(parent); + init: function(parent, action) { + this._super(parent, action); + var options = actions.params || {}; if (options.apps_user) { sessionStorage.setItem('apps.login', options.apps_user); From 9381aaf362c94b06287e24e1bbb7bb77037447d4 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 8 Nov 2012 12:48:18 +0100 Subject: [PATCH 34/64] another big bag of changes bzr revid: chs@openerp.com-20121108114818-jcxk0q0f202v2310 --- openerp/addons/base/static/src/js/apps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 7c5090567f7..a2427525ce8 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -76,7 +76,7 @@ openerp.base = function(instance) { init: function(parent, action) { this._super(parent, action); - var options = actions.params || {}; + var options = action.params || {}; if (options.apps_user) { sessionStorage.setItem('apps.login', options.apps_user); From 7ea98f28d788ab11b5f6a0f0fa0c210c3fa32d31 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 8 Nov 2012 17:46:11 +0100 Subject: [PATCH 35/64] [IMP] add TODO/FIXME comments bzr revid: chs@openerp.com-20121108164611-34l07gsjer1lrqc2 --- openerp/addons/base/static/src/js/apps.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index a2427525ce8..9102574b1ee 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -1,5 +1,10 @@ openerp.base = function(instance) { +// FIXME do not work on safari +// TODO test on IE +// FIXME when apps server is not available, redirect to failback action but do not highligth the good menu +// FIXME when back from oe_account (via oe_apps), error is show: load action 3 times !!! + instance.base = {apps:{}}; instance.base.apps.remote_instance = null; From deb730e562e0357b909e169dbf99ccee8c469c15 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 8 Nov 2012 17:56:08 +0100 Subject: [PATCH 36/64] [FIX] then -> done; pipe -> then bzr revid: chs@openerp.com-20121108165608-e67f0dwwufdpfmzt --- openerp/addons/base/static/src/js/apps.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 9102574b1ee..ebcf197e600 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -20,7 +20,7 @@ openerp.base = function(instance) { i.onload = function() { console.log('client is available', client); - client.session.session_bind(client.origin).then(function() { + client.session.session_bind(client.origin).done(function() { // check if client can authenticate client.authenticate().done(function() { d.resolve(client); @@ -51,7 +51,7 @@ openerp.base = function(instance) { var DEFAULT_SERVER = 'http://apps.v7.openerp.com:8069/apps'; // TEST //var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7'; // DEV var ICP = new instance.web.Model('ir.config_parameter'); - return ICP.call('get_param', ['loempia.server', DEFAULT_SERVER]).pipe(function(u) { + return ICP.call('get_param', ['loempia.server', DEFAULT_SERVER]).then(function(u) { var link = $(_.str.sprintf('', u))[0]; var host = _.str.sprintf('%s//%s', link.protocol, link.host); var dbname = link.pathname.substr(1); From 885880675a1beb200de89f14f86841a04acb8a23 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 8 Nov 2012 19:00:26 +0100 Subject: [PATCH 37/64] [REM] fixed // FIXME bzr revid: chs@openerp.com-20121108180026-vw2lg0thd9v0rivq --- openerp/addons/base/static/src/js/apps.js | 1 - 1 file changed, 1 deletion(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index ebcf197e600..dde7a0a72e1 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -3,7 +3,6 @@ openerp.base = function(instance) { // FIXME do not work on safari // TODO test on IE // FIXME when apps server is not available, redirect to failback action but do not highligth the good menu -// FIXME when back from oe_account (via oe_apps), error is show: load action 3 times !!! instance.base = {apps:{}}; From 83462b5830470e8a14ab2abb461781bf93c4609b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 9 Nov 2012 18:31:46 +0100 Subject: [PATCH 38/64] [FIX] correct then/done errors + highlight "installed modules" menu when apps is not reachable bzr revid: chs@openerp.com-20121109173146-5mzdtyni92v3ub1d --- openerp/addons/base/static/src/js/apps.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index dde7a0a72e1..d755cf6d780 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -19,20 +19,22 @@ openerp.base = function(instance) { i.onload = function() { console.log('client is available', client); - client.session.session_bind(client.origin).done(function() { + client.session.session_bind(client.origin).then(function() { // check if client can authenticate - client.authenticate().done(function() { + client.authenticate().then( + function() { /* done */ d.resolve(client); - }).fail(function() { + }, function() { /* fail */ if (client.login === 'anonymous') { d.reject(client); } else { sessionStorage.removeItem('apps.login'); sessionStorage.removeItem('apps.access_token'); client.bind(client.dbname, 'anonymous', 'anonymous'); - client.authenticate().done(function() { + client.authenticate().then( + function() { /* done */ d.resolve(client); - }).fail(function() { + }, function() { /* fail */ d.reject(client); }); } @@ -118,7 +120,10 @@ openerp.base = function(instance) { }). fail(function(client) { self.do_warn('Apps Server not reachable.', 'Showing local modules.', true); - self.do_action(self.failback_action_id); + self.rpc('/web/action/load', {action_id: self.failback_action_id}).done(function(action) { + self.do_action(action); + instance.webclient.menu.open_action(action.id); + }); }); }, From 0ec72b1ca01c1f7c31deb6646f8a9a536dfbc7a5 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 13 Nov 2012 11:37:15 +0100 Subject: [PATCH 39/64] [FIX] apps: correct strip of "/" in dbname bzr revid: chs@openerp.com-20121113103715-5fiu9tg05o6ouxc9 --- openerp/addons/base/static/src/js/apps.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index d755cf6d780..f4cf5223a67 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -55,7 +55,10 @@ openerp.base = function(instance) { return ICP.call('get_param', ['loempia.server', DEFAULT_SERVER]).then(function(u) { var link = $(_.str.sprintf('', u))[0]; var host = _.str.sprintf('%s//%s', link.protocol, link.host); - var dbname = link.pathname.substr(1); + var dbname = link.pathname; + if (dbname[0] === '/') { + dbname = dbname.substr(1); + } var login = (sessionStorage ? sessionStorage.getItem('apps.login') : null) || 'anonymous'; var passwd = (sessionStorage ? sessionStorage.getItem('apps.access_token') : null) || 'anonymous'; From 1360cceff89ec80063f1f74d472759b4b73fe3aa Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 14 Nov 2012 17:57:17 +0100 Subject: [PATCH 40/64] [REM] remove // FIXME comments are they are now fixed [REM] console.* bzr revid: chs@openerp.com-20121114165717-iyumkzldvab4r8l1 --- openerp/addons/base/static/src/js/apps.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index f4cf5223a67..0b0eea68216 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -1,9 +1,5 @@ openerp.base = function(instance) { -// FIXME do not work on safari -// TODO test on IE -// FIXME when apps server is not available, redirect to failback action but do not highligth the good menu - instance.base = {apps:{}}; instance.base.apps.remote_instance = null; @@ -17,8 +13,6 @@ openerp.base = function(instance) { d.reject(client); }; i.onload = function() { - console.log('client is available', client); - client.session.session_bind(client.origin).then(function() { // check if client can authenticate client.authenticate().then( @@ -68,8 +62,6 @@ openerp.base = function(instance) { } var client = new instance.base.apps.remote_instance.web.EmbeddedClient(null, host, dbname, login, passwd); - - console.log('new client', client); instance.base.apps._client = client; return check_client_available(client); }); @@ -108,16 +100,11 @@ openerp.base = function(instance) { start: function() { var self = this; - console.time('apps'); - console.time('client'); - console.log('Apps.start()'); return instance.base.apps.get_client(). done(function(client) { - console.timeEnd('client'); client.replace(self.$el). done(function() { client.$el.removeClass('openerp'); - console.timeEnd('apps'); client.do_action(self.remote_action_id); }); }). From 927c5635b807ad683667e9b39ecde0d85db7ace5 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 23 Nov 2012 15:08:38 +0100 Subject: [PATCH 41/64] [IMP] extract method to reexec server bzr revid: chs@openerp.com-20121123140838-pz47cw4jtlxx8e74 --- openerp/main.py | 7 +------ openerp/service/__init__.py | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/openerp/main.py b/openerp/main.py index c1991992011..f8b5c6ec2ed 100644 --- a/openerp/main.py +++ b/openerp/main.py @@ -210,12 +210,7 @@ def quit_on_signals(): if getattr(openerp, 'phoenix', False): # like the phoenix, reborn from ashes... - strip_args = ['-d', '-u'] - a = sys.argv[:] - args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] - - # FIXME http socket cannot be rebind ?!? socket seems to not be freed, even shutdown() is called - os.execv(sys.executable, [sys.executable] + args) + openerp.service._reexec() return if config['pidfile']: diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index 72a246d38a1..60c3fc8474e 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -22,6 +22,7 @@ import logging import os import signal +import sys import threading import time @@ -126,15 +127,25 @@ def start_services_workers(): openerp.multi_process = True openerp.service.workers.Multicorn(openerp.service.wsgi_server.application).run() +def _reexec(): + """reexecute openerp-server process with (nearly) the same arguments""" + strip_args = ['-d', '-u'] + a = sys.argv[:] + args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] + os.execv(sys.executable, [sys.executable] + args) + def restart_server(): if openerp.multi_process: raise NotImplementedError("Multicorn is not supported (but gunicorn was)") pid = openerp.wsgi.core.arbiter_pid os.kill(pid, signal.SIGHUP) else: - openerp.phoenix = True - signame = 'CTRL_C_EVENT' if os.name == 'nt' else 'SIGINT' - sig = getattr(signal, signame) - os.kill(os.getpid(), sig) + if os.name == 'nt': + # TODO check if parent is a service + stop_services() + _reexec() + else: + openerp.phoenix = True + os.kill(os.getpid(), signal.SIGINT) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From bec3abd64c3f7594b1db27fc25ff3a2e759ed01d Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 26 Nov 2012 13:22:20 +0100 Subject: [PATCH 42/64] [FIX] restart of server on windows bzr revid: chs@openerp.com-20121126122220-38s3hla3hyl1b15p --- openerp/service/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index 60c3fc8474e..f34ef0c9461 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -129,6 +129,7 @@ def start_services_workers(): def _reexec(): """reexecute openerp-server process with (nearly) the same arguments""" + # TODO check if parent is a NT service strip_args = ['-d', '-u'] a = sys.argv[:] args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] @@ -141,9 +142,12 @@ def restart_server(): os.kill(pid, signal.SIGHUP) else: if os.name == 'nt': - # TODO check if parent is a service - stop_services() - _reexec() + def reborn(): + stop_services() + _reexec() + + # run in a thread to let the current thread return response to the caller. + threading.Thread(target=reborn).start() else: openerp.phoenix = True os.kill(os.getpid(), signal.SIGINT) From ec58393f72bc5a73977c8d45152fb2f581b9aa9b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 26 Nov 2012 19:12:00 +0100 Subject: [PATCH 43/64] [FIX] service win32: improve service: stop as same exitcode as openerp-server + auto config service to restart if exits with non-zero exitcode bzr revid: chs@openerp.com-20121126181200-01y0jqh46xsis7fb --- win32/OpenERPServerService.py | 71 ++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/win32/OpenERPServerService.py b/win32/OpenERPServerService.py index bf7c83e74a4..efd9243fc31 100644 --- a/win32/OpenERPServerService.py +++ b/win32/OpenERPServerService.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). # @@ -15,14 +15,12 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## -# Win32 python extensions modules import win32serviceutil import win32service -import win32event import win32api import win32process import servicemanager @@ -30,35 +28,27 @@ import servicemanager import sys import subprocess import os -import thread + +from ..openerp.release import serie class OpenERPServerService(win32serviceutil.ServiceFramework): # required info - _svc_name_ = "openerp-server-6.1" - _svc_display_name_ = "OpenERP Server 6.1" + _svc_name_ = "openerp-server-" + serie + _svc_display_name_ = "OpenERP Server " + serie # optionnal info - _svc_description_ = "OpenERP Server 6.1 service" + _svc_description_ = "OpenERP Server %s service" % (serie,) def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) - # Create an event which we will use to wait on. - # The "service stop" request will set this event. - self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) # a reference to the server's process self.terpprocess = None - # info if the service terminates correctly or if the server crashed - self.stopping = False - def SvcStop(self): # Before we do anything, tell the SCM we are starting the stop process. self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) - # stop the running TERP Server: say it's a normal exit + # stop the running OpenERP Server: say it's a normal exit win32api.TerminateProcess(int(self.terpprocess._handle), 0) servicemanager.LogInfoMsg("OpenERP Server stopped correctly") - # And set my event. - win32event.SetEvent(self.hWaitStop) - def StartTERP(self): # The server finds now its configuration automatically on Windows @@ -69,29 +59,40 @@ class OpenERPServerService(win32serviceutil.ServiceFramework): server_path = os.path.join(server_dir, 'server', 'openerp-server.exe') self.terpprocess = subprocess.Popen([server_path], cwd=server_dir, creationflags=win32process.CREATE_NO_WINDOW) - - def StartControl(self,ws): - # this listens to the Service Manager's events - win32event.WaitForSingleObject(ws, win32event.INFINITE) - self.stopping = True - def SvcDoRun(self): - # Start OpenERP Server itself self.StartTERP() - # start the loop waiting for the Service Manager's stop signal - thread.start_new_thread(self.StartControl, (self.hWaitStop,)) - # Log a info message that the server is running servicemanager.LogInfoMsg("OpenERP Server up and running") - # verification if the server is really running, else quit with an error - self.terpprocess.wait() - if not self.stopping: - sys.exit("OpenERP Server check: server not running, check the logfile for more info") + # exit with same exit code as OpenERP process + sys.exit(self.terpprocess.wait()) +def option_handler(opts): + # configure the service to auto restart on failures... + service_name = OpenERPServerService._svc_name -if __name__=='__main__': + hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) + try: + hs = win32serviceutil.SmartOpenService(hscm, service_name, win32service.SERVICE_ALL_ACCESS) + try: + service_failure_actions = { + 'ResetPeriod': 0, # Time in ms after which to reset the failure count to zero. + 'RebootMsg': u'', # Not using reboot option + 'Command': u'', # Not using run-command option + 'Actions': [ + (win32service.SC_ACTION_RESTART, 10), # action, delay in ms + (win32service.SC_ACTION_RESTART, 10), + (win32service.SC_ACTION_RESTART, 10), + ] + } + win32service.ChangeServiceConfig2(hs, win32service.SERVICE_CONFIG_FAILURE_ACTIONS, service_failure_actions) + finally: + win32service.CloseServiceHandle(hs) + finally: + win32service.CloseServiceHandle(hscm) + + +if __name__ == '__main__': # Do with the service whatever option is passed in the command line - win32serviceutil.HandleCommandLine(OpenERPServerService) + win32serviceutil.HandleCommandLine(OpenERPServerService, customOptionHandler=option_handler) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - From 9432574fecc1af8a9d7b24ea98bd2a52c8600cfc Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 26 Nov 2012 19:47:33 +0100 Subject: [PATCH 44/64] [FIX] restart of server on windows when running as nt service bzr revid: chs@openerp.com-20121126184733-i4blfoh0d57s5s4l --- openerp/service/__init__.py | 3 +- openerp/tools/osutil.py | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index f34ef0c9461..3d641abf9b4 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -129,7 +129,8 @@ def start_services_workers(): def _reexec(): """reexecute openerp-server process with (nearly) the same arguments""" - # TODO check if parent is a NT service + if openerp.tools.osutil.is_running_as_nt_service(): + os._exit(1) strip_args = ['-d', '-u'] a = sys.argv[:] args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] diff --git a/openerp/tools/osutil.py b/openerp/tools/osutil.py index 3da9fa624a3..949ba2a8422 100644 --- a/openerp/tools/osutil.py +++ b/openerp/tools/osutil.py @@ -26,6 +26,11 @@ Some functions related to the os and os.path module import os from os.path import join as opj +if os.name == 'nt': + import ctypes + import win32service as ws + + def listdir(dir, recursive=False): """Allow to recursively get the file listing""" dir = os.path.normpath(dir) @@ -56,6 +61,61 @@ def walksymlinks(top, topdown=True, onerror=None): yield dirpath, dirnames, filenames +if os.name != 'nt': + getppid = os.getppid + is_running_as_nt_service = lambda: False +else: + # based on http://mail.python.org/pipermail/python-win32/2007-June/006174.html + _TH32CS_SNAPPROCESS = 0x00000002 + class _PROCESSENTRY32(ctypes.Structure): + _fields_ = [("dwSize", ctypes.c_ulong), + ("cntUsage", ctypes.c_ulong), + ("th32ProcessID", ctypes.c_ulong), + ("th32DefaultHeapID", ctypes.c_ulong), + ("th32ModuleID", ctypes.c_ulong), + ("cntThreads", ctypes.c_ulong), + ("th32ParentProcessID", ctypes.c_ulong), + ("pcPriClassBase", ctypes.c_ulong), + ("dwFlags", ctypes.c_ulong), + ("szExeFile", ctypes.c_char * 260)] + + def getppid(): + CreateToolhelp32Snapshot = ctypes.windll.kernel32.CreateToolhelp32Snapshot + Process32First = ctypes.windll.kernel32.Process32First + Process32Next = ctypes.windll.kernel32.Process32Next + CloseHandle = ctypes.windll.kernel32.CloseHandle + hProcessSnap = CreateToolhelp32Snapshot(_TH32CS_SNAPPROCESS, 0) + current_pid = os.getpid() + try: + pe32 = _PROCESSENTRY32() + pe32.dwSize = ctypes.sizeof(_PROCESSENTRY32) + if not Process32First(hProcessSnap, ctypes.byref(pe32)): + raise OSError('Failed getting first process.') + while True: + if pe32.th32ProcessID == current_pid: + return pe32.th32ParentProcessID + if not Process32Next(hProcessSnap, ctypes.byref(pe32)): + return None + finally: + CloseHandle(hProcessSnap) + + from contextlib import contextmanager + from openerp.release import serie + + def is_running_as_nt_service(): + @contextmanager + def close_srv(srv): + try: + yield srv + finally: + ws.CloseServiceHandle(srv) + + service_name = 'openerp-server-' + serie + + with close_srv(ws.OpenSCManager(None, None, ws.SC_MANAGER_ALL_ACCESS)) as hscm: + with close_srv(ws.SmartOpenService(hscm, service_name, ws.SERVICE_ALL_ACCESS)) as hs: + info = ws.QueryServiceStatusEx(hs) + return info.ProcessId == getppid() if __name__ == '__main__': from pprint import pprint as pp From a55a26c777a0e6d9e8c49f35e6154734d3933171 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 28 Nov 2012 13:09:50 +0100 Subject: [PATCH 45/64] [IMP] rewrite win32/setup.py to generate dynamic files bzr revid: chs@openerp.com-20121128120950-bi6uv3bn73gotmwi --- .bzrignore | 2 ++ openerp/release.py | 2 ++ openerp/tools/osutil.py | 26 +++++++++--------- win32/OpenERPServerService.py | 15 +++++++---- win32/setup.py | 51 ++++++++++++++++++++++++++++------- win32/start.bat | 7 ----- win32/stop.bat | 5 ---- 7 files changed, 67 insertions(+), 41 deletions(-) delete mode 100644 win32/start.bat delete mode 100644 win32/stop.bat diff --git a/.bzrignore b/.bzrignore index 8531ad42bbb..e7618c7b0ce 100644 --- a/.bzrignore +++ b/.bzrignore @@ -17,3 +17,5 @@ include/ lib/ share/ doc/_build/* +win32/*.bat +win32/meta.py diff --git a/openerp/release.py b/openerp/release.py index 50d9b8ac760..e66d924906b 100644 --- a/openerp/release.py +++ b/openerp/release.py @@ -50,4 +50,6 @@ author = 'OpenERP S.A.' author_email = 'info@openerp.com' license = 'AGPL-3' +nt_service_name = "openerp-server-" + serie + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tools/osutil.py b/openerp/tools/osutil.py index 949ba2a8422..2f72e099f7f 100644 --- a/openerp/tools/osutil.py +++ b/openerp/tools/osutil.py @@ -68,16 +68,16 @@ else: # based on http://mail.python.org/pipermail/python-win32/2007-June/006174.html _TH32CS_SNAPPROCESS = 0x00000002 class _PROCESSENTRY32(ctypes.Structure): - _fields_ = [("dwSize", ctypes.c_ulong), - ("cntUsage", ctypes.c_ulong), - ("th32ProcessID", ctypes.c_ulong), - ("th32DefaultHeapID", ctypes.c_ulong), - ("th32ModuleID", ctypes.c_ulong), - ("cntThreads", ctypes.c_ulong), - ("th32ParentProcessID", ctypes.c_ulong), - ("pcPriClassBase", ctypes.c_ulong), - ("dwFlags", ctypes.c_ulong), - ("szExeFile", ctypes.c_char * 260)] + _fields_ = [("dwSize", ctypes.c_ulong), + ("cntUsage", ctypes.c_ulong), + ("th32ProcessID", ctypes.c_ulong), + ("th32DefaultHeapID", ctypes.c_ulong), + ("th32ModuleID", ctypes.c_ulong), + ("cntThreads", ctypes.c_ulong), + ("th32ParentProcessID", ctypes.c_ulong), + ("pcPriClassBase", ctypes.c_ulong), + ("dwFlags", ctypes.c_ulong), + ("szExeFile", ctypes.c_char * 260)] def getppid(): CreateToolhelp32Snapshot = ctypes.windll.kernel32.CreateToolhelp32Snapshot @@ -100,7 +100,7 @@ else: CloseHandle(hProcessSnap) from contextlib import contextmanager - from openerp.release import serie + from openerp.release import nt_service_name def is_running_as_nt_service(): @contextmanager @@ -110,10 +110,8 @@ else: finally: ws.CloseServiceHandle(srv) - service_name = 'openerp-server-' + serie - with close_srv(ws.OpenSCManager(None, None, ws.SC_MANAGER_ALL_ACCESS)) as hscm: - with close_srv(ws.SmartOpenService(hscm, service_name, ws.SERVICE_ALL_ACCESS)) as hs: + with close_srv(ws.SmartOpenService(hscm, nt_service_name, ws.SERVICE_ALL_ACCESS)) as hs: info = ws.QueryServiceStatusEx(hs) return info.ProcessId == getppid() diff --git a/win32/OpenERPServerService.py b/win32/OpenERPServerService.py index efd9243fc31..c529b582ba4 100644 --- a/win32/OpenERPServerService.py +++ b/win32/OpenERPServerService.py @@ -29,14 +29,19 @@ import sys import subprocess import os -from ..openerp.release import serie +try: + import meta +except ImportError: + if hasattr(sys, 'frozen'): + raise + from setup import generate_files + generate_files() + import meta class OpenERPServerService(win32serviceutil.ServiceFramework): # required info - _svc_name_ = "openerp-server-" + serie - _svc_display_name_ = "OpenERP Server " + serie - # optionnal info - _svc_description_ = "OpenERP Server %s service" % (serie,) + _svc_name_ = meta.nt_service_name + _svc_display_name_ = "%s %s" % (meta.description, meta.serie) def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) diff --git a/win32/setup.py b/win32/setup.py index 9c064c1f6d8..5366b63ab4d 100644 --- a/win32/setup.py +++ b/win32/setup.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2010 Tiny SPRL (). # @@ -15,22 +15,53 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## from distutils.core import setup +import os import py2exe +meta = {} +execfile(os.path.join(os.path.dirname(__file__), '..', 'openerp', 'release.py'), meta) -setup(service=["OpenERPServerService"], - options={"py2exe":{"excludes":["Tkconstants","Tkinter","tcl", - "_imagingtk","PIL._imagingtk", - "ImageTk", "PIL.ImageTk", - "FixTk"], - "skip_archive": 1, - "optimize": 2,}} +def generate_files(): + actions = { + 'start': ['stop', 'start'], + 'stop': ['stop'], + } + + files = [] + for action, steps in actions.items(): + fname = action + '.bat' + files.append(fname) + with open(fname, 'w') as fp: + fp.write('@PATH=%WINDIR%\system32;%WINDIR%;%WINDIR%\System32\Wbem;.') + for step in steps: + fp.write('@net %s %s' % (step, meta['nt_service_name'])) + + files.append('meta.py') + with open('meta.py', 'w') as fp: + for m in 'description serie nt_service_name'.split(): + fp.write("%s = %r" % (m, meta[m],)) + + return files + +excludes = "Tkconstants Tkinter tcl _imagingtk PIL._imagingtk ImageTk PIL.ImageTk FixTk".split() + +setup(service = ["OpenERPServerService"], + version = meta['version'], + licence = meta['licence'], + url = meta['url'], + author = meta['author'], + author_email = meta['author_email'], + data_files = generate_files(), + options = {"py2exe": { + "excludes": excludes, + "skip_archive": 1, + "optimize": 2, + }} ) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/win32/start.bat b/win32/start.bat deleted file mode 100644 index ff3c49b1397..00000000000 --- a/win32/start.bat +++ /dev/null @@ -1,7 +0,0 @@ -@PATH=%WINDIR%\system32;%WINDIR%;%WINDIR%\System32\Wbem;. - -@net stop openerp-server-6.1 - -@net start openerp-server-6.1 - -cls diff --git a/win32/stop.bat b/win32/stop.bat deleted file mode 100644 index 76a35b7e91f..00000000000 --- a/win32/stop.bat +++ /dev/null @@ -1,5 +0,0 @@ -@PATH=%WINDIR%\system32;%WINDIR%;%WINDIR%\System32\Wbem;. - -@net stop openerp-server-6.1 - -cls From af7fbd40abe038e91fcda28cd908a8d582989605 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 28 Nov 2012 14:24:13 +0100 Subject: [PATCH 46/64] some brief changes bzr revid: chs@openerp.com-20121128132413-op2z4vmv78y04u95 --- win32/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/setup.py b/win32/setup.py index 5366b63ab4d..0d8f504cc01 100644 --- a/win32/setup.py +++ b/win32/setup.py @@ -52,7 +52,7 @@ excludes = "Tkconstants Tkinter tcl _imagingtk PIL._imagingtk ImageTk PIL.ImageT setup(service = ["OpenERPServerService"], version = meta['version'], - licence = meta['licence'], + license = meta['license'], url = meta['url'], author = meta['author'], author_email = meta['author_email'], From 7773d0d431d8d3c4195bc80c118f34a5396ce186 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 28 Nov 2012 15:25:21 +0100 Subject: [PATCH 47/64] [FIX] win32/setup.py: forgot \n bzr revid: chs@openerp.com-20121128142521-1giiba0fvxhq84mu --- win32/setup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win32/setup.py b/win32/setup.py index 0d8f504cc01..d6920e0be61 100644 --- a/win32/setup.py +++ b/win32/setup.py @@ -37,14 +37,14 @@ def generate_files(): fname = action + '.bat' files.append(fname) with open(fname, 'w') as fp: - fp.write('@PATH=%WINDIR%\system32;%WINDIR%;%WINDIR%\System32\Wbem;.') + fp.write('@PATH=%WINDIR%\system32;%WINDIR%;%WINDIR%\System32\Wbem;.\n') for step in steps: - fp.write('@net %s %s' % (step, meta['nt_service_name'])) + fp.write('@net %s %s\n' % (step, meta['nt_service_name'])) files.append('meta.py') with open('meta.py', 'w') as fp: for m in 'description serie nt_service_name'.split(): - fp.write("%s = %r" % (m, meta[m],)) + fp.write("%s = %r\n" % (m, meta[m],)) return files From 4d91b6a87c9fd6f8cc923d1bc375eb80db5dbec3 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 29 Nov 2012 16:17:46 +0100 Subject: [PATCH 48/64] [FIX] osutils: missing import bzr revid: chs@openerp.com-20121129151746-r7t5xgddekvoq23w --- openerp/tools/osutil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openerp/tools/osutil.py b/openerp/tools/osutil.py index 2f72e099f7f..622679cc63e 100644 --- a/openerp/tools/osutil.py +++ b/openerp/tools/osutil.py @@ -29,6 +29,7 @@ from os.path import join as opj if os.name == 'nt': import ctypes import win32service as ws + import win32serviceutil as wsu def listdir(dir, recursive=False): @@ -111,7 +112,7 @@ else: ws.CloseServiceHandle(srv) with close_srv(ws.OpenSCManager(None, None, ws.SC_MANAGER_ALL_ACCESS)) as hscm: - with close_srv(ws.SmartOpenService(hscm, nt_service_name, ws.SERVICE_ALL_ACCESS)) as hs: + with close_srv(wsu.SmartOpenService(hscm, nt_service_name, ws.SERVICE_ALL_ACCESS)) as hs: info = ws.QueryServiceStatusEx(hs) return info.ProcessId == getppid() From 25bd671e9eda815787a82db04f27965b47d1ab88 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 30 Nov 2012 11:35:03 +0100 Subject: [PATCH 49/64] [FIX] osutils: correct nt service check bzr revid: chs@openerp.com-20121130103503-9l3elc3o1dgkovhe --- openerp/tools/osutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tools/osutil.py b/openerp/tools/osutil.py index 622679cc63e..1ef5aa2def3 100644 --- a/openerp/tools/osutil.py +++ b/openerp/tools/osutil.py @@ -114,7 +114,7 @@ else: with close_srv(ws.OpenSCManager(None, None, ws.SC_MANAGER_ALL_ACCESS)) as hscm: with close_srv(wsu.SmartOpenService(hscm, nt_service_name, ws.SERVICE_ALL_ACCESS)) as hs: info = ws.QueryServiceStatusEx(hs) - return info.ProcessId == getppid() + return info['ProcessId'] == getppid() if __name__ == '__main__': from pprint import pprint as pp From 5ec2748e04c0377edbd864ab662bd717c56d0363 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 30 Nov 2012 11:45:05 +0100 Subject: [PATCH 50/64] [FIX] services: call os.abort() for killing bzr revid: chs@openerp.com-20121130104505-1p2arb61jnnogeb9 --- openerp/service/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index 3d641abf9b4..7cd1442e38f 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -130,7 +130,7 @@ def start_services_workers(): def _reexec(): """reexecute openerp-server process with (nearly) the same arguments""" if openerp.tools.osutil.is_running_as_nt_service(): - os._exit(1) + os.abort() strip_args = ['-d', '-u'] a = sys.argv[:] args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] From 9e3a6c6cc3dd2233b82bebc79acf3f63cfd2a433 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 30 Nov 2012 12:38:28 +0100 Subject: [PATCH 51/64] [FIX] win32 service: configure service via sc.exe bzr revid: chs@openerp.com-20121130113828-abweveb1ryzptvhf --- win32/OpenERPServerService.py | 41 +++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/win32/OpenERPServerService.py b/win32/OpenERPServerService.py index c529b582ba4..3f86c40aa4b 100644 --- a/win32/OpenERPServerService.py +++ b/win32/OpenERPServerService.py @@ -74,26 +74,29 @@ class OpenERPServerService(win32serviceutil.ServiceFramework): def option_handler(opts): # configure the service to auto restart on failures... service_name = OpenERPServerService._svc_name + restart_msg = "Restarting %s" % (OpenERPServerService._svc_display_name_,) - hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) - try: - hs = win32serviceutil.SmartOpenService(hscm, service_name, win32service.SERVICE_ALL_ACCESS) - try: - service_failure_actions = { - 'ResetPeriod': 0, # Time in ms after which to reset the failure count to zero. - 'RebootMsg': u'', # Not using reboot option - 'Command': u'', # Not using run-command option - 'Actions': [ - (win32service.SC_ACTION_RESTART, 10), # action, delay in ms - (win32service.SC_ACTION_RESTART, 10), - (win32service.SC_ACTION_RESTART, 10), - ] - } - win32service.ChangeServiceConfig2(hs, win32service.SERVICE_CONFIG_FAILURE_ACTIONS, service_failure_actions) - finally: - win32service.CloseServiceHandle(hs) - finally: - win32service.CloseServiceHandle(hscm) + subprocess.call('sc failure %s reset= 0 reboot= %r actions= reboot/0/reboot/0/reboot/0' % (service_name, restart_msg)) + + # hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) + # try: + # hs = win32serviceutil.SmartOpenService(hscm, service_name, win32service.SERVICE_ALL_ACCESS) + # try: + # service_failure_actions = { + # 'ResetPeriod': 0, # Time in ms after which to reset the failure count to zero. + # 'RebootMsg': u'', # Not using reboot option + # 'Command': u'', # Not using run-command option + # 'Actions': [ + # (win32service.SC_ACTION_RESTART, 10), # action, delay in ms + # (win32service.SC_ACTION_RESTART, 10), + # (win32service.SC_ACTION_RESTART, 10), + # ] + # } + # win32service.ChangeServiceConfig2(hs, win32service.SERVICE_CONFIG_FAILURE_ACTIONS, service_failure_actions) + # finally: + # win32service.CloseServiceHandle(hs) + # finally: + # win32service.CloseServiceHandle(hscm) if __name__ == '__main__': From 4d4c11bbbee24deb6eba67ae70a9ffd8903dc15c Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 30 Nov 2012 14:58:29 +0100 Subject: [PATCH 52/64] [FIX] setup.py: add pytz data files on windows bzr revid: chs@openerp.com-20121130135829-8i2pd5kqlyhhfx2r --- setup.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 4f1435c0603..79d9b2d5a07 100755 --- a/setup.py +++ b/setup.py @@ -41,10 +41,13 @@ def data(): if os.name == 'nt': r.append(("Microsoft.VC90.CRT", glob.glob('C:\Microsoft.VC90.CRT\*.*'))) - import babel - r.append(("localedata", - glob.glob(os.path.join(os.path.dirname(babel.__file__), "localedata" , '*')))) + import babel + r.append(("localedata", + glob.glob(os.path.join(os.path.dirname(babel.__file__), "localedata", '*')))) + import pytz + r.append((os.path.join("pytz", "zoneinfo"), + glob.glob(os.path.join(os.path.dirname(pytz.__file__), "zoneinfo", '*')))) return r def gen_manifest(): @@ -64,7 +67,7 @@ def py2exe_options(): "skip_archive": 1, "optimize": 2, "dist_dir": 'dist', - "packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "docutils", "email", "encodings", "imaplib", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber", "vobject", "xml", "xml.dom", "yaml", ], + "packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "docutils", "email", "encodings", "imaplib", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "pytz", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber", "vobject", "xml", "xml.dom", "yaml", ], "excludes" : ["Tkconstants","Tkinter","tcl"], } } From 7d73d767b18cb91da51ca7a71904716620f678b6 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 30 Nov 2012 15:54:52 +0100 Subject: [PATCH 53/64] [FIX] setup.py bzr revid: chs@openerp.com-20121130145452-afqxovwvncys6d4n --- setup.py | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/setup.py b/setup.py index 79d9b2d5a07..b64bde31234 100755 --- a/setup.py +++ b/setup.py @@ -21,34 +21,29 @@ ############################################################################## import glob, os, re, setuptools, sys -from os.path import join, isfile +from os.path import join # List all data files def data(): - files = [] + r = {} for root, dirnames, filenames in os.walk('openerp'): for filename in filenames: - if not re.match(r'.*(\.pyc|\.pyo|\~)$',filename): - files.append(os.path.join(root, filename)) - d = {} - for v in files: - k=os.path.dirname(v) - if k in d: - d[k].append(v) - else: - d[k]=[v] - r = d.items() + if not re.match(r'.*(\.pyc|\.pyo|\~)$', filename): + r.setdefault(root, []).append(os.path.join(root, filename)) + if os.name == 'nt': - r.append(("Microsoft.VC90.CRT", glob.glob('C:\Microsoft.VC90.CRT\*.*'))) + r["Microsoft.VC90.CRT"] = glob.glob('C:\Microsoft.VC90.CRT\*.*') import babel - r.append(("localedata", - glob.glob(os.path.join(os.path.dirname(babel.__file__), "localedata", '*')))) + r["localedata"] = glob.glob(os.path.join(os.path.dirname(babel.__file__), "localedata", '*')) import pytz - r.append((os.path.join("pytz", "zoneinfo"), - glob.glob(os.path.join(os.path.dirname(pytz.__file__), "zoneinfo", '*')))) - return r + tzdir = os.path.dirname(pytz.__file__) + for root, _, filenames in os.walk(os.path.join(tzdir, "zoneinfo")): + base = root[len(tzdir) + 1:] + r[base] = [os.path.join(root, f) for f in filenames] + + return r.items() def gen_manifest(): file_list="\n".join(data()) From b2099e17bbe4442b8353af9a72d73131404e9f9b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 30 Nov 2012 17:12:10 +0100 Subject: [PATCH 54/64] [zen] Mind your words, they are important. bzr revid: chs@openerp.com-20121130161210-3ih3bnx4oc9gv2w3 --- win32/OpenERPServerService.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/win32/OpenERPServerService.py b/win32/OpenERPServerService.py index 3f86c40aa4b..ce7e21d50af 100644 --- a/win32/OpenERPServerService.py +++ b/win32/OpenERPServerService.py @@ -36,7 +36,7 @@ except ImportError: raise from setup import generate_files generate_files() - import meta + import meta # noqa class OpenERPServerService(win32serviceutil.ServiceFramework): # required info @@ -74,9 +74,8 @@ class OpenERPServerService(win32serviceutil.ServiceFramework): def option_handler(opts): # configure the service to auto restart on failures... service_name = OpenERPServerService._svc_name - restart_msg = "Restarting %s" % (OpenERPServerService._svc_display_name_,) - subprocess.call('sc failure %s reset= 0 reboot= %r actions= reboot/0/reboot/0/reboot/0' % (service_name, restart_msg)) + subprocess.call('sc failure %s reset= 0 actions= restart/0/restart/0/restart/0' % (service_name,)) # hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) # try: From 050f65c21e9a5ef5af919158c448b1666bf14bb4 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 30 Nov 2012 17:50:26 +0100 Subject: [PATCH 55/64] [FIX] correct path for pytz datafiles bzr revid: chs@openerp.com-20121130165026-3p6coxwignmzl92g --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b64bde31234..7d41e4d5c3c 100755 --- a/setup.py +++ b/setup.py @@ -40,7 +40,7 @@ def data(): import pytz tzdir = os.path.dirname(pytz.__file__) for root, _, filenames in os.walk(os.path.join(tzdir, "zoneinfo")): - base = root[len(tzdir) + 1:] + base = os.path.join('pytz', root[len(tzdir) + 1:]) r[base] = [os.path.join(root, f) for f in filenames] return r.items() From 3ff3f1f87fd50d363a1a0b502a34208966b24e0a Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 30 Nov 2012 17:50:46 +0100 Subject: [PATCH 56/64] [FIX] win32 service: configure service via sc.exe bzr revid: chs@openerp.com-20121130165046-l1ezj4ykrhnyfzjp --- win32/OpenERPServerService.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/OpenERPServerService.py b/win32/OpenERPServerService.py index ce7e21d50af..f2a6007d118 100644 --- a/win32/OpenERPServerService.py +++ b/win32/OpenERPServerService.py @@ -75,7 +75,7 @@ def option_handler(opts): # configure the service to auto restart on failures... service_name = OpenERPServerService._svc_name - subprocess.call('sc failure %s reset= 0 actions= restart/0/restart/0/restart/0' % (service_name,)) + subprocess.call(['sc', 'failure', service_name, 'reset=', '0', 'actions=', 'restart/0/restart/0/restart/0']) # hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) # try: From 097254fe00a10ba81669d5d2212faa1db25a8db9 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 5 Dec 2012 16:52:09 +0100 Subject: [PATCH 57/64] [FIX] correct reexecute. works on windows bzr revid: chs@openerp.com-20121205155209-aqra9rtvq11uq37d --- openerp/service/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index 5ae9efb2716..849df170eaa 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -133,10 +133,13 @@ def _reexec(): """reexecute openerp-server process with (nearly) the same arguments""" if openerp.tools.osutil.is_running_as_nt_service(): os.abort() + exe = os.path.basename(sys.executable) strip_args = ['-d', '-u'] a = sys.argv[:] args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] - os.execv(sys.executable, [sys.executable] + args) + if not args or args[0] != exe: + args.insert(0, exe) + os.execv(sys.executable, args) def restart_server(): if openerp.multi_process: From effec78db7524006bc387556aacf460e7424637b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 5 Dec 2012 18:56:30 +0100 Subject: [PATCH 58/64] [FIX] correct reexecute. works for windows service bzr revid: chs@openerp.com-20121205175630-6y8ul4ki13z0coyh --- openerp/service/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index 849df170eaa..c714c0178f0 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -23,6 +23,7 @@ import logging import os import signal +import subprocess import sys import threading import time @@ -34,6 +35,7 @@ import openerp.cron import openerp.modules import openerp.netsvc import openerp.osv +from openerp.release import nt_service_name import openerp.tools import openerp.service.wsgi_server @@ -132,7 +134,7 @@ def start_services_workers(): def _reexec(): """reexecute openerp-server process with (nearly) the same arguments""" if openerp.tools.osutil.is_running_as_nt_service(): - os.abort() + subprocess.call('sc stop {0} && sc start {0}'.format(nt_service_name), shell=True) exe = os.path.basename(sys.executable) strip_args = ['-d', '-u'] a = sys.argv[:] From 9065642cc9699a39e69f5e97c5b66fb0911ffd34 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 5 Dec 2012 18:57:50 +0100 Subject: [PATCH 59/64] [FIX] win32 service: remove commented code bzr revid: chs@openerp.com-20121205175750-hqo058i7bp1g68rp --- win32/OpenERPServerService.py | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/win32/OpenERPServerService.py b/win32/OpenERPServerService.py index f2a6007d118..8b3c117c03d 100644 --- a/win32/OpenERPServerService.py +++ b/win32/OpenERPServerService.py @@ -73,30 +73,7 @@ class OpenERPServerService(win32serviceutil.ServiceFramework): def option_handler(opts): # configure the service to auto restart on failures... - service_name = OpenERPServerService._svc_name - - subprocess.call(['sc', 'failure', service_name, 'reset=', '0', 'actions=', 'restart/0/restart/0/restart/0']) - - # hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) - # try: - # hs = win32serviceutil.SmartOpenService(hscm, service_name, win32service.SERVICE_ALL_ACCESS) - # try: - # service_failure_actions = { - # 'ResetPeriod': 0, # Time in ms after which to reset the failure count to zero. - # 'RebootMsg': u'', # Not using reboot option - # 'Command': u'', # Not using run-command option - # 'Actions': [ - # (win32service.SC_ACTION_RESTART, 10), # action, delay in ms - # (win32service.SC_ACTION_RESTART, 10), - # (win32service.SC_ACTION_RESTART, 10), - # ] - # } - # win32service.ChangeServiceConfig2(hs, win32service.SERVICE_CONFIG_FAILURE_ACTIONS, service_failure_actions) - # finally: - # win32service.CloseServiceHandle(hs) - # finally: - # win32service.CloseServiceHandle(hscm) - + subprocess.call(['sc', 'failure', meta.nt_service_name, 'reset=', '0', 'actions=', 'restart/0/restart/0/restart/0']) if __name__ == '__main__': # Do with the service whatever option is passed in the command line From edef11eaafd25e0414ebd82d31bc6b8ca8576572 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Wed, 19 Dec 2012 03:32:26 +0100 Subject: [PATCH 60/64] apps dont break protocol bzr revid: al@openerp.com-20121219023226-gfceiyrmi50my80e --- openerp/addons/base/static/src/js/apps.js | 5 +---- openerp/service/web_services.py | 12 ++++-------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 0b0eea68216..343ca24f9ba 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -42,11 +42,8 @@ openerp.base = function(instance) { if (instance.base.apps._client) { return check_client_available(instance.base.apps._client); } else { - //var DEFAULT_SERVER = 'http://apps.openerp.com/loempia'; // PROD - var DEFAULT_SERVER = 'http://apps.v7.openerp.com:8069/apps'; // TEST - //var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7'; // DEV var ICP = new instance.web.Model('ir.config_parameter'); - return ICP.call('get_param', ['loempia.server', DEFAULT_SERVER]).then(function(u) { + return ICP.call('get_param', ['apps.server', 'https://apps.openerp.com/apps']).then(function(u) { var link = $(_.str.sprintf('', u))[0]; var host = _.str.sprintf('%s//%s', link.protocol, link.host); var dbname = link.pathname; diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 154086dd564..842d1606e47 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -55,14 +55,10 @@ from openerp import SUPERUSER_ID _logger = logging.getLogger(__name__) RPC_VERSION_1 = { - 'openerp': { - 'version': release.version, - 'version_info': release.version_info, - 'serie': release.serie, - }, - 'protocol': { - 'version': 1 - }, + 'server_version': release.version, + 'server_version_info': release.version_info, + 'server_serie': release.serie, + 'protocol_version': 1, } # This should be moved to openerp.modules.db, along side initialize(). From c7d6df8fa390ff6076a1f3cfbe8bb80a66a5b83f Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Wed, 19 Dec 2012 03:59:08 +0100 Subject: [PATCH 61/64] [MERGE] module update_list signal wsgi handlers bzr revid: al@openerp.com-20121219025908-hd8megr7fc6m4o7m --- openerp/addons/base/module/module.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 1332b6567c4..a70ba72b2d2 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -610,6 +610,13 @@ class module(osv.osv): self._update_dependencies(cr, uid, mod, terp.get('depends', [])) self._update_category(cr, uid, mod, terp.get('category', 'Uncategorized')) + # Trigger load_addons if new module have been discovered it exists on + # wsgi handlers, so they can react accordingly + if tuple(res) != (0, 0): + for handler in openerp.service.wsgi_server.module_handlers: + if hasattr(handler,'load_addons'): + handler.load_addons() + return res def download(self, cr, uid, ids, download=True, context=None): From 2370566ca0331fa987f99c6caabf3ff2334027c7 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Wed, 19 Dec 2012 18:21:28 +0100 Subject: [PATCH 62/64] move get_client in Apps bzr revid: al@openerp.com-20121219172128-19u850blwf5cryex --- openerp/addons/base/static/src/js/apps.js | 142 ++++++++++------------ 1 file changed, 67 insertions(+), 75 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index 343ca24f9ba..ab056ae2567 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -1,74 +1,10 @@ openerp.base = function(instance) { - instance.base = {apps:{}}; + instance.base.apps_remote = null; + instance.base.apps_client = null; - instance.base.apps.remote_instance = null; - - instance.base.apps.get_client = function() { - // return the client via a deferred, resolved or rejected depending if the remote host is available or not. - var check_client_available = function(client) { - var d = $.Deferred(); - var i = new Image(); - i.onerror = function() { - d.reject(client); - }; - i.onload = function() { - client.session.session_bind(client.origin).then(function() { - // check if client can authenticate - client.authenticate().then( - function() { /* done */ - d.resolve(client); - }, function() { /* fail */ - if (client.login === 'anonymous') { - d.reject(client); - } else { - sessionStorage.removeItem('apps.login'); - sessionStorage.removeItem('apps.access_token'); - client.bind(client.dbname, 'anonymous', 'anonymous'); - client.authenticate().then( - function() { /* done */ - d.resolve(client); - }, function() { /* fail */ - d.reject(client); - }); - } - }); - }); - - }; - i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif', client.origin); - return d.promise(); - }; - if (instance.base.apps._client) { - return check_client_available(instance.base.apps._client); - } else { - var ICP = new instance.web.Model('ir.config_parameter'); - return ICP.call('get_param', ['apps.server', 'https://apps.openerp.com/apps']).then(function(u) { - var link = $(_.str.sprintf('', u))[0]; - var host = _.str.sprintf('%s//%s', link.protocol, link.host); - var dbname = link.pathname; - if (dbname[0] === '/') { - dbname = dbname.substr(1); - } - - var login = (sessionStorage ? sessionStorage.getItem('apps.login') : null) || 'anonymous'; - var passwd = (sessionStorage ? sessionStorage.getItem('apps.access_token') : null) || 'anonymous'; - - if (_.isNull(instance.base.apps.remote_instance)) { - instance.base.apps.remote_instance = new openerp.init(); - } - var client = new instance.base.apps.remote_instance.web.EmbeddedClient(null, host, - dbname, login, passwd); - instance.base.apps._client = client; - return check_client_available(client); - }); - } - - }; - - instance.base.apps.Apps = instance.web.Widget.extend({ + instance.base.Apps = instance.web.Widget.extend({ template: 'EmptyComponent', - remote_action_id: 'loempia.action_embed', failback_action_id: 'base.open_module_tree', @@ -83,11 +19,69 @@ openerp.base = function(instance) { sessionStorage.setItem('apps.access_token', options.apps_access_token); } - this.params = options; // NOTE read by embedded client action + this.params = options; // NOTE read by embedded client action + }, + + get_client: function() { + // return the client via a deferred, resolved or rejected depending if the remote host is available or not. + var check_client_available = function(client) { + var d = $.Deferred(); + var i = new Image(); + i.onerror = function() { + d.reject(client); + }; + i.onload = function() { + client.session.session_bind(client.origin).then(function() { + // check if client can authenticate + client.authenticate().then( + function() { /* done */ + d.resolve(client); + }, function() { /* fail */ + if (client.login === 'anonymous') { + d.reject(client); + } else { + sessionStorage.removeItem('apps.login'); + sessionStorage.removeItem('apps.access_token'); + client.bind_crendentials(client.dbname, 'anonymous', 'anonymous'); + client.authenticate().then( + function() { /* done */ + d.resolve(client); + }, function() { /* fail */ + d.reject(client); + }); + } + }); + }); + + }; + i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif', client.origin); + return d.promise(); + }; + if (instance.base.apps_client) { + return check_client_available(instance.base.apps_client); + } else { + var ICP = new instance.web.Model('ir.config_parameter'); + return ICP.call('get_param', ['apps.server', 'https://apps.openerp.com/apps']).then(function(u) { + var link = $(_.str.sprintf('', u))[0]; + var host = _.str.sprintf('%s//%s', link.protocol, link.host); + var dbname = link.pathname; + if (dbname[0] === '/') { + dbname = dbname.substr(1); + } + var login = (sessionStorage ? sessionStorage.getItem('apps.login') : null) || 'anonymous'; + var passwd = (sessionStorage ? sessionStorage.getItem('apps.access_token') : null) || 'anonymous'; + if (_.isNull(instance.base.apps_remote)) { + instance.base.apps_remote = new openerp.init(); + } + var client = new instance.base.apps_remote.web.EmbeddedClient(null, host, dbname, login, passwd); + instance.base.apps_client = client; + return check_client_available(client); + }); + } }, clean: function() { - instance.base.apps.get_client().always(function(client) { client.destroy(); }); + self.get_client().always(function(client) { client.destroy(); }); }, destroy: function() { @@ -97,7 +91,7 @@ openerp.base = function(instance) { start: function() { var self = this; - return instance.base.apps.get_client(). + return self.get_client(). done(function(client) { client.replace(self.$el). done(function() { @@ -113,15 +107,13 @@ openerp.base = function(instance) { }); }); }, - - 0:0 }); - instance.base.apps.UpdatesAvailable = instance.base.apps.Apps.extend({ + instance.base.AppsUpdates = instance.base.Apps.extend({ remote_action_id: 'loempia.action_embed_updates' }); - instance.web.client_actions.add("apps", "instance.base.apps.Apps"); - instance.web.client_actions.add("apps.updates", "instance.base.apps.UpdatesAvailable"); + instance.web.client_actions.add("apps", "instance.base.Apps"); + instance.web.client_actions.add("apps.updates", "instance.base.AppsUpdates"); }; From fb34208b683451c443b02d94d6fc5dd4ea2d7f9c Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Wed, 19 Dec 2012 21:30:58 +0100 Subject: [PATCH 63/64] apps fix destroy bzr revid: al@openerp.com-20121219203058-4kb5urrb8rca8eti --- openerp/addons/base/static/src/js/apps.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index ab056ae2567..397f028c1fd 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -80,12 +80,10 @@ openerp.base = function(instance) { } }, - clean: function() { - self.get_client().always(function(client) { client.destroy(); }); - }, - destroy: function() { - this.clean(); + if (instance.base.apps_client) { + instance.base.apps_client.destroy(); + } return this._super(); }, From e1329cc4e0b1997dd2811f075ce496ae1f63adad Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 20 Dec 2012 14:26:52 +0100 Subject: [PATCH 64/64] temp menu bzr revid: al@openerp.com-20121220132652-01hgfi0q64zo02un --- openerp/addons/base/module/module_view.xml | 109 +++++++++--------- .../module/wizard/base_module_update_view.xml | 2 +- .../wizard/base_module_upgrade_view.xml | 2 +- 3 files changed, 58 insertions(+), 55 deletions(-) diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index 6ec7fcd7167..3a43a2591ba 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -1,24 +1,7 @@ - - - Modules - apps - - - - - - Updates Available - apps.updates - {} - - - - - ir.module.category.form ir.module.category @@ -47,7 +30,6 @@ - ir.module.module.list.select ir.module.module @@ -68,37 +50,6 @@ - - - Modules Kanban - ir.module.module - - - - - - - - -
- - -
-

-

-
- -

- - -
-
-
-
-
-
-
- Modules ir.module.module @@ -115,7 +66,6 @@ - ir.module.module.form ir.module.module @@ -191,21 +141,74 @@ - + + Modules Kanban + ir.module.module + + + + + + + + +
+ + +
+

+

+
+ +

+ + +
+
+
+
+
+
+
+ + Modules ir.module.module form kanban,tree,form +

No module found!

You should try others search criteria.

- + + + + + + Apps + apps + + + + + + Updates + apps.updates + {} + + +
diff --git a/openerp/addons/base/module/wizard/base_module_update_view.xml b/openerp/addons/base/module/wizard/base_module_update_view.xml index 64461e12707..cb9b9090294 100644 --- a/openerp/addons/base/module/wizard/base_module_update_view.xml +++ b/openerp/addons/base/module/wizard/base_module_update_view.xml @@ -45,7 +45,7 @@ id="menu_view_base_module_update" groups="base.group_no_one" parent="menu_management" - sequence="4" + sequence="40" icon="STOCK_CONVERT"/> diff --git a/openerp/addons/base/module/wizard/base_module_upgrade_view.xml b/openerp/addons/base/module/wizard/base_module_upgrade_view.xml index 9b45c4915b2..1a1225befcb 100644 --- a/openerp/addons/base/module/wizard/base_module_upgrade_view.xml +++ b/openerp/addons/base/module/wizard/base_module_upgrade_view.xml @@ -35,7 +35,7 @@ groups="base.group_no_one" id="menu_view_base_module_upgrade" parent="menu_management" - sequence="5"/> + sequence="50"/> Module Upgrade Install