Files
MusicServer/app/sdk/platforms/bd/music_search.py
T
snowy-yang dfc06bf4de feat(python): 完成 Python 全量迁移——剩余平台、登录通道与公共层修复
- 新增 5sing/apple/xm/me/qt/lr 平台包与取流实现(含 xm-sign、MissEvan 签名、蜻蜓 HMAC、Apple developer token)
- 新增 wy/kg/tx/lr 登录:扫码、手机号、账密(kg 20028 风控指纹)、cookie 绑定、kg/tx 续期
- request 层:保留多值 Set-Cookie;JSON body 紧凑化(修复 kg 网关验签);直连不经系统代理(对齐 Node)
- 登录路由统一 Body(embed=True),修复扫码轮询 422;lifespan 接入登录续期调度
- ruff/format/pyright 全绿;14 平台真实联网与 HTTP 路由验证通过
2026-10-23 21:55:45 +08:00

42 lines
2.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""千千音乐搜索(对应 sdk/bd/musicSearch.ts)。
`/v1/search?word=&type=1&pageNo=&pageSize=`,appid + 签名。
响应 `data.typeTrack[]`:TSID/title/albumTitle/albumAssetCode/pic/duration/artist/rateFileInfo/isVip。
注:上游会跳过 isVip != 0 的曲目(VIP 无法匿名取流);本实现保留并标记 payPlay,
以便聚合搜索/顺播时仍能展示(取流失败会返回明确错误,路由可走兜底链路)。
"""
from __future__ import annotations
import math
from typing import Any
from app.sdk.platforms.bd.util import APP_ID, api_get, api_ok, error_text, map_track, to_int, to_number
async def search(keyword: str, page: int = 1, limit: int = 20, retry_num: int = 0) -> dict[str, Any]:
word = str(keyword if keyword is not None else "").strip()
if not word:
return {"list": [], "allPage": 1, "total": 0, "limit": limit, "source": "bd"}
body = await api_get(
"/v1/search",
{"word": word, "type": "1", "pageNo": str(page), "pageSize": str(limit), "appid": APP_ID},
)
# 23001 = 服务端不认该搜索类型/关键词,与原文一致:按空结果处理而不是报错
if not api_ok(body) and to_number(body.get("errno") if isinstance(body, dict) else None) != 23001:
raise RuntimeError(error_text(body, "千千搜索失败"))
data = (body.get("data") if isinstance(body, dict) else None) or {}
tracks = data.get("typeTrack") if isinstance(data, dict) else None
raw = tracks if isinstance(tracks, list) else []
total = to_int(data.get("total") if isinstance(data, dict) else None, len(raw))
have_more = to_number(data.get("haveMore") if isinstance(data, dict) else None) == 1
songs = [song for song in (map_track(item) for item in raw) if song["songmid"]]
page_size = max(1, limit)
all_page = page + 1 if have_more else max(page, math.ceil(total / page_size) or 1)
return {"list": songs, "allPage": all_page, "total": total, "limit": limit, "source": "bd"}