141 lines
3.6 KiB
C#
141 lines
3.6 KiB
C#
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<string, SearchTv> _cache = new();
|
||
|
||
private TMDbClient _client;
|
||
|
||
private async Task<SearchTv> 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<TMDBConfig>().ApiKey;
|
||
var proxy = configs.Get<ProxyConfig>().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<bool> 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;
|
||
}
|
||
} |