diff options
Diffstat (limited to 'bin/tools')
| -rw-r--r-- | bin/tools/config.py | 22 | ||||
| -rw-r--r-- | bin/tools/convert.py | 41 | ||||
| -rw-r--r-- | bin/tools/misc.py | 46 | ||||
| -rw-r--r-- | bin/tools/translate.py | 57 |
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('&','&').replace('<','<').replace('>','>') +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'])]) |
