import tarfile
import tempfile
import threading
+import sys
from os.path import join
from datetime import datetime
if line.startswith('#~ '):
break
if line.startswith('#:'):
- if ' ' in line[2:].strip():
- for lpart in line[2:].strip().split(' '):
- tmp_tnrs.append(lpart.strip().split(':',2))
- else:
- tmp_tnrs.append( line[2:].strip().split(':',2) )
+ for lpart in line[2:].strip().split(' '):
+ trans_info = lpart.strip().split(':',2)
+ if trans_info and len(trans_info) == 2:
+ # looks like the translation type is missing, which is not
+ # unexpected because it is not a GetText standard. Default: 'code'
+ trans_info[:0] = ['code']
+ if trans_info and len(trans_info) == 3:
+ tmp_tnrs.append(trans_info)
elif line.startswith('#,') and (line[2:].strip() == 'fuzzy'):
fuzzy = True
line = self.lines.pop(0).strip()
if name is None:
if not fuzzy:
- self.warn('Missing "#:" formated comment at line %d for the following source:\n\t%s',
+ self.warn('Missing "#:" formated comment at line %d for the following source:\n\t%s',
self.cur_line(), source[:30])
return self.next()
return type, name, res_id, source, trad
'version': release.version,
'modules': reduce(lambda s, m: s + "#\t* %s\n" % m, modules, ""),
'bugmail': release.support_email,
- 'now': datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')+"+0000",
+ 'now': datetime.utcnow().strftime('%Y-%m-%d %H:%M')+"+0000",
}
)
# Methods to export the translation file
-def trans_export(lang, modules, buffer, format, dbname=None):
+def trans_export(lang, modules, buffer, format, cr):
def _process(format, modules, rows, buffer, lang, newlang):
if format == 'csv':
newlang = not bool(lang)
if newlang:
lang = 'en_US'
- trans = trans_generate(lang, modules, dbname)
+ trans = trans_generate(lang, modules, cr)
if newlang and format!='csv':
for trx in trans:
trx[-1] = ''
module = module_dict.get(module, module)
return module in modules
-def trans_generate(lang, modules, dbname=None):
+def trans_generate(lang, modules, cr):
logger = logging.getLogger('i18n')
- if not dbname:
- dbname=tools.config['db_name']
- if not modules:
- modules = ['all']
+ dbname = cr.dbname
pool = pooler.get_pool(dbname)
trans_obj = pool.get('ir.translation')
model_data_obj = pool.get('ir.model.data')
- cr = pooler.get_db(dbname).cursor()
uid = 1
l = pool.obj_pool.items()
l.sort()
query = 'SELECT name, model, res_id, module' \
' FROM ir_model_data'
-
- query_models = """SELECT m.id, m.model, imd.module
- FROM ir_model AS m, ir_model_data AS imd
+
+ query_models = """SELECT m.id, m.model, imd.module
+ FROM ir_model AS m, ir_model_data AS imd
WHERE m.id = imd.res_id AND imd.model = 'ir.model' """
if 'all_installed' in modules:
report_type = "xsl"
if fname and obj.report_type in ('pdf', 'xsl'):
try:
- d = etree.parse(tools.file_open(fname))
- for t in parse_func(d.iter()):
- push_translation(module, report_type, name, 0, t)
+ report_file = tools.file_open(fname)
+ try:
+ d = etree.parse(report_file)
+ for t in parse_func(d.iter()):
+ push_translation(module, report_type, name, 0, t)
+ finally:
+ report_file.close()
except (IOError, etree.XMLSyntaxError):
logger.exception("couldn't export translation for report %s %s %s", name, report_type, fname)
is_mod_installed = module in installed_modules
if (('all' in modules) or (module in modules)) and is_mod_installed:
logger.debug("Scanning code of %s at module: %s", frelativepath, module)
- code_string = tools.file_open(fabsolutepath, subdir='').read()
+ src_file = tools.file_open(fabsolutepath, subdir='')
+ try:
+ code_string = src_file.read()
+ finally:
+ src_file.close()
if module in installed_modules:
frelativepath = str("addons" + frelativepath)
ite = re_dquotes.finditer(code_string)
trans = trans_obj._get_source(cr, uid, name, type, lang, source)
out.append([module, type, name, id, source, encode(trans) or ''])
- cr.close()
return out
-def trans_load(db_name, filename, lang, verbose=True, context=None):
+def trans_load(cr, filename, lang, verbose=True, context=None):
logger = logging.getLogger('i18n')
try:
fileobj = open(filename,'r')
logger.info("loading %s", filename)
fileformat = os.path.splitext(filename)[-1][1:].lower()
- r = trans_load_data(db_name, fileobj, fileformat, lang, verbose=verbose, context=context)
+ r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context)
fileobj.close()
return r
except IOError:
logger.error("couldn't read translation file %s", filename)
return None
-def trans_load_data(db_name, fileobj, fileformat, lang, lang_name=None, verbose=True, context=None):
+def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, context=None):
+ """Populates the ir_translation table. Fixing the res_ids so that they point
+ correctly to ir_model_data is done in a separate step, using the
+ 'trans_update_res_ids' function below."""
logger = logging.getLogger('i18n')
if verbose:
logger.info('loading translation file for language %s', lang)
if context is None:
context = {}
+ db_name = cr.dbname
pool = pooler.get_pool(db_name)
lang_obj = pool.get('res.lang')
trans_obj = pool.get('ir.translation')
iso_lang = tools.get_iso_codes(lang)
try:
uid = 1
- cr = pooler.get_db(db_name).cursor()
ids = lang_obj.search(cr, uid, [('code','=', lang)])
if not ids:
# lets create the language with locale information
- fail = True
- for ln in get_locales(lang):
- try:
- locale.setlocale(locale.LC_ALL, str(ln))
- fail = False
- break
- except locale.Error:
- continue
- if fail:
- lc = locale.getdefaultlocale()[0]
- msg = 'Unable to get information for locale %s. Information from the default locale (%s) have been used.'
- logger.warning(msg, lang, lc)
-
- 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,
- 'name': 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' : 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:
- resetlocale()
+ lang_obj.load_lang(cr, 1, lang=lang, lang_name=lang_name)
# now, the serious things: we read the language file
fileobj.seek(0)
if fileformat == 'csv':
+ #Setting the limit of data while loading a CSV
+ csv.field_size_limit(sys.maxint)
reader = csv.reader(fileobj, quotechar='"', delimiter=',')
# read the first line of the file (it contains columns titles)
for row in reader:
try:
dic['res_id'] = dic['res_id'] and int(dic['res_id']) or 0
+ dic['module'] = False
+ dic['xml_id'] = False
except:
- model_data_ids = model_data_obj.search(cr, uid, [
- ('model', '=', dic['name'].split(',')[0]),
- ('module', '=', dic['res_id'].split('.', 1)[0]),
- ('name', '=', dic['res_id'].split('.', 1)[1]),
- ])
- if model_data_ids:
- dic['res_id'] = model_data_obj.browse(cr, uid,
- model_data_ids[0]).res_id
- else:
- dic['res_id'] = False
+ split_id = dic['res_id'].split('.', 1)
+ dic['module'] = split_id[0]
+ dic['xml_id'] = split_id[1]
+ dic['res_id'] = False
args = [
('lang', '=', lang),
('type', '=', dic['type']),
('name', '=', dic['name']),
- ('src', '=', dic['src']),
]
if dic['type'] == 'model':
- args.append(('res_id', '=', dic['res_id']))
+ if dic['res_id'] is False:
+ args.append(('module', '=', dic['module']))
+ args.append(('xml_id', '=', dic['xml_id']))
+ else:
+ args.append(('res_id', '=', dic['res_id']))
+ else:
+ args.append(('src', '=', dic['src']))
+
ids = trans_obj.search(cr, uid, args)
if ids:
if context.get('overwrite') and dic['value']:
trans_obj.write(cr, uid, ids, {'value': dic['value']})
else:
trans_obj.create(cr, uid, dic)
- cr.commit()
- cr.close()
if verbose:
logger.info("translation file loaded succesfully")
except IOError:
filename = '[lang: %s][format: %s]' % (iso_lang or 'new', fileformat)
logger.exception("couldn't read translation file %s", filename)
+def trans_update_res_ids(cr):
+ cr.execute("""
+ UPDATE ir_translation
+ SET res_id = COALESCE ((SELECT ir_model_data.res_id
+ FROM ir_model_data
+ WHERE ir_translation.module = ir_model_data.module
+ AND ir_translation.xml_id = ir_model_data.name), 0)
+ WHERE ir_translation.module is not null
+ AND ir_translation.xml_id is not null
+ AND ir_translation.res_id = 0;
+ """)
+
def get_locales(lang=None):
if lang is None:
lang = locale.getdefaultlocale()[0]
except locale.Error:
continue
+def load_language(cr, lang):
+ """Loads a translation terms for a language.
+ Used mainly to automate language loading at db initialization.
+
+ :param lang: language ISO code with optional _underscore_ and l10n flavor (ex: 'fr', 'fr_BE', but not 'fr-BE')
+ :type lang: str
+ """
+ pool = pooler.get_pool(cr.dbname)
+ language_installer = pool.get('base.language.install')
+ uid = 1
+ oid = language_installer.create(cr, uid, {'lang': lang})
+ language_installer.lang_install(cr, uid, [oid], context=None)
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: