1
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
- /wd/volc/media/tv:/data/media/tv:rw
|
- /wd/volc/media/tv:/data/media/tv:rw
|
||||||
- /wd/volc/media/anime:/data/media/anime:rw
|
- /wd/volc/media/anime:/data/media/anime:rw
|
||||||
- /wd/volc/media/anime-other:/data/media/anime-other:rw
|
- /wd/volc/media/anime-other:/data/media/anime-other:rw
|
||||||
|
- /wd/apps/vols/nas_robot:/app/data:rw
|
||||||
- /wd:/host/wd:ro
|
- /wd:/host/wd:ro
|
||||||
- /proc/mounts:/host/proc/mounts:ro
|
- /proc/mounts:/host/proc/mounts:ro
|
||||||
|
|
||||||
|
|||||||
482
src/Service/Jobs/ChineseNfoRegistry.Bak.cs
Normal file
482
src/Service/Jobs/ChineseNfoRegistry.Bak.cs
Normal file
@@ -0,0 +1,482 @@
|
|||||||
|
// using System.Diagnostics;
|
||||||
|
// using System.Net;
|
||||||
|
// using System.Text.Json.Nodes;
|
||||||
|
// using System.Xml;
|
||||||
|
// using Core;
|
||||||
|
// 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 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);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// _client = new HttpClient(httpClientHandler);
|
||||||
|
// _client.BaseAddress = new Uri("http://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;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var successCount = 0;
|
||||||
|
// var failedCount = 0;
|
||||||
|
// var skippedCount = 0;
|
||||||
|
//
|
||||||
|
// // 扫描 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;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// await SetTvInfo(tvShowFile, tvXml, tmdbId);
|
||||||
|
//
|
||||||
|
// // 获取 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 episodeFile in seasonFiles)
|
||||||
|
// {
|
||||||
|
// await SetEpisodeInfo(episodeFile, tmdbId);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// await WxNotify.SendCommonAsync($"ChineseNfoRegistry.Job() success: {successCount}, failed: {failedCount}, skipped: {skippedCount}");
|
||||||
|
//
|
||||||
|
// async Task SetTvInfo(string tvShowFile,XmlDocument tvXml, int tmdbId)
|
||||||
|
// {
|
||||||
|
// // 检查 lockdata
|
||||||
|
// var lockedNode = tvXml.SelectSingleNode("//lockdata");
|
||||||
|
// if (lockedNode != null && lockedNode.InnerText == "true" && ignoreLocked == false)
|
||||||
|
// {
|
||||||
|
// skippedCount++;
|
||||||
|
// Console.WriteLine($"{tvShowFile} & 已锁定");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 获取tv info
|
||||||
|
// var tvJson = await GetTmdbTv(tvShowFile, tmdbId);
|
||||||
|
//
|
||||||
|
// if (tvJson == null)
|
||||||
|
// {
|
||||||
|
// failedCount++;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var title = tvJson["name"]?.ToString();
|
||||||
|
// var overview = tvJson["overview"]?.ToString();
|
||||||
|
// var poster =tvJson["poster_path"]?.ToString();
|
||||||
|
// var genres = tvJson["genres"]
|
||||||
|
// ?.AsArray()
|
||||||
|
// .Select(x => x?["name"]?.ToString())
|
||||||
|
// .Where(x=> !string.IsNullOrEmpty(x))
|
||||||
|
// .ToList();
|
||||||
|
//
|
||||||
|
// if (!string.IsNullOrEmpty(title))
|
||||||
|
// {
|
||||||
|
// title = $"<![CDATA[{title}]]>";
|
||||||
|
// var titleNode = tvXml.SelectSingleNode("//title");
|
||||||
|
// if (titleNode != null)
|
||||||
|
// {
|
||||||
|
// if (titleNode.InnerXml != title)
|
||||||
|
// {
|
||||||
|
// titleNode.InnerXml = title;
|
||||||
|
// successCount++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var sorttitleNode = tvXml.SelectSingleNode("//sorttitle");
|
||||||
|
// if (sorttitleNode != null)
|
||||||
|
// {
|
||||||
|
// if (sorttitleNode.InnerXml != title)
|
||||||
|
// {
|
||||||
|
// sorttitleNode.InnerXml = title;
|
||||||
|
// successCount++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!string.IsNullOrEmpty(overview))
|
||||||
|
// {
|
||||||
|
// overview = $"<![CDATA[{overview}]]>";
|
||||||
|
// var plotNode = tvXml.SelectSingleNode("//plot");
|
||||||
|
// if (plotNode != null)
|
||||||
|
// {
|
||||||
|
// if (plotNode.InnerXml != overview)
|
||||||
|
// {
|
||||||
|
// plotNode.InnerXml = overview;
|
||||||
|
// successCount++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var outlineNode = tvXml.SelectSingleNode("//outline");
|
||||||
|
// if (outlineNode != null)
|
||||||
|
// {
|
||||||
|
// if (outlineNode.InnerXml != overview)
|
||||||
|
// {
|
||||||
|
// outlineNode.InnerXml = overview;
|
||||||
|
// successCount++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(!string.IsNullOrEmpty(poster))
|
||||||
|
// {
|
||||||
|
// poster = $"http://image.tmdb.org/t/p/w1280/{poster}";
|
||||||
|
// // 下载并覆盖海报
|
||||||
|
// var posterPath = tvShowFile.Replace("tvshow.nfo", $"poster.{poster.Split('.').Last()}");
|
||||||
|
//
|
||||||
|
// using var client = new HttpClient();
|
||||||
|
// var response = await client.GetAsync(poster);
|
||||||
|
// if (response.IsSuccessStatusCode)
|
||||||
|
// {
|
||||||
|
// var bytes = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
//
|
||||||
|
// if (File.Exists(posterPath))
|
||||||
|
// {
|
||||||
|
// File.Delete(posterPath);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// await File.WriteAllBytesAsync(posterPath, bytes);
|
||||||
|
// successCount++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if (genres?.Any() == true)
|
||||||
|
// {
|
||||||
|
// // 删除原有的 <genre> 节点
|
||||||
|
// var genreNodes = tvXml.SelectNodes("//genre");
|
||||||
|
// if (genreNodes != null)
|
||||||
|
// {
|
||||||
|
// foreach (XmlNode genreNode in genreNodes)
|
||||||
|
// {
|
||||||
|
// tvXml.DocumentElement?.RemoveChild(genreNode);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 添加新的 <genre> 节点
|
||||||
|
// foreach (var genre in genres)
|
||||||
|
// {
|
||||||
|
// var genreNode = tvXml.CreateElement("genre");
|
||||||
|
// genreNode.InnerText = genre!;
|
||||||
|
// tvXml.DocumentElement?.AppendChild(genreNode);
|
||||||
|
// }
|
||||||
|
// successCount++;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (successCount == 0)
|
||||||
|
// {
|
||||||
|
// skippedCount++;
|
||||||
|
// Console.WriteLine($"{tvShowFile} & 无更新");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 锁定节点
|
||||||
|
// if(lockedNode == null)
|
||||||
|
// {
|
||||||
|
// lockedNode = tvXml.CreateElement("lockdata");
|
||||||
|
// tvXml.DocumentElement?.AppendChild(lockedNode);
|
||||||
|
// lockedNode.InnerText = "true";
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// lockedNode.InnerText = "true";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 添加一个已完成节点
|
||||||
|
// var completedNode = tvXml.SelectSingleNode("//completed");
|
||||||
|
// if (completedNode == null)
|
||||||
|
// {
|
||||||
|
// completedNode = tvXml.CreateElement("completed");
|
||||||
|
// tvXml.DocumentElement?.AppendChild(completedNode);
|
||||||
|
// }
|
||||||
|
// completedNode.InnerText = "true";
|
||||||
|
//
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// tvXml.Save(tvShowFile);
|
||||||
|
// }
|
||||||
|
// catch (Exception e)
|
||||||
|
// {
|
||||||
|
// Console.WriteLine(e);
|
||||||
|
// failedCount++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// async Task SetEpisodeInfo(string episodeFile, int tmdbId)
|
||||||
|
// {
|
||||||
|
// var episodeContent = await File.ReadAllTextAsync(episodeFile);
|
||||||
|
// var episodeXml = new XmlDocument();
|
||||||
|
// episodeXml.LoadXml(episodeContent);
|
||||||
|
//
|
||||||
|
// // 判断有无 completed 节点
|
||||||
|
// var completedNode = episodeXml.SelectSingleNode("//completed");
|
||||||
|
// if (completedNode != null && ignoreCompleted == false)
|
||||||
|
// {
|
||||||
|
// skippedCount++;
|
||||||
|
// Console.WriteLine($"{episodeFile} & 已完成");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 判断 locked == true
|
||||||
|
// var lockedNode = episodeXml.SelectSingleNode("//lockdata");
|
||||||
|
// if (lockedNode != null && lockedNode.InnerText == "true" && ignoreLocked == false)
|
||||||
|
// {
|
||||||
|
// skippedCount++;
|
||||||
|
// Console.WriteLine($"{episodeFile} & 已锁定");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 读取 <season>1</season>
|
||||||
|
// var seasonNode = episodeXml.SelectSingleNode("//season");
|
||||||
|
// if (seasonNode == null)
|
||||||
|
// {
|
||||||
|
// failedCount++;
|
||||||
|
// Console.WriteLine($"{episodeFile} & 未找到 season");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 读取 <episode>1</episode>
|
||||||
|
// var episodeNode = episodeXml.SelectSingleNode("//episode");
|
||||||
|
// if (episodeNode == null)
|
||||||
|
// {
|
||||||
|
// failedCount++;
|
||||||
|
// Console.WriteLine($"{episodeFile} & 未找到 episode");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!int.TryParse(seasonNode.InnerText, out var season))
|
||||||
|
// {
|
||||||
|
// failedCount++;
|
||||||
|
// Console.WriteLine($"{episodeFile} & season 不是数字");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!int.TryParse(episodeNode.InnerText, out var episode))
|
||||||
|
// {
|
||||||
|
// failedCount++;
|
||||||
|
// Console.WriteLine($"{episodeFile} & episode 不是数字");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 设置 title
|
||||||
|
// var titleNode = episodeXml.SelectSingleNode("//title");
|
||||||
|
// if (titleNode == null)
|
||||||
|
// {
|
||||||
|
// failedCount++;
|
||||||
|
// Console.WriteLine($"{episodeFile} & 未找到 title");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var json = await GetTmdbEpisode(
|
||||||
|
// episodeFile,
|
||||||
|
// tmdbId,
|
||||||
|
// season,
|
||||||
|
// episode);
|
||||||
|
//
|
||||||
|
// if (json == null)
|
||||||
|
// {
|
||||||
|
// failedCount++;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
// {
|
||||||
|
// skippedCount++;
|
||||||
|
// Console.WriteLine($"{episodeFile} & 无更新");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// successCount++;
|
||||||
|
//
|
||||||
|
// // 添加一个已完成节点
|
||||||
|
// 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";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// episodeXml.Save(episodeFile);
|
||||||
|
// }
|
||||||
|
// catch (Exception e)
|
||||||
|
// {
|
||||||
|
// Console.WriteLine(e);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Console.WriteLine($"{episodeFile} & {title} & {overview}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private async Task<JsonObject?> GetTmdbTv(
|
||||||
|
// string path,
|
||||||
|
// int tmdbId)
|
||||||
|
// {
|
||||||
|
// const string tvUrl = "/3/tv/{0}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN";
|
||||||
|
// var requestUrl = string.Format(tvUrl, tmdbId);
|
||||||
|
//
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// var response = await _client.GetAsync(requestUrl);
|
||||||
|
//
|
||||||
|
// if (!response.IsSuccessStatusCode)
|
||||||
|
// {
|
||||||
|
// Console.WriteLine($"{requestUrl} & {path} & {response.StatusCode}");
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// await Task.Delay(10000);
|
||||||
|
//
|
||||||
|
// var content = await response.Content.ReadAsStringAsync();
|
||||||
|
// var json = JsonNode.Parse(content);
|
||||||
|
// return json as JsonObject;
|
||||||
|
// }
|
||||||
|
// catch (Exception e)
|
||||||
|
// {
|
||||||
|
// Console.WriteLine($"{requestUrl} & {path} \r {e}");
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private async Task<JsonObject?> GetTmdbEpisode(
|
||||||
|
// string path,
|
||||||
|
// int tmdbId,
|
||||||
|
// int season,
|
||||||
|
// int episode)
|
||||||
|
// {
|
||||||
|
// const string episodeUrl = "/3/tv/{0}/season/{1}/episode/{2}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN";
|
||||||
|
// var requestUrl = string.Format(episodeUrl, tmdbId, season, episode);
|
||||||
|
//
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// var response = await _client.GetAsync(requestUrl);
|
||||||
|
//
|
||||||
|
// await Task.Delay(10000);
|
||||||
|
//
|
||||||
|
// if (!response.IsSuccessStatusCode)
|
||||||
|
// {
|
||||||
|
// Console.WriteLine($"{requestUrl} & {path} & {response.StatusCode}");
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var content = await response.Content.ReadAsStringAsync();
|
||||||
|
// var json = JsonNode.Parse(content);
|
||||||
|
// return json as JsonObject;
|
||||||
|
// }
|
||||||
|
// catch (Exception e)
|
||||||
|
// {
|
||||||
|
// Console.WriteLine($"{requestUrl} & {path} \r {e}");
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@@ -1,20 +1,22 @@
|
|||||||
using System.Diagnostics;
|
using System.Net;
|
||||||
using System.Net;
|
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Core;
|
|
||||||
using FluentScheduler;
|
using FluentScheduler;
|
||||||
|
using FreeSql;
|
||||||
|
using FreeSql.DataAnnotations;
|
||||||
using Interface.Jobs;
|
using Interface.Jobs;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Service.Jobs;
|
namespace Service.Jobs;
|
||||||
|
|
||||||
public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
|
public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
|
||||||
{
|
{
|
||||||
|
private readonly HttpClient _apiClient;
|
||||||
|
private readonly HttpClient _imageClient;
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
private readonly ILogger<ChineseNfoRegistry> _logger;
|
private readonly ILogger<ChineseNfoRegistry> _logger;
|
||||||
private readonly HttpClient _client;
|
private readonly IFreeSql _freeSql;
|
||||||
|
|
||||||
public ChineseNfoRegistry(IConfiguration configuration, ILogger<ChineseNfoRegistry> logger)
|
public ChineseNfoRegistry(IConfiguration configuration, ILogger<ChineseNfoRegistry> logger)
|
||||||
{
|
{
|
||||||
@@ -31,8 +33,16 @@ public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
|
|||||||
httpClientHandler.UseProxy = !string.IsNullOrEmpty(proxyAddress);
|
httpClientHandler.UseProxy = !string.IsNullOrEmpty(proxyAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
_client = new HttpClient(httpClientHandler);
|
_apiClient = new HttpClient(httpClientHandler);
|
||||||
_client.BaseAddress = new Uri("http://api.themoviedb.org");
|
_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(true, true)).ToRunEvery(1).Days();
|
Schedule(() => Job(true, true)).ToRunEvery(1).Days();
|
||||||
}
|
}
|
||||||
@@ -49,397 +59,134 @@ public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task JobExecute(
|
||||||
private async Task JobExecute(bool ignoreLocked, bool ignoreCompleted)
|
bool ignoreLocked,
|
||||||
|
bool ignoreCompleted,
|
||||||
|
string[]? includeFields = null)
|
||||||
{
|
{
|
||||||
// 读取环境变量 tv folder
|
|
||||||
var tvFolder = _configuration["ChineseNfo:TvFolder"];
|
var tvFolder = _configuration["ChineseNfo:TvFolder"];
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(tvFolder))
|
if (string.IsNullOrEmpty(tvFolder))
|
||||||
{
|
{
|
||||||
Console.WriteLine("请设置环境变量 tv_folder");
|
_logger.LogError("ChineseNfoRegistry.Job() tvFolder is null or empty");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var successCount = 0;
|
/*
|
||||||
var failedCount = 0;
|
* 1. 支持指定字段
|
||||||
var skippedCount = 0;
|
* 2. 接口数据保留
|
||||||
|
* 3. 支持语言降级到繁体
|
||||||
|
* 4. 支持演员名称翻译
|
||||||
|
*/
|
||||||
|
|
||||||
// 扫描 tvshow.nfo 文件
|
var fields =
|
||||||
var tvShowFiles = Directory.GetFiles(tvFolder, "tvshow.nfo", SearchOption.AllDirectories);
|
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",
|
||||||
|
];
|
||||||
|
|
||||||
foreach (var tvShowFile in tvShowFiles)
|
var tvNfos = Directory.GetFiles(tvFolder, "tvshow.nfo", SearchOption.AllDirectories);
|
||||||
|
|
||||||
|
if (tvNfos.Length == 0)
|
||||||
{
|
{
|
||||||
var nfoContent = File.ReadAllText(tvShowFile);
|
_logger.LogError("ChineseNfoRegistry.Job() tvNfo is null or empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var tv in tvNfos)
|
||||||
|
{
|
||||||
|
await HandleTv(tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async Task<string[]?> HandleTv(string tvNfo)
|
||||||
|
{
|
||||||
|
var nfoContent = File.ReadAllText(tvNfo);
|
||||||
|
|
||||||
// 读取 使用XML解析器 读取 <uniqueid type="tmdb">60059</uniqueid>
|
|
||||||
var tvXml = new XmlDocument();
|
var tvXml = new XmlDocument();
|
||||||
tvXml.LoadXml(nfoContent);
|
tvXml.LoadXml(nfoContent);
|
||||||
var uniqueIdNode = tvXml.SelectSingleNode("//uniqueid[@type='tmdb']");
|
var uniqueIdNode = tvXml.SelectSingleNode("//uniqueid[@type='tmdb']");
|
||||||
|
|
||||||
if (uniqueIdNode == null)
|
if (uniqueIdNode == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{tvShowFile} & 未找到 tmdb id");
|
_logger.LogError("ChineseNfoRegistry.Job() uniqueIdNode is null");
|
||||||
continue;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!int.TryParse(uniqueIdNode.InnerText, out var tmdbId))
|
if (!int.TryParse(uniqueIdNode.InnerText, out var tmdbId))
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{tvShowFile} & tmdb id 不是数字");
|
_logger.LogError("ChineseNfoRegistry.Job() tmdbId is null");
|
||||||
continue;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
await SetTvInfo(tvShowFile, tvXml, tmdbId);
|
var a = await GetTmdbTv(tvNfo, tmdbId);
|
||||||
|
|
||||||
// 获取 tvShowFile 的文件夹
|
_logger.LogInformation("ChineseNfoRegistry.Job() tmdbId: {tmdbId}, name: {name}", tmdbId,a?["name"]?.ToString());
|
||||||
var folderPath = Path.GetDirectoryName(tvShowFile);
|
return [];
|
||||||
|
|
||||||
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 episodeFile in seasonFiles)
|
|
||||||
{
|
|
||||||
await SetEpisodeInfo(episodeFile, tmdbId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await WxNotify.SendCommonAsync($"ChineseNfoRegistry.Job() success: {successCount}, failed: {failedCount}, skipped: {skippedCount}");
|
|
||||||
|
|
||||||
async Task SetTvInfo(string tvShowFile,XmlDocument tvXml, int tmdbId)
|
|
||||||
{
|
|
||||||
// 检查 lockdata
|
|
||||||
var lockedNode = tvXml.SelectSingleNode("//lockdata");
|
|
||||||
if (lockedNode != null && lockedNode.InnerText == "true" && ignoreLocked == false)
|
|
||||||
{
|
|
||||||
skippedCount++;
|
|
||||||
Console.WriteLine($"{tvShowFile} & 已锁定");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取tv info
|
|
||||||
var tvJson = await GetTmdbTv(tvShowFile, tmdbId);
|
|
||||||
|
|
||||||
if (tvJson == null)
|
|
||||||
{
|
|
||||||
failedCount++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var title = tvJson["name"]?.ToString();
|
|
||||||
var overview = tvJson["overview"]?.ToString();
|
|
||||||
var poster =tvJson["poster_path"]?.ToString();
|
|
||||||
var genres = tvJson["genres"]
|
|
||||||
?.AsArray()
|
|
||||||
.Select(x => x?["name"]?.ToString())
|
|
||||||
.Where(x=> !string.IsNullOrEmpty(x))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(title))
|
|
||||||
{
|
|
||||||
title = $"<![CDATA[{title}]]>";
|
|
||||||
var titleNode = tvXml.SelectSingleNode("//title");
|
|
||||||
if (titleNode != null)
|
|
||||||
{
|
|
||||||
if (titleNode.InnerXml != title)
|
|
||||||
{
|
|
||||||
titleNode.InnerXml = title;
|
|
||||||
successCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sorttitleNode = tvXml.SelectSingleNode("//sorttitle");
|
|
||||||
if (sorttitleNode != null)
|
|
||||||
{
|
|
||||||
if (sorttitleNode.InnerXml != title)
|
|
||||||
{
|
|
||||||
sorttitleNode.InnerXml = title;
|
|
||||||
successCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(overview))
|
|
||||||
{
|
|
||||||
overview = $"<![CDATA[{overview}]]>";
|
|
||||||
var plotNode = tvXml.SelectSingleNode("//plot");
|
|
||||||
if (plotNode != null)
|
|
||||||
{
|
|
||||||
if (plotNode.InnerXml != overview)
|
|
||||||
{
|
|
||||||
plotNode.InnerXml = overview;
|
|
||||||
successCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var outlineNode = tvXml.SelectSingleNode("//outline");
|
|
||||||
if (outlineNode != null)
|
|
||||||
{
|
|
||||||
if (outlineNode.InnerXml != overview)
|
|
||||||
{
|
|
||||||
outlineNode.InnerXml = overview;
|
|
||||||
successCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(poster))
|
|
||||||
{
|
|
||||||
poster = $"http://image.tmdb.org/t/p/w1280/{poster}";
|
|
||||||
// 下载并覆盖海报
|
|
||||||
var posterPath = tvShowFile.Replace("tvshow.nfo", $"poster.{poster.Split('.').Last()}");
|
|
||||||
|
|
||||||
using var client = new HttpClient();
|
|
||||||
var response = await client.GetAsync(poster);
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
var bytes = await response.Content.ReadAsByteArrayAsync();
|
|
||||||
|
|
||||||
if (File.Exists(posterPath))
|
|
||||||
{
|
|
||||||
File.Delete(posterPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
await File.WriteAllBytesAsync(posterPath, bytes);
|
|
||||||
successCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (genres?.Any() == true)
|
|
||||||
{
|
|
||||||
// 删除原有的 <genre> 节点
|
|
||||||
var genreNodes = tvXml.SelectNodes("//genre");
|
|
||||||
if (genreNodes != null)
|
|
||||||
{
|
|
||||||
foreach (XmlNode genreNode in genreNodes)
|
|
||||||
{
|
|
||||||
tvXml.DocumentElement?.RemoveChild(genreNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加新的 <genre> 节点
|
|
||||||
foreach (var genre in genres)
|
|
||||||
{
|
|
||||||
var genreNode = tvXml.CreateElement("genre");
|
|
||||||
genreNode.InnerText = genre!;
|
|
||||||
tvXml.DocumentElement?.AppendChild(genreNode);
|
|
||||||
}
|
|
||||||
successCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (successCount == 0)
|
|
||||||
{
|
|
||||||
skippedCount++;
|
|
||||||
Console.WriteLine($"{tvShowFile} & 无更新");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 锁定节点
|
|
||||||
if(lockedNode == null)
|
|
||||||
{
|
|
||||||
lockedNode = tvXml.CreateElement("lockdata");
|
|
||||||
tvXml.DocumentElement?.AppendChild(lockedNode);
|
|
||||||
lockedNode.InnerText = "true";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lockedNode.InnerText = "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加一个已完成节点
|
|
||||||
var completedNode = tvXml.SelectSingleNode("//completed");
|
|
||||||
if (completedNode == null)
|
|
||||||
{
|
|
||||||
completedNode = tvXml.CreateElement("completed");
|
|
||||||
tvXml.DocumentElement?.AppendChild(completedNode);
|
|
||||||
}
|
|
||||||
completedNode.InnerText = "true";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tvXml.Save(tvShowFile);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e);
|
|
||||||
failedCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task SetEpisodeInfo(string episodeFile, int tmdbId)
|
|
||||||
{
|
|
||||||
var episodeContent = await File.ReadAllTextAsync(episodeFile);
|
|
||||||
var episodeXml = new XmlDocument();
|
|
||||||
episodeXml.LoadXml(episodeContent);
|
|
||||||
|
|
||||||
// 判断有无 completed 节点
|
|
||||||
var completedNode = episodeXml.SelectSingleNode("//completed");
|
|
||||||
if (completedNode != null && ignoreCompleted == false)
|
|
||||||
{
|
|
||||||
skippedCount++;
|
|
||||||
Console.WriteLine($"{episodeFile} & 已完成");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断 locked == true
|
|
||||||
var lockedNode = episodeXml.SelectSingleNode("//lockdata");
|
|
||||||
if (lockedNode != null && lockedNode.InnerText == "true" && ignoreLocked == false)
|
|
||||||
{
|
|
||||||
skippedCount++;
|
|
||||||
Console.WriteLine($"{episodeFile} & 已锁定");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 读取 <season>1</season>
|
|
||||||
var seasonNode = episodeXml.SelectSingleNode("//season");
|
|
||||||
if (seasonNode == null)
|
|
||||||
{
|
|
||||||
failedCount++;
|
|
||||||
Console.WriteLine($"{episodeFile} & 未找到 season");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 读取 <episode>1</episode>
|
|
||||||
var episodeNode = episodeXml.SelectSingleNode("//episode");
|
|
||||||
if (episodeNode == null)
|
|
||||||
{
|
|
||||||
failedCount++;
|
|
||||||
Console.WriteLine($"{episodeFile} & 未找到 episode");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!int.TryParse(seasonNode.InnerText, out var season))
|
|
||||||
{
|
|
||||||
failedCount++;
|
|
||||||
Console.WriteLine($"{episodeFile} & season 不是数字");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!int.TryParse(episodeNode.InnerText, out var episode))
|
|
||||||
{
|
|
||||||
failedCount++;
|
|
||||||
Console.WriteLine($"{episodeFile} & episode 不是数字");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置 title
|
|
||||||
var titleNode = episodeXml.SelectSingleNode("//title");
|
|
||||||
if (titleNode == null)
|
|
||||||
{
|
|
||||||
failedCount++;
|
|
||||||
Console.WriteLine($"{episodeFile} & 未找到 title");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var json = await GetTmdbEpisode(
|
|
||||||
episodeFile,
|
|
||||||
tmdbId,
|
|
||||||
season,
|
|
||||||
episode);
|
|
||||||
|
|
||||||
if (json == null)
|
|
||||||
{
|
|
||||||
failedCount++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
skippedCount++;
|
|
||||||
Console.WriteLine($"{episodeFile} & 无更新");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
successCount++;
|
|
||||||
|
|
||||||
// 添加一个已完成节点
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
episodeXml.Save(episodeFile);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine($"{episodeFile} & {title} & {overview}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<JsonObject?> GetTmdbTv(
|
private async Task<JObject?> GetTmdbTv(
|
||||||
string path,
|
string path,
|
||||||
int tmdbId)
|
int tmdbId,
|
||||||
|
TheMovieDbLanguage language = TheMovieDbLanguage.ZhCn)
|
||||||
{
|
{
|
||||||
|
var record = await _freeSql.Select<TheMovieDbRecord>()
|
||||||
|
.Where(x => x.UniqueId == tmdbId.ToString())
|
||||||
|
.FirstAsync();
|
||||||
|
|
||||||
|
if (record != null)
|
||||||
|
{
|
||||||
|
return JObject.Parse(record.Json);
|
||||||
|
}
|
||||||
|
|
||||||
|
record = new TheMovieDbRecord
|
||||||
|
{
|
||||||
|
Type = TheMovieDbType.Tv,
|
||||||
|
UniqueId = tmdbId.ToString(),
|
||||||
|
Language = language
|
||||||
|
};
|
||||||
|
|
||||||
const string tvUrl = "/3/tv/{0}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN";
|
const string tvUrl = "/3/tv/{0}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN";
|
||||||
var requestUrl = string.Format(tvUrl, tmdbId);
|
var requestUrl = string.Format(tvUrl, tmdbId);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await _client.GetAsync(requestUrl);
|
var response = await _apiClient.GetAsync(requestUrl);
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{requestUrl} & {path} & {response.StatusCode}");
|
Console.WriteLine($"{requestUrl} & {path} & {response.StatusCode}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.Delay(10000);
|
|
||||||
|
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var str = await response.Content.ReadAsStringAsync();
|
||||||
var json = JsonNode.Parse(content);
|
|
||||||
return json as JsonObject;
|
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)
|
||||||
|
{
|
||||||
|
// 降级到繁体
|
||||||
|
return await GetTmdbTv(path, tmdbId, TheMovieDbLanguage.ZhTw);
|
||||||
|
}
|
||||||
|
|
||||||
|
record.Json = str;
|
||||||
|
_freeSql.Insert(record);
|
||||||
|
|
||||||
|
return json;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -447,36 +194,30 @@ public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private async Task<JsonObject?> GetTmdbEpisode(
|
|
||||||
string path,
|
|
||||||
int tmdbId,
|
|
||||||
int season,
|
|
||||||
int episode)
|
|
||||||
{
|
|
||||||
const string episodeUrl = "/3/tv/{0}/season/{1}/episode/{2}?api_key=e28e1bc408db7adefc8bacce225c5085&language=zh-CN";
|
|
||||||
var requestUrl = string.Format(episodeUrl, tmdbId, season, episode);
|
|
||||||
|
|
||||||
try
|
public class TheMovieDbRecord
|
||||||
{
|
{
|
||||||
var response = await _client.GetAsync(requestUrl);
|
public long Id { get; set; }
|
||||||
|
|
||||||
await Task.Delay(10000);
|
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"{requestUrl} & {path} & {response.StatusCode}");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
public TheMovieDbType Type { get; set; }
|
||||||
var json = JsonNode.Parse(content);
|
|
||||||
return json as JsonObject;
|
public string UniqueId { get; set; } = string.Empty;
|
||||||
}
|
|
||||||
catch (Exception e)
|
public TheMovieDbLanguage Language { get; set; }
|
||||||
{
|
|
||||||
Console.WriteLine($"{requestUrl} & {path} \r {e}");
|
[Column(DbType = "varchar(max)")] public string Json { get; set; } = string.Empty;
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
}
|
public enum TheMovieDbType
|
||||||
|
{
|
||||||
|
Tv = 1,
|
||||||
|
Season = 2,
|
||||||
|
Episode = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TheMovieDbLanguage
|
||||||
|
{
|
||||||
|
ZhCn = 1,
|
||||||
|
ZhTw = 2
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="FreeSql" Version="3.5.201" />
|
||||||
|
<PackageReference Include="FreeSql.Provider.Sqlite" Version="3.5.200" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
],
|
],
|
||||||
"ChineseNfo": {
|
"ChineseNfo": {
|
||||||
"TvFolder": "/data/media",
|
"TvFolder": "/data/media",
|
||||||
"HttpProxy": ""
|
"HttpProxy": "",
|
||||||
|
"ConnectionString": "Data Source=/app/data/chinesenfo.db;"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user