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 @@
-
- Modulesir.module.moduleformkanban,tree,form
-
No module found!
You should try others search criteria.
-
+
@@ -195,20 +190,14 @@
Appsapps
-
-
+
Updatesapps.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():