Index: branches/stable/l10n-kde4/scripts/extract-doc-assoc-ui-cats.py =================================================================== --- branches/stable/l10n-kde4/scripts/extract-doc-assoc-ui-cats.py (revision 1571924) +++ branches/stable/l10n-kde4/scripts/extract-doc-assoc-ui-cats.py (revision 1571925) @@ -1,49 +1,49 @@ #!/usr/bin/env python # -*- coding: UTF-8 -*- # Documentation docbooks may state which PO catalogs contain the user-interface # labels (those used in , , etc.) # This information is encoded as a comment, starting with ui-catalogs: keyword, # followed by whitespace-separated list of UI catalogs: # # # # The UI catalogs are given only by name, without any path or .po extension. # Catalogs should be ordered by decreasing priority, same as that for the # application which is being documented. # # The scripts takes docbook file names, parses each for these references, # and writes to standard output the union of all found catalog names as # whitespace separated list. The list is ordered by the appearance order # of catalog names during parsing. import sys import xml.parsers.expat # Union of extracted catalog names. catnames = [] # Comment handler. def handler_comment (data): p = data.find(":") if p >= 0 and data[:p].strip().lower() == "ui-catalogs": for cname in data[p+1:].split(): if cname not in catnames: catnames.append(cname) # Prepare XML parser. p = xml.parsers.expat.ParserCreate() p.UseForeignDTD() # not to barf on non-default XML entities p.CommentHandler = handler_comment # Go through all docbooks collecting catalog references. for fname in sys.argv[1:]: try: file = open(fname, "r") p.ParseFile(file) file.close() except xml.parsers.expat.ExpatError, inst: - print >>sys.stderr, "%s: parse error: %s" % (fname, inst) + print("%s: parse error: %s" % (fname, inst), file=sys.stderr) # Output collected catalogs. -print " ".join(catnames) +print(" ".join(catnames)) Index: branches/stable/l10n-kde4/scripts/fillxmlfrompo.py =================================================================== --- branches/stable/l10n-kde4/scripts/fillxmlfrompo.py (revision 1571924) +++ branches/stable/l10n-kde4/scripts/fillxmlfrompo.py (revision 1571925) @@ -1,70 +1,70 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ Copyright 2014 Burkhard Lück Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. """ import sys, os, glob, re, codecs import polib if len(sys.argv) != 5: - print '\nUsage: python %s path/to/xmlfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0]) + print('\nUsage: python %s path/to/xmlfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0])) else: xmlfilepath, xmlfilename, l10ndirpath, l10nmodulename, pofilename = sys.argv[1], sys.argv[1].split("/")[-1], sys.argv[2], sys.argv[3], sys.argv[4] begincommenttag = "" endcommenttag = "" begincommentlangtag = ' Copyright 2016 Alex Richardson Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. """ import sys, os, json, time, pprint, codecs from jsontranslationcommon import * # a map msgctxt -> (msgid, filename) to merge duplicate fields translations = {} def potheader(): headertxt = "#, fuzzy\n" headertxt += "msgid \"\"\n" headertxt += "msgstr \"\"\n" headertxt += "\"Project-Id-Version: json files\\n\"\n" headertxt += "\"Report-Msgid-Bugs-To: https://bugs.kde.org\\n\"\n" headertxt += "\"POT-Creation-Date: %s+0000\\n\"\n" %time.strftime("%Y-%m-%d %H:%M") headertxt += "\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n" headertxt += "\"Last-Translator: FULL NAME \\n\"\n" headertxt += "\"Language-Team: LANGUAGE \\n\"\n" headertxt += "\"MIME-Version: 1.0\\n\"\n" headertxt += "\"Content-Type: text/plain; charset=UTF-8\\n\"\n" headertxt += "\"Content-Transfer-Encoding: 8bit\\n\"\n" headertxt += "\n" return headertxt def addPotEntry(context, value, filename): global translations if not value: return # make sure multiline strings and strings containing quotes are escaped properly for the .pot file: msgid = value.replace('"', '\\"').replace('\n', '\\n"\n"') ids = translations.get(context, []) # debugPrint("context: " + context + " msgid: " + msgid + ", " + pprint.pformat(ids)) for idx, val in enumerate(ids): if val[0] == msgid: debugPrint('Found identical entry: id="%s", ctx="%s"' % (msgid, context)) ids[idx] = (msgid, val[1] + ' ' + filename) translations[context] = ids return ids.append((msgid, filename)) translations[context] = ids def handleKAboutPersonObject(context, json, filename): for author in json: # translatable keys are Name and Task (see KAboutPerson::fromJSON()) addPotEntry(context + ' Name', author.get('Name'), filename) addPotEntry(context + ' Task', author.get('Task'), filename) def handleKioProtocols(json, filename): if not json: return for key in json.keys(): obj = json[key] names = obj.get('ExtraNames') if not names: continue addPotEntry(key + ' ExtraNames', serializeList(names), filename) if len(sys.argv) < 3: - print 'wrong number of args: %s' % sys.argv - print '\nUsage: python %s jsonfilenamelist basedir' %os.path.basename(sys.argv[0]) + print('wrong number of args: %s' % sys.argv) + print('\nUsage: python %s jsonfilenamelist basedir' %os.path.basename(sys.argv[0])) else: jsonfilenamelist = [os.path.abspath(filename) for filename in sys.argv[1:-1]] basedir = os.path.abspath(sys.argv[-1]) pottxt = "" for jsonfilename in jsonfilenamelist: with open(jsonfilename, 'r') as data_file: error = False try: jsondatadict = json.load(data_file, encoding='utf-8', strict=False) filename = os.path.relpath(jsonfilename, basedir) # try handling KDE-KIO-Protocols handleKioProtocols(jsondatadict.get(kioprotocolsfield), filename) kplugin = jsondatadict.get(kpluginfield) if not kplugin: continue for field in translationfields: addPotEntry(field, kplugin.get(field), filename) for field in kaboutpersonfields: if field in kplugin: handleKAboutPersonObject(field, kplugin[field], filename) except: debugPrint('json file %s unsupported by scripty: %s' % (jsonfilename, sys.exc_info())) if translations: pottxt = '' debugPrint('Found translations:\n' + pprint.pformat(translations)) for (context, values) in translations.items(): for entry in values: msgid = entry[0] filename = entry[1] pottxt += '#: %s\nmsgctxt "%s"\nmsgid "%s"\nmsgstr ""\n\n' % (filename, context, msgid) - print (potheader() + pottxt).encode('utf-8') + print((potheader() + pottxt).encode('utf-8')) Index: branches/stable/l10n-kf5/scripts/extract-doc-assoc-ui-cats.py =================================================================== --- branches/stable/l10n-kf5/scripts/extract-doc-assoc-ui-cats.py (revision 1571924) +++ branches/stable/l10n-kf5/scripts/extract-doc-assoc-ui-cats.py (revision 1571925) @@ -1,49 +1,49 @@ #!/usr/bin/env python # -*- coding: UTF-8 -*- # Documentation docbooks may state which PO catalogs contain the user-interface # labels (those used in , , etc.) # This information is encoded as a comment, starting with ui-catalogs: keyword, # followed by whitespace-separated list of UI catalogs: # # # # The UI catalogs are given only by name, without any path or .po extension. # Catalogs should be ordered by decreasing priority, same as that for the # application which is being documented. # # The scripts takes docbook file names, parses each for these references, # and writes to standard output the union of all found catalog names as # whitespace separated list. The list is ordered by the appearance order # of catalog names during parsing. import sys import xml.parsers.expat # Union of extracted catalog names. catnames = [] # Comment handler. def handler_comment (data): p = data.find(":") if p >= 0 and data[:p].strip().lower() == "ui-catalogs": for cname in data[p+1:].split(): if cname not in catnames: catnames.append(cname) # Prepare XML parser. p = xml.parsers.expat.ParserCreate() p.UseForeignDTD() # not to barf on non-default XML entities p.CommentHandler = handler_comment # Go through all docbooks collecting catalog references. for fname in sys.argv[1:]: try: file = open(fname, "r") p.ParseFile(file) file.close() except xml.parsers.expat.ExpatError, inst: - print >>sys.stderr, "%s: parse error: %s" % (fname, inst) + print("%s: parse error: %s" % (fname, inst), file=sys.stderr) # Output collected catalogs. -print " ".join(catnames) +print(" ".join(catnames)) Index: branches/stable/l10n-kf5/scripts/filljsonfrompo.py =================================================================== --- branches/stable/l10n-kf5/scripts/filljsonfrompo.py (revision 1571924) +++ branches/stable/l10n-kf5/scripts/filljsonfrompo.py (revision 1571925) @@ -1,144 +1,144 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ Copyright 2014 Burkhard Lück Copyright 2016 Alex Richardson Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. """ import sys, os, glob, polib, json, pprint, codecs, csv, io, traceback from jsontranslationcommon import * pofiledict = {} def findTranslations(json, field, msgctxt): global pofiledict if not json.get(field): return json # remove the old translations before inserting new ones: for key in json.keys(): if key.startswith(field + '['): del json[key] msgid = json[field] islist = type(msgid) is list if islist: msgid = serializeList(msgid) debugPrint('Handling JSON list entry %s: %s' % (field, msgid)) for lang in pofiledict: langkey = '%s[%s]' % (field, lang) for entry in pofiledict[lang].translated_entries(): if entry.msgid != msgid: continue if entry.msgctxt != msgctxt: debugPrint('Found JSON translation with same id, but different context: "%s" vs "%s": "%s"' % (entry.msgctxt, msgctxt, msgid)) continue if entry.msgstr == '': continue if islist: json[langkey] = deserializeList(entry.msgstr) else: json[langkey] = entry.msgstr return json def handleKioProtocols(json, filename): protocols = json.get(kioprotocolsfield) if not protocols: return debugPrint('Handling KIO protocol (%s)' % filename) for name in protocols.keys(): debugPrint('Checking KIO protocol %s (%s)' % (name, filename)) if protocols[name].get('ExtraNames'): debugPrint('Found KIO protocol %s (%s) with ExtraNames' % (name, filename)) protocols[name] = findTranslations(protocols[name], 'ExtraNames', name + ' ExtraNames') # debugPrint(pprint.pformat(json)) def main(): jsonfilename, l10ndirpath, l10nmodulename, pofilename = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4] jsonpofilelist = glob.glob("%s/*/messages/%s/%s" %(l10ndirpath, l10nmodulename, pofilename)) if not l10ndirpath.endswith("/"): l10ndirpath += "/" for pofile in jsonpofilelist: langcode = pofile.split(l10ndirpath)[1].split("/")[0] po = polib.pofile(pofile) pofiledict[langcode] = po debugPrint('Found translations for %s' % pofiledict.keys()) with open(jsonfilename, 'r') as data_file: try: jsondata = json.load(data_file, encoding='utf-8') except ValueError as v: raise RuntimeError('%s seems to be malformed json: %s' % (jsonfilename, v.message)) if not type(jsondata) is dict: debugPrint('Cannot fill translations since JSON file %s is not an object' % jsonfilename) return if kpluginfield not in jsondata and kioprotocolsfield not in jsondata: debugPrint('Skipping JSON file %s as it does not have a "%s" or a "%s" key' % (jsonfilename, kpluginfield, kioprotocolsfield)) return else: try: if len(set(jsondata.get(kpluginfield).keys()).intersection(translationfields)) == 0: debugPrint('Skipping JSON file %s as it does not have a translationfield' %jsonfilename) return except AttributeError: debugPrint('AttributeError: "NoneType" object has no attribute "keys", skipping JSON file %s' %jsonfilename) return if pofiledict == {}: debugPrint('no translations found') debugPrint('args: %s' % sys.argv) # verbosePrint('original:\n "%s"\n\n' % pprint.pformat(kplugin)) handleKioProtocols(jsondata, os.path.basename(jsonfilename)) kplugin = jsondata.get(kpluginfield) if kplugin: for field in translationfields: findTranslations(kplugin, field, field) # now handle the KAboutPerson objects: for field in kaboutpersonfields: for obj in kplugin.get(field, []): findTranslations(obj, "Name", field + ' Name') findTranslations(obj, "Task", field + ' Task') # verbosePrint('final result:\n "%s"\n\n' % (pprint.pformat(jsondata))) with io.open(jsonfilename, 'w', encoding='utf-8') as data_file: # python2 adds trailing whitespace if the indent parameter is set. # To prevent this behavior we use custom separators. # TODO: this won't be necessary anymore with python >= 3.4 output = json.dumps(jsondata, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) output += '\n' data_file.write(output) if __name__ == "__main__": if len(sys.argv) != 5: - print 'wrong number of args: %s' %sys.argv - print '\nUsage: python %s path/to/jsonfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0]) + print('wrong number of args: %s' %sys.argv) + print('\nUsage: python %s path/to/jsonfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0])) else: try: main() except: - print 'cannot process %s: %s' % (sys.argv[1], traceback.format_exc()) + print('cannot process %s: %s' % (sys.argv[1], traceback.format_exc())) traceback.print_exc() Index: branches/stable/l10n-kf5/scripts/fillxmlfrompo.py =================================================================== --- branches/stable/l10n-kf5/scripts/fillxmlfrompo.py (revision 1571924) +++ branches/stable/l10n-kf5/scripts/fillxmlfrompo.py (revision 1571925) @@ -1,70 +1,70 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ Copyright 2014 Burkhard Lück Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. """ import sys, os, glob, re, codecs import polib if len(sys.argv) != 5: - print '\nUsage: python %s path/to/xmlfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0]) + print('\nUsage: python %s path/to/xmlfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0])) else: xmlfilepath, xmlfilename, l10ndirpath, l10nmodulename, pofilename = sys.argv[1], sys.argv[1].split("/")[-1], sys.argv[2], sys.argv[3], sys.argv[4] begincommenttag = "" endcommenttag = "" begincommentlangtag = ' Copyright 2016 Alex Richardson Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. """ import sys, os, json, time, pprint, codecs from jsontranslationcommon import * # a map msgctxt -> (msgid, filename) to merge duplicate fields translations = {} def potheader(): headertxt = "#, fuzzy\n" headertxt += "msgid \"\"\n" headertxt += "msgstr \"\"\n" headertxt += "\"Project-Id-Version: json files\\n\"\n" headertxt += "\"Report-Msgid-Bugs-To: https://bugs.kde.org\\n\"\n" headertxt += "\"POT-Creation-Date: %s+0000\\n\"\n" %time.strftime("%Y-%m-%d %H:%M") headertxt += "\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n" headertxt += "\"Last-Translator: FULL NAME \\n\"\n" headertxt += "\"Language-Team: LANGUAGE \\n\"\n" headertxt += "\"MIME-Version: 1.0\\n\"\n" headertxt += "\"Content-Type: text/plain; charset=UTF-8\\n\"\n" headertxt += "\"Content-Transfer-Encoding: 8bit\\n\"\n" headertxt += "\n" return headertxt def addPotEntry(context, value, filename): global translations if not value: return # make sure multiline strings and strings containing quotes are escaped properly for the .pot file: msgid = value.replace('"', '\\"').replace('\n', '\\n"\n"') ids = translations.get(context, []) # debugPrint("context: " + context + " msgid: " + msgid + ", " + pprint.pformat(ids)) for idx, val in enumerate(ids): if val[0] == msgid: debugPrint('Found identical entry: id="%s", ctx="%s"' % (msgid, context)) ids[idx] = (msgid, val[1] + ' ' + filename) translations[context] = ids return ids.append((msgid, filename)) translations[context] = ids def handleKAboutPersonObject(context, json, filename): for author in json: # translatable keys are Name and Task (see KAboutPerson::fromJSON()) addPotEntry(context + ' Name', author.get('Name'), filename) addPotEntry(context + ' Task', author.get('Task'), filename) def handleKioProtocols(json, filename): if not json: return for key in json.keys(): obj = json[key] names = obj.get('ExtraNames') if not names: continue addPotEntry(key + ' ExtraNames', serializeList(names), filename) if len(sys.argv) < 3: - print 'wrong number of args: %s' % sys.argv - print '\nUsage: python %s jsonfilenamelist basedir' %os.path.basename(sys.argv[0]) + print('wrong number of args: %s' % sys.argv) + print('\nUsage: python %s jsonfilenamelist basedir' %os.path.basename(sys.argv[0])) else: jsonfilenamelist = [os.path.abspath(filename) for filename in sys.argv[1:-1]] basedir = os.path.abspath(sys.argv[-1]) pottxt = "" for jsonfilename in jsonfilenamelist: with open(jsonfilename, 'r') as data_file: error = False try: jsondatadict = json.load(data_file, encoding='utf-8', strict=False) filename = os.path.relpath(jsonfilename, basedir) # try handling KDE-KIO-Protocols handleKioProtocols(jsondatadict.get(kioprotocolsfield), filename) kplugin = jsondatadict.get(kpluginfield) if not kplugin: continue for field in translationfields: addPotEntry(field, kplugin.get(field), filename) for field in kaboutpersonfields: if field in kplugin: handleKAboutPersonObject(field, kplugin[field], filename) except: debugPrint('json file %s unsupported by scripty: %s' % (jsonfilename, sys.exc_info())) if translations: pottxt = '' debugPrint('Found translations:\n' + pprint.pformat(translations)) for (context, values) in translations.items(): for entry in values: msgid = entry[0] filename = entry[1] pottxt += '#: %s\nmsgctxt "%s"\nmsgid "%s"\nmsgstr ""\n\n' % (filename, context, msgid) - print (potheader() + pottxt).encode('utf-8') + print((potheader() + pottxt).encode('utf-8')) Index: branches/stable/l10n-kf5-plasma-lts/scripts/extract-doc-assoc-ui-cats.py =================================================================== --- branches/stable/l10n-kf5-plasma-lts/scripts/extract-doc-assoc-ui-cats.py (revision 1571924) +++ branches/stable/l10n-kf5-plasma-lts/scripts/extract-doc-assoc-ui-cats.py (revision 1571925) @@ -1,49 +1,49 @@ #!/usr/bin/env python # -*- coding: UTF-8 -*- # Documentation docbooks may state which PO catalogs contain the user-interface # labels (those used in , , etc.) # This information is encoded as a comment, starting with ui-catalogs: keyword, # followed by whitespace-separated list of UI catalogs: # # # # The UI catalogs are given only by name, without any path or .po extension. # Catalogs should be ordered by decreasing priority, same as that for the # application which is being documented. # # The scripts takes docbook file names, parses each for these references, # and writes to standard output the union of all found catalog names as # whitespace separated list. The list is ordered by the appearance order # of catalog names during parsing. import sys import xml.parsers.expat # Union of extracted catalog names. catnames = [] # Comment handler. def handler_comment (data): p = data.find(":") if p >= 0 and data[:p].strip().lower() == "ui-catalogs": for cname in data[p+1:].split(): if cname not in catnames: catnames.append(cname) # Prepare XML parser. p = xml.parsers.expat.ParserCreate() p.UseForeignDTD() # not to barf on non-default XML entities p.CommentHandler = handler_comment # Go through all docbooks collecting catalog references. for fname in sys.argv[1:]: try: file = open(fname, "r") p.ParseFile(file) file.close() except xml.parsers.expat.ExpatError, inst: - print >>sys.stderr, "%s: parse error: %s" % (fname, inst) + print("%s: parse error: %s" % (fname, inst), file=sys.stderr) # Output collected catalogs. -print " ".join(catnames) +print(" ".join(catnames)) Index: branches/stable/l10n-kf5-plasma-lts/scripts/filljsonfrompo.py =================================================================== --- branches/stable/l10n-kf5-plasma-lts/scripts/filljsonfrompo.py (revision 1571924) +++ branches/stable/l10n-kf5-plasma-lts/scripts/filljsonfrompo.py (revision 1571925) @@ -1,144 +1,144 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ Copyright 2014 Burkhard Lück Copyright 2016 Alex Richardson Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. """ import sys, os, glob, polib, json, pprint, codecs, csv, io, traceback from jsontranslationcommon import * pofiledict = {} def findTranslations(json, field, msgctxt): global pofiledict if not json.get(field): return json # remove the old translations before inserting new ones: for key in json.keys(): if key.startswith(field + '['): del json[key] msgid = json[field] islist = type(msgid) is list if islist: msgid = serializeList(msgid) debugPrint('Handling JSON list entry %s: %s' % (field, msgid)) for lang in pofiledict: langkey = '%s[%s]' % (field, lang) for entry in pofiledict[lang].translated_entries(): if entry.msgid != msgid: continue if entry.msgctxt != msgctxt: debugPrint('Found JSON translation with same id, but different context: "%s" vs "%s": "%s"' % (entry.msgctxt, msgctxt, msgid)) continue if entry.msgstr == '': continue if islist: json[langkey] = deserializeList(entry.msgstr) else: json[langkey] = entry.msgstr return json def handleKioProtocols(json, filename): protocols = json.get(kioprotocolsfield) if not protocols: return debugPrint('Handling KIO protocol (%s)' % filename) for name in protocols.keys(): debugPrint('Checking KIO protocol %s (%s)' % (name, filename)) if protocols[name].get('ExtraNames'): debugPrint('Found KIO protocol %s (%s) with ExtraNames' % (name, filename)) protocols[name] = findTranslations(protocols[name], 'ExtraNames', name + ' ExtraNames') # debugPrint(pprint.pformat(json)) def main(): jsonfilename, l10ndirpath, l10nmodulename, pofilename = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4] jsonpofilelist = glob.glob("%s/*/messages/%s/%s" %(l10ndirpath, l10nmodulename, pofilename)) if not l10ndirpath.endswith("/"): l10ndirpath += "/" for pofile in jsonpofilelist: langcode = pofile.split(l10ndirpath)[1].split("/")[0] po = polib.pofile(pofile) pofiledict[langcode] = po debugPrint('Found translations for %s' % pofiledict.keys()) with open(jsonfilename, 'r') as data_file: try: jsondata = json.load(data_file, encoding='utf-8') except ValueError as v: raise RuntimeError('%s seems to be malformed json: %s' % (jsonfilename, v.message)) if not type(jsondata) is dict: debugPrint('Cannot fill translations since JSON file %s is not an object' % jsonfilename) return if kpluginfield not in jsondata and kioprotocolsfield not in jsondata: debugPrint('Skipping JSON file %s as it does not have a "%s" or a "%s" key' % (jsonfilename, kpluginfield, kioprotocolsfield)) return else: try: if len(set(jsondata.get(kpluginfield).keys()).intersection(translationfields)) == 0: debugPrint('Skipping JSON file %s as it does not have a translationfield' %jsonfilename) return except AttributeError: debugPrint('AttributeError: "NoneType" object has no attribute "keys", skipping JSON file %s' %jsonfilename) return if pofiledict == {}: debugPrint('no translations found') debugPrint('args: %s' % sys.argv) # verbosePrint('original:\n "%s"\n\n' % pprint.pformat(kplugin)) handleKioProtocols(jsondata, os.path.basename(jsonfilename)) kplugin = jsondata.get(kpluginfield) if kplugin: for field in translationfields: findTranslations(kplugin, field, field) # now handle the KAboutPerson objects: for field in kaboutpersonfields: for obj in kplugin.get(field, []): findTranslations(obj, "Name", field + ' Name') findTranslations(obj, "Task", field + ' Task') # verbosePrint('final result:\n "%s"\n\n' % (pprint.pformat(jsondata))) with io.open(jsonfilename, 'w', encoding='utf-8') as data_file: # python2 adds trailing whitespace if the indent parameter is set. # To prevent this behavior we use custom separators. # TODO: this won't be necessary anymore with python >= 3.4 output = json.dumps(jsondata, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) output += '\n' data_file.write(output) if __name__ == "__main__": if len(sys.argv) != 5: - print 'wrong number of args: %s' %sys.argv - print '\nUsage: python %s path/to/jsonfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0]) + print('wrong number of args: %s' %sys.argv) + print('\nUsage: python %s path/to/jsonfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0])) else: try: main() except: - print 'cannot process %s: %s' % (sys.argv[1], traceback.format_exc()) + print('cannot process %s: %s' % (sys.argv[1], traceback.format_exc())) traceback.print_exc() Index: branches/stable/l10n-kf5-plasma-lts/scripts/fillxmlfrompo.py =================================================================== --- branches/stable/l10n-kf5-plasma-lts/scripts/fillxmlfrompo.py (revision 1571924) +++ branches/stable/l10n-kf5-plasma-lts/scripts/fillxmlfrompo.py (revision 1571925) @@ -1,70 +1,70 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ Copyright 2014 Burkhard Lück Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. """ import sys, os, glob, re, codecs import polib if len(sys.argv) != 5: - print '\nUsage: python %s path/to/xmlfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0]) + print('\nUsage: python %s path/to/xmlfile path/to/l10ndir/ l10nmodulename pofilename.po' %os.path.basename(sys.argv[0])) else: xmlfilepath, xmlfilename, l10ndirpath, l10nmodulename, pofilename = sys.argv[1], sys.argv[1].split("/")[-1], sys.argv[2], sys.argv[3], sys.argv[4] begincommenttag = "" endcommenttag = "" begincommentlangtag = '