Files
NasRobot/src/Service/Jobs/ChineseNfoRegistry.cs

879 lines
27 KiB
C#
Raw Normal View History

2025-04-03 16:22:31 +08:00
using System.Net;
using System.Text.RegularExpressions;
2025-02-27 16:58:21 +08:00
using System.Xml;
using FluentScheduler;
2025-04-03 16:22:31 +08:00
using FreeSql;
using FreeSql.DataAnnotations;
2025-02-27 16:58:21 +08:00
using Interface.Jobs;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
2025-04-03 16:22:31 +08:00
using Newtonsoft.Json.Linq;
2025-02-27 16:58:21 +08:00
namespace Service.Jobs;
public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
{
2025-04-03 16:22:31 +08:00
private readonly HttpClient _apiClient;
private readonly HttpClient _imageClient;
2025-02-27 16:58:21 +08:00
private readonly IConfiguration _configuration;
private readonly ILogger<ChineseNfoRegistry> _logger;
2025-04-03 16:22:31 +08:00
private readonly IFreeSql _freeSql;
2025-02-27 16:58:21 +08:00
public ChineseNfoRegistry(IConfiguration configuration, ILogger<ChineseNfoRegistry> logger)
{
_configuration = configuration;
_logger = logger;
2025-03-06 17:25:10 +08:00
var httpClientHandler = new HttpClientHandler();
2025-02-27 16:58:21 +08:00
var proxyAddress = _configuration["ChineseNfo:HttpProxy"];
if (string.IsNullOrEmpty(proxyAddress) == false)
2025-02-27 16:58:21 +08:00
{
2025-03-06 17:25:10 +08:00
httpClientHandler.Proxy = string.IsNullOrEmpty(proxyAddress) ? null : new WebProxy(proxyAddress, false);
httpClientHandler.UseProxy = !string.IsNullOrEmpty(proxyAddress);
}
2025-02-27 16:58:21 +08:00
2025-04-03 16:22:31 +08:00
_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();
2025-02-27 16:58:21 +08:00
}
public async void Job(
string? tmdbId = null,
string? seasonNumber = null,
string? episodeNumber = null,
bool ignoreLocked = false,
bool ignoreCompleted = false
)
2025-02-27 16:58:21 +08:00
{
try
{
await JobExecute(ignoreLocked, ignoreCompleted);
}
catch (Exception e)
{
_logger.LogError(e, "ChineseNfoRegistry.Job() error");
}
}
2025-04-03 16:22:31 +08:00
private async Task JobExecute(
bool ignoreLocked,
bool ignoreCompleted)
2025-02-27 16:58:21 +08:00
{
var tvFolder = _configuration["ChineseNfo:TvFolder"];
2025-04-03 16:22:31 +08:00
2025-02-27 16:58:21 +08:00
if (string.IsNullOrEmpty(tvFolder))
{
2025-04-03 16:22:31 +08:00
_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");
2025-02-27 16:58:21 +08:00
return;
}
2025-04-03 16:22:31 +08:00
foreach (var tv in tvNfos)
{
await HandleTv(tv);
var seasonNfos = Directory.GetFiles(Path.GetDirectoryName(tv) ?? string.Empty, "season.nfo", SearchOption.AllDirectories);
foreach (var season in seasonNfos)
{
await HandleSeason(tv, season);
var episodeNfos = Directory
.GetFiles(Path.GetDirectoryName(season) ?? string.Empty, "*.nfo", SearchOption.AllDirectories)
.Where(x => !x.EndsWith("season.nfo"))
.ToList();
foreach (var episode in episodeNfos)
{
await HandleEpisode(tv, season, episode);
}
}
2025-04-03 16:22:31 +08:00
}
2025-02-27 16:58:21 +08:00
async Task HandleTv(string tvNfo)
2025-02-27 16:58:21 +08:00
{
2025-04-03 16:22:31 +08:00
var nfoContent = File.ReadAllText(tvNfo);
2025-02-27 16:58:21 +08:00
var tvXml = new XmlDocument();
tvXml.LoadXml(nfoContent);
var isLockedNode = tvXml.SelectSingleNode("//locked");
if (isLockedNode != null && isLockedNode.InnerText == "true" && ignoreLocked)
{
_logger.LogError("ChineseNfoRegistry.Job() tvNfo is locked");
return;
}
var isCompletedNode = tvXml.SelectSingleNode("//completed");
if (isCompletedNode != null && isCompletedNode.InnerText == "true" && ignoreCompleted)
{
_logger.LogError("ChineseNfoRegistry.Job() tvNfo is completed");
return;
}
2025-02-27 16:58:21 +08:00
var uniqueIdNode = tvXml.SelectSingleNode("//uniqueid[@type='tmdb']");
2025-04-03 16:22:31 +08:00
2025-02-27 16:58:21 +08:00
if (uniqueIdNode == null)
{
2025-04-03 16:22:31 +08:00
_logger.LogError("ChineseNfoRegistry.Job() uniqueIdNode is null");
return;
2025-02-27 16:58:21 +08:00
}
if (!int.TryParse(uniqueIdNode.InnerText, out var tmdbId))
{
2025-04-03 16:22:31 +08:00
_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"]}]]>";
}
}
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"]}]]>";
}
}
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
{
tvXml.CreateElement("locked");
isLockedNode = tvXml.SelectSingleNode("//locked");
isLockedNode!.InnerText = "true";
}
if (isCompletedNode != null)
{
isCompletedNode.InnerText = "true";
}
else
{
tvXml.CreateElement("completed");
isCompletedNode = tvXml.SelectSingleNode("//completed");
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.LogError("ChineseNfoRegistry.Job() tvNfo is locked");
return;
}
var isCompletedNode = seasonXml.SelectSingleNode("//completed");
if (isCompletedNode != null && isCompletedNode.InnerText == "true" && ignoreCompleted)
{
_logger.LogError("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;
}
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)
{
titleNode.InnerXml = $"<![CDATA[{seasonInfo["name"]}]]>";
}
var plotNode = seasonXml.SelectSingleNode("//plot");
if (plotNode != null && seasonInfo["overview"] != null)
{
plotNode.InnerXml = $"<![CDATA[{seasonInfo["overview"]}]]>";
}
var outlineNode = seasonXml.SelectSingleNode("//outline");
if (outlineNode != null && seasonInfo["overview"] != null)
{
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)
{
// season01-poster.jpg
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
{
tvXml.CreateElement("locked");
isLockedNode = tvXml.SelectSingleNode("//locked");
isLockedNode!.InnerText = "true";
2025-02-27 16:58:21 +08:00
}
if (isCompletedNode != null)
{
isCompletedNode.InnerText = "true";
}
else
{
tvXml.CreateElement("completed");
isCompletedNode = tvXml.SelectSingleNode("//completed");
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.LogError("ChineseNfoRegistry.Job() tvNfo is locked");
return;
}
var isCompletedNode = episodeXml.SelectSingleNode("//completed");
if (isCompletedNode != null && isCompletedNode.InnerText == "true" && ignoreCompleted)
{
_logger.LogError("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;
}
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)
{
// 特殊符号保留
titleNode.InnerXml = $"<![CDATA[{episodeInfo["name"]}]]>";
}
var plotNode = episodeXml.SelectSingleNode("//plot");
if (plotNode != null && episodeInfo["overview"] != null)
{
plotNode.InnerXml = $"<![CDATA[{episodeInfo["overview"]}]]>";
}
var outlineNode = episodeXml.SelectSingleNode("//outline");
if (outlineNode != null && episodeInfo["overview"] != null)
{
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
{
tvXml.CreateElement("locked");
isLockedNode = tvXml.SelectSingleNode("//locked");
isLockedNode!.InnerText = "true";
}
if (isCompletedNode != null)
{
isCompletedNode.InnerText = "true";
}
else
{
tvXml.CreateElement("completed");
isCompletedNode = tvXml.SelectSingleNode("//completed");
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}]]>";
}
}
}
2025-04-03 16:22:31 +08:00
}
2025-02-27 16:58:21 +08:00
2025-04-03 16:22:31 +08:00
private async Task<JObject?> GetTmdbTv(
string path,
int tmdbId)
2025-04-03 16:22:31 +08:00
{
var record = await _freeSql.Select<TheMovieDbRecord>()
.Where(x => x.Type == TheMovieDbType.Tv)
2025-04-03 16:22:31 +08:00
.Where(x => x.UniqueId == tmdbId.ToString())
.FirstAsync();
2025-02-27 16:58:21 +08:00
2025-04-03 16:22:31 +08:00
if (record != null)
{
2025-04-03 16:22:31 +08:00
return JObject.Parse(record.Json);
}
2025-02-27 16:58:21 +08:00
2025-04-03 16:22:31 +08:00
record = new TheMovieDbRecord
{
2025-04-03 16:22:31 +08:00
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)
{
Console.WriteLine($"{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() 接口调用, 休眠 5S");
await Task.Delay(5000);
return json;
}
catch (Exception e)
{
Console.WriteLine($"{requestUrl} & {path} \r {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,
2025-04-03 16:22:31 +08:00
UniqueId = tmdbId.ToString(),
Language = TheMovieDbLanguage.ZhCn
2025-04-03 16:22:31 +08:00
};
var requestUrl = string.Format("/3/person/{0}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN", tmdbId);
try
{
var response = await _apiClient.GetAsync(requestUrl);
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"{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() 接口调用, 休眠 5S");
await Task.Delay(5000);
return json;
}
catch (Exception e)
{
Console.WriteLine($"{requestUrl} & {path} \r {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
{
2025-04-03 16:22:31 +08:00
var response = await _apiClient.GetAsync(requestUrl);
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"{requestUrl} & {path} & {response.StatusCode}");
return null;
}
2025-04-03 16:22:31 +08:00
var str = await response.Content.ReadAsStringAsync();
2025-04-03 16:22:31 +08:00
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() 接口调用, 休眠 5S");
await Task.Delay(5000);
return result;
}
}
return null;
}
catch (Exception e)
{
Console.WriteLine($"{requestUrl} & {path} \r {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)
2025-02-27 16:58:21 +08:00
{
Console.WriteLine($"{requestUrl} & {path} & {response.StatusCode}");
return null;
}
return await response.Content.ReadAsByteArrayAsync();
}
catch (Exception e)
{
Console.WriteLine($"{requestUrl} & {path} \r {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)
{
Console.WriteLine($"{requestUrl} & {path} & {response.StatusCode}");
return null;
2025-02-27 16:58:21 +08:00
}
var str = await response.Content.ReadAsStringAsync();
2025-04-03 16:22:31 +08:00
record.Json = str;
await _freeSql.Insert(record).ExecuteIdentityAsync();
_logger.LogInformation("ChineseNfoRegistry.GetTmdbSeason() 接口调用, 休眠 5S");
await Task.Delay(5000);
return JObject.Parse(str);
}
catch (Exception e)
{
Console.WriteLine($"{requestUrl} & {path} \r {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)
{
Console.WriteLine($"{requestUrl} & {path} & {response.StatusCode}");
return null;
}
var str = await response.Content.ReadAsStringAsync();
record.Json = str;
await _freeSql.Insert(record).ExecuteIdentityAsync();
_logger.LogInformation("ChineseNfoRegistry.GetTmdbEpisode() 接口调用, 休眠 5S");
await Task.Delay(5000);
return JObject.Parse(str);
2025-02-27 16:58:21 +08:00
}
catch (Exception e)
{
Console.WriteLine($"{requestUrl} & {path} \r {e}");
2025-02-27 16:58:21 +08:00
return null;
}
}
2025-04-03 16:22:31 +08:00
}
public class TheMovieDbRecord
{
2025-04-03 17:03:42 +08:00
[Column(IsPrimary = true, IsIdentity = true)]
2025-04-03 16:22:31 +08:00
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;
2025-04-03 16:22:31 +08:00
}
public enum TheMovieDbType
{
Tv = 1,
Season = 2,
Episode = 3,
Person = 4
2025-04-03 16:22:31 +08:00
}
public enum TheMovieDbLanguage
{
ZhCn = 1,
ZhTw = 2
2025-02-27 16:58:21 +08:00
}