mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-14 02:05:13 +08:00
fix(music): default Douban explore to categories
This commit is contained in:
@@ -29,7 +29,7 @@ MusicExploreSourceParam = Annotated[
|
||||
str,
|
||||
Query(pattern="^(musicbrainz|doubanmusic)$"),
|
||||
]
|
||||
MusicModeParam = Annotated[str, Query(pattern="^(chart|fresh|tag)$")]
|
||||
MusicModeParam = Annotated[str, Query(pattern="^(chart|fresh)$")]
|
||||
MusicEntityParam = Annotated[str, Query(pattern="^(recording|album)$")]
|
||||
MusicRangeParam = Annotated[str, Query(pattern=f"^({'|'.join(LISTENBRAINZ_CHART_RANGES)})$")]
|
||||
MusicSortParam = Annotated[str, Query(pattern="^listen_count\\.(desc|asc)$")]
|
||||
@@ -153,7 +153,7 @@ async def explore_music(
|
||||
douban_sort: DoubanMusicSortParam = "U",
|
||||
_: schemas.TokenPayload = Depends(verify_token),
|
||||
) -> list[schemas.MusicInfo]:
|
||||
"""按音乐来源返回可订阅的榜单或新发行候选。"""
|
||||
"""MusicBrainz 返回榜单或新发行,豆瓣音乐固定按官方标签分类浏览。"""
|
||||
chain = MusicChain()
|
||||
if media_source != "musicbrainz":
|
||||
results = await chain.async_discover(
|
||||
@@ -161,7 +161,7 @@ async def explore_music(
|
||||
page=page,
|
||||
count=count,
|
||||
entity=entity,
|
||||
mode=mode,
|
||||
mode="tag",
|
||||
tags=tags,
|
||||
sort=douban_sort,
|
||||
)
|
||||
|
||||
@@ -194,18 +194,16 @@ AniList 榜单、探索、详情、人物和推荐接口优先通过 `anilist-ch
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
| :--- | :--- | :--- |
|
||||
| GET | `/api/v1/media/search` | 当 `type=music` 或 `source=musicbrainz` 时按歌曲、专辑或歌手关键词搜索音乐元数据,参数:`title`、`type`、`count` |
|
||||
| POST | `/api/v1/music/recognize` | 按 `source` + `media_id` 识别音乐详情,请求体:`MusicRecognizeRequest` |
|
||||
| GET | `/api/v1/music/explore` | 按来源浏览音乐;`source=musicbrainz` 支持热门榜单与新发行,`source=theaudiodb` 支持国家/地区趋势专辑或单曲,`source=doubanmusic` 支持豆瓣音乐推荐。参数:`source`、`mode=chart|fresh`、`entity=recording|album`、`country`、`range_name`、`sort_by`、`sort`、`days`、`past`、`future`、`min_listen_count`、`with_cover`、`page`、`count` |
|
||||
| GET | `/api/v1/music/album/{album_id}` | 按来源专辑 ID 查询专辑详情、完整曲目和发行版本,参数:`source` |
|
||||
| GET | `/api/v1/music/album/{album_id}/related` | 按来源查询关联专辑,参数:`source`、`count` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}` | 查询艺术家详情;艺术家为只读浏览实体,参数:`source` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}/albums` | 分页查询艺术家的专辑、EP 和单曲,参数:`source`、`page`、`count`、`album_type` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}/related` | 查询关联艺术家,参数:`source`、`count` |
|
||||
| GET | `/api/v1/media/search` | 当 `type=music` 或指定音乐 `media_source` 时按歌曲、专辑或歌手关键词搜索音乐元数据,参数:`title`、`type`、`count`、`media_source` |
|
||||
| POST | `/api/v1/music/recognize` | 按 `media_source` + `media_id` 识别音乐详情,请求体:`MusicRecognizeRequest` |
|
||||
| GET | `/api/v1/music/explore` | 按来源浏览音乐;`media_source=musicbrainz` 支持 `mode=chart|fresh` 榜单与新发行,`media_source=doubanmusic` 固定按官方标签分类浏览,使用 `tags` 和 `douban_sort=U|S|R|O` 筛选。其它参数:`entity=recording|album`、`range_name`、`sort_by`、`sort`、`days`、`past`、`future`、`min_listen_count`、`with_cover`、`page`、`count` |
|
||||
| GET | `/api/v1/music/album/{album_id}` | 按来源专辑 ID 查询专辑详情、完整曲目和发行版本,参数:`media_source` |
|
||||
| GET | `/api/v1/music/album/{album_id}/related` | 按来源查询关联专辑,参数:`media_source`、`count` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}` | 查询艺术家详情;艺术家为只读浏览实体,参数:`media_source` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}/albums` | 分页查询艺术家的专辑、EP 和单曲,参数:`media_source`、`page`、`count`、`album_type` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}/related` | 查询关联艺术家,参数:`media_source`、`count` |
|
||||
| GET | `/api/v1/recommend/music_weekly` | 浏览本周热门音乐,参数:`page`、`count` |
|
||||
| GET | `/api/v1/recommend/music_theaudiodb_albums` | 浏览 TheAudioDB 热门专辑,参数:`country`、`page`、`count` |
|
||||
| GET | `/api/v1/recommend/music_theaudiodb_tracks` | 浏览 TheAudioDB 热门单曲,参数:`country`、`page`、`count` |
|
||||
| GET | `/api/v1/recommend/music_douban` | 浏览豆瓣音乐推荐,参数:`page`、`count` |
|
||||
| GET | `/api/v1/recommend/music_douban` | 浏览豆瓣音乐新碟榜,参数:`page`、`count` |
|
||||
|
||||
专辑下载与订阅按“整包”处理:下载层会读取种子文件清单并以专辑 `total_tracks` 校验独立音频文件数量;未确认完整覆盖时不会把专辑订阅销订,也不会把部分曲目报告为完整专辑已入库。音乐刮削遵循 `music` 的标签、封面和歌词策略,歌词通过带有界 TTL/LRU 缓存的 LRCLIB 模块保存为同名 `.lrc` 或 `.txt` 旁挂文件。
|
||||
|
||||
|
||||
@@ -187,18 +187,18 @@ music on configured music-capable media servers; it does not manage playlists.
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/v1/media/search` | Search tracks, albums, or artists with `type=music` or `source=musicbrainz`. Params: `title`, `type`, `count` |
|
||||
| POST | `/api/v1/music/recognize` | Resolve music metadata. Body: `source`, `media_id` |
|
||||
| GET | `/api/v1/music/explore` | Explore music by `source`: MusicBrainz charts/fresh releases, TheAudioDB country trends, or Douban music recommendations. Params: `source`, `mode`, `entity`, `country`, `range_name`, `sort_by`, `sort`, `days`, `past`, `future`, `min_listen_count`, `with_cover`, `page`, `count` |
|
||||
| GET | `/api/v1/music/album/{album_id}` | Album detail with tracks and releases. Params: `source` |
|
||||
| GET | `/api/v1/music/album/{album_id}/related` | Related albums for the selected source. Params: `source`, `count` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}` | Browse artist detail. Params: `source` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}/albums` | Browse artist albums/EPs/singles. Params: `source`, `page`, `count`, `album_type` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}/related` | Browse related artists. Params: `source`, `count` |
|
||||
| GET | `/api/v1/media/search` | Search tracks, albums, or artists with `type=music` or a music `media_source`. Params: `title`, `type`, `count`, `media_source` |
|
||||
| POST | `/api/v1/music/recognize` | Resolve music metadata. Body: `media_source`, `media_id` |
|
||||
| GET | `/api/v1/music/explore` | Explore by `media_source`: MusicBrainz supports `mode=chart|fresh`; Douban Music always uses official tag categories with `tags` and `douban_sort=U|S|R|O`. Other params: `entity`, `range_name`, `sort_by`, `sort`, `days`, `past`, `future`, `min_listen_count`, `with_cover`, `page`, `count` |
|
||||
| GET | `/api/v1/music/album/{album_id}` | Album detail with tracks and releases. Params: `media_source` |
|
||||
| GET | `/api/v1/music/album/{album_id}/related` | Related albums for the selected source. Params: `media_source`, `count` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}` | Browse artist detail. Params: `media_source` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}/albums` | Browse artist albums/EPs/singles. Params: `media_source`, `page`, `count`, `album_type` |
|
||||
| GET | `/api/v1/music/artist/{artist_id}/related` | Browse related artists. Params: `media_source`, `count` |
|
||||
|
||||
Music acquisition rules:
|
||||
|
||||
- Reuse `source`, `media_id`, and `music_type` from search/detail results. Never substitute a same-name entity.
|
||||
- Reuse `media_source`, `media_id`, and `music_type` from search/detail results. Never substitute a same-name entity.
|
||||
- Subscribe/download one recording as one track. Subscribe/download one album as a complete multi-track pack.
|
||||
- Album torrent validation compares supported audio files with `total_tracks`; incomplete resources do not complete the subscription.
|
||||
- Artist IDs are never subscription, torrent, download, transfer, or library-existence targets.
|
||||
@@ -474,9 +474,7 @@ Streaming search sends `{"type":"heartbeat"}` every 15 seconds without business
|
||||
| GET | `/api/v1/recommend/source` | Recommendation data sources |
|
||||
| GET | `/api/v1/recommend/bangumi_calendar` | Bangumi daily schedule. Params: `page`, `count` |
|
||||
| GET | `/api/v1/recommend/music_weekly` | ListenBrainz weekly site-wide music chart. Params: `page`, `count` |
|
||||
| GET | `/api/v1/recommend/music_theaudiodb_albums` | TheAudioDB trending albums. Params: `country`, `page`, `count` |
|
||||
| GET | `/api/v1/recommend/music_theaudiodb_tracks` | TheAudioDB trending tracks. Params: `country`, `page`, `count` |
|
||||
| GET | `/api/v1/recommend/music_douban` | Douban music recommendations. Params: `page`, `count` |
|
||||
| GET | `/api/v1/recommend/music_douban` | Douban new album chart. Params: `page`, `count` |
|
||||
| GET | `/api/v1/recommend/douban_showing` | Douban now showing. Params: `page`, `count` |
|
||||
| GET | `/api/v1/recommend/douban_movies` | Douban movies. Params: `sort`, `tags`, `page`, `count` |
|
||||
| GET | `/api/v1/recommend/douban_tvs` | Douban TV. Params: `sort`, `tags`, `page`, `count` |
|
||||
|
||||
@@ -258,8 +258,8 @@ def test_explore_music_supports_official_fresh_release_mode():
|
||||
)
|
||||
|
||||
|
||||
def test_explore_music_forwards_douban_music_source():
|
||||
"""豆瓣音乐探索应走可扩展发现链而不是 ListenBrainz。"""
|
||||
def test_explore_music_forces_douban_music_to_tag_browsing():
|
||||
"""豆瓣音乐探索即使收到榜单模式也应固定分类浏览,不与推荐页重复。"""
|
||||
chain = Mock()
|
||||
chain.async_discover = AsyncMock(
|
||||
return_value=[
|
||||
@@ -277,7 +277,7 @@ def test_explore_music_forwards_douban_music_source():
|
||||
explore_music(
|
||||
media_source="doubanmusic",
|
||||
entity="album",
|
||||
mode="tag",
|
||||
mode="chart",
|
||||
tags="流行,华语",
|
||||
douban_sort="S",
|
||||
page=2,
|
||||
|
||||
Reference in New Issue
Block a user