From b794f02733fd1ee137a3d3fe27f8a0aec0737412 Mon Sep 17 00:00:00 2001 From: woleigedouer <38418090+woleigedouer@users.noreply.github.com> Date: Mon, 27 Oct 2025 22:34:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E6=BA=90=E7=B1=BB=E5=9E=8B=E8=AF=86=E5=88=AB=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=8A=A8=E6=BC=AB=E8=AF=AF=E5=88=A4?= =?UTF-8?q?=E4=B8=BA=E7=94=B5=E8=A7=86=E5=89=A7=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20(#77)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- danmu_api/sources/bilibili.js | 43 ++++++++++++++++++++++++++- danmu_api/sources/iqiyi.js | 15 +++++++--- danmu_api/sources/mango.js | 41 ++++++++++++++++++++++++-- danmu_api/sources/youku.js | 55 ++++++++++++++++++++++++++++------- 4 files changed, 137 insertions(+), 17 deletions(-) diff --git a/danmu_api/sources/bilibili.js b/danmu_api/sources/bilibili.js index e60b079..00a9759 100644 --- a/danmu_api/sources/bilibili.js +++ b/danmu_api/sources/bilibili.js @@ -169,7 +169,8 @@ export default class BilibiliSource extends BaseSource { const mediaId = item.season_id ? `ss${item.season_id}` : item.bvid ? `bv${item.bvid}` : ""; if (!mediaId) continue; - const mediaType = item.season_type_name === "电影" ? "电影" : "电视剧"; + // 提取媒体类型(参考 bilibili.py 和优化后的 youku.js) + const mediaType = this._extractMediaType(item.season_type_name); const episodeCount = mediaType === "电影" ? 1 : (item.ep_size || 0); // 提取年份 @@ -217,6 +218,46 @@ export default class BilibiliSource extends BaseSource { } } + /** + * 从 season_type_name 提取媒体类型 + * B站 API 返回的类型包括:电影、番剧、国创、纪录片、综艺、电视剧等 + * @param {string} seasonTypeName - API 返回的 season_type_name + * @returns {string} 标准化的媒体类型 + */ + _extractMediaType(seasonTypeName) { + const typeName = (seasonTypeName || "").toLowerCase(); + + // 电影类型 + if (typeName.includes("电影") || typeName.includes("movie")) { + return "电影"; + } + + // 动漫类型(包括番剧和国创) + if (typeName.includes("番剧") || typeName.includes("国创") || + typeName.includes("动漫") || typeName.includes("anime")) { + return "动漫"; + } + + // 纪录片类型 + if (typeName.includes("纪录片") || typeName.includes("documentary")) { + return "纪录片"; + } + + // 综艺类型 + if (typeName.includes("综艺") || typeName.includes("variety")) { + return "综艺"; + } + + // 电视剧类型 + if (typeName.includes("电视剧") || typeName.includes("剧集") || + typeName.includes("drama") || typeName.includes("tv")) { + return "电视剧"; + } + + // 默认返回电视剧(最常见的类型) + return "电视剧"; + } + async search(keyword) { try { log("info", `[Bilibili] 开始搜索: ${keyword}`); diff --git a/danmu_api/sources/iqiyi.js b/danmu_api/sources/iqiyi.js index 863535b..25e4d1e 100644 --- a/danmu_api/sources/iqiyi.js +++ b/danmu_api/sources/iqiyi.js @@ -140,15 +140,22 @@ export default class IqiyiSource extends BaseSource { return null; } - // 过滤不相关频道 + // 提取媒体类型(参考优化后的 youku.js 和 bilibili.js) const channel = album.channel || ""; - let mediaType = "电视剧"; + let mediaType = "电视剧"; // 默认类型 + if (channel.includes("电影")) { mediaType = "电影"; - } else if (channel.includes("电视剧") || channel.includes("动漫")) { + } else if (channel.includes("动漫")) { + mediaType = "动漫"; + } else if (channel.includes("综艺")) { + mediaType = "综艺"; + } else if (channel.includes("纪录片")) { + mediaType = "纪录片"; + } else if (channel.includes("电视剧")) { mediaType = "电视剧"; } else { - // 只保留电影、电视剧、动漫 + // 只保留支持的类型:电影、电视剧、动漫、综艺、纪录片 return null; } diff --git a/danmu_api/sources/mango.js b/danmu_api/sources/mango.js index 18bfd3c..1f0cb4a 100644 --- a/danmu_api/sources/mango.js +++ b/danmu_api/sources/mango.js @@ -40,6 +40,43 @@ export default class MangoSource extends BaseSource { return Math.floor((leftColor + rightColor) / 2); } + /** + * 从类型字符串中提取标准化的媒体类型 + * @param {string} typeStr - API 返回的类型字符串 + * @returns {string} 标准化的媒体类型 + */ + _extractMediaType(typeStr) { + const type = (typeStr || "").toLowerCase(); + + // 电影类型 + if (type.includes("电影") || type.includes("movie")) { + return "电影"; + } + + // 动漫类型 + if (type.includes("动漫") || type.includes("动画") || type.includes("anime")) { + return "动漫"; + } + + // 综艺类型 + if (type.includes("综艺") || type.includes("真人秀") || type.includes("variety")) { + return "综艺"; + } + + // 纪录片类型 + if (type.includes("纪录片") || type.includes("documentary")) { + return "纪录片"; + } + + // 电视剧类型 + if (type.includes("电视剧") || type.includes("剧集") || type.includes("drama") || type.includes("tv")) { + return "电视剧"; + } + + // 默认返回电视剧(最常见的类型) + return "电视剧"; + } + async search(keyword) { try { log("info", `[Mango] 开始搜索: ${keyword}`); @@ -95,9 +132,9 @@ export default class MangoSource extends BaseSource { const yearMatch = item.desc && item.desc[0] ? item.desc[0].match(/[12][890][0-9][0-9]/) : null; const year = yearMatch ? parseInt(yearMatch[0]) : null; - // 提取类型 + // 提取媒体类型(参考优化后的 youku.js 和 bilibili.js) const typeMatch = item.desc && item.desc[0] ? item.desc[0].split('/')[0].replace("类型:", "").trim() : ''; - const mediaType = typeMatch === "电影" ? "电影" : "电视剧"; + const mediaType = this._extractMediaType(typeMatch); results.push({ provider: "imgo", diff --git a/danmu_api/sources/youku.js b/danmu_api/sources/youku.js index 92581c7..e874bbc 100644 --- a/danmu_api/sources/youku.js +++ b/danmu_api/sources/youku.js @@ -55,8 +55,31 @@ export default class YoukuSource extends BaseSource { // 清理标题 (移除HTML标签和特殊符号) let cleanedTitle = title.replace(/<[^>]+>/g, '').replace(/【.+?】/g, '').trim().replace(/:/g, ':'); - // 提取媒体类型 - const mediaType = commonData.feature.includes("电影") ? "电影" : "电视剧"; + // 提取媒体类型(参考 Python 版本的 _extract_media_type_from_response) + let mediaType = "电视剧"; // 默认类型 + const cats = (commonData.cats || "").toLowerCase(); + const feature = (commonData.feature || "").toLowerCase(); + + // 优先使用 cats 字段 + if (cats.includes("动漫") || cats.includes("anime")) { + mediaType = "动漫"; + } else if (cats.includes("电影") || cats.includes("movie")) { + mediaType = "电影"; + } else if (cats.includes("电视剧") || cats.includes("drama")) { + mediaType = "电视剧"; + } else if (cats.includes("综艺") || cats.includes("variety")) { + mediaType = "综艺"; + } + // 备用:从 feature 字段提取 + else if (feature.includes("动漫")) { + mediaType = "动漫"; + } else if (feature.includes("电影")) { + mediaType = "电影"; + } else if (feature.includes("电视剧")) { + mediaType = "电视剧"; + } else if (feature.includes("综艺")) { + mediaType = "综艺"; + } return { provider: "youku", @@ -323,27 +346,39 @@ export default class YoukuSource extends BaseSource { } /** - * 从分类信息中提取媒体类型 + * 从分类信息中提取媒体类型(参考 Python 版本的 _extract_media_type_from_response) * @param {string} cats - 分类字符串 * @param {string} feature - 特征字符串 - * @returns {string} 媒体类型 + * @returns {string} 媒体类型 (variety/movie/anime/drama) */ _extractMediaType(cats, feature) { const catsLower = (cats || '').toLowerCase(); const featureLower = (feature || '').toLowerCase(); - if (catsLower.includes('综艺') || catsLower.includes('variety') || featureLower.includes('综艺')) { + // 优先使用 cats 字段 + if (catsLower.includes('综艺') || catsLower.includes('variety')) { return 'variety'; - } else if (catsLower.includes('电影') || catsLower.includes('movie') || featureLower.includes('电影')) { + } else if (catsLower.includes('电影') || catsLower.includes('movie')) { return 'movie'; - } else if (catsLower.includes('动漫') || catsLower.includes('anime') || featureLower.includes('动漫')) { + } else if (catsLower.includes('动漫') || catsLower.includes('anime')) { return 'anime'; - } else if (catsLower.includes('电视剧') || catsLower.includes('drama') || featureLower.includes('电视剧')) { + } else if (catsLower.includes('电视剧') || catsLower.includes('drama')) { + return 'drama'; + } + + // 备用:从 feature 字段提取 + if (featureLower.includes('综艺')) { + return 'variety'; + } else if (featureLower.includes('电影')) { + return 'movie'; + } else if (featureLower.includes('动漫')) { + return 'anime'; + } else if (featureLower.includes('电视剧')) { return 'drama'; } - // 默认返回综艺 - return 'variety'; + // 默认返回电视剧类型 + return 'drama'; } async getEpisodeDanmu(id) {