#!/usr/bin/env python3 import os import sys import re from xml.dom import minidom # STRINGTABLE MERGER TOOL # Author: KoffeinFlummi # -------------------------- # Automatically merges all stringtable entries # in the given language from the given dir. def get_modules(projectpath): """ Get all the modules of the project. """ modules = [] for i in os.listdir(projectpath): path = os.path.join(projectpath, i) if not os.path.isdir(path): continue if i[0] == ".": continue modules.append(i) return modules def contains_language(key, language): """ Checks whether a given key contains a certain language. """ for child in key.childNodes: try: assert(child.tagName == language) return True except: pass return False def get_entry_by_id(keys, keyid): """ Returns the first child of keys with ID='keyid'. """ for key in keys: if key.getAttribute("ID") == keyid: return key return False def replace_entries(oldpath, newpath, language, breakdown): """ Replaces all new entries of the given language in the given module. """ oldfile = minidom.parse(oldpath) newfile = minidom.parse(newpath) oldkeys = oldfile.getElementsByTagName("Key") newkeys = newfile.getElementsByTagName("Key") newkeys = list(filter(lambda x: contains_language(x, language), newkeys)) for newkey in newkeys: keyid = newkey.getAttribute("ID") oldkey = get_entry_by_id(oldkeys, keyid) if not oldkey: continue if breakdown: print(" Merging %s translation for %s" % (language, keyid)) newentry = newkey.getElementsByTagName(language)[0].firstChild try: # An entry for this language already exists, overwrite it oldentry = oldkey.getElementsByTagName(language)[0].firstChild oldentry.replaceWholeText(newentry.wholeText) except: # There is no entry for this language yet, make one oldentry = oldfile.createElement(language) oldentry.appendChild(oldfile.createTextNode(newentry.wholeText)) # Some whitespace tetris to maintain file structure oldkey.insertBefore(oldfile.createTextNode("\n "), oldkey.lastChild) oldkey.insertBefore(oldentry, oldkey.lastChild) # Make a nice string xmlstring = oldfile.toxml() xmlstring = xmlstring.replace('" ?>', '" encoding="utf-8"?>') # Replace the newlines that minidom swallows xmlstring = xmlstring.replace("><", ">\n<") xmlstring += "\n" fhandle = open(oldpath, "w") fhandle.write(xmlstring) fhandle.close() return len(newkeys) def main(sourcepath, language, breakdown): scriptpath = os.path.realpath(__file__) projectpath = os.path.dirname(os.path.dirname(scriptpath)) projectpath = os.path.join(projectpath, "addons") modules = get_modules(projectpath) modulecounter = 0 keycounter = 0 for module in modules: oldpath = os.path.join(projectpath, module, "stringtable.xml") newpath = os.path.join(sourcepath, module, "stringtable.xml") # Some translators extract the lowercase PBOs, so the module name might # be lowercase (obviously only matters on Linux) if not os.path.exists(newpath): newpath = os.path.join(sourcepath, module.lower(), "stringtable.xml") # Translator didn't include this module, skip if not os.path.exists(newpath): continue keynum = replace_entries(oldpath, newpath, language, breakdown) modulecounter += 1 keycounter += keynum print("# Merged %i entry/entries in %s" % (keynum, module)) if breakdown: print("") print("") print("# Merged %i entry/entries in %i modules" % (keycounter, modulecounter)) if __name__ == "__main__": try: sourcepath = os.path.normpath(os.path.join(os.getcwd(), sys.argv[1])) language = sys.argv[2] assert(os.path.exists(sourcepath)) except: print("ERROR: Missing arguments of invalid path.") print("\nUsage:") print("[script] [path to new project] [language]") sys.exit(1) main(sourcepath, language, "--breakdown" in sys.argv)