""" 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 . """ import abc import dataclasses import re from typing import ClassVar, Optional __all__ = [ "ArcaeaApkAsset", "ArcaeaApkAssetJacket", "ArcaeaApkAssetList", "ArcaeaApkAssetPartnerIcon", ] @dataclasses.dataclass class ArcaeaApkAsset(metaclass=abc.ABCMeta): PATTERN: ClassVar[re.Pattern] zip_filename: str @classmethod def _get_match(cls, string: str) -> Optional[re.Match]: return cls.PATTERN.match(string) @classmethod @abc.abstractmethod def from_zip_filename( cls, asset_zip_filename: str ) -> Optional["ArcaeaApkAsset"]: ... @dataclasses.dataclass class ArcaeaApkAssetJacket(ArcaeaApkAsset): PATTERN = re.compile( r"^assets/songs/(?P.*)/(1080_)?(?P\d|base)(_(?P.*))?\.(jpg|png)" ) song_id: str rating_class: Optional[str] lang: Optional[str] @classmethod def from_zip_filename(cls, asset_zip_filename: str): match = cls._get_match(asset_zip_filename) if match is None: return None return cls( zip_filename=asset_zip_filename, song_id=match.group("raw_song_id").replace("dl_", ""), rating_class=( None if match.group("raw_rating_class") == "base" else match.group("raw_rating_class") ), lang=match.group("lang"), ) @dataclasses.dataclass class ArcaeaApkAssetPartnerIcon(ArcaeaApkAsset): PATTERN = re.compile(r"^assets/char/(?P\d+u?)_icon\.(jpg|png)") char_id: str @classmethod def from_zip_filename(cls, asset_zip_filename: str): match = cls._get_match(asset_zip_filename) if match is None: return None return cls( zip_filename=asset_zip_filename, char_id=match.group("char_id"), ) @dataclasses.dataclass class ArcaeaApkAssetList(ArcaeaApkAsset): PATTERN = re.compile(r"^assets/songs/(?P(pack|song)list|unlocks)") filename: str @classmethod def from_zip_filename(cls, asset_zip_filename: str): match = cls._get_match(asset_zip_filename) if match is None: return None return cls( zip_filename=asset_zip_filename, filename=match.group("filename"), )