feat(scrape): TMDB 标志写 clearlogo.png
- 富详情请求加 images(include_image_language=zh,en,null),作品原语言不是中英文时另取 /images; 选一张 PNG 标志(原语言 → 中文 → 英文 → 无文字,同语言按评分)存作品字段 logoPath,变化时触发重刮 - 刮削布局新角色 clearlogo:电影写影片目录 clearlogo.png、剧集写剧集根目录,库根 / 平铺电影 <视频名>-clearlogo.png; 覆盖方式与 hash 规则同其它图片 - 布局金样差分登记偏离 tmdb_clearlogo;mock TMDB 支持 logos 与 /images Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
1dca95f883
commit
680419bb64
16 files changed
+379
-12
No files matched your search
@@ -60,6 +60,8 @@ export interface TmdbFixture {
|
||||
genre_ids?: number[];
|
||||
/** 剧集组(`/tv/{id}/episode_groups`、`/tv/episode_group/{id}`);组内集按 TMDB 默认季集号引用 seasons 里的集 */
|
||||
episode_groups?: TmdbFixtureEpisodeGroup[];
|
||||
/** 标志(append_to_response=images 与 `/{type}/{id}/images` 按 include_image_language 过滤);缺省没有 */
|
||||
logos?: { file_path: string; iso_639_1: string | null; vote_average?: number; vote_count?: number }[];
|
||||
}
|
||||
|
||||
export interface TmdbFixtureEpisodeGroup {
|
||||
|
||||
@@ -22,7 +22,7 @@ const notFound: MockReply = {
|
||||
/** 列表接口一页的条数(同 TMDB) */
|
||||
const LIST_PAGE = 20;
|
||||
|
||||
/** mock TMDB v3:/3/trending、/3/discover、电影 / 剧集榜单(按热度,一页 20 条)、/3/search/{movie,tv}、/3/find/:imdbId、/3/{movie,tv}/:id(append_to_response)、/3/tv/:id/season/:n、/3/tv/:id/episode_groups、/3/tv/episode_group/:id */
|
||||
/** mock TMDB v3:/3/trending、/3/discover、电影 / 剧集榜单(按热度,一页 20 条)、/3/search/{movie,tv}、/3/find/:imdbId、/3/{movie,tv}/:id(append_to_response)、/3/{movie,tv}/:id/images、/3/tv/:id/season/:n、/3/tv/:id/episode_groups、/3/tv/episode_group/:id */
|
||||
export async function createMockTmdb(opts: MockTmdbOptions = {}): Promise<MockTmdb> {
|
||||
const fx = opts.fixtures ?? TMDB_FIXTURES;
|
||||
const apiKey = opts.apiKey ?? "test-tmdb-key";
|
||||
@@ -59,6 +59,21 @@ export async function createMockTmdb(opts: MockTmdbOptions = {}): Promise<MockTm
|
||||
};
|
||||
};
|
||||
|
||||
/** images.logos 按 include_image_language(逗号分隔,null = 无文字)过滤;不给参数全给 */
|
||||
const images = (f: TmdbFixture, q: Record<string, string>) => {
|
||||
const langs = q.include_image_language ? q.include_image_language.split(",") : null;
|
||||
const logos = (f.logos ?? [])
|
||||
.filter((l) => !langs || langs.includes(l.iso_639_1 ?? "null"))
|
||||
.map((l) => ({
|
||||
...l,
|
||||
vote_average: l.vote_average ?? 5,
|
||||
vote_count: l.vote_count ?? 1,
|
||||
width: 500,
|
||||
height: 200,
|
||||
}));
|
||||
return { backdrops: [], posters: [], logos };
|
||||
};
|
||||
|
||||
const listItem = (f: TmdbFixture, lang?: string) => ({
|
||||
...brief(f, lang),
|
||||
genre_ids: f.genre_ids ?? [],
|
||||
@@ -222,6 +237,13 @@ export async function createMockTmdb(opts: MockTmdbOptions = {}): Promise<MockTm
|
||||
};
|
||||
},
|
||||
],
|
||||
[
|
||||
/^\/3\/(movie|tv)\/(\d+)\/images$/,
|
||||
(m, q) => {
|
||||
const f = find(m[1]!, m[2]!);
|
||||
return f ? { json: { id: f.id, ...images(f, q) } } : notFound;
|
||||
},
|
||||
],
|
||||
[
|
||||
/^\/3\/tv\/(\d+)\/season\/(\d+)$/,
|
||||
(m, q) => {
|
||||
@@ -298,6 +320,7 @@ export async function createMockTmdb(opts: MockTmdbOptions = {}): Promise<MockTm
|
||||
f.type === "movie" ? { titles: f.alternative_titles } : { results: f.alternative_titles };
|
||||
}
|
||||
if (append.has("external_ids")) out.external_ids = f.external_ids;
|
||||
if (append.has("images")) out.images = images(f, q);
|
||||
if (append.has("translations")) {
|
||||
const key = f.type === "movie" ? "title" : "name";
|
||||
out.translations = {
|
||||
|
||||
Reference in new issue
Block a user