init
This commit is contained in:
151
arcaea_apk_assets/parsers/packlist.py
Normal file
151
arcaea_apk_assets/parsers/packlist.py
Normal file
@ -0,0 +1,151 @@
|
||||
"""
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from ._shared import blank_str_to_none
|
||||
from .defs import ARCAEA_LANGUAGE_KEYS, Pack, PackLocalization
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PacklistFormatError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ArcaeaPacklistParser:
|
||||
@staticmethod
|
||||
def _assert_root_content(root: Any):
|
||||
if not isinstance(root, dict):
|
||||
msg = f"packlist root should be `dict`, got {type(root)}"
|
||||
raise PacklistFormatError(msg)
|
||||
|
||||
packs = root.get("packs")
|
||||
if packs is None:
|
||||
msg = "`packs` field does not exist"
|
||||
raise PacklistFormatError(msg)
|
||||
|
||||
if not isinstance(packs, list):
|
||||
msg = f"`packs` field should be `list`, got {type(packs)}"
|
||||
raise PacklistFormatError(msg)
|
||||
|
||||
@staticmethod
|
||||
def _assert_pack_object(obj: Any):
|
||||
if not isinstance(obj, dict):
|
||||
msg = f"A pack object should be `dict`, got {type(obj)}"
|
||||
raise PacklistFormatError(msg)
|
||||
|
||||
id_ = obj.get("id")
|
||||
if not isinstance(id_, str):
|
||||
msg = f"`id` attribute of a pack should be `str`, got value {id_!r}"
|
||||
raise PacklistFormatError(msg)
|
||||
|
||||
@classmethod
|
||||
def items(
|
||||
cls, packlist_content: dict, *, skip_asserts: bool = False
|
||||
) -> list[Pack | PackLocalization]:
|
||||
try:
|
||||
cls._assert_root_content(packlist_content)
|
||||
except PacklistFormatError as e:
|
||||
if skip_asserts:
|
||||
logger.exception("Error skipped during packlist parsing:")
|
||||
return []
|
||||
|
||||
raise e
|
||||
|
||||
packs = packlist_content["packs"]
|
||||
results: list[Pack | PackLocalization] = [
|
||||
Pack(
|
||||
id="single",
|
||||
name="Memory Archive",
|
||||
description=None,
|
||||
section=None,
|
||||
plus_character=None,
|
||||
append_parent_id=None,
|
||||
)
|
||||
]
|
||||
|
||||
for pack in packs:
|
||||
try:
|
||||
cls._assert_pack_object(pack)
|
||||
except PacklistFormatError as e:
|
||||
if skip_asserts:
|
||||
logger.exception("Error skipped during packlist parsing:")
|
||||
continue
|
||||
|
||||
raise e
|
||||
|
||||
name_localized = pack.get("name_localized", {})
|
||||
description_localized = pack.get("description_localized", {})
|
||||
|
||||
id_ = pack["id"]
|
||||
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
|
||||
)
|
||||
|
||||
results.append(
|
||||
Pack(
|
||||
id=id_,
|
||||
name=name,
|
||||
description=description,
|
||||
section=section,
|
||||
plus_character=plus_character,
|
||||
append_parent_id=append_parent_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(
|
||||
PackLocalization(
|
||||
id=id_,
|
||||
lang=lang_key,
|
||||
name=name_l10n,
|
||||
description=description_l10n,
|
||||
)
|
||||
)
|
||||
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def packs(cls, packlist_content: dict, *, skip_asserts: bool = False) -> list[Pack]:
|
||||
return [
|
||||
item
|
||||
for item in cls.items(packlist_content, skip_asserts=skip_asserts)
|
||||
if isinstance(item, Pack)
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def pack_localizations(
|
||||
cls, packlist_content: dict, *, skip_asserts: bool = False
|
||||
) -> list[PackLocalization]:
|
||||
return [
|
||||
item
|
||||
for item in cls.items(packlist_content, skip_asserts=skip_asserts)
|
||||
if isinstance(item, PackLocalization)
|
||||
]
|
Reference in New Issue
Block a user