feat(tmdb): 多语言保留规则——译名 / 别名只留简繁中文、英文与原语言
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
69d820a6bf
commit
9c5f04b02f
8 files changed
+423
-29
No files matched your search
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
import { redactUrl } from "@umt/contracts";
|
||||
import { RequestLimiter, TtlLruCache } from "./cache.ts";
|
||||
import { allowedLanguage, altTitleLanguage, isAllowedLanguage } from "./language-policy.ts";
|
||||
|
||||
export type TmdbErrorKind = "auth" | "network" | "timeout" | "notfound" | "rate" | "protocol";
|
||||
|
||||
@@ -27,7 +28,7 @@ export type MediaEntityType = "movie" | "tv";
|
||||
|
||||
export interface CandidateTitle {
|
||||
text: string;
|
||||
/** BCP47,如 zh-CN;原名为原始语言;别名为 null */
|
||||
/** BCP47,如 zh-CN;原名为原始语言;别名为按地区 + 文字推断的语言(language-policy altTitleLanguage) */
|
||||
lang: string | null;
|
||||
kind: "localized" | "original" | "alias" | "translation";
|
||||
/** 别名/翻译的地区(iso_3166_1) */
|
||||
@@ -395,9 +396,13 @@ export class TmdbClient {
|
||||
),
|
||||
);
|
||||
const c = this.fromBrief(type, first!.j, first!.lang);
|
||||
// 多语言保留规则(language-policy.ts):本地化名 / 译名只留简中 / 繁中 / 英文 / 原语言;别名按地区 + 文字推断语言,
|
||||
// 推断不出的不要。MP __get_names 把全部别名与译名都计入可匹配名称,这里收窄(用户规则 2026-10-06)
|
||||
const work = { originalLanguage: c.originalLanguage, originCountry: c.originCountry };
|
||||
c.titles = c.titles.filter((t) => t.kind !== "localized" || isAllowedLanguage(t.lang, work));
|
||||
for (const { lang, j } of rest) {
|
||||
const t = s(type === "movie" ? j.title : j.name);
|
||||
if (t) TmdbClient.mergeTitle(c, { text: t, lang, kind: "localized" });
|
||||
if (t && isAllowedLanguage(lang, work)) TmdbClient.mergeTitle(c, { text: t, lang, kind: "localized" });
|
||||
}
|
||||
const alt = first!.j.alternative_titles as Json | undefined;
|
||||
const altList = ((type === "movie" ? alt?.titles : alt?.results) ?? []) as Json[];
|
||||
@@ -405,25 +410,24 @@ export class TmdbClient {
|
||||
for (const a of altList) {
|
||||
const text = s(a.title);
|
||||
if (!text) continue;
|
||||
aliases.add(text);
|
||||
const region = s(a.iso_3166_1);
|
||||
c.titles.push({ text, lang: null, kind: "alias", ...(region ? { region } : {}) });
|
||||
const lang = altTitleLanguage({ title: text, region, type: s(a.type) }, work);
|
||||
if (!lang) continue;
|
||||
aliases.add(text);
|
||||
c.titles.push({ text, lang, kind: "alias", ...(region ? { region } : {}) });
|
||||
}
|
||||
// translations:MP __get_names 同样把各语言译名计入可匹配名称
|
||||
// translations:MP __get_names 同样把各语言译名计入可匹配名称(这里只留保留语言)
|
||||
const trs = (((first!.j.translations as Json | undefined)?.translations ?? []) as Json[]).filter(Boolean);
|
||||
for (const tr of trs) {
|
||||
const data = tr.data as Json | undefined;
|
||||
const text = s(type === "movie" ? data?.title : data?.name);
|
||||
if (!text) continue;
|
||||
aliases.add(text);
|
||||
const l = s(tr.iso_639_1);
|
||||
const region = s(tr.iso_3166_1);
|
||||
TmdbClient.mergeTitle(c, {
|
||||
text,
|
||||
lang: l ? (region ? `${l}-${region}` : l) : null,
|
||||
kind: "translation",
|
||||
...(region ? { region } : {}),
|
||||
});
|
||||
const lang = allowedLanguage(l ? (region ? `${l}-${region}` : l) : null, work);
|
||||
if (!lang) continue;
|
||||
aliases.add(text);
|
||||
TmdbClient.mergeTitle(c, { text, lang, kind: "translation", ...(region ? { region } : {}) });
|
||||
}
|
||||
c.aliases = [...aliases];
|
||||
const ext = first!.j.external_ids as Json | undefined;
|
||||
|
||||
Reference in new issue
Block a user