* allow export of translation po files into a tgz archive.

* allow export of a new language from the command line

bzr revid: christophe@tinyerp.com-20080819131016-nghtt1x274evlwi4
This commit is contained in:
Christophe Simonis 2008-08-19 15:10:16 +02:00
parent a513f446d0
commit c4c6bea2d1
4 changed files with 62 additions and 90 deletions

View File

@ -37,81 +37,14 @@ import pooler
from osv import fields,osv
'''
view_form_init="""<?xml version="1.0"?>
<form string="Export language">
<image name="gtk-dialog-info" colspan="2"/>
<group colspan="2" col="4">
<separator string="Export translation file" colspan="4"/>
<label align="0.0" string="Choose a language to export:" colspan="4"/>
<field name="lang" colspan="4"/>
</group>
</form>"""
view_form_finish="""<?xml version="1.0"?>
<form string="Export language">
<image name="gtk-dialog-info" colspan="2"/>
<group colspan="2" col="4">
<separator string="Export done" colspan="4"/>
<field name="data" readonly="1" colspan="3"/>
<label align="0.0" string="Save this document to a .CSV file and open it with\n your favourite spreadsheet software. The file\n encoding is UTF-8. You have to translate the latest\n column before reimporting it." colspan="4"/>
</group>
</form>"""
class wizard_export_lang(wizard.interface):
def _get_language(self, cr, uid, context):
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]
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, 'UNIX')
for row in file:
writer.writerow(row)
del file
out=base64.encodestring(buf.getvalue())
buf.close()
return {'data': out}
fields_form={
'lang': {'string':'Language', 'type':'selection', 'selection':_get_language,},
}
fields_form_finish={
'data': {'string':'File', 'type':'binary', 'readonly': True,},
}
states={
'init':{
'actions': [],
'result': {'type': 'form', 'arch': view_form_init, 'fields': fields_form,
'state': [
('end', 'Cancel', 'gtk-cancel'),
('finish', 'Ok', 'gtk-ok', True)
]
}
},
'finish':{
'actions': [_get_file],
'result': {'type': 'form', 'arch': view_form_finish,
'fields': fields_form_finish,
'state': [
('end', 'Close', 'gtk-cancel', True)
]
}
},
}
wizard_export_lang('module.lang.export')
'''
class wizard_export_lang(osv.osv_memory):
def _get_languages(self, cr, uid, context):
lang_obj=pooler.get_pool(cr.dbname).get('res.lang')
ids=lang_obj.search(cr, uid, [('active', '=', True),])
ids=lang_obj.search(cr, uid, ['&', ('active', '=', True), ('translatable', '=', True),])
langs=lang_obj.browse(cr, uid, ids)
return [(lang.code, lang.translatable and lang.name or _('New language')) for lang in langs]
return [('', _('New language'))] + [(lang.code, lang.name) for lang in langs]
def act_cancel(self, cr, uid, ids, context=None):
@ -132,7 +65,11 @@ class wizard_export_lang(osv.osv_memory):
if this.format == 'csv':
this.advice = _("Save this document to a .CSV file and open it with your favourite spreadsheet software. The file encoding is UTF-8. You have to translate the latest column before reimporting it.")
elif this.format == 'po':
this.advice = _("Save this document to a .po file and edit it with a specific software or a text editor. The file encoding is UTF-8.")
ext = this.lang and '.po' or '.pot'
this.advice = _("Save this document to a %s file and edit it with a specific software or a text editor. The file encoding is UTF-8." % (ext,))
elif this.format == 'tgz':
ext = this.lang and '.po' or '.pot'
this.advice = _('Save this document to a .tgz file. This archive containt UTF-8 %s files and may be uploaded to launchpad.' % (ext,))
out=base64.encodestring(buf.getvalue())
buf.close()
@ -140,8 +77,8 @@ class wizard_export_lang(osv.osv_memory):
_name = "wizard.module.lang.export"
_columns = {
'lang': fields.selection(_get_languages, 'Language',required=True),
'format': fields.selection( ( ('csv','CSV File'), ('po','PO File') ), 'File Format', required=True),
'lang': fields.selection(_get_languages, 'Language'), # not required: unset = new language
'format': fields.selection( ( ('csv','CSV File'), ('po','PO File'), ('tgz', 'TGZ Archive')), 'File Format', required=True),
'modules': fields.many2many('ir.module.module', 'rel_modules_langexport', 'wiz_id', 'module_id', 'Modules', domain=[('state','=','installed')]),
'data': fields.binary('File', readonly=True),
'advice': fields.text('', readonly=True),

View File

@ -184,7 +184,11 @@ if tools.config['init'] or tools.config['update']:
if tools.config["translate_out"]:
import csv
logger.notifyChannel("init", netsvc.LOG_INFO, 'writing translation file for language %s to %s' % (tools.config["language"], tools.config["translate_out"]))
if tools.config["language"]:
msg = "language %s" % (tools.config["language"],)
else:
msg = "new language"
logger.notifyChannel("init", netsvc.LOG_INFO, 'writing translation file for %s to %s' % (msg, tools.config["translate_out"]))
fileformat = os.path.splitext(tools.config["translate_out"])[-1][1:].lower()
buf = file(tools.config["translate_out"], "w")

View File

@ -119,18 +119,21 @@ class configmanager(object):
group = optparse.OptionGroup(parser, "Internationalisation options",
"Use these options to translate Tiny ERP to another language."
"See i18n section of the user manual. Options '-l' and '-d' are mandatory.")
"See i18n section of the user manual. Option '-d' is mandatory."
"Option '-l' is mandatory in case of importation"
)
group.add_option('-l', "--language", dest="language", help="specify the language of the translation file. Use it with --i18n-export and --i18n-import")
group.add_option("--i18n-export", dest="translate_out", help="export all sentences to be translated to a CSV or a PO file and exit")
group.add_option("--i18n-import", dest="translate_in", help="import a CSV or a PO file with translations and exit")
group.add_option('-l', "--language", dest="language", help="specify the language of the translation file. Use it with --i18n-export or --i18n-import")
group.add_option("--i18n-export", dest="translate_out", help="export all sentences to be translated to a CSV file, a PO file or a TGZ archive and exit")
group.add_option("--i18n-import", dest="translate_in", help="import a CSV or a PO file with translations and exit. The '-l' option is required.")
group.add_option("--modules", dest="translate_modules", help="specify modules to export. Use in combination with --i18n-export")
group.add_option("--addons-path", dest="addons_path", help="specify an alternative addons path.")
parser.add_option_group(group)
(opt, args) = parser.parse_args()
assert not ((opt.translate_in or opt.translate_out) and (not opt.language or not opt.db_name)), "the i18n-import and i18n-export options cannot be used without the language (-l) and database (-d) options"
assert not (opt.translate_in and (not opt.language or not opt.db_name)), "the i18n-import option cannot be used without the language (-l) and the database (-d) options"
assert not (opt.translate_out and (not opt.db_name)), "the i18n-export option cannot be used without the database (-d) option"
# place/search the config file on Win32 near the server installation
# (../etc from the server)

