2
This commit is contained in:
@ -16,11 +16,15 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
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, Pack, PackLocalization
|
||||
from .defs import ARCAEA_LANGUAGE_KEYS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -31,121 +35,145 @@ class PacklistFormatError(Exception):
|
||||
|
||||
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)
|
||||
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 _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]:
|
||||
def check_pack_object(obj: dict) -> None:
|
||||
try:
|
||||
cls._assert_root_content(packlist_content)
|
||||
except PacklistFormatError as e:
|
||||
if skip_asserts:
|
||||
logger.exception("Error skipped during packlist parsing:")
|
||||
return []
|
||||
check_type(obj, dict)
|
||||
check_type(obj["id"], str)
|
||||
except (KeyError, TypeCheckError) as e:
|
||||
raise PacklistFormatError from e
|
||||
|
||||
raise e
|
||||
@staticmethod
|
||||
def parse_pack(pack: dict) -> AodisPack:
|
||||
id_ = pack["id"]
|
||||
|
||||
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,
|
||||
)
|
||||
]
|
||||
name_localized = pack.get("name_localized", {})
|
||||
description_localized = pack.get("description_localized", {})
|
||||
|
||||
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
|
||||
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
|
||||
)
|
||||
|
||||
raise e
|
||||
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,
|
||||
)
|
||||
|
||||
name_localized = pack.get("name_localized", {})
|
||||
description_localized = pack.get("description_localized", {})
|
||||
@staticmethod
|
||||
def parse_pack_localizations(pack: dict) -> list[AodisPackLocalization]:
|
||||
results = []
|
||||
|
||||
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
|
||||
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),
|
||||
)
|
||||
|
||||
results.append(
|
||||
Pack(
|
||||
id=id_,
|
||||
name=name,
|
||||
description=description,
|
||||
section=section,
|
||||
plus_character=plus_character,
|
||||
append_parent_id=append_parent_id,
|
||||
if name_l10n or description_l10n:
|
||||
results.append(
|
||||
AodisPackLocalization(
|
||||
id=id_,
|
||||
lang=lang_key,
|
||||
name=name_l10n,
|
||||
description=description_l10n,
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
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]:
|
||||
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_asserts=skip_asserts)
|
||||
if isinstance(item, Pack)
|
||||
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_asserts: bool = False
|
||||
) -> list[PackLocalization]:
|
||||
cls,
|
||||
packlist_content: dict,
|
||||
*,
|
||||
skip_format_checks: bool = False,
|
||||
) -> list[AodisPackLocalization]:
|
||||
return [
|
||||
item
|
||||
for item in cls.items(packlist_content, skip_asserts=skip_asserts)
|
||||
if isinstance(item, PackLocalization)
|
||||
for item in cls.items(
|
||||
packlist_content,
|
||||
skip_format_checks=skip_format_checks,
|
||||
)
|
||||
if isinstance(item, AodisPackLocalization)
|
||||
]
|
||||
|
Reference in New Issue
Block a user