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

223 lines
6.3 KiB
C#
Raw Normal View History

2025-04-03 16:22:31 +08:00
using System.Net;
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();
2025-02-27 16:58:21 +08:00
Schedule(() => Job(true, true)).ToRunEvery(1).Days();
}
public async void Job(bool ignoreLocked, bool ignoreCompleted)
{
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,
string[]? includeFields = null)
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;
}
/*
* 1.
* 2.
* 3.
* 4.
*/
var fields =
includeFields ??
[
"tv.title",
"tv.plot",
"tv.outline",
"tv.poster",
"tv.genre",
"tv.actor.name",
"tv.actor.role",
"season.title",
"season.plot",
"episode.title",
"episode.plot",
"episode.actor.name",
];
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);
}
2025-02-27 16:58:21 +08:00
2025-04-03 16:22:31 +08:00
async Task<string[]?> 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 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 null;
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 null;
2025-02-27 16:58:21 +08:00
}
2025-04-03 16:22:31 +08:00
var a = await GetTmdbTv(tvNfo, tmdbId);
2025-04-03 16:22:31 +08:00
_logger.LogInformation("ChineseNfoRegistry.Job() tmdbId: {tmdbId}, name: {name}", tmdbId,a?["name"]?.ToString());
return [];
}
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,
TheMovieDbLanguage language = TheMovieDbLanguage.ZhCn)
{
var record = await _freeSql.Select<TheMovieDbRecord>()
.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(),
Language = language
};
const string tvUrl = "/3/tv/{0}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN";
var requestUrl = string.Format(tvUrl, tmdbId);
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 name = json["name"];
// 判断是否包含中文字符
var isChinese = name != null && name.ToString().Any(c => c >= 0x4E00 && c <= 0x9FA5);
if (language == TheMovieDbLanguage.ZhCn && !isChinese)
2025-02-27 16:58:21 +08:00
{
2025-04-03 16:22:31 +08:00
// 降级到繁体
return await GetTmdbTv(path, tmdbId, TheMovieDbLanguage.ZhTw);
2025-02-27 16:58:21 +08:00
}
2025-04-03 16:22:31 +08:00
record.Json = str;
_freeSql.Insert(record);
return json;
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
{
public long Id { get; set; }
public TheMovieDbType Type { get; set; }
public string UniqueId { get; set; } = string.Empty;
public TheMovieDbLanguage Language { get; set; }
[Column(DbType = "varchar(max)")] public string Json { get; set; } = string.Empty;
}
public enum TheMovieDbType
{
Tv = 1,
Season = 2,
Episode = 3,
}
public enum TheMovieDbLanguage
{
ZhCn = 1,
ZhTw = 2
2025-02-27 16:58:21 +08:00
}