init
This commit is contained in:
245
src/Service/Jobs/ChineseNfoRegistry.cs
Normal file
245
src/Service/Jobs/ChineseNfoRegistry.cs
Normal file
@@ -0,0 +1,245 @@
|
||||
using System.Net;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Xml;
|
||||
using FluentScheduler;
|
||||
using Interface.Jobs;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Service.Jobs;
|
||||
|
||||
public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
|
||||
{
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILogger<ChineseNfoRegistry> _logger;
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public ChineseNfoRegistry(IConfiguration configuration, ILogger<ChineseNfoRegistry> logger)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_logger = logger;
|
||||
|
||||
var proxyAddress = _configuration["ChineseNfo:HttpProxy"];
|
||||
var httpClientHandler = new HttpClientHandler
|
||||
{
|
||||
Proxy = string.IsNullOrEmpty(proxyAddress) ? null : new WebProxy(proxyAddress, false),
|
||||
UseProxy = !string.IsNullOrEmpty(proxyAddress)
|
||||
};
|
||||
|
||||
_client = new HttpClient(httpClientHandler);
|
||||
_client.BaseAddress = new Uri("https://api.themoviedb.org");
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task JobExecute(bool ignoreLocked, bool ignoreCompleted)
|
||||
{
|
||||
// 读取环境变量 tv folder
|
||||
var tvFolder = _configuration["ChineseNfo:TvFolder"];
|
||||
if (string.IsNullOrEmpty(tvFolder))
|
||||
{
|
||||
Console.WriteLine("请设置环境变量 tv_folder");
|
||||
return;
|
||||
}
|
||||
|
||||
// 扫描 tvshow.nfo 文件
|
||||
var tvShowFiles = Directory.GetFiles(tvFolder, "tvshow.nfo", SearchOption.AllDirectories);
|
||||
|
||||
foreach (var tvShowFile in tvShowFiles)
|
||||
{
|
||||
var nfoContent = File.ReadAllText(tvShowFile);
|
||||
|
||||
// 读取 使用XML解析器 读取 <uniqueid type="tmdb">60059</uniqueid>
|
||||
var tvXml = new XmlDocument();
|
||||
tvXml.LoadXml(nfoContent);
|
||||
var uniqueIdNode = tvXml.SelectSingleNode("//uniqueid[@type='tmdb']");
|
||||
if (uniqueIdNode == null)
|
||||
{
|
||||
Console.WriteLine($"{tvShowFile} & 未找到 tmdb id");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!int.TryParse(uniqueIdNode.InnerText, out var tmdbId))
|
||||
{
|
||||
Console.WriteLine($"{tvShowFile} & tmdb id 不是数字");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取 tvShowFile 的文件夹
|
||||
var folderPath = Path.GetDirectoryName(tvShowFile);
|
||||
|
||||
if (folderPath == null)
|
||||
{
|
||||
Console.WriteLine($"{tvShowFile} & 未找到文件夹");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 扫描文件夹下其他 nfo 文件
|
||||
var seasonFiles = Directory.GetFiles(folderPath, "*.nfo", SearchOption.AllDirectories);
|
||||
|
||||
seasonFiles = seasonFiles.Where(x => !x.EndsWith("tvshow.nfo")).ToArray();
|
||||
|
||||
foreach (var seasonFile in seasonFiles)
|
||||
{
|
||||
var episodeContent = File.ReadAllText(seasonFile);
|
||||
var episodeXml = new XmlDocument();
|
||||
episodeXml.LoadXml(episodeContent);
|
||||
|
||||
// 判断有无 completed 节点
|
||||
var completedNode = episodeXml.SelectSingleNode("//completed");
|
||||
if (completedNode != null && ignoreCompleted == false)
|
||||
{
|
||||
Console.WriteLine($"{seasonFile} & 已完成");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 判断 locked == true
|
||||
var lockedNode = episodeXml.SelectSingleNode("//lockdata");
|
||||
if (lockedNode != null && lockedNode.InnerText == "true" && ignoreLocked == false)
|
||||
{
|
||||
Console.WriteLine($"{seasonFile} & 已锁定");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 读取 <season>1</season>
|
||||
var seasonNode = episodeXml.SelectSingleNode("//season");
|
||||
if (seasonNode == null)
|
||||
{
|
||||
Console.WriteLine($"{seasonFile} & 未找到 season");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 读取 <episode>1</episode>
|
||||
var episodeNode = episodeXml.SelectSingleNode("//episode");
|
||||
if (episodeNode == null)
|
||||
{
|
||||
Console.WriteLine($"{seasonFile} & 未找到 episode");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!int.TryParse(seasonNode.InnerText, out var season))
|
||||
{
|
||||
Console.WriteLine($"{seasonFile} & season 不是数字");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!int.TryParse(episodeNode.InnerText, out var episode))
|
||||
{
|
||||
Console.WriteLine($"{seasonFile} & episode 不是数字");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 设置 title
|
||||
var titleNode = episodeXml.SelectSingleNode("//title");
|
||||
if (titleNode == null)
|
||||
{
|
||||
Console.WriteLine($"{seasonFile} & 未找到 title");
|
||||
continue;
|
||||
}
|
||||
|
||||
var json = await GetTmdbEpisode(tmdbId, season, episode);
|
||||
|
||||
if (json == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var title = json["name"]?.ToString();
|
||||
var overview = json["overview"]?.ToString();
|
||||
|
||||
var isUpdate = false;
|
||||
if (!string.IsNullOrEmpty(title))
|
||||
{
|
||||
title = $"<![CDATA[{title}]]>";
|
||||
|
||||
if (titleNode.InnerXml != title)
|
||||
{
|
||||
isUpdate = true;
|
||||
// 写入且不转义
|
||||
titleNode.InnerXml = title;
|
||||
}
|
||||
}
|
||||
|
||||
var plotNode = episodeXml.SelectSingleNode("//plot");
|
||||
|
||||
if (!string.IsNullOrEmpty(overview) && plotNode != null)
|
||||
{
|
||||
overview = $"<![CDATA[{overview}]]>";
|
||||
if (plotNode.InnerXml != overview)
|
||||
{
|
||||
isUpdate = true;
|
||||
plotNode.InnerXml = overview;
|
||||
}
|
||||
}
|
||||
|
||||
if (isUpdate)
|
||||
{
|
||||
// 添加一个已完成节点
|
||||
if (completedNode == null)
|
||||
{
|
||||
episodeXml.DocumentElement?.AppendChild(episodeXml.CreateElement("completed"));
|
||||
}
|
||||
|
||||
// 锁定
|
||||
if (lockedNode == null)
|
||||
{
|
||||
lockedNode = episodeXml.CreateElement("lockdata");
|
||||
episodeXml.DocumentElement?.AppendChild(lockedNode);
|
||||
lockedNode.InnerText = "true";
|
||||
}
|
||||
else
|
||||
{
|
||||
lockedNode.InnerText = "true";
|
||||
}
|
||||
|
||||
episodeXml.Save(seasonFile);
|
||||
Console.WriteLine($"{seasonFile} & {title} & {overview}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"{seasonFile} & 无更新");
|
||||
}
|
||||
|
||||
await Task.Delay(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<JsonObject?> GetTmdbEpisode(int tmdbId, int season, int episode)
|
||||
{
|
||||
try
|
||||
{
|
||||
const string episodeUrl = "/3/tv/{0}/season/{1}/episode/{2}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN";
|
||||
|
||||
var requestUrl = string.Format(episodeUrl, tmdbId, season, episode);
|
||||
var response = await _client.GetAsync(requestUrl);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
Console.WriteLine($"{requestUrl} & {response.StatusCode}");
|
||||
return null;
|
||||
}
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
var json = JsonNode.Parse(content);
|
||||
return json as JsonObject;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"{tmdbId} & {season} & {episode} & {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user