diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index 26dbe93a661..1cd9ed94d4c 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -21,12 +21,15 @@ import hashlib import itertools +import logging import os import re from openerp import tools from openerp.osv import fields,osv +_logger = logging.getLogger(__name__) + class ir_attachment(osv.osv): """Attachments are used to link binary files or url to any openerp document. diff --git a/openerp/addons/base/ir/ir_filters.xml b/openerp/addons/base/ir/ir_filters.xml index 51215132079..72c5dad8885 100644 --- a/openerp/addons/base/ir/ir_filters.xml +++ b/openerp/addons/base/ir/ir_filters.xml @@ -19,6 +19,7 @@ + @@ -35,6 +36,7 @@ + @@ -45,12 +47,14 @@ - - + + + - + + + + diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index ed6f843f898..5927b500a0f 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -1062,9 +1062,13 @@ class ir_model_data(osv.osv): continue _logger.info('Deleting %s@%s', res_id, model) try: + cr.execute('SAVEPOINT record_unlink_save') self.pool.get(model).unlink(cr, uid, [res_id], context=context) except Exception: _logger.info('Unable to delete %s@%s', res_id, model, exc_info=True) + cr.execute('ROLLBACK TO SAVEPOINT record_unlink_save') + else: + cr.execute('RELEASE SAVEPOINT record_unlink_save') # Remove non-model records first, then model fields, and finish with models unlink_if_refcount((model, res_id) for model, res_id in to_unlink diff --git a/openerp/addons/base/ir/osv_memory_autovacuum.py b/openerp/addons/base/ir/osv_memory_autovacuum.py index 1b3ca507eb8..b5224c0e7de 100644 --- a/openerp/addons/base/ir/osv_memory_autovacuum.py +++ b/openerp/addons/base/ir/osv_memory_autovacuum.py @@ -28,7 +28,7 @@ class osv_memory_autovacuum(openerp.osv.osv.osv_memory): def power_on(self, cr, uid, context=None): for model in self.pool.models.values(): if model.is_transient(): - model._transient_vacuum(cr, uid) + model._transient_vacuum(cr, uid, force=True) return True diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 47a4cfc8174..a0d1eedef2b 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2004-2012 OpenERP S.A. (). +# Copyright (C) 2004-2013 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 @@ -254,9 +254,9 @@ class module(osv.osv): 'website': fields.char("Website", size=256, readonly=True), # attention: Incorrect field names !! - # 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 refers the latest version (the one on disk) + # latest_version refers the installed version (the one in database) + # published_version refers the version available on the repository '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), @@ -500,6 +500,7 @@ class module(osv.osv): raise orm.except_orm(_('Error'), _("The `base` module cannot be uninstalled")) dep_ids = self.downstream_dependencies(cr, uid, ids, context=context) self.write(cr, uid, ids + dep_ids, {'state': 'to remove'}) + openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname) return dict(ACTION_DICT, name=_('Uninstall')) def button_uninstall_cancel(self, cr, uid, ids, context=None): @@ -656,32 +657,38 @@ class module(osv.osv): def install_from_urls(self, cr, uid, urls, context=None): OPENERP = 'openerp' tmp = tempfile.mkdtemp() + _logger.debug('Install from url: %r', urls) try: + # 1. Download & unzip missing modules for module_name, url in urls.items(): if not url: continue # nothing to download, local version is already the last one try: + _logger.info('Downloading module `%s` from OpenERP Apps', module_name) content = urllib2.urlopen(url).read() - except Exception, e: - _logger.exception('ggr') - raise osv.except_osv('grrr', e) + except Exception: + _logger.exception('Failed to fetch module %s', module_name) + raise osv.except_osv(_('Module not found'), + _('The `%s` module appears to be unavailable at the moment, please try again later.') % module_name) else: zipfile.ZipFile(StringIO(content)).extractall(tmp) assert os.path.isdir(os.path.join(tmp, module_name)) - for module_name in urls: - if module_name == OPENERP: - continue # special case. handled below + # 2a. Copy/Replace module source in addons path + for module_name, url in urls.items(): + if module_name == OPENERP or not url: + continue # OPENERP is special case, handled below, and no URL means local module module_path = modules.get_module_path(module_name, downloaded=True, display_warning=False) bck = backup(module_path, False) + _logger.info('Copy downloaded module `%s` to `%s`', module_name, module_path) shutil.move(os.path.join(tmp, module_name), module_path) if bck: shutil.rmtree(bck) + # 2b. Copy/Replace server+base module source if downloaded if urls.get(OPENERP, None): - # special case. it containt the server and the base module. + # special case. it contains the server and the base module. # extract path is not the same - 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) @@ -693,15 +700,22 @@ class module(osv.osv): # then replace the server by the new "base" module server_dir = openerp.tools.config['root_path'] # XXX or dirname() bck = backup(server_dir) + _logger.info('Copy downloaded module `openerp` to `%s`', server_dir) shutil.move(os.path.join(tmp, OPENERP), 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 + with_urls = [m for m, u in urls.items() if u] + downloaded_ids = self.search(cr, uid, [('name', 'in', with_urls)], context=context) + already_installed = self.search(cr, uid, [('id', 'in', downloaded_ids), ('state', '=', 'installed')], context=context) + + to_install_ids = self.search(cr, uid, [('name', 'in', urls.keys()), ('state', '=', 'uninstalled')], context=context) + post_install_action = self.button_immediate_install(cr, uid, to_install_ids, context=context) + + if already_installed: + # in this case, force server restart to reload python code... cr.commit() openerp.service.restart_server() return { @@ -709,7 +723,7 @@ class module(osv.osv): 'tag': 'home', 'params': {'wait': True}, } - return self.button_immediate_install(cr, uid, ids, context=context) + return post_install_action finally: shutil.rmtree(tmp) diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index 3a43a2591ba..3923c9de3bd 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -171,23 +171,18 @@ - - Modules ir.module.module form kanban,tree,form -

No module found!

You should try others search criteria.

- + @@ -195,20 +190,14 @@ Apps apps - - + Updates apps.updates {} - - + diff --git a/openerp/addons/base/res/res_bank_view.xml b/openerp/addons/base/res/res_bank_view.xml index 33b98c690c6..1c289d07141 100644 --- a/openerp/addons/base/res/res_bank_view.xml +++ b/openerp/addons/base/res/res_bank_view.xml @@ -125,6 +125,7 @@ res.partner.bank + diff --git a/openerp/addons/base/res/res_company.py b/openerp/addons/base/res/res_company.py index 6b90a612fb9..21c9b854ca3 100644 --- a/openerp/addons/base/res/res_company.py +++ b/openerp/addons/base/res/res_company.py @@ -318,7 +318,7 @@ class res_company(osv.osv): 1.3cm %s 20cm %s [[ company.rml_header1 ]] [[ company.partner_id.name ]] - + [[ display_address(company.partner_id) or '' ]] Phone: @@ -344,8 +344,8 @@ class res_company(osv.osv): """ - _header_a4 = _header_main % ('23.0cm', '27.6cm', '27.7cm', '27.7cm', '27.8cm', '27.4cm', '25.8cm', '26.0cm', '26.0cm', '25.6cm', '25.6cm', '25.5cm', '25.5cm') - _header_letter = _header_main % ('21.3cm', '25.9cm', '26.0cm', '26.0cm', '26.1cm', '25.7cm', '24.1cm', '24.3cm', '24.3cm', '23.9cm', '23.9cm', '23.8cm', '23.8cm') + _header_a4 = _header_main % ('23.0cm', '27.6cm', '27.7cm', '27.7cm', '27.8cm', '27.3cm', '25.3cm', '25.0cm', '25.0cm', '24.6cm', '24.6cm', '24.5cm', '24.5cm') + _header_letter = _header_main % ('21.3cm', '25.9cm', '26.0cm', '26.0cm', '26.1cm', '25.6cm', '23.6cm', '23.3cm', '23.3cm', '22.9cm', '22.9cm', '22.8cm', '22.8cm') def onchange_paper_format(self, cr, uid, ids, paper_format, context=None): if paper_format == 'us_letter': diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index ff0c3bfe6ad..a2368a9f508 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -21,6 +21,7 @@ import logging from operator import attrgetter +import openerp from openerp import pooler from openerp.osv import osv, fields from openerp.tools import ustr @@ -358,7 +359,8 @@ class res_config_installer(osv.osv_memory): cr, uid, modules.search(cr, uid, [('name','in',to_install)]), 'to install', ['uninstalled'], context=context) - cr.commit() #TOFIX: after remove this statement, installation wizard is fail + cr.commit() + openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname) new_db, self.pool = pooler.restart_pool(cr.dbname, update_module=True) res_config_installer() diff --git a/openerp/addons/base/res/res_country.py b/openerp/addons/base/res/res_country.py index a1b8ad29ac0..6ed4e76fa78 100644 --- a/openerp/addons/base/res/res_country.py +++ b/openerp/addons/base/res/res_country.py @@ -71,7 +71,7 @@ addresses belonging to this country.\n\nYou can use the python-style string pate name_search = location_name_search def create(self, cursor, user, vals, context=None): - if 'code' in vals: + if vals.get('code'): vals['code'] = vals['code'].upper() return super(Country, self).create(cursor, user, vals, context=context) diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml index d3f204e102a..c6bda5111ce 100644 --- a/openerp/addons/base/res/res_partner_view.xml +++ b/openerp/addons/base/res/res_partner_view.xml @@ -316,6 +316,7 @@ + diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py index fb68642f137..638a40c9fa8 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -3,7 +3,7 @@ # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). -# Copyright (C) 2010-2012 OpenERP s.a. (). +# Copyright (C) 2010-2013 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 @@ -36,14 +36,12 @@ import openerp.modules.graph import openerp.modules.migration import openerp.osv as osv import openerp.pooler as pooler -import openerp.release as release import openerp.tools as tools from openerp import SUPERUSER_ID -from openerp import SUPERUSER_ID from openerp.tools.translate import _ from openerp.modules.module import initialize_sys_path, \ - load_openerp_module, init_module_models + load_openerp_module, init_module_models, adapt_version _logger = logging.getLogger(__name__) @@ -213,7 +211,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= migrations.migrate_module(package, 'post') - ver = release.major_version + '.' + package.data['version'] + ver = adapt_version(package.data['version']) # Set new modules and dependencies modobj.write(cr, SUPERUSER_ID, [module_id], {'state': 'installed', 'latest_version': ver}) # Update translations for all installed languages diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 6056e405b78..67d365ecf6f 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -3555,7 +3555,7 @@ class BaseModel(object): if field_name not in self._all_columns: return True field = self._all_columns[field_name].column - if field.groups: + if user != SUPERUSER_ID and field.groups: return self.user_has_groups(cr, user, groups=field.groups, context=context) else: return True diff --git a/setup.py b/setup.py index b144924d022..e4e6001d302 100755 --- a/setup.py +++ b/setup.py @@ -43,6 +43,12 @@ def data(): base = os.path.join('pytz', root[len(tzdir) + 1:]) r[base] = [os.path.join(root, f) for f in filenames] + import docutils + dudir = os.path.dirname(docutils.__file__) + for root, _, filenames in os.walk(dudir): + base = os.path.join('docutils', root[len(dudir) + 1:]) + r[base] = [os.path.join(root, f) for f in filenames if not f.endswith(('.py', '.pyc', '.pyo'))] + return r.items() def gen_manifest():