Skip to content

Commit ec799bb

Browse files
ubejdullahsdaqo
andauthored
fix: allanime aareq runtime fetch (#333)
* fix: fetch AllAnime aaReq crypto values at runtime AllAnime rotates the epoch and the encryption secrets used to sign the aaReq token every few days. With those values hardcoded, episode sources stop resolving after each rotation and playback fails. Fetch the current values at runtime instead: epoch and partB come from window.__aaCrypto on the mkissa frontend, and the key mask is the lone hex constant in the app chunk it statically imports. The result is cached for the epoch window and falls back to the last known good hardcoded values when the fetch fails, so playback keeps working even if the site is unreachable. * feat: report AllAnime aaReq crypto refresh through an info callback Add an optional info_callback to BaseProvider and get_provider, mirroring the callback the Downloader already uses. The AllAnime provider calls it to report whether it fetched fresh crypto values or fell back to the hardcoded ones, including the active epoch and the first bytes of the fetched hash. Wire the CLI to pass logger.info as this callback wherever it builds a provider (get_prefered_providers and the MAL and AniList proxies), so the messages surface at -V verbosity and in the log file. * refactor: extract AllAnime aaReq crypto into its own class Move the runtime aaReq crypto (fetching and caching the rotating values, token generation, tobeparsed decryption and the last known good fallback values) out of the provider module and into a dedicated AllAnimeCrypto class in its own file. The provider builds it in its constructor and delegates to it, so the crypto lives in one place instead of module level state and loose functions scattered through the provider. No behaviour change: episode sources and the -V info logging work exactly as before. * feat: fetch the AllAnime source query hash and drop the unused buildId The two remaining hardcoded aaReq values are no longer pinned: - The persisted-query hash is now derived at runtime. The source query is assembled from its template and fragments in the app chunk (the same chunk the mask comes from) and sha256'd, falling back to the last known good hash if the template cannot be fully resolved. - buildId is dropped entirely. The api does not check it, it only exists obfuscated in the chunk, and the source request is accepted without it, so the payload and iv no longer carry it. * misc: merge allanime crypto into provider * version: bump --------- Co-authored-by: sdaqo <sdaqo.dev@protonmail.com>
1 parent 4734076 commit ec799bb

10 files changed

Lines changed: 239 additions & 71 deletions

File tree

api/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "anipy-api"
3-
version = "3.8.13"
3+
version = "3.8.14"
44
description = "api for anipy-cli"
55
authors = ["sdaqo <sdaqo.dev@protonmail.com>"]
66
license = "GPL-3.0"

api/src/anipy_api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
__appname__ = "anipy-api"
2-
__version__ = "3.8.13"
2+
__version__ = "3.8.14"

api/src/anipy_api/provider/base.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from abc import ABC, abstractmethod
22
from dataclasses import dataclass
33
from enum import Enum
4-
from typing import List, Optional, Set, Union, Dict
4+
from typing import List, Optional, Protocol, Set, Union, Dict
55

66
from requests import Request, Session, ConnectionError as RequestConnectionError
77

@@ -105,6 +105,18 @@ def __hash__(self) -> int:
105105
return hash(self.url)
106106

107107

108+
class InfoCallback(Protocol):
109+
"""Callback that accepts a message argument, and an exception."""
110+
111+
def __call__(self, message: str, exc_info: Optional[BaseException] = None):
112+
"""
113+
Args:
114+
message: Message argument passed to the callback
115+
exc_info: An exception to pass for logging
116+
"""
117+
...
118+
119+
108120
class BaseProvider(ABC):
109121
"""
110122
This is the abstract base class for all the providers,
@@ -125,15 +137,24 @@ class BaseProvider(ABC):
125137
BASE_URL: str
126138
FILTER_CAPS: FilterCapabilities
127139

128-
def __init__(self, base_url_override: Optional[str] = None):
140+
def __init__(
141+
self,
142+
base_url_override: Optional[str] = None,
143+
info_callback: Optional[InfoCallback] = None,
144+
):
129145
"""__init__ of BaseProvider
130146
131147
Args:
132148
base_url_override: Override the url used by the provider.
149+
info_callback: A callback with a message argument, that gets called
150+
on certain events (e.g. when a provider refreshes api tokens).
133151
"""
134152
if base_url_override is not None:
135153
self.BASE_URL = base_url_override
136154

155+
self._info_callback: InfoCallback = info_callback or (
156+
lambda message, exc_info=None: None
157+
)
137158
self._generate_new_session()
138159

139160
def __init_subclass__(cls) -> None:

api/src/anipy_api/provider/provider.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
if TYPE_CHECKING:
77
from anipy_api.provider import BaseProvider
8+
from anipy_api.provider.base import InfoCallback
89

910

1011
def list_providers() -> Iterator[Type["BaseProvider"]]:
@@ -38,17 +39,20 @@ def get_prefered_providers(mode: str) -> Iterator["BaseProvider"]:
3839

3940

4041
def get_provider(
41-
name: str, base_url_override: Optional[str] = None
42+
name: str,
43+
base_url_override: Optional[str] = None,
44+
info_callback: Optional["InfoCallback"] = None,
4245
) -> Optional["BaseProvider"]:
4346
"""Get a provider by name.
4447
4548
Arguments:
4649
name: Name of the provider to get
4750
base_url_override: Override the url used by the provider.
51+
info_callback: A callback that gets called on certain provider events.
4852
4953
Returns:
5054
The provider by name, if it exsists
5155
"""
5256
for p in list_providers():
5357
if p.NAME == name:
54-
return p(base_url_override)
58+
return p(base_url_override, info_callback)

0 commit comments

Comments
 (0)