feat(metadata): overview falls back to Chinese variants only (MD-2)
- adapters: overviewLanguages() limits overview/tagline chain to Chinese variants (zh-CN→zh-SG→zh-TW→zh-HK); titles keep full chain; season supplement fetch skips languages useless for overview - setting metadata.overviewNonChineseFallback (default off) + UI switch - media detail shows "暂无简介" for empty entity/episode overview - scripts/overview-recompute.ts: recompute stored non-Chinese overviews from kv_cache only (no TMDB requests), dry-run by default, --apply - tests: chain unit tests, Heart Signal (103147) fixture, server recompute test, MP differential for episode overview - runbook + CHANGELOG Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
081db4651c
commit
f9901b514b
22 files changed
+887
-38
No files matched your search
@@ -147,7 +147,26 @@ export function pickChineseTitle(chain: readonly string[], src: TitleSources): P
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 简介 / 标语:按链取 translations 的非空值;全部落空时用 primary(请求语言下的原值) */
|
||||
/** 语言标签是否中文(zh / zh-CN / zh-TW …) */
|
||||
export const isChineseTag = (tag: string): boolean => splitTag(tag).lang === "zh";
|
||||
|
||||
/**
|
||||
* MD-2 简介 / 标语用的语言链:缺省只回退到中文变体,不回退到非中文(TMDB 上不少剧集没有中文简介,
|
||||
* 英文"简介"常是标题英译,中文界面里显得不对)。规则:
|
||||
* - allowNonChinese = true(设置 metadata.overviewNonChineseFallback):原链不变;
|
||||
* - 链里没有中文:原链不变(用户本来就选了非中文);
|
||||
* - 否则:第一个中文之前的语言(用户排在中文前面、是首选而不是回退)+ 链中的全部中文,之后的非中文去掉。
|
||||
* 缺省链 zh-CN → zh-SG → zh-TW → zh-HK → en-US 得到 zh-CN → zh-SG → zh-TW → zh-HK。
|
||||
* 标题 / 别名不受影响,仍按完整链回退。MP 对照:tmdbapi 每集信息只按配置语言取,简介为空就为空。
|
||||
*/
|
||||
export function overviewLanguages(chain: readonly string[], allowNonChinese = false): string[] {
|
||||
if (allowNonChinese) return [...chain];
|
||||
const firstZh = chain.findIndex(isChineseTag);
|
||||
if (firstZh < 0) return [...chain];
|
||||
return chain.filter((t, i) => i < firstZh || isChineseTag(t));
|
||||
}
|
||||
|
||||
/** 简介 / 标语:按链取 translations 的非空值;全部落空时用 primary(请求语言下的原值,等于链外语言译文时不用) */
|
||||
export function pickText(
|
||||
chain: readonly string[],
|
||||
translations: readonly TmdbTranslation[],
|
||||
@@ -158,7 +177,9 @@ export function pickText(
|
||||
const tr = translations.find((t) => tagMatches(tag, t) && t[key]);
|
||||
if (tr?.[key]) return { value: tr[key]!, language: tag, via: "translation" };
|
||||
}
|
||||
if (primary?.value) return { value: primary.value, language: primary.language, via: "primary" };
|
||||
// 请求语言下的原值若正是链外某语言的译文(TMDB / 反代把缺译名的字段回退成了别的语言),不当作链内的值
|
||||
const foreign = translations.some((t) => t[key] === primary?.value && !chain.some((tag) => tagMatches(tag, t)));
|
||||
if (primary?.value && !foreign) return { value: primary.value, language: primary.language, via: "primary" };
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user