From 3008bfed616c0661197ab58e12a16b1fe2077fa9 Mon Sep 17 00:00:00 2001 From: Nemris Date: Wed, 26 Apr 2023 02:15:26 +0200 Subject: [PATCH] Reduce noise and drop dataclasses --- utils/transriff.py | 268 ++++++++++++--------------------------------- 1 file changed, 68 insertions(+), 200 deletions(-) diff --git a/utils/transriff.py b/utils/transriff.py index aa4c5f4..5a8d57d 100755 --- a/utils/transriff.py +++ b/utils/transriff.py @@ -1,11 +1,8 @@ #!/usr/bin/env python3 -""" Create an TRF translation for GodMode9 from a translation JSON. """ - -from __future__ import annotations +""" Create a TRF translation for GodMode9 from a translation JSON. """ import argparse -import dataclasses import json import math import pathlib @@ -16,36 +13,6 @@ import sys LANGUAGE_NAME = "GM9_LANGUAGE" -def read_args() -> argparse.Namespace: - """ - Parse command-line args. - - Returns: - The parsed command-line args. - """ - parser = argparse.ArgumentParser( - description="Create an TRF translation for GodMode9 from a translation JSON." - ) - - parser.add_argument( - "source", - type=pathlib.Path, - help="JSON to convert from" - ) - parser.add_argument( - "dest", - type=pathlib.Path, - help="TRF file to write" - ) - parser.add_argument( - "version", - type=int, - help="translation version, from language.yml" - ) - - return parser.parse_args() - - def ceil_to_multiple(num: int, base: int) -> int: """ Return the ceiling of num which is a multiple of base. @@ -75,7 +42,7 @@ def get_language(data: dict) -> bytes: """ try: return data[LANGUAGE_NAME].encode("utf-8") - except AttributeError as exception: + except KeyError as exception: raise ValueError("invalid language data") from exception @@ -96,180 +63,60 @@ def load_translations(data: dict) -> dict[str, bytearray]: } -@dataclasses.dataclass -class TRFMetadata: +def strings_to_trf(mapping: dict[str, bytearray], version: int, language: str) -> bytearray: """ - A TRF file's metadata section. + Create a TRF file from translated strings. Args: + mapping: Mapping between labels and translated strings. version: Translation version. - nstrings: Total strings in the translation. language: Translation language. + + Returns: + The translation strings as TRF data. """ - version: int - nstrings: int - language: bytes + # File header. + trfdata = bytearray(b"RIFF\0\0\0\0") - def as_bytearray(self) -> bytearray: - """ - Return a bytearray representation of this TRF section. + # Metadata section. + trfdata += ( + b"META" + + struct.pack(" int: - return len(self.as_bytearray()) + trfdata += ( + b"SDAT" + + struct.pack(" TRFCharacterData: - """ - Construct an instance of this class from a translation mapping. + # Fill in cumulative section size. + trfdata[4:8] = struct.pack(" bytearray: - """ - Return a bytearray representation of this TRF section. - - Returns: - This TRF character data section as a bytearray. - """ - size = ceil_to_multiple(len(self.data), 4) - padding = size - len(self.data) - - return ( - bytearray(b"SDAT") - + struct.pack(" int: - return len(self.as_bytearray()) - - -@dataclasses.dataclass -class TRFCharacterMap: - """ - A TRF file's character map section. - - Args: - data: Translation strings' offsets. - """ - data: bytearray - - @classmethod - def from_mapping(cls, mapping: dict[str, bytearray]) -> TRFCharacterMap: - """ - Construct an instance of this class from a translation mapping. - - Args: - mapping: Mapping between translation labels and strings. - - Returns: - An instance of TRFCharacterMap. - """ - data = bytearray() - offset = 0 - - for item in mapping.values(): - data.extend(struct.pack(" bytearray: - """ - Return a bytearray representation of this TRF section. - - Returns: - This TRF character map section as a bytearray. - """ - size = ceil_to_multiple(len(self.data), 4) - padding = size - len(self.data) - - return ( - bytearray(b"SMAP") - + struct.pack(" int: - return len(self.as_bytearray()) - - -@dataclasses.dataclass -class TRFFile: - """ - A TRF file. - - Args: - metadata: The TRF META section. - chardata: The TRF SDAT section. - charmap: The TRF SMAP section. - """ - metadata: TRFMetadata - chardata: TRFCharacterData - charmap: TRFCharacterMap - - @classmethod - def new(cls, version: int, mapping: dict, language: bytes) -> TRFFile: - """ - Construct an instance of this class and its attributes. - - Args: - version: Translation version. - mapping: Mapping between translation labels and strings. - language: Translation language. - - Returns: - An instance of TRFFile. - """ - return cls( - TRFMetadata(version, len(mapping), language), - TRFCharacterData.from_mapping(mapping), - TRFCharacterMap.from_mapping(mapping) - ) - - def as_bytearray(self) -> bytearray: - """ - Return a bytearray representation of this TRF file. - - Returns: - This TRF file as a bytearray. - """ - size = len(self.metadata) + len(self.chardata) + len(self.charmap) - - return ( - bytearray(b"RIFF") - + struct.pack(" None: @@ -287,14 +134,35 @@ def main(source: pathlib.Path, dest: pathlib.Path, version: int) -> None: language = get_language(data) except ValueError as exception: sys.exit(f"Fatal: {exception}.") - strings = load_translations(data) + mapping = load_translations(data) - trf_file = TRFFile.new(version, strings, language) + trf_file = strings_to_trf(mapping, version, language) - dest.write_bytes(trf_file.as_bytearray()) - print(f"Info: {dest.as_posix()} created with {len(strings)} strings.") + dest.write_bytes(trf_file) + print(f"Info: {dest.as_posix()} created with {len(mapping)} strings.") if __name__ == "__main__": - args = read_args() + parser = argparse.ArgumentParser( + description="Create an TRF translation for GodMode9 from a translation JSON." + ) + + parser.add_argument( + "source", + type=pathlib.Path, + help="JSON to convert from" + ) + parser.add_argument( + "dest", + type=pathlib.Path, + help="TRF file to write" + ) + parser.add_argument( + "version", + type=int, + help="translation version, from language.yml" + ) + + args = parser.parse_args() + main(args.source, args.dest, args.version)