78 lines
2.3 KiB
Python
Executable File
78 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import ast
|
|
import struct
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def read_po(path):
|
|
messages = {}
|
|
current = None
|
|
buffers = {"msgid": [], "msgstr": []}
|
|
|
|
def flush():
|
|
if buffers["msgid"] or buffers["msgstr"]:
|
|
messages["".join(buffers["msgid"])] = "".join(buffers["msgstr"])
|
|
buffers["msgid"] = []
|
|
buffers["msgstr"] = []
|
|
|
|
for raw_line in path.read_text(encoding="utf-8").splitlines():
|
|
line = raw_line.strip()
|
|
if not line or line.startswith("#"):
|
|
continue
|
|
if line.startswith("msgid "):
|
|
flush()
|
|
current = "msgid"
|
|
buffers[current].append(ast.literal_eval(line[6:].strip()))
|
|
continue
|
|
if line.startswith("msgstr "):
|
|
current = "msgstr"
|
|
buffers[current].append(ast.literal_eval(line[7:].strip()))
|
|
continue
|
|
if line.startswith('"') and current:
|
|
buffers[current].append(ast.literal_eval(line))
|
|
flush()
|
|
return messages
|
|
|
|
|
|
def write_mo(messages, path):
|
|
keys = sorted(messages)
|
|
ids = b"\x00".join(key.encode("utf-8") for key in keys) + b"\x00"
|
|
strs = b"\x00".join(messages[key].encode("utf-8") for key in keys) + b"\x00"
|
|
|
|
keystart = 7 * 4 + len(keys) * 16
|
|
valuestart = keystart + len(ids)
|
|
koffsets = []
|
|
voffsets = []
|
|
offset = keystart
|
|
for key in keys:
|
|
encoded = key.encode("utf-8")
|
|
koffsets.append((len(encoded), offset))
|
|
offset += len(encoded) + 1
|
|
offset = valuestart
|
|
for key in keys:
|
|
encoded = messages[key].encode("utf-8")
|
|
voffsets.append((len(encoded), offset))
|
|
offset += len(encoded) + 1
|
|
|
|
output = [
|
|
struct.pack("Iiiiiii", 0x950412DE, 0, len(keys), 7 * 4, 7 * 4 + len(keys) * 8, 0, 0)
|
|
]
|
|
output.extend(struct.pack("ii", length, offset) for length, offset in koffsets)
|
|
output.extend(struct.pack("ii", length, offset) for length, offset in voffsets)
|
|
output.append(ids)
|
|
output.append(strs)
|
|
path.write_bytes(b"".join(output))
|
|
|
|
|
|
def main():
|
|
root = Path(sys.argv[1] if len(sys.argv) > 1 else "locale")
|
|
for po in root.glob("*/LC_MESSAGES/*.po"):
|
|
mo = po.with_suffix(".mo")
|
|
write_mo(read_po(po), mo)
|
|
print(mo)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|