View File

@ -37,6 +37,8 @@ import netsvc
from tools.misc import UpdateableStr
import inspect
import mx.DateTime as mxdt
import tempfile
import tarfile
class UNIX_LINE_TERMINATOR(csv.excel):
lineterminator = '\n'
@ -170,19 +172,45 @@ class TinyPoFile(object):
# Methods to export the translation file
def trans_export(lang, modules, buffer, format, dbname=None):
def _process(format, modules, rows, buffer, lang, newlang):
if format == 'csv':
writer=csv.writer(buffer, 'UNIX')
for row in rows:
writer.writerow(row)
elif format == 'po':
rows.pop(0)
writer = tools.TinyPoFile(buffer)
writer.write_infos(modules)
for module, type, name, res_id, src, trad in rows:
writer.write(module, type, name, res_id, src, trad)
elif format == 'tgz':
rows.pop(0)
rows_by_module = {}
for row in rows:
module = row[0]
rows_by_module.setdefault(module, []).append(row)
tmpdir = tempfile.mkdtemp()
for mod, modrows in rows_by_module.items():
tmpmoddir = join(tmpdir, mod, 'i18n')
os.makedirs(tmpmoddir)
pofilename = (newlang and mod or lang) + ".po" + (newlang and 't' or '')
buf = open(join(tmpmoddir, pofilename), 'w')
_process('po', [mod], modrows, buf, lang, newlang)
tar = tarfile.open(fileobj=buffer, mode='w|gz')
tar.add(tmpdir, '/')
tar.close()
else:
raise Exception(_('Bad file format'))
newlang = not bool(lang)
if newlang:
lang = 'en_US'
trans = trans_generate(lang, modules, dbname)
if format == 'csv':
writer=csv.writer(buffer, 'UNIX')
for row in trans:
writer.writerow(row)
elif format == 'po':
trans.pop(0)
writer = tools.TinyPoFile(buffer)
writer.write_infos(modules)
for module, type, name, res_id, src, trad in trans:
writer.write(module, type, name, res_id, src, trad)
else:
raise Exception(_('Bad file format'))
_process(format, modules, trans, buffer, lang, newlang)
del trans