""" Copyright (C) 2025 283375 This file is part of "arcaea-apk-assets" (stated as "this program" below). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ from __future__ import annotations import logging from arcaea_offline_schemas.dis.v5.dataclass import AodisPack, AodisPackLocalization from typeguard import TypeCheckError, check_type from ._shared import blank_str_to_none from .defs import ARCAEA_LANGUAGE_KEYS logger = logging.getLogger(__name__) class PacklistFormatError(Exception): pass class ArcaeaPacklistParser: @staticmethod def check_root_content(root: dict) -> None: try: check_type(root, dict) check_type(root["packs"], list[dict]) except (KeyError, TypeCheckError) as e: raise PacklistFormatError from e @staticmethod def check_pack_object(obj: dict) -> None: try: check_type(obj, dict) check_type(obj["id"], str) except (KeyError, TypeCheckError) as e: raise PacklistFormatError from e @staticmethod def parse_pack(pack: dict) -> AodisPack: id_ = pack["id"] name_localized = pack.get("name_localized", {}) description_localized = pack.get("description_localized", {}) name = blank_str_to_none(name_localized.get("en")) description = blank_str_to_none(description_localized.get("en")) section = blank_str_to_none(pack.get("section")) append_parent_id = pack.get("pack_parent") plus_character = ( pack["plus_character"] if pack.get("plus_character", -1) > -1 else None ) return AodisPack( id=id_, name=name or "", isWorldExtend=pack.get("is_extend_pack") is True, description=description, section=section, unlocksPartner=plus_character, appendParentId=append_parent_id, ) @staticmethod def parse_pack_localizations(pack: dict) -> list[AodisPackLocalization]: results = [] name_localized = pack.get("name_localized", {}) description_localized = pack.get("description_localized", {}) id_ = pack["id"] for lang_key in ARCAEA_LANGUAGE_KEYS: name_l10n = blank_str_to_none(name_localized.get(lang_key)) description_l10n = blank_str_to_none( description_localized.get(lang_key), ) if name_l10n or description_l10n: results.append( AodisPackLocalization( id=id_, lang=lang_key, name=name_l10n, description=description_l10n, ), ) return results @classmethod def items( cls, packlist_content: dict, *, skip_format_checks: bool = False, ) -> list[AodisPack | AodisPackLocalization]: try: cls.check_root_content(packlist_content) except PacklistFormatError: if skip_format_checks: logger.exception("Error skipped during packlist parsing:") return [] raise packs = packlist_content["packs"] results: list[AodisPack | AodisPackLocalization] = [ AodisPack( id="single", name="Memory Archive", isWorldExtend=False, description=None, section=None, unlocksPartner=None, appendParentId=None, ), ] for pack in packs: try: cls.check_pack_object(pack) except PacklistFormatError: if skip_format_checks: logger.exception("Error skipped during packlist parsing:") continue raise results.append(cls.parse_pack(pack)) results.extend(cls.parse_pack_localizations(pack)) return results @classmethod def packs( cls, packlist_content: dict, *, skip_format_checks: bool = False, ) -> list[AodisPack]: return [ item for item in cls.items( packlist_content, skip_format_checks=skip_format_checks, ) if isinstance(item, AodisPack) ] @classmethod def pack_localizations( cls, packlist_content: dict, *, skip_format_checks: bool = False, ) -> list[AodisPackLocalization]: return [ item for item in cls.items( packlist_content, skip_format_checks=skip_format_checks, ) if isinstance(item, AodisPackLocalization) ]