From b2dfde599986ddd76a9917e9d320dd022aaae78d Mon Sep 17 00:00:00 2001 From: jxxghp Date: Fri, 9 Oct 2026 23:54:47 +0800 Subject: [PATCH] fix(bangumi): use HTTPS for calendar covers --- app/modules/bangumi/bangumi.py | 35 ++++++++++++++++++++++++++++++++-- tests/test_bangumi_api.py | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/app/modules/bangumi/bangumi.py b/app/modules/bangumi/bangumi.py index 2ae1350c3..a8eb0e900 100644 --- a/app/modules/bangumi/bangumi.py +++ b/app/modules/bangumi/bangumi.py @@ -204,13 +204,44 @@ class BangumiApi: @staticmethod def _calendar_items(result: Any) -> list[dict[str, Any]]: - """按星期顺序展开每日放送条目。""" - return [ + """按星期顺序展开每日放送条目,并规范化其封面地址。""" + items = [ item for weekday in result or [] if isinstance(weekday, dict) for item in weekday.get("items") or [] ] + normalized_items = [] + for item in items: + if not isinstance(item, dict): + normalized_items.append(item) + continue + normalized_item = dict(item) + images = item.get("images") + if isinstance(images, dict): + normalized_item["images"] = { + size: BangumiApi._normalize_calendar_image_url(url) + for size, url in images.items() + } + if "image" in item: + normalized_item["image"] = BangumiApi._normalize_calendar_image_url( + item["image"] + ) + normalized_items.append(normalized_item) + return normalized_items + + @staticmethod + def _normalize_calendar_image_url(url: Any) -> Any: + """将 Bangumi 日历图片域名返回的 HTTP 地址升级为 HTTPS。""" + if not isinstance(url, str): + return url + try: + parsed = urlsplit(url) + except ValueError: + return url + if parsed.scheme != "http" or parsed.hostname != "lain.bgm.tv": + return url + return parsed._replace(scheme="https").geturl() @staticmethod def _credit_people(result: Any) -> list[dict[str, Any]]: diff --git a/tests/test_bangumi_api.py b/tests/test_bangumi_api.py index b43fdf1c6..efecdf55f 100644 --- a/tests/test_bangumi_api.py +++ b/tests/test_bangumi_api.py @@ -32,3 +32,36 @@ def test_bangumi_api_empty_data_proxy_uses_official_endpoint() -> None: assert api.base_url == "https://api.bgm.tv/" api.close() + + +def test_bangumi_calendar_upgrades_only_lain_http_image_urls_to_https() -> None: + """每日放送封面使用 HTTPS,其他图片与非图片地址保持原样。""" + original_item = { + "id": 646154, + "url": "http://lain.bgm.tv/subject/646154", + "image": "http://lain.bgm.tv/pic/cover/legacy.jpg", + "images": { + "large": "http://lain.bgm.tv/pic/cover/l/89/fc/646154_uQi81.jpg", + "small": "https://lain.bgm.tv/pic/cover/s/646154.jpg", + "common": "http://cdn.example/cover.jpg", + "untrusted": "http://lain.bgm.tv.evil.example/cover.jpg", + }, + } + response = [{"weekday": {"id": 1}, "items": [original_item]}] + + result = BangumiApi._calendar_items(response) + + assert result == [ + { + "id": 646154, + "url": "http://lain.bgm.tv/subject/646154", + "image": "https://lain.bgm.tv/pic/cover/legacy.jpg", + "images": { + "large": "https://lain.bgm.tv/pic/cover/l/89/fc/646154_uQi81.jpg", + "small": "https://lain.bgm.tv/pic/cover/s/646154.jpg", + "common": "http://cdn.example/cover.jpg", + "untrusted": "http://lain.bgm.tv.evil.example/cover.jpg", + }, + } + ] + assert response[0]["items"][0] == original_item