using System.Collections.Generic; using System.Linq; using System.Net; using System.Text.RegularExpressions; using System.Threading.Tasks; using Godot; using Learn.Config; using Learn.Models; using Learn.Utils; using TMDbLib.Client; using TMDbLib.Objects.Search; namespace Learn.Parsers; public class TMDBParser(Configs configs) : ItemParser { private readonly Dictionary _cache = new(); private TMDbClient _client; private async Task QueryTMDB(string title) { if (string.IsNullOrEmpty(title)) return null; if (_cache.TryGetValue(title, out var result)) { return result; } var results = (await GetTMDbClient().SearchTvShowAsync(title, language: "zh-CN")).Results; result = results.FirstOrDefault(); _cache[title] = result; return result; } private TMDbClient GetTMDbClient() { if (_client != null) return _client; var apiKey = configs.Get().ApiKey; var proxy = configs.Get().HttpProxy; if (string.IsNullOrEmpty(proxy)) { _client = new TMDbClient(apiKey); } else { _client = new TMDbClient(apiKey , proxy: new WebProxy(proxy)); } return _client; } private string ParseSeason(string season) { if (int.TryParse(season, out _)) return season; switch (season) { case "零": return "0"; case "一": return "1"; case "二": return "2"; case "三": return "3"; case "四": return "4"; case "五": return "5"; case "六": return "6"; case "七": return "7"; case "八": return "8"; case "九": return "9"; } return season; } private bool DoRawParse(TreeNode node) { var item = node.Info; var name = item.Name(); var matches = Regex.Matches(name, @"[^\[\]_]+").Select(match => match.Value).ToArray(); if (matches.Length == 0) return false; if (matches.Length == 1) { node.Info.SetRawTitleIfNotExist(matches[0]); return true; } if (matches.Length >= 2) { node.Info.SetGroupIfNotExist(matches[0]); var title = matches[1].Trim(); var match = Regex.Match(title, "(.+)第(.+)季"); if (match.Success) { node.Info.SetSeasonIfNotExist(ParseSeason(match.Groups[2].Value.Trim())); node.Info.SetRawTitleIfNotExist(match.Groups[1].Value.Trim()); } else { node.Info.SetRawTitleIfNotExist(title); } } return true; } public async Task DoParse(TreeNode node) { if (!node.TryGetValue(ItemFields.Key_RawTitle, out var rawTitle, out _)) { if (!DoRawParse(node)) { return false; } node.TryGetValue(ItemFields.Key_RawTitle, out rawTitle, out _); } if (string.IsNullOrEmpty(rawTitle)) { return false; } var result = await QueryTMDB(rawTitle); if (result == null) { GD.PrintErr($"找不到对应的TV:{rawTitle}"); return false; } if (result.FirstAirDate != null) { node.Info.SetYear(result.FirstAirDate.Value.Year); } node.Info.SetTitleIfNotExist(result.Name); return true; } }