2012-03-12 22:13:12 +05:30
|
|
|
#! /usr/bin/env python
|
|
|
|
#
|
2012-03-15 22:41:31 +05:30
|
|
|
# update_po - a gramps tool to update translations
|
2012-03-12 22:13:12 +05:30
|
|
|
#
|
|
|
|
# Copyright (C) 2006-2006 Kees Bakker
|
2012-03-14 19:40:21 +05:30
|
|
|
# Copyright (C) 2006 Brian Matherly
|
|
|
|
# Copyright (C) 2008 Stephen George
|
2012-03-12 22:13:12 +05:30
|
|
|
# Copyright (C) 2012
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
2012-03-17 00:05:35 +05:30
|
|
|
from optparse import OptionParser, OptionGroup
|
2012-03-12 22:13:12 +05:30
|
|
|
|
|
|
|
|
2012-03-15 22:41:31 +05:30
|
|
|
if sys.platform == 'win32':
|
|
|
|
# GetText Win 32 obtained from http://gnuwin32.sourceforge.net/packages/gettext.htm
|
|
|
|
# ....\gettext\bin\msgmerge.exe needs to be on the path
|
2012-03-17 00:05:35 +05:30
|
|
|
msgmergeCmd = 'c:\Program_files\gettext\bin\msgmerge.exe'
|
|
|
|
msgfmtCmd = 'c:\Program_files\gettext\bin\msgfmt.exe'
|
|
|
|
xgettextCmd = os.path.join('c:', 'Program_files', 'bin', 'xgettext.exe')
|
|
|
|
pythonCmd = 'c:\Program_files\python\bin\python.exe'
|
|
|
|
elif sys.platform == 'linux2' or os.name == 'darwin':
|
2012-03-15 22:41:31 +05:30
|
|
|
msgmergeCmd = 'msgmerge'
|
|
|
|
msgfmtCmd = 'msgfmt'
|
2012-03-17 00:05:35 +05:30
|
|
|
xgettextCmd = 'xgettext'
|
2012-03-15 22:41:31 +05:30
|
|
|
pythonCmd = 'python'
|
|
|
|
|
|
|
|
def tests():
|
|
|
|
"""
|
|
|
|
Testing installed programs.
|
|
|
|
We made tests (-t flag) by displaying versions of tools if properly
|
|
|
|
installed. Cannot run all commands without 'gettext' and 'python'.
|
|
|
|
"""
|
|
|
|
|
|
|
|
try:
|
|
|
|
print("====='msgmerge'=(merge our translation)=================")
|
|
|
|
os.system('''%(program)s -V''' % {'program': msgmergeCmd})
|
|
|
|
except:
|
|
|
|
print('Please, install %(program)s for updating your translation' % {'program': msgmergeCmd})
|
|
|
|
|
|
|
|
try:
|
|
|
|
print("===='msgfmt'=(format our translation for installation)==")
|
|
|
|
os.system('''%(program)s -V''' % {'program': msgfmtCmd})
|
|
|
|
except:
|
|
|
|
print('Please, install %(program)s for checking your translation' % {'program': msgfmtCmd})
|
|
|
|
|
|
|
|
try:
|
2012-03-17 00:05:35 +05:30
|
|
|
print("===='xgettext' =(generate a new template)===============")
|
|
|
|
os.system('''%(program)s -V''' % {'program': xgettextCmd})
|
|
|
|
except:
|
|
|
|
print('Please, install %(program)s for generating a new template' % {'program': xgettextCmd})
|
|
|
|
|
|
|
|
try:
|
|
|
|
print("=================='python'=============================")
|
2012-03-15 22:41:31 +05:30
|
|
|
os.system('''%(program)s -V''' % {'program': pythonCmd})
|
|
|
|
except:
|
|
|
|
print('Please, install python')
|
|
|
|
|
|
|
|
|
|
|
|
def XMLParse(filename, mark):
|
|
|
|
"""
|
|
|
|
Experimental alternative to 'intltool-extract' for XML based files.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# in progress ...
|
|
|
|
from xml.etree import ElementTree
|
|
|
|
|
|
|
|
tree = ElementTree.parse(filename)
|
|
|
|
root = tree.getroot()
|
|
|
|
|
2012-03-17 00:05:35 +05:30
|
|
|
for key in root.getiterator(mark):
|
|
|
|
print(ElementTree.tostring(key, encoding="UTF-8"))
|
2012-03-15 22:41:31 +05:30
|
|
|
|
2012-03-12 22:13:12 +05:30
|
|
|
|
|
|
|
def main():
|
2012-03-15 22:41:31 +05:30
|
|
|
"""
|
|
|
|
The utility for handling translation stuff.
|
|
|
|
What is need by Gramps, nothing more.
|
|
|
|
"""
|
2012-03-12 22:13:12 +05:30
|
|
|
|
|
|
|
parser = OptionParser(
|
2012-03-15 22:41:31 +05:30
|
|
|
description='This program generates a new template and '
|
2012-03-17 00:05:35 +05:30
|
|
|
'also provides some common features.',
|
2012-03-15 22:41:31 +05:30
|
|
|
usage='%prog [options]'
|
2012-03-12 22:13:12 +05:30
|
|
|
)
|
|
|
|
|
2012-03-17 00:05:35 +05:30
|
|
|
extract = OptionGroup(
|
|
|
|
parser,
|
|
|
|
"Extract Options",
|
|
|
|
"Everything around extraction for message strings."
|
|
|
|
)
|
|
|
|
parser.add_option_group(extract)
|
|
|
|
|
|
|
|
update = OptionGroup(
|
|
|
|
parser,
|
|
|
|
"Update Options",
|
|
|
|
"Everything around update for translation files."
|
|
|
|
)
|
|
|
|
parser.add_option_group(update)
|
|
|
|
|
2012-03-15 22:41:31 +05:30
|
|
|
parser.add_option("-t", "--test",
|
|
|
|
action="store_true", dest="test", default=False,
|
|
|
|
help="test if 'python' and 'gettext' are properly installed")
|
2012-03-17 00:05:35 +05:30
|
|
|
|
|
|
|
extract.add_option("-x", "--xml",
|
2012-03-15 22:41:31 +05:30
|
|
|
action="store_true", dest="xml", default=False,
|
|
|
|
help="extract messages from xml based file formats")
|
2012-03-17 00:05:35 +05:30
|
|
|
extract.add_option("-g", "--glade",
|
2012-03-15 22:41:31 +05:30
|
|
|
action="store_true", dest="glade", default=False,
|
|
|
|
help="extract messages from glade file format only")
|
2012-03-17 00:05:35 +05:30
|
|
|
extract.add_option("-c", "--clean",
|
2012-03-15 22:41:31 +05:30
|
|
|
action="store_true", dest="clean", default=False,
|
|
|
|
help="remove created files")
|
2012-03-17 00:05:35 +05:30
|
|
|
extract.add_option("-p", "--pot",
|
2012-03-15 22:41:31 +05:30
|
|
|
action="store_true", dest="catalog", default=False,
|
|
|
|
help="create a new catalog")
|
|
|
|
|
|
|
|
# need at least one argument (sv.po, de.po, etc ...)
|
2012-03-17 00:05:35 +05:30
|
|
|
update.add_option("-m", "--merge",
|
2012-03-15 22:41:31 +05:30
|
|
|
action="store_true", dest="merge", default=False,
|
|
|
|
help="merge lang.po files with last catalog")
|
2012-03-17 00:05:35 +05:30
|
|
|
update.add_option("-k", "--check",
|
2012-03-15 22:41:31 +05:30
|
|
|
action="store_true", dest="check", default=False,
|
|
|
|
help="check lang.po files")
|
2012-03-12 22:13:12 +05:30
|
|
|
|
|
|
|
(options, args) = parser.parse_args()
|
2012-03-15 22:41:31 +05:30
|
|
|
|
|
|
|
if options.test:
|
|
|
|
tests()
|
2012-03-14 19:40:21 +05:30
|
|
|
|
2012-03-15 22:41:31 +05:30
|
|
|
if options.xml:
|
|
|
|
extract_xml()
|
2012-03-14 19:40:21 +05:30
|
|
|
|
2012-03-15 22:41:31 +05:30
|
|
|
if options.glade:
|
|
|
|
extract_glade()
|
|
|
|
|
|
|
|
if options.catalog:
|
|
|
|
retrieve()
|
|
|
|
|
|
|
|
if options.clean:
|
|
|
|
clean()
|
|
|
|
|
|
|
|
if options.merge:
|
|
|
|
merge(args)
|
|
|
|
|
|
|
|
if options.check:
|
|
|
|
check(args)
|
|
|
|
|
|
|
|
def listing(name, extension):
|
|
|
|
"""
|
|
|
|
List files according to extensions.
|
|
|
|
Parsing from a textual file (gramps) is faster and easy for maintenance.
|
|
|
|
Like POTFILES.in and POTFILES.skip
|
|
|
|
"""
|
|
|
|
|
|
|
|
f = open('gramps')
|
|
|
|
files = [file.strip() for file in f]
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
temp = open(name, 'w')
|
2012-03-12 22:13:12 +05:30
|
|
|
|
2012-03-15 22:41:31 +05:30
|
|
|
for entry in files:
|
|
|
|
(module, ext) = os.path.splitext(entry)
|
|
|
|
if ext == extension:
|
|
|
|
temp.write(entry)
|
|
|
|
temp.write('\n')
|
|
|
|
|
|
|
|
temp.close()
|
|
|
|
|
|
|
|
|
|
|
|
def headers():
|
|
|
|
"""
|
|
|
|
Look at existing C file format headers.
|
|
|
|
Generated by 'intltool-extract' but want to get rid of this
|
|
|
|
dependency (perl, just a set of tools).
|
|
|
|
"""
|
|
|
|
|
|
|
|
headers = []
|
|
|
|
|
|
|
|
# in.h; extract_xml
|
|
|
|
if os.path.isfile('''../src/data/tips.xml.in.h'''):
|
|
|
|
headers.append('''../src/data/tips.xml.in.h''')
|
|
|
|
if os.path.isfile('''../src/plugins/lib/holidays.xml.in.h'''):
|
|
|
|
headers.append('''../src/plugins/lib/holidays.xml.in.h''')
|
|
|
|
|
|
|
|
# cosmetic
|
|
|
|
if os.path.isfile('''../data/gramps.xml.in.h'''):
|
|
|
|
headers.append('''../data/gramps.xml.in.h''')
|
|
|
|
if os.path.isfile('''../data/gramps.desktop.in.h'''):
|
|
|
|
headers.append('''../data/gramps.desktop.in.h''')
|
|
|
|
if os.path.isfile('''../data/gramps.keys.in.h'''):
|
|
|
|
headers.append('''../data/gramps.keys.in.h''')
|
|
|
|
|
|
|
|
return headers
|
|
|
|
|
|
|
|
|
|
|
|
def extract_xml():
|
|
|
|
"""
|
|
|
|
Extract translation strings from XML based, keys, mime and desktop
|
|
|
|
files. Still performed by 'intltool-update'.
|
|
|
|
Need to look at own XML files parsing and custom translation marks.
|
|
|
|
"""
|
|
|
|
|
|
|
|
os.system('''intltool-extract --type=gettext/xml ../src/data/tips.xml.in''')
|
|
|
|
#XMLParse('../src/data/tips.xml.in', '_tip')
|
|
|
|
os.system('''intltool-extract --type=gettext/xml ../src/plugins/lib/holidays.xml.in''')
|
2012-03-17 00:05:35 +05:30
|
|
|
#XMLParse('../src/plugins/lib/holidays.xml.in', 'country')
|
2012-03-15 22:41:31 +05:30
|
|
|
|
|
|
|
# cosmetic
|
|
|
|
# could be simple copies without .in extension
|
|
|
|
os.system('''intltool-extract --type=gettext/xml ../data/gramps.xml.in''')
|
|
|
|
os.system('''intltool-extract --type=gettext/ini ../data/gramps.desktop.in''')
|
|
|
|
os.system('''intltool-extract --type=gettext/keys ../data/gramps.keys.in''')
|
|
|
|
|
|
|
|
|
|
|
|
def create_template():
|
|
|
|
"""
|
|
|
|
Create a new file for template, if it does not exist.
|
|
|
|
"""
|
|
|
|
|
|
|
|
template = open('gramps.pot', 'w')
|
|
|
|
template.close()
|
|
|
|
|
|
|
|
|
|
|
|
def extract_glade():
|
|
|
|
"""
|
|
|
|
Extract messages from a temp file with all .glade
|
|
|
|
"""
|
|
|
|
|
|
|
|
if not os.path.isfile('gramps.pot'):
|
|
|
|
create_template()
|
2012-03-12 22:13:12 +05:30
|
|
|
|
2012-03-15 22:41:31 +05:30
|
|
|
listing('glade.txt', '.glade')
|
2012-03-17 00:05:35 +05:30
|
|
|
os.system('''%(xgettext)s --add-comments -j -L Glade '''
|
2012-03-15 22:41:31 +05:30
|
|
|
'''--from-code=UTF-8 -o gramps.pot --files-from=glade.txt'''
|
2012-03-17 00:05:35 +05:30
|
|
|
% {'xgettext': xgettextCmd}
|
2012-03-15 22:41:31 +05:30
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def retrieve():
|
|
|
|
"""
|
|
|
|
Extract messages from all files used by Gramps (python, glade, xml)
|
|
|
|
"""
|
|
|
|
|
|
|
|
extract_xml()
|
|
|
|
|
|
|
|
if not os.path.isfile('gramps.pot'):
|
|
|
|
create_template()
|
|
|
|
|
|
|
|
listing('python.txt', '.py')
|
2012-03-17 00:05:35 +05:30
|
|
|
os.system('''%(xgettext)s --add-comments -j --directory=. -d gramps '''
|
2012-03-15 22:41:31 +05:30
|
|
|
'''-L Python -o gramps.pot --files-from=python.txt '''
|
|
|
|
'''--keyword=_ --keyword=ngettext '''
|
2012-03-17 00:05:35 +05:30
|
|
|
'''--keyword=sgettext --from-code=UTF-8''' % {'xgettext': xgettextCmd}
|
2012-03-15 22:41:31 +05:30
|
|
|
)
|
|
|
|
|
|
|
|
extract_glade()
|
|
|
|
|
|
|
|
# C format header (.h extension)
|
|
|
|
for h in headers():
|
|
|
|
print('xgettext for %s') % h
|
2012-03-17 00:05:35 +05:30
|
|
|
os.system('''%(xgettext)s --add-comments -j -o gramps.pot '''
|
|
|
|
'''--keyword=N_ --from-code=UTF-8 %(head)s'''
|
|
|
|
% {'xgettext': xgettextCmd, 'head': h}
|
2012-03-15 22:41:31 +05:30
|
|
|
)
|
|
|
|
|
|
|
|
clean()
|
|
|
|
|
|
|
|
|
|
|
|
def clean():
|
|
|
|
"""
|
|
|
|
Remove created files (C format headers, temp listings)
|
|
|
|
"""
|
|
|
|
|
|
|
|
for h in headers():
|
|
|
|
if os.path.isfile(h):
|
|
|
|
os.system('''rm %s''' % h)
|
|
|
|
print('Remove %(head)s' % {'head': h})
|
|
|
|
|
|
|
|
if os.path.isfile('python.txt'):
|
2012-03-17 00:05:35 +05:30
|
|
|
os.unlink('python.txt')
|
2012-03-15 22:41:31 +05:30
|
|
|
print("Remove 'python.txt'")
|
|
|
|
|
|
|
|
if os.path.isfile('glade.txt'):
|
2012-03-17 00:05:35 +05:30
|
|
|
os.unlink('glade.txt')
|
2012-03-15 22:41:31 +05:30
|
|
|
print("Remove 'glade.txt'")
|
|
|
|
|
|
|
|
|
|
|
|
def merge(args):
|
|
|
|
"""
|
|
|
|
Merge messages with 'gramps.pot'
|
|
|
|
"""
|
|
|
|
|
|
|
|
if not args:
|
|
|
|
print('Please, add at least one argument (sv.po, de.po).')
|
|
|
|
|
|
|
|
for arg in args:
|
|
|
|
if arg[-3:] == '.po':
|
|
|
|
print('Merge %(lang)s with current template' % {'lang': arg})
|
|
|
|
os.system('''%(msgmerge)s --no-wrap %(lang)s gramps.pot -o updated_%(lang)s''' \
|
|
|
|
% {'msgmerge': msgmergeCmd, 'lang': arg})
|
|
|
|
print("Updated file: 'updated_%(lang)s'." % {'lang': arg})
|
|
|
|
else:
|
|
|
|
print("Please, try to set an argument with .po extension like '%(arg)s.po'." % {'arg': arg})
|
|
|
|
|
|
|
|
|
|
|
|
def check(args):
|
|
|
|
"""
|
|
|
|
Check the translation file
|
|
|
|
"""
|
|
|
|
|
|
|
|
if not args:
|
|
|
|
print('Please, add at least one argument (sv.po, de.po).')
|
|
|
|
|
|
|
|
for arg in args:
|
|
|
|
if arg[-3:] == '.po':
|
|
|
|
print("Checked file: '%(lang.po)s'. See '%(txt)s.txt'." \
|
|
|
|
% {'lang.po': arg, 'txt': arg[:2]})
|
|
|
|
os.system('''%(python)s ./check_po ./%(lang.po)s > %(lang)s.txt''' \
|
|
|
|
% {'python': pythonCmd, 'lang.po': arg, 'lang': arg[:2]})
|
|
|
|
os.system('''%(msgfmt)s -c -v %(lang.po)s''' % {'msgfmt': msgfmtCmd, 'lang.po': arg})
|
|
|
|
else:
|
|
|
|
print("Please, try to set an argument with .po extension like '%(arg)s.po'." % {'arg': arg})
|
2012-03-12 22:13:12 +05:30
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|