Files
NasRobot/src/Service/Jobs/ChineseNfoRegistry.cs
孙诚 d379f516c5
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 9s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
更新 ChineseNfoRegistry 类,增强日志记录以反映季号和集号的比较结果,改进路径和参数验证逻辑。
2025-04-21 17:27:19 +08:00

1021 lines
34 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Net;
using System.Text.RegularExpressions;
using System.Xml;
using FluentScheduler;
using FreeSql;
using FreeSql.DataAnnotations;
using Interface.Jobs;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
namespace Service.Jobs;
public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
{
private readonly HttpClient _apiClient;
private readonly HttpClient _imageClient;
private readonly IConfiguration _configuration;
private readonly ILogger<ChineseNfoRegistry> _logger;
private readonly IFreeSql _freeSql;
public ChineseNfoRegistry(IConfiguration configuration, ILogger<ChineseNfoRegistry> logger)
{
_configuration = configuration;
_logger = logger;
var httpClientHandler = new HttpClientHandler();
var proxyAddress = _configuration["ChineseNfo:HttpProxy"];
if (string.IsNullOrEmpty(proxyAddress) == false)
{
httpClientHandler.Proxy = string.IsNullOrEmpty(proxyAddress) ? null : new WebProxy(proxyAddress, false);
httpClientHandler.UseProxy = !string.IsNullOrEmpty(proxyAddress);
}
_apiClient = new HttpClient(httpClientHandler);
_apiClient.BaseAddress = new Uri("http://api.themoviedb.org");
_imageClient = new HttpClient(httpClientHandler);
_imageClient.BaseAddress = new Uri("http://image.tmdb.org");
_freeSql = new FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Sqlite, _configuration["ChineseNfo:ConnectionString"])
.UseAutoSyncStructure(true)
.Build();
Schedule(() => Job(ignoreLocked: true, ignoreCompleted: true)).ToRunEvery(1).Days();
}
public async void Job(
string? path = null,
string? seasonNumber = null,
string? episodeNumber = null,
bool ignoreLocked = false,
bool ignoreCompleted = false
)
{
try
{
await JobExecute(path, seasonNumber, episodeNumber, ignoreLocked, ignoreCompleted);
}
catch (Exception e)
{
_logger.LogError(e, "ChineseNfoRegistry.Job() error");
}
}
private async Task JobExecute(
string? requestPath = null,
string? requestSeasonNumber = null,
string? requestEpisodeNumber = null,
bool ignoreLocked = false,
bool ignoreCompleted = false)
{
var tvFolder = _configuration["ChineseNfo:TvFolder"];
if (string.IsNullOrEmpty(tvFolder))
{
_logger.LogError("ChineseNfoRegistry.Job() tvFolder is null or empty");
return;
}
/*
* 2. 接口数据保留
* 3. 支持语言降级到繁体
* 4. 支持演员名称翻译
*/
var tvNfos = Directory.GetFiles(tvFolder, "tvshow.nfo", SearchOption.AllDirectories);
if (tvNfos.Length == 0)
{
_logger.LogError("ChineseNfoRegistry.Job() tvNfo is null or empty");
return;
}
foreach (var tv in tvNfos)
{
if (!string.IsNullOrEmpty(requestPath))
{
var latestPath = Path.GetFileName(requestPath) ?? string.Empty;
if (!tv.Contains(latestPath))
{
continue;
}
else
{
_logger.LogInformation("ChineseNfoRegistry.Job() tv is contains path");
}
}
try
{
await HandleTv(tv);
}
catch (Exception e)
{
_logger.LogError(e, "ChineseNfoRegistry.Job() HandleTv() error");
}
var seasonNfos = Directory.GetFiles(Path.GetDirectoryName(tv) ?? string.Empty, "season.nfo", SearchOption.AllDirectories);
// 如果seasonNfos为空则创建
if (seasonNfos.Length == 0)
{
var sseasons = Directory.GetDirectories(Path.GetDirectoryName(tv) ?? string.Empty, "Season *", SearchOption.AllDirectories);
var sseasonsNumbers = sseasons.Select(x => x.Split("Season ", StringSplitOptions.None)[1]).Select(int.Parse).ToList();
foreach (var seasonNumber in sseasonsNumbers)
{
var seasonNfo = Path.Combine(Path.GetDirectoryName(tv) ?? string.Empty,$"Season {seasonNumber}", "season.nfo");
await File.WriteAllTextAsync(seasonNfo, string.Format(
"""
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<season>
<plot></plot>
<outline></outline>
<lockdata></lockdata>
<seasonnumber>{0}</seasonnumber>
</season>
"""
, seasonNumber)
);
seasonNfos = seasonNfos.Append(seasonNfo).ToArray();
}
}
foreach (var season in seasonNfos)
{
var seasonNumber = Path.GetFileName(season).Split("Season ", StringSplitOptions.None)[1];
try
{
if (!string.IsNullOrEmpty(requestSeasonNumber))
{
if (seasonNumber != requestSeasonNumber)
{
continue;
}
else
{
_logger.LogInformation("ChineseNfoRegistry.Job() seasonNumber is equal");
}
}
await HandleSeason(tv, season);
}
catch (Exception e)
{
_logger.LogError(e, "ChineseNfoRegistry.Job() HandleSeason() error");
}
var episodeNfos = Directory
.GetFiles(Path.GetDirectoryName(season) ?? string.Empty, "*.nfo", SearchOption.AllDirectories)
.Where(x => !x.EndsWith("season.nfo"))
.ToList();
foreach (var episode in episodeNfos)
{
try
{
var split = $"S{(seasonNumber.Length == 1 ? $"0{seasonNumber}" : seasonNumber)}E";
var episodeNumber = Path.GetFileName(episode)
.Split(split, StringSplitOptions.None)[1]
.Split(" - ", StringSplitOptions.None)[0];
if (!string.IsNullOrEmpty(requestEpisodeNumber))
{
if (episodeNumber != requestEpisodeNumber)
{
continue;
}
else
{
_logger.LogInformation("ChineseNfoRegistry.Job() episodeNumber is equal");
}
}
await HandleEpisode(tv, season, episode);
}
catch (Exception e)
{
_logger.LogError(e, "ChineseNfoRegistry.Job() episodeNfo is null or empty");
}
}
}
}
async Task HandleTv(string tvNfo)
{
var nfoContent = File.ReadAllText(tvNfo);
var tvXml = new XmlDocument();
tvXml.LoadXml(nfoContent);
var isLockedNode = tvXml.SelectSingleNode("//locked");
if (isLockedNode != null && isLockedNode.InnerText == "true" && ignoreLocked)
{
_logger.LogInformation("ChineseNfoRegistry.Job() tvNfo is locked");
return;
}
var isCompletedNode = tvXml.SelectSingleNode("//completed");
if (isCompletedNode != null && isCompletedNode.InnerText == "true" && ignoreCompleted)
{
_logger.LogInformation("ChineseNfoRegistry.Job() tvNfo is completed");
return;
}
var uniqueIdNode = tvXml.SelectSingleNode("//uniqueid[@type='tmdb']");
if (uniqueIdNode == null)
{
_logger.LogError("ChineseNfoRegistry.Job() uniqueIdNode is null");
return;
}
if (!int.TryParse(uniqueIdNode.InnerText, out var tmdbId))
{
_logger.LogError("ChineseNfoRegistry.Job() tmdbId is null");
return;
}
var tvInfo = await GetTmdbTv(tvNfo, tmdbId);
if (tvInfo == null)
{
_logger.LogError("ChineseNfoRegistry.Job() tvInfo is null");
return;
}
if (tvInfo["name"] != null)
{
var titleNode = tvXml.SelectSingleNode("//title");
if (titleNode != null)
{
titleNode.InnerXml = $"<![CDATA[{tvInfo["name"]}]]>";
}
var sorttitleNode = tvXml.SelectSingleNode("//sorttitle");
if (sorttitleNode != null)
{
sorttitleNode.InnerXml = $"<![CDATA[{tvInfo["name"]}]]>";
}
_logger.LogInformation("ChineseNfoRegistry.Job() tvInfo: {tvInfo}", tvInfo["name"]);
}
if (tvInfo["overview"] != null)
{
var plotNode = tvXml.SelectSingleNode("//plot");
if (plotNode != null)
{
plotNode.InnerXml = $"<![CDATA[{tvInfo["overview"]}]]>";
}
var outlineNode = tvXml.SelectSingleNode("//outline");
if (outlineNode != null)
{
outlineNode.InnerXml = $"<![CDATA[{tvInfo["overview"]}]]>";
}
_logger.LogInformation("ChineseNfoRegistry.Job() tvInfo: {tvInfo}", tvInfo["overview"]);
}
if (tvInfo["poster_path"] != null)
{
var posterPath = tvInfo["poster_path"]!.ToString();
var image = await GetTmdbImage(tvNfo, posterPath);
if (image != null)
{
var imagePath = Path.Combine(Path.GetDirectoryName(tvNfo) ?? string.Empty, "poster" + Path.GetExtension(posterPath));
await File.WriteAllBytesAsync(imagePath, image);
}
}
var actors = tvXml.SelectNodes("//actor");
if (actors != null)
{
foreach (XmlNode actor in actors)
{
await HandleActor(actor);
}
}
_logger.LogInformation("ChineseNfoRegistry.Job() tmdbId: {tmdbId}, name: {name}", tmdbId, tvInfo["name"]?.ToString());
if (isLockedNode != null)
{
isLockedNode.InnerText = "true";
}
else
{
isLockedNode = tvXml.CreateElement("locked");
tvXml.DocumentElement?.AppendChild(isLockedNode);
isLockedNode.InnerText = "true";
}
if (isCompletedNode != null)
{
isCompletedNode.InnerText = "true";
}
else
{
isCompletedNode = tvXml.CreateElement("completed");
tvXml.DocumentElement?.AppendChild(isCompletedNode);
isCompletedNode.InnerText = "true";
}
// 保存
tvXml.Save(tvNfo);
}
async Task HandleSeason(string tvNfo, string seasonNfo)
{
var tvNfoContent = File.ReadAllText(tvNfo);
var tvXml = new XmlDocument();
tvXml.LoadXml(tvNfoContent);
var uniqueIdNode = tvXml.SelectSingleNode("//uniqueid[@type='tmdb']");
if (uniqueIdNode == null)
{
_logger.LogError("ChineseNfoRegistry.Job() uniqueIdNode is null");
return;
}
if (!int.TryParse(uniqueIdNode.InnerText, out var tmdbId))
{
_logger.LogError("ChineseNfoRegistry.Job() tmdbId is null");
return;
}
var nfoContent = File.ReadAllText(seasonNfo);
var seasonXml = new XmlDocument();
seasonXml.LoadXml(nfoContent);
var isLockedNode = seasonXml.SelectSingleNode("//locked");
if (isLockedNode != null && isLockedNode.InnerText == "true" && ignoreLocked)
{
_logger.LogInformation("ChineseNfoRegistry.Job() tvNfo is locked");
return;
}
var isCompletedNode = seasonXml.SelectSingleNode("//completed");
if (isCompletedNode != null && isCompletedNode.InnerText == "true" && ignoreCompleted)
{
_logger.LogInformation("ChineseNfoRegistry.Job() tvNfo is completed");
return;
}
var seasonNumberNode = seasonXml.SelectSingleNode("//seasonnumber");
if (seasonNumberNode == null)
{
_logger.LogError("ChineseNfoRegistry.Job() seasonNumberNode is null");
return;
}
if (!int.TryParse(seasonNumberNode.InnerText, out var seasonNumber))
{
_logger.LogError("ChineseNfoRegistry.Job() seasonNumber is null");
return;
}
if (!string.IsNullOrEmpty(requestPath))
{
if (!string.IsNullOrEmpty(requestSeasonNumber))
{
if (seasonNumber != int.Parse(requestSeasonNumber))
{
return;
}
else
{
_logger.LogInformation("ChineseNfoRegistry.Job() seasonNumber is equal");
return;
}
}
}
var seasonInfo = await GetTmdbSeason(seasonNfo, tmdbId, seasonNumber);
if (seasonInfo == null)
{
_logger.LogError("ChineseNfoRegistry.Job() seasonInfo is null");
return;
}
var titleNode = seasonXml.SelectSingleNode("//sorttitle");
if (titleNode != null && seasonInfo["name"] != null)
{
_logger.LogInformation("ChineseNfoRegistry.Job() seasonInfo: {seasonInfo}", seasonInfo["name"]);
titleNode.InnerXml = $"<![CDATA[{seasonInfo["name"]}]]>";
}
var plotNode = seasonXml.SelectSingleNode("//plot");
if (plotNode != null && seasonInfo["overview"] != null)
{
_logger.LogInformation("ChineseNfoRegistry.Job() seasonInfo: {seasonInfo}", seasonInfo["overview"]);
plotNode.InnerXml = $"<![CDATA[{seasonInfo["overview"]}]]>";
}
var outlineNode = seasonXml.SelectSingleNode("//outline");
if (outlineNode != null && seasonInfo["overview"] != null)
{
_logger.LogInformation("ChineseNfoRegistry.Job() seasonInfo: {seasonInfo}", seasonInfo["overview"]);
outlineNode.InnerXml = $"<![CDATA[{seasonInfo["overview"]}]]>";
}
var poster_path = seasonInfo["poster_path"]?.ToString();
if (poster_path != null)
{
var image = await GetTmdbImage(seasonNfo, poster_path);
if (image != null)
{
var imagePath = Path.Combine(Path.GetDirectoryName(tvNfo) ?? string.Empty, "season" + seasonNumber.ToString("D2") + "-poster" + Path.GetExtension(poster_path));
await File.WriteAllBytesAsync(imagePath, image);
}
}
if (isLockedNode != null)
{
isLockedNode.InnerText = "true";
}
else
{
isLockedNode = seasonXml.CreateElement("locked");
seasonXml.DocumentElement?.AppendChild(isLockedNode);
isLockedNode.InnerText = "true";
}
if (isCompletedNode != null)
{
isCompletedNode.InnerText = "true";
}
else
{
isCompletedNode = seasonXml.CreateElement("completed");
seasonXml.DocumentElement?.AppendChild(isCompletedNode);
isCompletedNode.InnerText = "true";
}
seasonXml.Save(seasonNfo);
}
async Task HandleEpisode(string tvNfo, string seasonNfo, string episodeNfo)
{
var tvNfoContent = File.ReadAllText(tvNfo);
var tvXml = new XmlDocument();
tvXml.LoadXml(tvNfoContent);
var uniqueIdNode = tvXml.SelectSingleNode("//uniqueid[@type='tmdb']");
if (uniqueIdNode == null)
{
_logger.LogError("ChineseNfoRegistry.Job() uniqueIdNode is null");
return;
}
if (!int.TryParse(uniqueIdNode.InnerText, out var tmdbId))
{
_logger.LogError("ChineseNfoRegistry.Job() tmdbId is null");
return;
}
var seasonNfoContent = File.ReadAllText(seasonNfo);
var seasonXml = new XmlDocument();
seasonXml.LoadXml(seasonNfoContent);
var seasonNumberNode = seasonXml.SelectSingleNode("//seasonnumber");
if (seasonNumberNode == null)
{
_logger.LogError("ChineseNfoRegistry.Job() seasonNumberNode is null");
return;
}
if (!int.TryParse(seasonNumberNode.InnerText, out var seasonNumber))
{
_logger.LogError("ChineseNfoRegistry.Job() seasonNumber is null");
return;
}
var nfoContent = File.ReadAllText(episodeNfo);
var episodeXml = new XmlDocument();
episodeXml.LoadXml(nfoContent);
var isLockedNode = episodeXml.SelectSingleNode("//locked");
if (isLockedNode != null && isLockedNode.InnerText == "true" && ignoreLocked)
{
_logger.LogInformation("ChineseNfoRegistry.Job() tvNfo is locked");
return;
}
var isCompletedNode = episodeXml.SelectSingleNode("//completed");
if (isCompletedNode != null && isCompletedNode.InnerText == "true" && ignoreCompleted)
{
_logger.LogInformation("ChineseNfoRegistry.Job() tvNfo is completed");
return;
}
var episodeNumberNode = episodeXml.SelectSingleNode("//episode");
if (episodeNumberNode == null)
{
_logger.LogError("ChineseNfoRegistry.Job() episodeNumberNode is null");
return;
}
if (!int.TryParse(episodeNumberNode.InnerText, out var episodeNumber))
{
_logger.LogError("ChineseNfoRegistry.Job() episodeNumber is null");
return;
}
if (!string.IsNullOrEmpty(requestPath))
{
if (!string.IsNullOrEmpty(requestSeasonNumber))
{
if (!string.IsNullOrEmpty(requestEpisodeNumber))
{
if (seasonNumber != int.Parse(requestSeasonNumber) || episodeNumber != int.Parse(requestEpisodeNumber))
{
return;
}
else
{
_logger.LogInformation("ChineseNfoRegistry.Job() episodeNumber is equal");
return;
}
}
}
}
var episodeInfo = await GetTmdbEpisode(episodeNfo, tmdbId, seasonNumber, episodeNumber);
if (episodeInfo == null)
{
_logger.LogError("ChineseNfoRegistry.Job() episodeInfo is null");
return;
}
var titleNode = episodeXml.SelectSingleNode("//title");
if (titleNode != null && episodeInfo["name"] != null)
{
_logger.LogInformation("ChineseNfoRegistry.Job() episodeInfo: {episodeInfo}", episodeInfo["name"]);
titleNode.InnerXml = $"<![CDATA[{episodeInfo["name"]}]]>";
}
var plotNode = episodeXml.SelectSingleNode("//plot");
if (plotNode != null && episodeInfo["overview"] != null)
{
_logger.LogInformation("ChineseNfoRegistry.Job() episodeInfo: {episodeInfo}", episodeInfo["overview"]);
plotNode.InnerXml = $"<![CDATA[{episodeInfo["overview"]}]]>";
}
var outlineNode = episodeXml.SelectSingleNode("//outline");
if (outlineNode != null && episodeInfo["overview"] != null)
{
_logger.LogInformation("ChineseNfoRegistry.Job() episodeInfo: {episodeInfo}", episodeInfo["overview"]);
outlineNode.InnerXml = $"<![CDATA[{episodeInfo["overview"]}]]>";
}
var actors = episodeXml.SelectNodes("//actor");
if (actors != null)
{
foreach (XmlNode actor in actors)
{
await HandleActor(actor);
}
}
_logger.LogInformation("ChineseNfoRegistry.Job() tmdbId: {tmdbId}, name: {name}", tmdbId, episodeInfo["name"]?.ToString());
if (isLockedNode != null)
{
isLockedNode.InnerText = "true";
}
else
{
isLockedNode = episodeXml.CreateElement("locked");
episodeXml.DocumentElement?.AppendChild(isLockedNode);
isLockedNode.InnerText = "true";
}
if (isCompletedNode != null)
{
isCompletedNode.InnerText = "true";
}
else
{
isCompletedNode = episodeXml.CreateElement("completed");
episodeXml.DocumentElement?.AppendChild(isCompletedNode);
isCompletedNode.InnerText = "true";
}
// 保存
episodeXml.Save(episodeNfo);
}
async Task<string?> GetTmdbPersonName(
string path,
int? tmdbId = null,
string? name = null
)
{
if (tmdbId != null)
{
var person = await GetTmdbPerson(path, tmdbId.Value);
return person?["name"]?.ToString() ?? name;
}
if (string.IsNullOrEmpty(name) == false)
{
// 如果名称是中文直接返回
if (Regex.IsMatch(name, "^[\u4e00-\u9fa5]+$"))
{
return name;
}
var person = await GetTmdbPersonSearch(path, name);
return person?["name"]?.ToString() ?? name;
}
return null;
}
async Task HandleActor(XmlNode actor)
{
var nameNode = actor.SelectSingleNode("name");
var tmdbIdNode = actor.SelectSingleNode("tmdbid");
if (nameNode != null || tmdbIdNode != null)
{
var name = await GetTmdbPersonName(
tvFolder,
int.TryParse(tmdbIdNode?.InnerText, out var actorTmdbId) ? actorTmdbId : null,
nameNode?.InnerText
);
if (name == null)
{
return;
}
if (nameNode != null)
{
nameNode.InnerXml = $"<![CDATA[{name}]]>";
}
else
{
actor.AppendChild(new XmlDocument().CreateElement("name"));
nameNode = actor.SelectSingleNode("name");
nameNode!.InnerXml = $"<![CDATA[{name}]]>";
}
_logger.LogInformation("ChineseNfoRegistry.Job() actor: {actor}", name);
}
}
}
private async Task<JObject?> GetTmdbTv(
string path,
int tmdbId)
{
var record = await _freeSql.Select<TheMovieDbRecord>()
.Where(x => x.Type == TheMovieDbType.Tv)
.Where(x => x.UniqueId == tmdbId.ToString())
.FirstAsync();
if (record != null)
{
return JObject.Parse(record.Json);
}
record = new TheMovieDbRecord
{
Type = TheMovieDbType.Tv,
UniqueId = tmdbId.ToString()
};
string tvUrl = "/3/tv/{0}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN";
var requestUrl = string.Format(tvUrl, tmdbId);
try
{
var response = await _apiClient.GetAsync(requestUrl);
if (!response.IsSuccessStatusCode)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbTv() 接口调用失败 {requestUrl} & {path} & {response.StatusCode}", requestUrl, path, response.StatusCode);
return null;
}
var str = await response.Content.ReadAsStringAsync();
var json = JObject.Parse(str);
record.Json = str;
await _freeSql.Insert(record).ExecuteIdentityAsync();
_logger.LogInformation("ChineseNfoRegistry.GetTmdbTv() 接口调用, 休眠 1S");
await Task.Delay(1000);
return json;
}
catch (Exception e)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbTv() 接口调用失败 {requestUrl} & {path} \r {e}", requestUrl, path, e);
return null;
}
}
private async Task<JObject?> GetTmdbPerson(
string path,
int tmdbId)
{
var record = await _freeSql.Select<TheMovieDbRecord>()
.Where(x => x.Type == TheMovieDbType.Person)
.Where(x => x.UniqueId == tmdbId.ToString())
.FirstAsync();
if (record != null)
{
return JObject.Parse(record.Json);
}
record = new TheMovieDbRecord
{
Type = TheMovieDbType.Person,
UniqueId = tmdbId.ToString(),
Language = TheMovieDbLanguage.ZhCn
};
var requestUrl = string.Format("/3/person/{0}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN", tmdbId);
try
{
var response = await _apiClient.GetAsync(requestUrl);
if (!response.IsSuccessStatusCode)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbPerson() 接口调用失败 {requestUrl} & {path} & {response.StatusCode}", requestUrl, path, response.StatusCode);
return null;
}
var str = await response.Content.ReadAsStringAsync();
var json = JObject.Parse(str);
record.Json = str;
await _freeSql.Insert(record).ExecuteIdentityAsync();
_logger.LogInformation("ChineseNfoRegistry.GetTmdbPerson() 接口调用, 休眠 1S");
await Task.Delay(1000);
return json;
}
catch (Exception e)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbPerson() 接口调用失败 {requestUrl} & {path} \r {e}", requestUrl, path, e);
return null;
}
}
private async Task<JObject?> GetTmdbPersonSearch(
string path,
string name)
{
var record = await _freeSql.Select<TheMovieDbRecord>()
.Where(x => x.Type == TheMovieDbType.Person)
.Where(x => x.UniqueId == name)
.FirstAsync();
if (record != null)
{
return JObject.Parse(record.Json);
}
record = new TheMovieDbRecord
{
Type = TheMovieDbType.Person,
UniqueId = name
};
var requestUrl = string.Format("/3/search/person?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN&query={0}", name);
try
{
var response = await _apiClient.GetAsync(requestUrl);
if (!response.IsSuccessStatusCode)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbPersonSearch() 接口调用失败 {requestUrl} & {path} & {response.StatusCode}", requestUrl, path, response.StatusCode);
return null;
}
var str = await response.Content.ReadAsStringAsync();
var json = JObject.Parse(str);
var results = json["results"];
if (results != null)
{
foreach (var result in results.Cast<JObject>())
{
record.Json = result.ToString();
await _freeSql.Insert(record).ExecuteIdentityAsync();
_logger.LogInformation("ChineseNfoRegistry.GetTmdbPersonSearch() 接口调用, 休眠 1S");
await Task.Delay(1000);
return result;
}
}
return null;
}
catch (Exception e)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbPersonSearch() 接口调用失败 {requestUrl} & {path} \r {e}", requestUrl, path, e);
return null;
}
}
private async Task<byte[]?> GetTmdbImage(
string path,
string posterPath)
{
var requestUrl = string.Format("/t/p/w1280/{0}", posterPath);
try
{
var response = await _imageClient.GetAsync(requestUrl);
if (!response.IsSuccessStatusCode)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbImage() 接口调用失败 {requestUrl} & {path} & {response.StatusCode}", requestUrl, path, response.StatusCode);
return null;
}
return await response.Content.ReadAsByteArrayAsync();
}
catch (Exception e)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbImage() 接口调用失败 {requestUrl} & {path} \r {e}", requestUrl, path, e);
return null;
}
}
private async Task<JObject?> GetTmdbSeason(
string path,
int tmdbId,
int seasonNumber)
{
var uniqueId = $"{tmdbId}-{seasonNumber}";
var record = await _freeSql.Select<TheMovieDbRecord>()
.Where(x => x.Type == TheMovieDbType.Season)
.Where(x => x.UniqueId == uniqueId)
.FirstAsync();
if (record != null)
{
return JObject.Parse(record.Json);
}
record = new TheMovieDbRecord
{
Type = TheMovieDbType.Season,
UniqueId = uniqueId
};
var requestUrl = string.Format("/3/tv/{0}/season/{1}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN", tmdbId, seasonNumber);
try
{
var response = await _apiClient.GetAsync(requestUrl);
if (!response.IsSuccessStatusCode)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbSeason() 接口调用失败 {requestUrl} & {path} & {response.StatusCode}", requestUrl, path, response.StatusCode);
return null;
}
var str = await response.Content.ReadAsStringAsync();
record.Json = str;
await _freeSql.Insert(record).ExecuteIdentityAsync();
_logger.LogInformation("ChineseNfoRegistry.GetTmdbSeason() 接口调用, 休眠 1S");
await Task.Delay(1000);
return JObject.Parse(str);
}
catch (Exception e)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbSeason() 接口调用失败 {requestUrl} & {path} \r {e}", requestUrl, path, e);
return null;
}
}
private async Task<JObject?> GetTmdbEpisode(
string path,
int tmdbId,
int seasonNumber,
int episodeNumber)
{
var uniqueId = $"{tmdbId}-{seasonNumber}-{episodeNumber}";
var record = await _freeSql.Select<TheMovieDbRecord>()
.Where(x => x.Type == TheMovieDbType.Episode)
.Where(x => x.UniqueId == uniqueId)
.FirstAsync();
if (record != null)
{
return JObject.Parse(record.Json);
}
record = new TheMovieDbRecord
{
Type = TheMovieDbType.Episode,
UniqueId = uniqueId
};
var requestUrl = string.Format("/3/tv/{0}/season/{1}/episode/{2}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN", tmdbId, seasonNumber, episodeNumber);
try
{
var response = await _apiClient.GetAsync(requestUrl);
if (!response.IsSuccessStatusCode)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbEpisode() 接口调用失败 {requestUrl} & {path} & {response.StatusCode}", requestUrl, path, response.StatusCode);
return null;
}
var str = await response.Content.ReadAsStringAsync();
record.Json = str;
await _freeSql.Insert(record).ExecuteIdentityAsync();
_logger.LogInformation("ChineseNfoRegistry.GetTmdbEpisode() 接口调用, 休眠 1S");
await Task.Delay(1000);
return JObject.Parse(str);
}
catch (Exception e)
{
_logger.LogError("ChineseNfoRegistry.GetTmdbEpisode() 接口调用失败 {requestUrl} & {path} \r {e}", requestUrl, path, e);
return null;
}
}
}
public class TheMovieDbRecord
{
[Column(IsPrimary = true, IsIdentity = true)]
public long Id { get; set; }
public TheMovieDbType Type { get; set; }
public string UniqueId { get; set; } = string.Empty;
public TheMovieDbLanguage Language { get; set; }
[Column(DbType = "text")] public string Json { get; set; } = string.Empty;
}
public enum TheMovieDbType
{
Tv = 1,
Season = 2,
Episode = 3,
Person = 4
}
public enum TheMovieDbLanguage
{
ZhCn = 1,
ZhTw = 2
}