diff options
-rw-r--r-- | scripts/update_po_with_changes.py | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/scripts/update_po_with_changes.py b/scripts/update_po_with_changes.py new file mode 100644 index 0000000000..4f3199b364 --- /dev/null +++ b/scripts/update_po_with_changes.py @@ -0,0 +1,121 @@ +import argparse + +from typing import List + +""" + Takes in one of the po files in resources/i18n/[LANG_CODE]/cura.po and updates it with translations from a + new po file without changing the translation ordering. + This script should be used when we get a po file that has updated translations but is no longer correctly ordered + so the merge becomes messy. + + If you are importing files from lionbridge/smartling use lionbridge_import.py. + + Note: This does NOT include new strings, it only UPDATES existing strings +""" + + +class Msg: + def __init__(self, msgctxt: str = "", msgid: str = "", msgstr: str = ""): + self.msgctxt = msgctxt + self.msgid = msgid + self.msgstr = msgstr + + def __str__(self): + return self.msgctxt + self.msgid + self.msgstr + + +def parse_po_file(filename: str) -> List[Msg]: + messages = [] + with open(filename) as f: + iterator = iter(f.readlines()) + while True: + try: + line = next(iterator) + if line[0:7] == "msgctxt": + # Start of a translation item block + msg = Msg() + msg.msgctxt = line + + while True: + line = next(iterator) + if line[0:5] == "msgid": + msg.msgid = line + break + + while True: + # msgstr can be split over multiple lines + line = next(iterator) + if line == "\n": + break + if line[0:6] == "msgstr": + msg.msgstr = line + else: + msg.msgstr += line + + messages.append(msg) + except StopIteration: + return messages + + +def get_different_messages(messages_original: List[Msg], messages_new: List[Msg]) -> List[Msg]: + # Return messages that have changed in messages_new + different_messages = [] + + for m_new in messages_new: + for m_original in messages_original: + if m_new.msgstr != m_original.msgstr \ + and m_new.msgid == m_original.msgid and m_new.msgctxt == m_original.msgctxt \ + and m_new.msgid != 'msgid ""\n': + different_messages.append(m_new) + + return different_messages + + +def update_po_file(input_filename: str, output_filename: str, messages: List[Msg]): + # Takes a list of changed messages and writes a copy of input file with updated message strings + with open(input_filename, "r") as input_file, open(output_filename, "w") as output_file: + iterator = iter(input_file.readlines()) + while True: + try: + line = next(iterator) + output_file.write(line) + if line[0: 7] == "msgctxt": + # Start of translation block + msgctxt = line + + msgid = next(iterator) + output_file.write(msgid) + + # Check for updated version of msgstr + message = list(filter(lambda m: m.msgctxt == msgctxt and m.msgid == msgid, messages)) + if message and message[0]: + # Write update translation + output_file.write(message[0].msgstr) + + # Skip lines until next translation. This should skip multiline msgstr + while True: + line = next(iterator) + if line == "\n": + output_file.write(line) + break + + except StopIteration: + return + + +if __name__ == "__main__": + print("********************************************************************************************************************") + print("This creates a new file 'updated.po' that is a copy of original_file with any changed translations from updated_file") + print("This does not change the order of translations") + print("This does not include new translations, only existing changed translations") + print("Do not use this to import lionbridge/smarting translations") + print("********************************************************************************************************************") + parser = argparse.ArgumentParser(description="Update po file with translations from new po file. This ") + parser.add_argument("original_file", type=str, help="Input .po file inside resources/i18n/[LANG]/") + parser.add_argument("updated_file", type=str, help="Input .po file with updated translations added") + args = parser.parse_args() + + messages_updated = parse_po_file(args.updated_file) + messages_original = parse_po_file(args.original_file) + different_messages = get_different_messages(messages_original, messages_updated) + update_po_file(args.original_file, "updated.po", different_messages) |