* 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:
parent
a513f446d0
commit
c4c6bea2d1
|
@ -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),
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue