diff --git a/bin/addons/base/ir/ir_model.py b/bin/addons/base/ir/ir_model.py index 15c3224e784..0c6bfc7edb1 100644 --- a/bin/addons/base/ir/ir_model.py +++ b/bin/addons/base/ir/ir_model.py @@ -71,7 +71,7 @@ class ir_model(osv.osv): def unlink(self, cr, user, ids, context=None): for model in self.browse(cr, user, ids, context): if model.state <> 'manual': - raise except_orm('Error', "You can not remove the model '%s' !" %(field.name,)) + raise except_orm(_('Error'), _("You can not remove the model '%s' !") %(field.name,)) res = super(ir_model, self).unlink(cr, user, ids, context) pooler.restart_pool(cr.dbname) return res @@ -138,7 +138,7 @@ class ir_model_fields(osv.osv): def unlink(self, cr, user, ids, context=None): for field in self.browse(cr, user, ids, context): if field.state <> 'manual': - raise except_orm('Error', "You can not remove the field '%s' !" %(field.name,)) + raise except_orm(_('Error'), _("You can not remove the field '%s' !") %(field.name,)) # # MAY BE ADD A ALTER TABLE DROP ? # @@ -153,7 +153,7 @@ class ir_model_fields(osv.osv): res = super(ir_model_fields,self).create(cr, user, vals, context) if vals.get('state','base')=='manual': if not vals['name'].startswith('x_'): - raise except_orm('Error', "Custom fields must have a name that starts with 'x_' !") + raise except_orm(_('Error'), _("Custom fields must have a name that starts with 'x_' !")) if self.pool.get(vals['model']): self.pool.get(vals['model']).__init__(self.pool, cr) self.pool.get(vals['model'])._auto_init(cr,{}) @@ -207,7 +207,7 @@ class ir_model_access(osv.osv): 'WHERE a.group_id IS NULL AND m.model = %s', (model_name,)) r= cr.fetchall() if r[0][0] == None: - return True + return False # by default, the user had no access if not r[0][0]: if raise_exception: @@ -282,8 +282,9 @@ class ir_model_data(osv.osv): def _update(self,cr, uid, model, module, values, xml_id=False, store=True, noupdate=False, mode='init', res_id=False): warning = True model_obj = self.pool.get(model) + context = {} if xml_id and ('.' in xml_id): - assert len(xml_id.split('.'))==2, '"%s" contains too many dots. XML ids should not contain dots ! These are used to refer to other modules data, as in module.reference_id' % (xml_id) + assert len(xml_id.split('.'))==2, _('"%s" contains too many dots. XML ids should not contain dots ! These are used to refer to other modules data, as in module.reference_id') % (xml_id) warning = False module, xml_id = xml_id.split('.') if (not xml_id) and (not self.doinit): diff --git a/bin/addons/base/ir/ir_report_custom.py b/bin/addons/base/ir/ir_report_custom.py index b962684035e..af413f54e41 100644 --- a/bin/addons/base/ir/ir_report_custom.py +++ b/bin/addons/base/ir/ir_report_custom.py @@ -31,6 +31,7 @@ from osv import fields,osv from osv.orm import browse_null import ir import report.custom +from tools.translate import _ class report_custom(osv.osv): _name = 'ir.report.custom' @@ -75,10 +76,10 @@ class report_custom(osv.osv): # required on field0 does not seem to work( cause we use o2m_l ?) if not report.fields_child0: - raise osv.except_osv('Invalid operation :', 'Enter at least one field !') + raise osv.except_osv(_('Invalid operation'), _('Enter at least one field !')) if report.type in ['pie', 'bar', 'line'] and report.field_parent: - raise osv.except_osv('Invalid operation :', 'Tree can only be used in tabular reports') + raise osv.except_osv(_('Invalid operation'), _('Tree can only be used in tabular reports')) # Otherwise it won't build a good tree. See level.pop in custom.py. if report.type == 'table' and report.field_parent and report.fields_child0 and not report.fields_child0[0].groupby: @@ -86,7 +87,7 @@ class report_custom(osv.osv): if report.type == 'pie': if len(report.fields_child0) != 2: - raise osv.except_osv('Invalid operation :', 'Pie charts need exactly two fields') + raise osv.except_osv(_('Invalid operation'), _('Pie charts need exactly two fields')) else: c_f = {} for i in range(2): @@ -95,11 +96,11 @@ class report_custom(osv.osv): for j in range(3): c_f[i].append((not isinstance(eval('tmp.field_child'+str(j)), browse_null) and eval('tmp.field_child'+str(j)+'.ttype')) or None) if not reduce(lambda x,y : x or y, map(lambda x: x in ['integer', 'float'], c_f[1])): - raise osv.except_osv('Invalid operation : ','Second field should be figures') + raise osv.except_osv(_('Invalid operation'), _('Second field should be figures')) if report.type == 'bar': if len(report.fields_child0) < 2: - raise osv.except_osv('Invalid operation : ','Bar charts need at least two fields') + raise osv.except_osv(_('Invalid operation'), _('Bar charts need at least two fields')) else: c_f = {} for i in range(len(report.fields_child0)): @@ -112,7 +113,7 @@ class report_custom(osv.osv): pass else: if not reduce(lambda x,y : x or y, map(lambda x: x in ['integer', 'float'], c_f[i])): - raise osv.except_osv('Invalid operation : ','Field %d should be a figure' %(i,)) + raise osv.except_osv(_('Invalid operation'), _('Field %d should be a figure') %(i,)) if report.state=='subscribed': continue @@ -193,7 +194,7 @@ class report_custom_fields(osv.osv): } } else: - print "Warning: using a relation field which uses an unknown object" + print _("Warning: using a relation field which uses an unknown object") #TODO use the logger return {'required': {next_level_field_name: True}} else: return {'domain': {next_level_field_name: []}} diff --git a/bin/addons/base/ir/ir_translation.py b/bin/addons/base/ir/ir_translation.py index 20d2b383405..211f9dbaf45 100644 --- a/bin/addons/base/ir/ir_translation.py +++ b/bin/addons/base/ir/ir_translation.py @@ -121,9 +121,8 @@ class ir_translation(osv.osv, Cacheable): return trans if source: - source = source.strip().replace('\n',' ') - if isinstance(source, unicode): - source = source.encode('utf8') + #if isinstance(source, unicode): + # source = source.encode('utf8') cr.execute('select value ' \ 'from ir_translation ' \ 'where lang=%s ' \ diff --git a/bin/addons/base/ir/ir_values.py b/bin/addons/base/ir/ir_values.py index 8940cc8521b..84fafefa3f4 100644 --- a/bin/addons/base/ir/ir_values.py +++ b/bin/addons/base/ir/ir_values.py @@ -29,6 +29,7 @@ from osv import osv,fields import pickle +from tools.translate import _ class ir_values(osv.osv): _name = 'ir.values' diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py index d124fbc4cdd..8442628a2e3 100644 --- a/bin/addons/base/module/module.py +++ b/bin/addons/base/module/module.py @@ -264,13 +264,13 @@ class module(osv.osv): ids = [ids] for mod in self.read(cr, uid, ids, ['state'], 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')) return super(module, self).unlink(cr, uid, ids, context=context) def state_change(self, cr, uid, ids, newstate, context={}, level=50): if level<1: - raise Exception, 'Recursion error in modules dependencies !' + raise Exception, _('Recursion error in modules dependencies !') demo = True for module in self.browse(cr, uid, ids): mdemo = True @@ -288,7 +288,7 @@ class module(osv.osv): def state_upgrade(self, cr, uid, ids, newstate, context=None, level=50): dep_obj = self.pool.get('ir.module.module.dependency') if level<1: - raise Exception, 'Recursion error in modules dependencies !' + raise Exception, _('Recursion error in modules dependencies !') for module in self.browse(cr, uid, ids): dep_ids = dep_obj.search(cr, uid, [('name', '=', module.name)]) if dep_ids: @@ -320,7 +320,7 @@ class module(osv.osv): m.state not in ('uninstalled','uninstallable','to remove')''', (module.name,)) res = cr.fetchall() if res: - raise orm.except_orm('Error', 'The module you are trying to remove depends on installed modules :\n' + '\n'.join(map(lambda x: '\t%s: %s' % (x[0], x[1]), res))) + raise orm.except_orm(_('Error'), _('The module you are trying to remove depends on installed modules :\n %s') % '\n'.join(map(lambda x: '\t%s: %s' % (x[0], x[1]), res))) self.write(cr, uid, ids, {'state': 'to remove'}) return True @@ -420,9 +420,8 @@ class module(osv.osv): index_page = urllib.urlopen(repository.url).read() except IOError, e: if e.errno == 21: - raise orm.except_orm('Error', - 'This url \'%s\' must provide an html file ' - 'with links to zip modules' % (repository.url)) + raise orm.except_orm(_('Error'), + _("This url '%s' must provide an html file with links to zip modules") % (repository.url)) else: raise modules = re.findall(repository.filter, index_page, re.I+re.M) @@ -493,8 +492,7 @@ class module(osv.osv): fp.write(zipfile) fp.close() except IOError, e: - raise orm.except_orm('Error', 'Can not create the module file:\n %s' - % (fname,)) + raise orm.except_orm(_('Error'), _('Can not create the module file:\n %s') % (fname,)) terp = self.get_module_info(mod.name) self.write(cr, uid, mod.id, { 'description': terp.get('description', ''), diff --git a/bin/addons/base/module/wizard/wizard_export_lang.py b/bin/addons/base/module/wizard/wizard_export_lang.py index a42e3ec430e..a855ad503c8 100644 --- a/bin/addons/base/module/wizard/wizard_export_lang.py +++ b/bin/addons/base/module/wizard/wizard_export_lang.py @@ -60,12 +60,12 @@ class wizard_export_lang(wizard.interface): lang_obj=pooler.get_pool(cr.dbname).get('res.lang') ids=lang_obj.search(cr, uid, [('active', '=', True),]) langs=lang_obj.browse(cr, uid, ids) - return [(lang.code, lang.translatable and lang.name or 'New language') for lang in langs] + return [(lang.code, lang.translatable and lang.name or _('New language')) for lang in langs] def _get_file(self, cr, uid, data, context): file=tools.trans_generate(data['form']['lang'], 'all', dbname=cr.dbname) buf=StringIO.StringIO() - writer=csv.writer(buf, 'TINY') + writer=csv.writer(buf, 'UNIX') for row in file: writer.writerow(row) del file diff --git a/bin/addons/base/module/wizard/wizard_import_lang.py b/bin/addons/base/module/wizard/wizard_import_lang.py index d9543b7f851..a6516bb24df 100644 --- a/bin/addons/base/module/wizard/wizard_import_lang.py +++ b/bin/addons/base/module/wizard/wizard_import_lang.py @@ -32,6 +32,7 @@ import wizard import tools import base64 import pooler +from tempfile import TemporaryFile view_form="""
@@ -56,8 +57,11 @@ class wizard_import_lang(wizard.interface): def _import_lang(self, cr, uid, data, context): form=data['form'] - buf=base64.decodestring(data['form']['data']).split('\n') - tools.trans_load_data(cr.dbname, buf, form['code'], lang_name=form['name']) + #buf=base64.decodestring(form['data']).split('\n') + fileobj = TemporaryFile('w+') + fileobj.write( base64.decodestring(form['data']) ) + tools.trans_load_data(cr.dbname, fileobj, form['code'], lang_name=form['name']) + fileobj.close() return {} states={ diff --git a/bin/addons/base/module/wizard/wizard_module_import.py b/bin/addons/base/module/wizard/wizard_module_import.py index acaf7e3a7cf..d59c635cd30 100644 --- a/bin/addons/base/module/wizard/wizard_module_import.py +++ b/bin/addons/base/module/wizard/wizard_module_import.py @@ -75,7 +75,7 @@ class move_module_wizard(wizard.interface): fp.write(val) fp.close() except IOError, e: - raise wizard.except_wizard('Error !', 'Can not create the module file:\n'+' '+fname+'!') + raise wizard.except_wizard(_('Error !'), _('Can not create the module file: %s !') % (fname,) ) pooler.get_pool(cr.dbname).get('ir.module.module').update_list(cr, uid) return {'module_name': module_name} diff --git a/bin/addons/base/res/partner/partner.py b/bin/addons/base/res/partner/partner.py index 7061f46baed..220b6aabd78 100644 --- a/bin/addons/base/res/partner/partner.py +++ b/bin/addons/base/res/partner/partner.py @@ -252,7 +252,7 @@ class res_partner(osv.osv): try: nextref = int(ref)+1 except e: - raise osv.except_osv('Warning', "Couldn't generate the next id because some partners have an alphabetic id !") + raise osv.except_osv(_('Warning'), _("Couldn't generate the next id because some partners have an alphabetic id !")) # update the current partner cr.execute("update res_partner set ref=%d where id=%d", (nextref, ids[0])) diff --git a/bin/addons/base/res/res_currency.py b/bin/addons/base/res/res_currency.py index 8b419100f83..30b61e0f0ac 100644 --- a/bin/addons/base/res/res_currency.py +++ b/bin/addons/base/res/res_currency.py @@ -33,6 +33,7 @@ from osv import fields, osv import ir from tools.misc import currency +from tools.translate import _ import mx.DateTime from mx.DateTime import RelativeDateTime, now, DateTime, localtime @@ -87,9 +88,9 @@ class res_currency(osv.osv): code = from_currency.code else: code = to_currency.code - raise osv.except_osv('Error', 'No rate found \n' \ + raise osv.except_osv(_('Error'), _('No rate found \n' \ 'for the currency: %s \n' \ - 'at the date: %s' % (code, date)) + 'at the date: %s') % (code, date)) if to_currency_id==from_currency_id: if round: return self.round(cr, uid, to_currency, from_amount) diff --git a/bin/addons/base/res/res_user.py b/bin/addons/base/res/res_user.py index 8ce752ebcd7..24e16e6a03a 100644 --- a/bin/addons/base/res/res_user.py +++ b/bin/addons/base/res/res_user.py @@ -48,8 +48,8 @@ class groups(osv.osv): def write(self, cr, uid, ids, vals, context=None): if 'name' in vals: if vals['name'].startswith('-'): - raise osv.except_osv('Error', - 'The name of the group can not start with "-"') + raise osv.except_osv(_('Error'), + _('The name of the group can not start with "-"')) res = super(groups, self).write(cr, uid, ids, vals, context=context) # Restart the cache on the company_get method self.pool.get('ir.rule').domain_get() @@ -58,8 +58,8 @@ class groups(osv.osv): def create(self, cr, uid, vals, context=None): if 'name' in vals: if vals['name'].startswith('-'): - raise osv.except_osv('Error', - 'The name of the group can not start with "-"') + raise osv.except_osv(_('Error'), + _('The name of the group can not start with "-"')) return super(groups, self).create(cr, uid, vals, context=context) groups() @@ -163,7 +163,7 @@ class users(osv.osv): def unlink(self, cr, uid, ids): if 1 in ids: - raise osv.except_osv('Can not remove root user !', 'You can not remove the root user as it is used internally for resources created by Tiny ERP (updates, module installation, ...)') + raise osv.except_osv(_('Can not remove root user!'), _('You can not remove the root user as it is used internally for resources created by Tiny ERP (updates, module installation, ...)')) return super(users, self).unlink(cr, uid, ids) def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=80): diff --git a/bin/osv/fields.py b/bin/osv/fields.py index 65975195605..32544bcb9c3 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -97,19 +97,19 @@ class _column(object): def set(self, cr, obj, id, name, value, user=None, context=None): cr.execute('update '+obj._table+' set '+name+'='+self._symbol_set[0]+' where id=%d', (self._symbol_set[1](value),id) ) def set_memory(self, cr, obj, id, name, value, user=None, context=None): - raise Exception, 'Not implemented set_memory method !' + raise Exception, _('Not implemented set_memory method !') def get_memory(self, cr, obj, ids, name, context=None, values=None): - raise Exception, 'Not implemented get_memory method !' + raise Exception, _('Not implemented get_memory method !') def get(self, cr, obj, ids, name, context=None, values=None): - raise Exception, 'undefined get method !' + raise Exception, _('undefined get method !') def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None): ids = obj.search(cr, uid, args+self._domain+[(name,'ilike',value)], offset, limit) res = obj.read(cr, uid, ids, [name]) return [x[name] for x in res] - def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None): - raise Exception, 'Not implemented search_memory method !' + def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, context=None): + raise Exception, _('Not implemented search_memory method !') # --------------------------------------------------------- # Simple fields @@ -362,8 +362,8 @@ class one2many(_column): for id2 in (act[2] or []): obj.datas[id2][self._fields_id] = id - def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like'): - raise 'Not Implemented' + def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like', context=None): + raise _('Not Implemented') def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None): @@ -507,18 +507,19 @@ class many2many(_column): if not values: return for act in values: + # TODO: use constants instead of these magic numbers if act[0]==0: - raise 'Not Implemented' + raise _('Not Implemented') elif act[0]==1: - raise 'Not Implemented' + raise _('Not Implemented') elif act[0]==2: - raise 'Not Implemented' + raise _('Not Implemented') elif act[0]==3: - raise 'Not Implemented' + raise _('Not Implemented') elif act[0]==4: - raise 'Not Implemented' + raise _('Not Implemented') elif act[0]==5: - raise 'Not Implemented' + raise _('Not Implemented') elif act[0]==6: obj.datas[id][name] = act[2] @@ -675,3 +676,4 @@ class property(function): def restart(self): self.field_id = {} + diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 57fc494efaf..793588ca772 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -115,7 +115,7 @@ class browse_record(object): ''' if not context: context = {} - assert id, 'Wrong ID for the browse record, got '+str(id)+ ', expected an integer.' + assert id, _('Wrong ID for the browse record, got %s, expected an integer.') % str(id) self._list_class = list_class or browse_record_list self._cr = cr self._uid = uid @@ -451,7 +451,7 @@ class orm_template(object): # for i in range(len(fields)): if i>=len(line): - raise Exception, 'Please check that all your lines have %d cols.' % (len(fields),) + raise Exception, _('Please check that all your lines have %d columns.') % (len(fields),) field = fields[i] if field == ["id"]: data_id= line[i] @@ -623,7 +623,7 @@ class orm_template(object): return (done, 0, 0, 0) def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'): - raise 'The read method is not implemented on this object !' + raise _('The read method is not implemented on this object !') def _validate(self, cr, uid, ids): field_error = [] @@ -641,16 +641,16 @@ class orm_template(object): return {} def perm_read(self, cr, user, ids, context=None, details=True): - raise 'The perm_read method is not implemented on this object !' + raise _('The perm_read method is not implemented on this object !') def unlink(self, cr, uid, ids, context=None): - raise 'The unlink method is not implemented on this object !' + raise _('The unlink method is not implemented on this object !') def write(self, cr, user, ids, vals, context=None): - raise 'The write method is not implemented on this object !' + raise _('The write method is not implemented on this object !') def create(self, cr, user, vals, context=None): - raise 'The create method is not implemented on this object !' + raise _('The create method is not implemented on this object !') # returns the definition of each field in the object # the optional fields parameter can limit the result to some fields @@ -783,11 +783,11 @@ class orm_template(object): # translate view if ('lang' in context) and not result: if node.hasAttribute('string') and node.getAttribute('string'): - trans = tools.translate(cr, user, self._name, 'view', context['lang'], node.getAttribute('string').encode('utf8')) + trans = tools.translate(cr, self._name, 'view', context['lang'], node.getAttribute('string').encode('utf8')) if trans: node.setAttribute('string', trans.decode('utf8')) if node.hasAttribute('sum') and node.getAttribute('sum'): - trans = tools.translate(cr, user, self._name, 'view', context['lang'], node.getAttribute('sum').encode('utf8')) + trans = tools.translate(cr, self._name, 'view', context['lang'], node.getAttribute('sum').encode('utf8')) if trans: node.setAttribute('sum', trans.decode('utf8')) # @@ -947,7 +947,7 @@ class orm_template(object): elif pos=='before': node.parentNode.insertBefore(child, node) else: - raise AttributeError, 'Unknown position in inherited view %s !' % pos + raise AttributeError, _('Unknown position in inherited view %s !') % pos else: attrs = ''.join([ ' %s="%s"' % (attr, node2.getAttribute(attr)) @@ -955,7 +955,7 @@ class orm_template(object): if attr != 'position' ]) tag = "<%s%s>" % (node2.localName, attrs) - raise AttributeError, "Couldn't find tag '%s' in parent view !" % tag + raise AttributeError, _("Couldn't find tag '%s' in parent view !") % tag return doc_src.toxml(encoding="utf-8").replace('\t', '') result = {'type':view_type, 'model':self._name} @@ -1072,16 +1072,16 @@ class orm_template(object): def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): - raise 'The search method is not implemented on this object !' + raise _('The search method is not implemented on this object !') def name_get(self, cr, user, ids, context=None): - raise 'The name_get method is not implemented on this object !' + raise _('The name_get method is not implemented on this object !') def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=80): - raise 'The name_search method is not implemented on this object !' + raise _('The name_search method is not implemented on this object !') def copy(self, cr, uid, id, default=None, context=None): - raise 'The copy method is not implemented on this object !' + raise _('The copy method is not implemented on this object !') class orm_memory(orm_template): _protected = ['read','write','create','default_get','perm_read','unlink','fields_get','fields_view_get','search','name_get','distinct_field_get','name_search','copy','import_data','search_count'] @@ -1303,7 +1303,7 @@ class orm(orm_template): for k in self._columns: if k in ('id','write_uid','write_date','create_uid','create_date'): continue - #raise 'Can not define a column %s. Reserved keyword !' % (k,) + #raise _('Can not define a column %s. Reserved keyword !') % (k,) f = self._columns[k] if isinstance(f, fields.one2many): @@ -1668,8 +1668,8 @@ class orm(orm_template): ','.join([str(x) for x in sub_ids]), d1, self._order),d2) if not cr.rowcount == len({}.fromkeys(sub_ids)): - raise except_orm('AccessError', - 'You try to bypass an access rule (Document type: %s).' % self._description) + raise except_orm(_('AccessError'), + _('You try to bypass an access rule (Document type: %s).') % self._description) else: cr.execute('SELECT %s FROM \"%s\" WHERE id IN (%s) ORDER BY %s' % \ (','.join(fields_pre2 + ['id']), self._table, @@ -1810,8 +1810,8 @@ class orm(orm_template): (delta, self._table, ",".join(map(str, sub_ids))) ) res= cr.fetchone() if res and res[0]: - raise except_orm('ConcurrencyException', - 'This record was modified in the meanwhile') + raise except_orm(_('ConcurrencyException'), + _('This record was modified in the meanwhile')) self.pool.get('ir.model.access').check(cr, uid, self._name, 'unlink') @@ -1836,8 +1836,8 @@ class orm(orm_template): cr.execute('SELECT id FROM "'+self._table+'" ' \ 'WHERE id IN ('+str_d+')'+d1, sub_ids+d2) if not cr.rowcount == len({}.fromkeys(ids)): - raise except_orm('AccessError', - 'You try to bypass an access rule (Document type: %s).' % \ + raise except_orm(_('AccessError'), + _('You try to bypass an access rule (Document type: %s).') % \ self._description) cr.execute('delete from inherit ' \ @@ -1907,8 +1907,8 @@ class orm(orm_template): if res and res[0]: for field in vals: if field in self._columns and self._columns[field]._classic_write: - raise except_orm('ConcurrencyException', - 'This record was modified in the meanwhile') + raise except_orm(_('ConcurrencyException'), + _('This record was modified in the meanwhile')) self.pool.get('ir.model.access').check(cr, user, self._name, 'write') @@ -1940,14 +1940,14 @@ class orm(orm_template): val = vals[field] if isinstance(self._columns[field].selection, (tuple, list)): if val not in dict(self._columns[field].selection): - raise except_orm('ValidateError', - 'The value "%s" for the field "%s" is not in the selection' \ + raise except_orm(_('ValidateError'), + _('The value "%s" for the field "%s" is not in the selection') \ % (vals[field], field)) else: if val not in dict(self._columns[field].selection( self, cr, user, context=context)): - raise except_orm('ValidateError', - 'The value "%s" for the field "%s" is not in the selection' \ + raise except_orm(_('ValidateError'), + _('The value "%s" for the field "%s" is not in the selection') \ % (vals[field], field)) if self._log_access: @@ -1968,15 +1968,15 @@ class orm(orm_template): cr.execute('SELECT id FROM "'+self._table+'" ' \ 'WHERE id IN ('+ids_str+')'+d1, d2) if not cr.rowcount == len({}.fromkeys(sub_ids)): - raise except_orm('AccessError', - 'You try to bypass an access rule (Document type: %s).'% \ + raise except_orm(_('AccessError'), + _('You try to bypass an access rule (Document type: %s).') % \ self._description) else: cr.execute('SELECT id FROM "'+self._table+'" WHERE id IN ('+ids_str+')') if not cr.rowcount == len({}.fromkeys(sub_ids)): - raise except_orm('AccessError', - 'You try to write on an record that doesn\'t exist ' \ - '(Document type: %s).' % self._description) + raise except_orm(_('AccessError'), + _('You try to write on an record that doesn\'t exist ' \ + '(Document type: %s).') % self._description) if d1: cr.execute('update "'+self._table+'" set '+string.join(upd0,',')+' ' \ 'where id in ('+ids_str+')'+d1, upd1+ d2) @@ -2105,14 +2105,14 @@ class orm(orm_template): val = vals[field] if isinstance(self._columns[field].selection, (tuple, list)): if val not in dict(self._columns[field].selection): - raise except_orm('ValidateError', - 'The value "%s" for the field "%s" is not in the selection' \ + raise except_orm(_('ValidateError'), + _('The value "%s" for the field "%s" is not in the selection') \ % (vals[field], field)) else: if val not in dict(self._columns[field].selection( self, cr, user, context=context)): - raise except_orm('ValidateError', - 'The value "%s" for the field "%s" is not in the selection' \ + raise except_orm(_('ValidateError'), + _('The value "%s" for the field "%s" is not in the selection') \ % (vals[field], field)) if self._log_access: upd0 += ',create_uid,create_date' @@ -2178,7 +2178,7 @@ class orm(orm_template): # TODO: Validate # def perm_write(self, cr, user, ids, fields, context=None): - raise 'This method does not exist anymore' + raise _('This method does not exist anymore') # TODO: ameliorer avec NULL def _where_calc(self, cr, user, args, active_test=True, context=None): @@ -2202,10 +2202,10 @@ class orm(orm_template): joins=[] while i','<','>','>=','<='), 'Error ! Bad clause operand "%s".' % (args[i][1],) + assert args[i][1] in ('like','!=','ilike','=like', 'not like', 'not ilike', 'not in','inselect','child_of','in','=','<>','<','>','>=','<='), _('Error ! Bad clause operand "%s".') % (args[i][1],) if args[i][1] == 'inselect': - raise except_orm('ValidateError', - 'The clause \'inselect\' can not be used outside the orm!') + raise except_orm(_('ValidateError'), + _("The clause 'inselect' can not be used outside the orm!")) if args[i][0] in self._inherit_fields: table=self.pool.get(self._inherit_fields[args[i][0]][0]) if ('"'+table._table+'"' not in tables): @@ -2373,7 +2373,7 @@ class orm(orm_template): #FIXME: this replace all (..., '=', False) values with 'is null' and this is # not what we want for real boolean fields. The problem is, we can't change it # easily because we use False everywhere instead of None -# NOTE FAB: we can't use None because it is not accepted by XML-RPC, that's why +# NOTE FAB: we can't use None becStay tunes ! ause it is not accepted by XML-RPC, that's why # boolean (0-1), None -> False # Ged> boolean fields are not always = 0 or 1 if (x[2] is False) and (x[1]=='='): @@ -2442,7 +2442,7 @@ class orm(orm_template): def _check_qorder(self, word): if not regex_order.match(word): - raise except_orm('AccessError', 'Bad query.') + raise except_orm(_('AccessError'), _('Bad query.')) return True def search(self, cr, user, args, offset=0, limit=None, order=None, diff --git a/bin/report/custom.py b/bin/report/custom.py index b3cb1653d24..77fb343b47c 100644 --- a/bin/report/custom.py +++ b/bin/report/custom.py @@ -571,7 +571,7 @@ class report_custom(report_int): colors = map(lambda x:fill_style.Plain(bgcolor=x), misc.choice_colors(len(results))) if reduce(lambda x,y : x+y, map(lambda x : x[1],results)) == 0.0: - raise('The sum of the data (2nd field) is null. \nWe can draw a pie chart !') + raise(_('The sum of the data (2nd field) is null.\nWe can draw a pie chart !')) plot = pie_plot.T(data=results, arc_offsets=[0,10,0,10], shadow = (2, -2, fill_style.gray50), diff --git a/bin/report/interface.py b/bin/report/interface.py index 1add275c727..5a5333cf462 100644 --- a/bin/report/interface.py +++ b/bin/report/interface.py @@ -55,7 +55,7 @@ def toxml(val): class report_int(netsvc.Service): def __init__(self, name, audience='*'): - assert not netsvc.service_exist(name), 'The report "%s" already exist!'%name + assert not netsvc.service_exist(name), 'The report "%s" already exist!' % name super(report_int, self).__init__(name, audience) if name[0:7]<>'report.': raise Exception, 'ConceptionError, bad report name, should start with "report."' diff --git a/bin/service/web_services.py b/bin/service/web_services.py index d4d77fa3910..896757f2be4 100644 --- a/bin/service/web_services.py +++ b/bin/service/web_services.py @@ -40,13 +40,10 @@ import base64 import addons import sql_db +from tools.translate import _ logging.basicConfig() -#TODO: use translation system -def _(str): - return str - class db(netsvc.Service): def __init__(self, name="db"): netsvc.Service.__init__(self, name) diff --git a/bin/tinyerp-server.py b/bin/tinyerp-server.py index 4d590f906d9..8bdeec75bc6 100755 --- a/bin/tinyerp-server.py +++ b/bin/tinyerp-server.py @@ -185,7 +185,7 @@ if tools.config["translate_out"]: logger.notifyChannel("init", netsvc.LOG_INFO, 'writing translation file for language %s to %s' % (tools.config["language"], tools.config["translate_out"])) trans=tools.trans_generate(tools.config["language"], tools.config["translate_modules"]) - writer=csv.writer(file(tools.config["translate_out"], "w"), 'TINY') + writer=csv.writer(file(tools.config["translate_out"], "w"), 'UNIX') for row in trans: writer.writerow(row) del trans diff --git a/bin/tools/translate.py b/bin/tools/translate.py index 834b8c8f54d..fa230e7241e 100644 --- a/bin/tools/translate.py +++ b/bin/tools/translate.py @@ -36,15 +36,15 @@ import netsvc from tools.misc import UpdateableStr -class TINY(csv.excel): +class UNIX_LINE_TERMINATOR(csv.excel): lineterminator = '\n' -csv.register_dialect("TINY", TINY) +csv.register_dialect("UNIX", UNIX_LINE_TERMINATOR) # # TODO: a caching method # -def translate(cr, uid, name, source_type, lang, source=None): +def translate(cr, name, source_type, lang, source=None): if source and name: cr.execute('select value from ir_translation where lang=%s and type=%s and name=%s and src=%s', (lang, source_type, str(name), source)) elif name: @@ -55,13 +55,13 @@ def translate(cr, uid, name, source_type, lang, source=None): res = res_trans and res_trans[0] or False return res -def translate_code(cr, uid, source, context): +def translate_code(cr, source, context): lang = context.get('lang', False) if lang: - return translate(cr, uid, None, 'code', lang, source) + return translate(cr, None, 'code', lang, source) or source else: return source -_ = lambda source: translate_code(cr, uid, source, context) +_ = lambda source: translate_code(cr, source, context) # Methods to export the translation file @@ -126,14 +126,28 @@ def trans_generate(lang, modules, dbname=None): uid = 1 l = pool.obj_pool.items() l.sort() - out = [["type","name","res_id","src","value"]] - to_translate = [] + query = 'SELECT name, model, res_id, module' \ + ' FROM ir_model_data' + if not 'all' in modules: + query += ' WHERE module IN (%s)' % ','.join(['%s']*len(modules)) + query += ' ORDER BY module, model, name' - if 'all' in modules: - cr.execute('select name,model,res_id,module from ir_model_data') - else: - cr.execute('select name,model,res_id,module from ir_model_data where module in ('+','.join(['%s']*len(modules))+')', modules) + query_param = not 'all' in modules and modules or None + cr.execute(query, query_param) + + #if 'all' in modules: + # cr.execute('select name,model,res_id,module from ir_model_data') + #else: + # cr.execute('select name,model,res_id,module from ir_model_data where module in ('+','.join(['%s']*len(modules))+')', modules) + + + _to_translate = [] + def push_translation(module, type, name, id, source): + tuple = (module, type, name, id, source) + if not tuple in _to_translate: + _to_translate.append(tuple) + for (xml_name,model,res_id,module) in cr.fetchall(): xml_name = module+'.'+xml_name @@ -141,7 +155,7 @@ def trans_generate(lang, modules, dbname=None): if model=='ir.ui.view': d = xml.dom.minidom.parseString(obj.arch) for t in trans_parse_view(d.documentElement): - to_translate.append(["view", obj.model, 0, t]) + push_translation(module, 'view', obj.model, 0, t) elif model=='ir.actions.wizard': service_name = 'wizard.'+obj.wiz_name obj2 = netsvc._service[service_name] @@ -157,31 +171,31 @@ def trans_generate(lang, modules, dbname=None): if 'string' in field_def: source = field_def['string'] res_name = name + ',' + field_name - to_translate.append(["wizard_field", res_name,0,source]) + push_translation(module, 'wizard_field', res_name, 0, source) # export arch arch = result['arch'] if not isinstance(arch, UpdateableStr): d = xml.dom.minidom.parseString(arch) for t in trans_parse_view(d.documentElement): - to_translate.append(["wizard_view", name, 0, t]) + push_translation(module, 'wizard_view', name, 0, t) # export button labels for but_args in result['state']: button_name = but_args[0] button_label = but_args[1] res_name = name + ',' + button_name - to_translate.append(["wizard_button", res_name, 0, button_label]) + push_translation(module, 'wizard_button', res_name, 0, button_label) elif model=='ir.model.fields': field_name = obj.name field_def = pool.get(obj.model)._columns[field_name] name = obj.model + "," + field_name - to_translate.append(["field", name, 0, field_def.string.encode('utf8')]) + push_translation(module, 'field', name, 0, field_def.string.encode('utf8')) if field_def.help: - to_translate.append(["help", name, 0, field_def.help.encode('utf8')]) + push_translation(module, 'help', name, 0, field_def.help.encode('utf8')) if field_def.translate: ids = pool.get(obj.model).search(cr, uid, []) @@ -195,11 +209,11 @@ def trans_generate(lang, modules, dbname=None): ('res_id', '=', res_id), ]) if not model_data_ids: - to_translate.append(['model', name, 0, obj_value[field_name]]) + push_translation(module, 'model', name, 0, obj_value[field_name]) if hasattr(field_def, 'selection') and isinstance(field_def.selection, (list, tuple)): for key, val in field_def.selection: - to_translate.append(["selection", name, 0, val.encode('utf8')]) + push_translation(module, 'selection', name, 0, val.encode('utf8')) elif model=='ir.actions.report.xml': name = obj.report_name @@ -216,7 +230,7 @@ def trans_generate(lang, modules, dbname=None): xmlstr = tools.file_open(fname).read() d = xml.dom.minidom.parseString(xmlstr) for t in parse_func(d.documentElement): - to_translate.append([report_type, name, 0, t]) + push_translation(module, report_type, name, 0, t) except IOError: if fname: logger.notifyChannel("init", netsvc.LOG_WARNING, "couldn't export translation for report %s %s %s" % (name, report_type, fname)) @@ -225,40 +239,57 @@ def trans_generate(lang, modules, dbname=None): for field_name,field_def in pool.get(model)._columns.items(): if field_def.translate: name = model + "," + field_name - to_translate.append(['model', name, xml_name, getattr(obj,field_name)]) + push_translation(module, 'model', name, xml_name, getattr(obj, field_name)) - # TODO: By module - # code - for root, dirs, files in os.walk(tools.config['root_path']): - for fname in fnmatch.filter(files, '*.py'): - frelativepath = join(root, fname) - code_string = tools.file_open(frelativepath, subdir='').read() - iter = re.finditer( - '[^a-zA-Z0-9_]_\([\s]*["\'](.*?)["\'][\s]*\)', - code_string) - sources = [] - for i in iter: - to_translate.append(['code', frelativepath, 0, i.group(1).encode('utf8')]) + # parse source code for _() calls + def get_module_from_path(path): + relative_addons_path = tools.config['addons_path'][len(tools.config['root_path'])+1:] + if path.startswith(relative_addons_path): + path = path[len(relative_addons_path)+1:] + return path.split(os.path.sep)[0] + return None + def parse_py_files(path): + for root, dirs, files in os.walk(path): + for fname in fnmatch.filter(files, '*.py'): + fabsolutepath = join(root, fname) + frelativepath = fabsolutepath[len(tools.config['root_path'])+1:] + module = get_module_from_path(frelativepath) + code_string = tools.file_open(fabsolutepath, subdir='').read() + iter = re.finditer( + '[^a-zA-Z0-9_]_\([\s]*["\'](.+?)["\'][\s]*\)', + code_string) + for i in iter: + push_translation(module, 'code', frelativepath, 0, i.group(1).encode('utf8')) + + + if 'all' in modules: + parse_py_files(tools.config['root_path']) + else: + for m in modules: + parse_py_files(join(tools.config['addons_path'], m)) + + + out = [["module","type","name","res_id","src","value"]] # header # translate strings marked as to be translated - for a in to_translate: - (type, name, id, source) = a + for module, type, name, id, source in _to_translate: trans = trans_obj._get_source(cr, uid, name, type, lang, source) - out.append([type, name, id, source, trans or '']) + out.append([module, type, name, id, source, trans or '']) cr.close() return out def trans_load(db_name, filename, lang, strict=False): logger = netsvc.Logger() - data='' try: - data=file(filename,'r').read().split('\n') + fileobj = open(filename,'r') except IOError: logger.notifyChannel("init", netsvc.LOG_ERROR, "couldn't read file") - return trans_load_data(db_name, data, lang, strict=False) + r = trans_load_data(db_name, fileobj, lang, strict=False) + fileobj.close() + return r -def trans_load_data(db_name, data, lang, strict=False, lang_name=None): +def trans_load_data(db_name, fileobj, lang, strict=False, lang_name=None): logger = netsvc.Logger() logger.notifyChannel("init", netsvc.LOG_INFO, 'loading translation file for language %s' % (lang)) @@ -288,7 +319,8 @@ def trans_load_data(db_name, data, lang, strict=False, lang_name=None): langs = lang_obj.read(cr, uid, lang_ids) ls = map(lambda x: (x['code'],x['name']), langs) - reader = csv.reader(data) + fileobj.seek(0) + reader = csv.reader(fileobj, quotechar='"', delimiter=',') # read the first line of the file (it contains columns titles) for row in reader: f = row @@ -299,8 +331,9 @@ def trans_load_data(db_name, data, lang, strict=False, lang_name=None): for row in reader: line += 1 #try: - # skip empty rows and rows where the translation field is empty - if (not row) or (not row[4]): + # skip empty rows and rows where the translation field (=last fiefd) is empty + if (not row) or (not row[:-1]): + print "translate: skip %s" % repr(row) continue # dictionary which holds values for this line of the csv file @@ -308,8 +341,8 @@ def trans_load_data(db_name, data, lang, strict=False, lang_name=None): # 'src': ..., 'value': ...} dic = {'lang': lang} for i in range(len(f)): -# if trans_obj._columns[f[i]]._type == 'integer': -# row[i] = row[i] and int(row[i]) or False + if f[i] in ('module',): + continue dic[f[i]] = row[i] try: diff --git a/bin/wizard/__init__.py b/bin/wizard/__init__.py index 8bd2257aa20..10e57e93585 100644 --- a/bin/wizard/__init__.py +++ b/bin/wizard/__init__.py @@ -55,14 +55,14 @@ class interface(netsvc.Service): self.exportMethod(self.execute) self.wiz_name = name - def translate_view(self, cr, uid, node, state, lang): + def translate_view(self, cr, node, state, lang): if node.nodeType == node.ELEMENT_NODE: if node.hasAttribute('string') and node.getAttribute('string'): - trans = translate(cr, uid, self.wiz_name+','+state, 'wizard_view', lang, node.getAttribute('string').encode('utf8')) + trans = translate(cr, self.wiz_name+','+state, 'wizard_view', lang, node.getAttribute('string').encode('utf8')) if trans: node.setAttribute('string', trans.decode('utf8')) for n in node.childNodes: - self.translate_view(cr, uid, n, state, lang) + self.translate_view(cr, n, state, lang) def execute_cr(self, cr, uid, data, state='init', context=None): if not context: @@ -119,21 +119,21 @@ class interface(netsvc.Service): if lang: # translate fields for field in fields: - trans = translate(cr, uid, self.wiz_name+','+state+','+field, 'wizard_field', lang) + trans = translate(cr, self.wiz_name+','+state+','+field, 'wizard_field', lang) if trans: fields[field]['string'] = trans # translate arch if not isinstance(arch, UpdateableStr): doc = dom.minidom.parseString(arch) - self.translate_view(cr, uid, doc, state, lang) + self.translate_view(cr, doc, state, lang) arch = doc.toxml() # translate buttons button_list = list(button_list) for i, aa in enumerate(button_list): button_name = aa[0] - trans = translate(cr, uid, self.wiz_name+','+state+','+button_name, 'wizard_button', lang) + trans = translate(cr, self.wiz_name+','+state+','+button_name, 'wizard_button', lang) if trans: aa = list(aa) aa[1] = trans