私人影库扫描增加年份辅助扫描

This commit is contained in:
mtvpls
2025-12-25 23:51:18 +08:00
parent 76b3349aa2
commit 5d593bafb2
3 changed files with 41 additions and 8 deletions

View File

@@ -201,18 +201,19 @@ async function performScan(
} }
try { try {
// 解析文件夹名称,提取季度信息 // 解析文件夹名称,提取季度信息和年份
const seasonInfo = parseSeasonFromTitle(folder.name); const seasonInfo = parseSeasonFromTitle(folder.name);
const searchQuery = seasonInfo.cleanTitle || folder.name; const searchQuery = seasonInfo.cleanTitle || folder.name;
console.log(`[OpenList Refresh] 处理文件夹: ${folder.name}`); console.log(`[OpenList Refresh] 处理文件夹: ${folder.name}`);
console.log(`[OpenList Refresh] 清理后标题: ${searchQuery}, 季度: ${seasonInfo.seasonNumber}`); console.log(`[OpenList Refresh] 清理后标题: ${searchQuery}, 季度: ${seasonInfo.seasonNumber}, 年份: ${seasonInfo.year}`);
// 搜索 TMDB使用清理后的标题 // 搜索 TMDB使用清理后的标题和年份
const searchResult = await searchTMDB( const searchResult = await searchTMDB(
tmdbApiKey, tmdbApiKey,
searchQuery, searchQuery,
tmdbProxy tmdbProxy,
seasonInfo.year || undefined
); );
if (searchResult.code === 200 && searchResult.result) { if (searchResult.code === 200 && searchResult.result) {

View File

@@ -4,10 +4,12 @@
*/ */
export interface SeasonInfo { export interface SeasonInfo {
/** 清理后的标题(移除季度标识) */ /** 清理后的标题(移除季度标识和年份 */
cleanTitle: string; cleanTitle: string;
/** 季度编号,如果未识别则为 null */ /** 季度编号,如果未识别则为 null */
seasonNumber: number | null; seasonNumber: number | null;
/** 年份,如果未识别则为 null */
year: number | null;
/** 原始标题 */ /** 原始标题 */
originalTitle: string; originalTitle: string;
} }
@@ -21,11 +23,13 @@ export interface SeasonInfo {
* - 第一季, 第1季, 第01季 * - 第一季, 第1季, 第01季
* - [第一季], [第1季] * - [第一季], [第1季]
* - 第一部, 第1部 * - 第一部, 第1部
* - 年份: 2023, [2023], (2023)
*/ */
export function parseSeasonFromTitle(title: string): SeasonInfo { export function parseSeasonFromTitle(title: string): SeasonInfo {
const originalTitle = title; const originalTitle = title;
let cleanTitle = title; let cleanTitle = title;
let seasonNumber: number | null = null; let seasonNumber: number | null = null;
let year: number | null = null;
// 定义季度匹配模式(按优先级排序) // 定义季度匹配模式(按优先级排序)
const patterns = [ const patterns = [
@@ -88,9 +92,30 @@ export function parseSeasonFromTitle(title: string): SeasonInfo {
} }
} }
// 提取年份(支持多种格式)
const yearPatterns = [
/\[(\d{4})\]/, // [2023]
/\((\d{4})\)/, // (2023)
/\b(\d{4})\b/, // 2023
];
for (const yearPattern of yearPatterns) {
const yearMatch = cleanTitle.match(yearPattern);
if (yearMatch) {
const extractedYear = parseInt(yearMatch[1], 10);
// 验证年份合理性1900-2100
if (extractedYear >= 1900 && extractedYear <= 2100) {
year = extractedYear;
cleanTitle = cleanTitle.replace(yearPattern, '').trim();
break;
}
}
}
// 清理标题:移除空的方括号和多余的空格 // 清理标题:移除空的方括号和多余的空格
cleanTitle = cleanTitle cleanTitle = cleanTitle
.replace(/\[\s*\]/g, '') // 移除空方括号 .replace(/\[\s*\]/g, '') // 移除空方括号
.replace(/\(\s*\)/g, '') // 移除空圆括号
.replace(/\s+/g, ' ') // 合并多个空格 .replace(/\s+/g, ' ') // 合并多个空格
.replace(/[·\-_\s]+$/, '') // 移除末尾的特殊字符 .replace(/[·\-_\s]+$/, '') // 移除末尾的特殊字符
.trim(); .trim();
@@ -98,6 +123,7 @@ export function parseSeasonFromTitle(title: string): SeasonInfo {
return { return {
cleanTitle, cleanTitle,
seasonNumber, seasonNumber,
year,
originalTitle, originalTitle,
}; };
} }

View File

@@ -28,7 +28,8 @@ interface TMDBSearchResponse {
export async function searchTMDB( export async function searchTMDB(
apiKey: string, apiKey: string,
query: string, query: string,
proxy?: string proxy?: string,
year?: number
): Promise<{ code: number; result: TMDBSearchResult | null }> { ): Promise<{ code: number; result: TMDBSearchResult | null }> {
try { try {
if (!apiKey) { if (!apiKey) {
@@ -36,8 +37,13 @@ export async function searchTMDB(
} }
// 使用 multi search 同时搜索电影和电视剧 // 使用 multi search 同时搜索电影和电视剧
const url = `https://api.themoviedb.org/3/search/multi?api_key=${apiKey}&language=zh-CN&query=${encodeURIComponent(query)}&page=1`; let url = `https://api.themoviedb.org/3/search/multi?api_key=${apiKey}&language=zh-CN&query=${encodeURIComponent(query)}&page=1`;
// 如果提供了年份,添加到搜索参数中
if (year) {
url += `&year=${year}`;
}
const fetchOptions: any = proxy const fetchOptions: any = proxy
? { ? {
agent: new HttpsProxyAgent(proxy, { agent: new HttpsProxyAgent(proxy, {