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):
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()
_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),
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)
from tools.misc import UpdateableStr
import inspect
import mx.DateTime as mxdt
+import tempfile
+import tarfile
class UNIX_LINE_TERMINATOR(csv.excel):
lineterminator = '\n'
# 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