summaryrefslogtreecommitdiff
path: root/bin/tools
diff options
context:
space:
mode:
authorJay (Open ERP) <jvo@tinyerp.com>2010-05-20 12:00:44 +0530
committerJay (Open ERP) <jvo@tinyerp.com>2010-05-20 12:00:44 +0530
commite3ccef27d33ff83ddbb7bfd3eacc80f8a98bd21d (patch)
treef14fb77ab9702c91bcb9309724e5aa63a96ee570 /bin/tools
parent2669744f4f09ca6ac9219dc91909e895559c74c0 (diff)
parentfe7673b7ba1f2706b8ed2abe6892ad33211063cd (diff)
[BACKPORT] Stable fixes and refactorings to Trunk
bzr revid: jvo@tinyerp.com-20100520063044-sviy1e9pybirhpsw
Diffstat (limited to 'bin/tools')
-rw-r--r--bin/tools/config.py22
-rw-r--r--bin/tools/convert.py41
-rw-r--r--bin/tools/misc.py46
-rw-r--r--bin/tools/translate.py57
4 files changed, 109 insertions, 57 deletions
diff --git a/bin/tools/config.py b/bin/tools/config.py
index c18a7422e2c..a629e97fc11 100644
--- a/bin/tools/config.py
+++ b/bin/tools/config.py
@@ -123,7 +123,6 @@ class configmanager(object):
parser.add_option("--assert-exit-level", dest='assert_exit_level', type="choice", choices=self._LOGLEVELS.keys(),
help="specify the level at which a failed assertion will stop the server. Accepted values: %s" % (self._LOGLEVELS.keys(),))
parser.add_option('--price_accuracy', dest='price_accuracy', default='2', help='deprecated since v6.0, replaced by module decimal_precision')
- parser.add_option('--no-database-list', action="store_false", dest='list_db', default=True, help="disable the ability to return the list of databases")
if self.has_ssl:
group = optparse.OptionGroup(parser, "SSL Configuration")
@@ -136,7 +135,7 @@ class configmanager(object):
default="server.pkey",
help="specify the private key file for the SSL connection")
parser.add_option_group(group)
-
+
# Testing Group
group = optparse.OptionGroup(parser, "Testing Configuration")
group.add_option("--test-disable", action="store_true", dest="test_disable",
@@ -144,7 +143,7 @@ class configmanager(object):
group.add_option("--test-commit", action="store_true", dest="test_commit",
default=False, help="Commit database changes performed by tests.")
parser.add_option_group(group)
-
+
# Logging Group
group = optparse.OptionGroup(parser, "Logging Configuration")
group.add_option("--logfile", dest="logfile", help="file where the server log will be stored")
@@ -161,8 +160,7 @@ class configmanager(object):
group.add_option('--email-from', dest='email_from', default='', help='specify the SMTP email address for sending email')
group.add_option('--smtp', dest='smtp_server', default='', help='specify the SMTP server for sending email')
group.add_option('--smtp-port', dest='smtp_port', default='25', help='specify the SMTP port', type="int")
- if self.has_ssl:
- group.add_option('--smtp-ssl', dest='smtp_ssl', default='', help='specify the SMTP server support SSL or not')
+ group.add_option('--smtp-ssl', dest='smtp_ssl', default='', help='specify the SMTP server support SSL or not')
group.add_option('--smtp-user', dest='smtp_user', default='', help='specify the SMTP username for sending email')
group.add_option('--smtp-password', dest='smtp_password', default='', help='specify the SMTP password for sending email')
parser.add_option_group(group)
@@ -199,6 +197,13 @@ class configmanager(object):
action="callback", callback=self._check_addons_path, nargs=1, type="string")
parser.add_option_group(group)
+ security = optparse.OptionGroup(parser, 'Security-related options')
+ security.add_option('--no-database-list', action="store_false", dest='list_db', default=True, help="disable the ability to return the list of databases")
+ security.add_option('--enable-code-actions', action='store_true',
+ dest='server_actions_allow_code', default=False,
+ help='Enables server actions of state "code". Warning, this is a security risk.')
+ parser.add_option_group(security)
+
def parse_config(self):
(opt, args) = self.parser.parse_args()
@@ -244,13 +249,13 @@ class configmanager(object):
self.options['pidfile'] = False
keys = ['interface', 'port', 'db_name', 'db_user', 'db_password', 'db_host',
- 'db_port', 'list_db', 'logfile', 'pidfile', 'smtp_port', 'cache_timeout',
+ 'db_port', 'list_db', 'logfile', 'pidfile', 'smtp_port', 'cache_timeout','smtp_ssl',
'email_from', 'smtp_server', 'smtp_user', 'smtp_password', 'price_accuracy',
'netinterface', 'netport', 'db_maxconn', 'import_partial', 'addons_path',
'netrpc', 'xmlrpc', 'syslog', 'without_demo', 'timezone',]
if self.has_ssl:
- keys.extend(['smtp_ssl', 'secure_cert_file', 'secure_pkey_file'])
+ keys.extend(['secure_cert_file', 'secure_pkey_file'])
keys.append('secure')
for arg in keys:
@@ -258,7 +263,8 @@ class configmanager(object):
self.options[arg] = getattr(opt, arg)
keys = ['language', 'translate_out', 'translate_in', 'debug_mode',
- 'stop_after_init', 'logrotate', 'without_demo', 'netrpc', 'xmlrpc', 'syslog', 'list_db']
+ 'stop_after_init', 'logrotate', 'without_demo', 'netrpc', 'xmlrpc', 'syslog',
+ 'list_db', 'server_actions_allow_code']
if self.has_ssl and not self.options['secure']:
keys.append('secure')
diff --git a/bin/tools/convert.py b/bin/tools/convert.py
index 1188f6deaa8..a7e002e1a61 100644
--- a/bin/tools/convert.py
+++ b/bin/tools/convert.py
@@ -26,11 +26,9 @@ import os.path
import pickle
import re
import sys
-import time
from datetime import datetime
from lxml import etree
-
import ir
import misc
import netsvc
@@ -79,6 +77,7 @@ def _eval_xml(self,node, pool, cr, uid, idref, context=None):
return f_val
a_eval = node.get('eval','')
if a_eval:
+ import time
idref2 = idref.copy()
idref2['time'] = time
idref2['DateTime'] = datetime
@@ -253,6 +252,14 @@ form: module.record_id""" % (xml_id,)
self.pool.get(d_model).unlink(cr, self.uid, ids)
self.pool.get('ir.model.data')._unlink(cr, self.uid, d_model, ids)
+ def _remove_ir_values(self, cr, name, value, model):
+ ir_value_ids = self.pool.get('ir.values').search(cr, self.uid, [('name','=',name),('value','=',value),('model','=',model)])
+ if ir_value_ids:
+ self.pool.get('ir.values').unlink(cr, self.uid, ir_value_ids)
+ self.pool.get('ir.model.data')._unlink(cr, self.uid, 'ir.values', ir_value_ids)
+
+ return True
+
def _tag_report(self, cr, rec, data_node=None):
res = {}
for dest,f in (('name','string'),('model','model'),('report_name','name')):
@@ -262,16 +269,17 @@ form: module.record_id""" % (xml_id,)
if rec.get(field):
res[dest] = rec.get(field).encode('utf8')
if rec.get('auto'):
- res['auto'] = eval(rec.get('auto'))
+ res['auto'] = eval(rec.get('auto','False'))
if rec.get('sxw'):
sxw_content = misc.file_open(rec.get('sxw')).read()
res['report_sxw_content'] = sxw_content
if rec.get('header'):
- res['header'] = eval(rec.get('header'))
+ res['header'] = eval(rec.get('header','False'))
if rec.get('report_type'):
res['report_type'] = rec.get('report_type')
- res['multi'] = rec.get('multi') and eval(rec.get('multi'))
+ res['multi'] = rec.get('multi') and eval(rec.get('multi','False'))
+
xml_id = rec.get('id','').encode('utf8')
self._test_xml_id(xml_id)
@@ -291,12 +299,16 @@ form: module.record_id""" % (xml_id,)
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
self.idref[xml_id] = int(id)
- if not rec.get('menu') or eval(rec.get('menu','')):
+ if not rec.get('menu') or eval(rec.get('menu','False')):
keyword = str(rec.get('keyword', 'client_print_multi'))
keys = [('action',keyword),('res_model',res['model'])]
value = 'ir.actions.report.xml,'+str(id)
replace = rec.get('replace', True)
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, res['name'], [res['model']], value, replace=replace, isobject=True, xml_id=xml_id)
+ elif self.mode=='update' and eval(rec.get('menu','False'))==False:
+ # Special check for report having attribute menu=False on update
+ value = 'ir.actions.report.xml,'+str(id)
+ self._remove_ir_values(cr, res['name'], value, res['model'])
return False
def _tag_function(self, cr, rec, data_node=None):
@@ -313,7 +325,7 @@ form: module.record_id""" % (xml_id,)
name = rec.get("name",'').encode('utf8')
xml_id = rec.get('id','').encode('utf8')
self._test_xml_id(xml_id)
- multi = rec.get('multi','') and eval(rec.get('multi',''))
+ multi = rec.get('multi','') and eval(rec.get('multi','False'))
res = {'name': string, 'wiz_name': name, 'multi': multi, 'model': model}
if rec.get('groups'):
@@ -332,12 +344,16 @@ form: module.record_id""" % (xml_id,)
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.wizard", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
self.idref[xml_id] = int(id)
# ir_set
- if (not rec.get('menu') or eval(rec.get('menu',''))) and id:
+ if (not rec.get('menu') or eval(rec.get('menu','False'))) and id:
keyword = str(rec.get('keyword','') or 'client_action_multi')
keys = [('action',keyword),('res_model',model)]
value = 'ir.actions.wizard,'+str(id)
replace = rec.get("replace",'') or True
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, string, [model], value, replace=replace, isobject=True, xml_id=xml_id)
+ elif self.mode=='update' and (rec.get('menu') and eval(rec.get('menu','False'))==False):
+ # Special check for wizard having attribute menu=False on update
+ value = 'ir.actions.wizard,'+str(id)
+ self._remove_ir_values(cr, string, value, model)
def _tag_url(self, cr, rec, data_node=None):
url = rec.get("string",'').encode('utf8')
@@ -351,12 +367,16 @@ form: module.record_id""" % (xml_id,)
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.url", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
self.idref[xml_id] = int(id)
# ir_set
- if (not rec.get('menu') or eval(rec.get('menu',''))) and id:
+ if (not rec.get('menu') or eval(rec.get('menu','False'))) and id:
keyword = str(rec.get('keyword','') or 'client_action_multi')
keys = [('action',keyword)]
value = 'ir.actions.url,'+str(id)
replace = rec.get("replace",'') or True
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, url, ["ir.actions.url"], value, replace=replace, isobject=True, xml_id=xml_id)
+ elif self.mode=='update' and (rec.get('menu') and eval(rec.get('menu','False'))==False):
+ # Special check for URL having attribute menu=False on update
+ value = 'ir.actions.url,'+str(id)
+ self._remove_ir_values(cr, url, value, "ir.actions.url")
def _tag_act_window(self, cr, rec, data_node=None):
name = rec.get('name','').encode('utf-8')
@@ -379,11 +399,12 @@ form: module.record_id""" % (xml_id,)
uid = self.uid
# def ref() added because , if context has ref('id') eval wil use this ref
- active_id=str("active_id") # for further reference in client/bin/tools/__init__.py
+ active_id = str("active_id") # for further reference in client/bin/tools/__init__.py
def ref(str_id):
return self.id_get(cr, None, str_id)
context = eval(context)
+# domain = eval(domain) # XXX need to test this line -> uid, active_id, active_ids, ...
res = {
'name': name,
diff --git a/bin/tools/misc.py b/bin/tools/misc.py
index 07e0fc38f8e..e60213ca740 100644
--- a/bin/tools/misc.py
+++ b/bin/tools/misc.py
@@ -820,6 +820,22 @@ class cache(object):
def to_xml(s):
return s.replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')
+def get_encodings():
+ yield 'utf8'
+ from locale import getpreferredencoding
+ prefenc = getpreferredencoding()
+ if prefenc:
+ yield prefenc
+
+ prefenc = {
+ 'latin1': 'latin9',
+ 'iso-8859-1': 'iso8859-15',
+ 'cp1252': '1252',
+ }.get(prefenc.lower())
+ if prefenc:
+ yield prefenc
+
+
def ustr(value):
"""This method is similar to the builtin `str` method, except
it will return Unicode string.
@@ -829,29 +845,25 @@ def ustr(value):
@rtype: unicode
@return: unicode string
"""
+ orig = value
+ if isinstance(value, Exception):
+ return exception_to_unicode(value)
if isinstance(value, unicode):
return value
- if hasattr(value, '__unicode__'):
+ try:
return unicode(value)
-
- if not isinstance(value, str):
- value = str(value)
-
- try: # first try utf-8
- return unicode(value, 'utf-8')
except:
pass
- try: # then extened iso-8858
- return unicode(value, 'iso-8859-15')
- except:
- pass
+ for ln in get_encodings():
+ try:
+ return unicode(value, ln)
+ except:
+ pass
+ raise UnicodeError('unable de to convert %r' % (orig,))
- # else use default system locale
- from locale import getlocale
- return unicode(value, getlocale()[1])
def exception_to_unicode(e):
if (sys.version_info[:2] < (2,6)) and hasattr(e, 'message'):
@@ -914,7 +926,7 @@ def get_languages():
'fr_BE': u'French (BE) / Français (BE)',
'fr_CH': u'French (CH) / Français (CH)',
'fr_FR': u'French / Français',
- 'gl_ES': u'Galician / Spain',
+ 'gl_ES': u'Galician / Galego',
'gu_IN': u'Gujarati / India',
'hi_IN': u'Hindi / India',
'hr_HR': u'Croatian / hrvatski jezik',
@@ -939,8 +951,8 @@ def get_languages():
'ro_RO': u'Romanian / limba română',
'ru_RU': u'Russian / русский язык',
'si_LK': u'Sinhalese / Sri Lanka',
- 'sk_SK': u'Slovak / Slovakia',
- 'sl_SL': u'Slovenian / slovenščina',
+ 'sl_SI': u'Slovenian / slovenščina',
+ 'sk_SK': u'Slovak / Slovenský jazyk',
'sq_AL': u'Albanian / Shqipëri',
'sr_RS': u'Serbian / Serbia',
'sv_SE': u'Swedish / svenska',
diff --git a/bin/tools/translate.py b/bin/tools/translate.py
index 05f7f95e9b4..9277bf6924b 100644
--- a/bin/tools/translate.py
+++ b/bin/tools/translate.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# 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 <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -596,23 +596,30 @@ def trans_generate(lang, modules, dbname=None):
push_translation(module, 'model', name, xml_name, encode(trad))
# parse source code for _() calls
- def get_module_from_path(path,mod_paths=None):
- if not mod_paths:
- # First, construct a list of possible paths
- def_path = os.path.abspath(os.path.join(tools.config['root_path'], 'addons')) # default addons path (base)
- ad_paths= map(lambda m: os.path.abspath(m.strip()),tools.config['addons_path'].split(','))
- mod_paths=[def_path]
- for adp in ad_paths:
- mod_paths.append(adp)
- if not adp.startswith('/'):
- mod_paths.append(os.path.join(def_path,adp))
- elif adp.startswith(def_path):
- mod_paths.append(adp[len(def_path)+1:])
-
- for mp in mod_paths:
- if path.startswith(mp) and (os.path.dirname(path) != mp):
- path = path[len(mp)+1:]
- return path.split(os.path.sep)[0]
+ def get_module_from_path(path, mod_paths=None):
+# if not mod_paths:
+## First, construct a list of possible paths
+# def_path = os.path.abspath(os.path.join(tools.config['root_path'], 'addons')) # default addons path (base)
+# ad_paths= map(lambda m: os.path.abspath(m.strip()),tools.config['addons_path'].split(','))
+# mod_paths=[def_path]
+# for adp in ad_paths:
+# mod_paths.append(adp)
+# if not adp.startswith('/'):
+# mod_paths.append(os.path.join(def_path,adp))
+# elif adp.startswith(def_path):
+# mod_paths.append(adp[len(def_path)+1:])
+# for mp in mod_paths:
+# if path.startswith(mp) and (os.path.dirname(path) != mp):
+# path = path[len(mp)+1:]
+# return path.split(os.path.sep)[0]
+ path_dir = os.path.dirname(path[1:])
+ if path_dir:
+ if os.path.exists(os.path.join(tools.config['addons_path'],path[1:])):
+ return path.split(os.path.sep)[1]
+ else:
+ root_addons = os.path.join(tools.config['root_path'], 'addons')
+ if os.path.exists(os.path.join(root_addons,path[1:])):
+ return path.split(os.path.sep)[1]
return 'base' # files that are not in a module are considered as being in 'base' module
modobj = pool.get('ir.module.module')
@@ -699,6 +706,11 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
if not lang_name:
lang_name = tools.get_languages().get(lang, lang)
+ def fix_xa0(s):
+ if s == '\xa0':
+ return '\xc2\xa0'
+ return s
+
lang_info = {
'code': lang,
'iso_code': iso_lang,
@@ -706,9 +718,10 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
'translatable': 1,
'date_format' : str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y')),
'time_format' : str(locale.nl_langinfo(locale.T_FMT)),
- 'decimal_point' : str(locale.localeconv()['decimal_point']).replace('\xa0', '\xc2\xa0'),
- 'thousands_sep' : str(locale.localeconv()['thousands_sep']).replace('\xa0', '\xc2\xa0'),
+ 'decimal_point' : fix_xa0(str(locale.localeconv()['decimal_point'])),
+ 'thousands_sep' : fix_xa0(str(locale.localeconv()['thousands_sep'])),
}
+
try:
lang_obj.create(cr, uid, lang_info)
finally:
@@ -767,7 +780,7 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
# the same source
obj = pool.get(model)
if obj:
- if not field in obj._columns:
+ if field not in obj.fields_get_keys(cr, uid):
continue
ids = obj.search(cr, uid, [(field, '=', dic['src'])])