Intro skip: parse Jikan v4's actual response shape
Jikan /anime/{id}/episodes returns the episode list DIRECTLY under
'data' (flat array), not {'episodes': [...]}. The old code called
.get() on that list -> AttributeError, swallowed by the endpoint's
except -> [] -> the skip button could never appear, even with Jikan
up. Accept both shapes now.
Verified end-to-end with a mocked /api/intros response: the button is
wired into the player, visible exactly while currentTime is inside the
intro window (111-188s test), hidden outside it.
The live button still awaits Jikan/MAL recovery (504ing since this
feature landed); failures are not cached, so it activates on the first
successful fetch.
Skipped: MAL-direct fallback — official API needs a client key
(403 without), and the keyless HTML page carries no intro data.
This commit is contained in:
1 parent
eb5082bd3b
commit
27de918cb0
2 files changed
+36
-2
No files matched your search
+6
-2
@@ -132,9 +132,13 @@ def _parse_intros(eps):
|
||||
|
||||
|
||||
def _intros(mal_id):
|
||||
"""Jikan (keyless MAL mirror): per-episode intro start/length, seconds"""
|
||||
"""Jikan (keyless MAL mirror): per-episode intro start/length, seconds."""
|
||||
# Jikan v4 returns the list directly under 'data'; tolerate a wrapped
|
||||
# shape too, so a format change doesn't silently kill the button
|
||||
r = _get("https://api.jikan.moe/v4/anime/{}".format(mal_id) + "/episodes")
|
||||
return _parse_intros(r.json().get("data", {}).get("episodes", []))
|
||||
d = r.json().get("data")
|
||||
eps = d if isinstance(d, list) else (d or {}).get("episodes", [])
|
||||
return _parse_intros(eps)
|
||||
|
||||
|
||||
def _master_m3u8(ep_id, lang="eng"):
|
||||
|
||||
@@ -312,3 +312,33 @@ def test_parse_intros():
|
||||
None,
|
||||
None,
|
||||
]
|
||||
|
||||
|
||||
def test_intros_parses_jikan_shapes():
|
||||
# _intros against a stubbed HTTP layer: Jikan v4 returns the episode
|
||||
# list directly under 'data' (not {'episodes': [...]}) — a regression
|
||||
# here would silently disable the skip button whenever Jikan is up.
|
||||
import server.upstream as u
|
||||
|
||||
class R:
|
||||
def json(self):
|
||||
return {"data": [
|
||||
{"title": "Episode 1", "intro": {"start": 111, "length": 77}},
|
||||
{"title": "Episode 2", "intro": {"start": 0, "length": 0}},
|
||||
]}
|
||||
|
||||
u._CACHE.clear()
|
||||
u._get = lambda url: R() # stub the network
|
||||
assert u._intros(92573) == [
|
||||
{"start": 111, "length": 77},
|
||||
{"start": 0, "length": 0},
|
||||
]
|
||||
# wrapped shape still works
|
||||
class W:
|
||||
def json(self):
|
||||
return {"data": {"episodes": [
|
||||
{"intro": {"start": 90, "length": 60}},
|
||||
]}}
|
||||
u._get = lambda url: W()
|
||||
assert u._intros(92573)[0]["start"] == 90
|
||||
u._CACHE.clear()
|
||||
Reference in new issue
Block a user