import os, re, string, sys
import polib
+from optparse import OptionParser
# we do unix/windows line trimming ourselves since it can happen that we
return ''
msg = lines[0][i:].strip('"')
for i in range(1, len(lines)):
- msg = msg + lines[i].strip('"')
- return msg
+ j = lines[i].find('"')
+ if j < 0:
+ return ''
+ msg = msg + lines[i][j:].strip('"')
+ return polib.unescape(msg)
-def translate(msgid, msgstr_lines, po2):
+def translate(msgid, msgstr_lines, po2, options):
msgstr = parse_msg(msgstr_lines)
- if msgstr != '':
- return 0
- other = po2.find(msgid)
- if not other:
- return 0
- if not other.translated():
+ if options.overwrite:
+ other = po2.find(msgid)
+ if not other:
+ return 0
+ if not other.translated():
+ return 0
+ if msgstr == other.msgstr:
+ return 0
+ else:
+ if msgstr != '':
+ return 0
+ other = po2.find(msgid)
+ if not other:
+ return 0
+ if not other.translated():
+ return 0
+ if options.nonnull and other.msgstr == other.msgid:
return 0
msgstr = other.msgstr
obsolete = (msgstr_lines[0].find('#~') == 0)
j = msgstr_lines[0].find('"')
# must not assign to msgstr_lines, because that would not be seen by our caller
- new_lines = polib.wrap(msgstr_lines[0][0:j+1] + msgstr, 76, drop_whitespace = False)
+ new_lines = polib.wrap(msgstr_lines[0][0:j+1] + polib.escape(msgstr), 76, drop_whitespace = False)
del msgstr_lines[:]
for i in range(0, len(new_lines)):
if i == 0:
return 1
-def mergepo_polib(target, source):
+def mergepo_polib(target, source, options):
changed = 0
po1 = polib.pofile(target)
po2 = polib.pofile(source)
- for entry in po1.untranslated_entries():
- other = po2.find(entry.msgid, include_obsolete_entries=True)
- if not other:
- continue
- if other.translated():
- entry.msgstr = other.msgstr
- changed = changed + 1
+ if options.overwrite:
+ for entry in po1.entries():
+ other = po2.find(entry.msgid, include_obsolete_entries=True)
+ if not other:
+ continue
+ if options.nonnull and other.msgstr == other.msgid:
+ continue
+ if other.translated() and other.msgstr != entry.msgstr:
+ entry.msgstr = other.msgstr
+ changed = changed + 1
+ else:
+ for entry in po1.untranslated_entries():
+ other = po2.find(entry.msgid, include_obsolete_entries=True)
+ if not other:
+ continue
+ if options.nonnull and other.msgstr == other.msgid:
+ continue
+ if other.translated():
+ entry.msgstr = other.msgstr
+ changed = changed + 1
if changed > 0:
po1.save(target)
return changed
-def mergepo_minimaldiff(target, source):
+def mergepo_minimaldiff(target, source, options):
changed = 0
po2 = polib.pofile(source)
target_enc = polib.detect_encoding(target)
msgid = ''
for line in oldlines:
if in_msgid:
- if line.find('"') == 0:
+ if line.find('"') == 0 or line.find('#~ "') == 0:
msgid_lines.append(line)
else:
in_msgid = False
newlines.extend(msgid_lines)
msgid_lines = []
elif in_msgstr:
- if line.find('"') == 0:
+ if line.find('"') == 0 or line.find('#~ "') == 0:
msgstr_lines.append(line)
else:
in_msgstr = False
- changed = changed + translate(msgid, msgstr_lines, po2)
+ changed = changed + translate(msgid, msgstr_lines, po2, options)
newlines.extend(msgstr_lines)
msgstr_lines = []
msgid = ''
newlines.append(line)
if msgid != '':
# the file ended with a msgstr
- changed = changed + translate(msgid, msgstr_lines, po2)
+ changed = changed + translate(msgid, msgstr_lines, po2, options)
newlines.extend(msgstr_lines)
msgstr_lines = []
msgid = ''
return changed
-def mergepo(target, source):
+def mergepo(target, source, options):
if not os.path.exists(source):
sys.stderr.write('Skipping %s since %s does not exist.\n' % (target, source))
return
return
sys.stderr.write('Merging %s into %s: ' % (source, target))
try:
- changed = mergepo_minimaldiff(target, source)
+ changed = mergepo_minimaldiff(target, source, options)
+ sys.stderr.write('Updated %d translations with minimal diff.\n' % changed)
except:
- changed = mergepo_polib(target, source)
- sys.stderr.write('Updated %d translations.\n' % changed)
+ changed = mergepo_polib(target, source, options)
+ sys.stderr.write('Updated %d translations using polib.\n' % changed)
def main(argv):
- toolsdir = os.path.dirname(argv[0])
- podir1 = os.path.normpath(os.path.join(toolsdir, '../../po'))
- if len(argv) <= 1:
- sys.stderr.write('''Usage: %s <dir> [lang] where dir is a directory containing the .po
- files you want to take missing translations from. If lang is not given, all languages
- are translated, otherwise only lang.\n''' % (argv[0]))
- podir2 = os.path.abspath(argv[1])
-
- if len(argv) > 2:
- name = argv[2] + '.po'
- mergepo(os.path.join(podir1, name), os.path.join(podir2, name))
+ parser = OptionParser(description = """This script reads translations from .po files in the given source directory
+and adds all translations that do not already exist to the corresponding .po
+files in the target directory. It is recommended to remerge strings from the
+source code before running this script. Otherwise translations that are not
+yet in the target .po files are not updated.""", usage = "Usage: %prog [options] sourcedir")
+ parser.add_option("-t", "--target", dest="target",
+ help="target directory containing .po files. If missing, it is determined from the script location.")
+ parser.add_option("-l", "--language", dest="language",
+ help="language for which translations are merged (if missing, all languages are merged)")
+ parser.add_option("-o", "--overwrite", action="store_true", dest="overwrite", default=False,
+ help="overwrite existing target translations with source translations (if missing, only new translations are added)")
+ parser.add_option("-n", "--nonnull", action="store_true", dest="nonnull", default=False,
+ help="do not update target translations with source translations that are identical to the untranslated text)")
+ (options, args) = parser.parse_args(argv)
+ if len(args) <= 1:
+ parser.print_help()
+ return 0
+
+ toolsdir = os.path.dirname(args[0])
+ if options.target:
+ podir1 = os.path.abspath(options.target)
+ else:
+ podir1 = os.path.normpath(os.path.join(toolsdir, '../../po'))
+ podir2 = os.path.abspath(args[1])
+
+ if options.language:
+ name = options.language + '.po'
+ mergepo(os.path.join(podir1, name), os.path.join(podir2, name), options)
else:
for i in os.listdir(podir1):
(base, ext) = os.path.splitext(i)
if ext != ".po":
continue
- mergepo(os.path.join(podir1, i), os.path.join(podir2, i))
+ mergepo(os.path.join(podir1, i), os.path.join(podir2, i), options)
return 0