diff --git a/src/Service/Jobs/ChineseNfoRegistry.cs b/src/Service/Jobs/ChineseNfoRegistry.cs
index 3706d5c..193396b 100644
--- a/src/Service/Jobs/ChineseNfoRegistry.cs
+++ b/src/Service/Jobs/ChineseNfoRegistry.cs
@@ -64,15 +64,6 @@ public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
var failedCount = 0;
var skippedCount = 0;
- // 使用 root 角色执行 chmod -R 666 设置全部文件的读写权限
- var permission = new ProcessStartInfo("chmod", "-R 777 " + tvFolder)
- {
- CreateNoWindow = true,
- UseShellExecute = false
- };
- Process.Start(permission);
-
-
// 扫描 tvshow.nfo 文件
var tvShowFiles = Directory.GetFiles(tvFolder, "tvshow.nfo", SearchOption.AllDirectories);
@@ -96,6 +87,10 @@ public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
continue;
}
+ await SetTvInfo(tvShowFile, tvXml, tmdbId);
+
+ await Task.Delay(10000);
+
// 获取 tvShowFile 的文件夹
var folderPath = Path.GetDirectoryName(tvShowFile);
@@ -112,155 +107,347 @@ public class ChineseNfoRegistry : Registry, IChineseNfoRegistry
foreach (var episodeFile in seasonFiles)
{
- 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} & 已完成");
- continue;
- }
-
- // 判断 locked == true
- var lockedNode = episodeXml.SelectSingleNode("//lockdata");
- if (lockedNode != null && lockedNode.InnerText == "true" && ignoreLocked == false)
- {
- skippedCount++;
- Console.WriteLine($"{episodeFile} & 已锁定");
- continue;
- }
-
- // 读取 1
- var seasonNode = episodeXml.SelectSingleNode("//season");
- if (seasonNode == null)
- {
- failedCount++;
- Console.WriteLine($"{episodeFile} & 未找到 season");
- continue;
- }
-
- // 读取 1
- var episodeNode = episodeXml.SelectSingleNode("//episode");
- if (episodeNode == null)
- {
- failedCount++;
- Console.WriteLine($"{episodeFile} & 未找到 episode");
- continue;
- }
-
- if (!int.TryParse(seasonNode.InnerText, out var season))
- {
- failedCount++;
- Console.WriteLine($"{episodeFile} & season 不是数字");
- continue;
- }
-
- if (!int.TryParse(episodeNode.InnerText, out var episode))
- {
- failedCount++;
- Console.WriteLine($"{episodeFile} & episode 不是数字");
- continue;
- }
-
- // 设置 title
- var titleNode = episodeXml.SelectSingleNode("//title");
- if (titleNode == null)
- {
- failedCount++;
- Console.WriteLine($"{episodeFile} & 未找到 title");
- continue;
- }
-
- var json = await GetTmdbEpisode(
- episodeFile,
- tmdbId,
- season,
- episode);
-
- if (json == null)
- {
- failedCount++;
- continue;
- }
-
- var title = json["name"]?.ToString();
- var overview = json["overview"]?.ToString();
-
- var isUpdate = false;
- if (!string.IsNullOrEmpty(title))
- {
- title = $"";
-
- if (titleNode.InnerXml != title)
- {
- isUpdate = true;
- // 写入且不转义
- titleNode.InnerXml = title;
- }
- }
-
- var plotNode = episodeXml.SelectSingleNode("//plot");
-
- if (!string.IsNullOrEmpty(overview) && plotNode != null)
- {
- overview = $"";
- if (plotNode.InnerXml != overview)
- {
- isUpdate = true;
- plotNode.InnerXml = overview;
- }
- }
-
- if (!isUpdate)
- {
- skippedCount++;
- Console.WriteLine($"{episodeFile} & 无更新");
- continue;
- }
-
- 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);
- continue;
- }
-
- Console.WriteLine($"{episodeFile} & {title} & {overview}");
+ await SetEpisodeInfo(episodeFile, tmdbId);
await Task.Delay(10000);
}
}
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 = $"";
+ 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 = $"";
+ 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 = $"https://image.tmdb.org/t/p/w1280/{poster}";
+ // 下载并覆盖海报
+ var posterPath = tvShowFile.Replace("tvshow.nfo", $"poster.{poster.Split('.').Last()}");
+
+ if (File.Exists(posterPath))
+ {
+ File.Delete(posterPath);
+ }
+
+ using var client = new HttpClient();
+ var response = await client.GetAsync(poster);
+ if (response.IsSuccessStatusCode)
+ {
+ var bytes = await response.Content.ReadAsByteArrayAsync();
+ await File.WriteAllBytesAsync(posterPath, bytes);
+ successCount++;
+ }
+ }
+
+
+ if (genres?.Any() == true)
+ {
+ // 删除原有的 节点
+ var genreNodes = tvXml.SelectNodes("//genre");
+ if (genreNodes != null)
+ {
+ foreach (XmlNode genreNode in genreNodes)
+ {
+ tvXml.DocumentElement?.RemoveChild(genreNode);
+ }
+ }
+
+ // 添加新的 节点
+ 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;
+ }
+
+ // 读取 1
+ var seasonNode = episodeXml.SelectSingleNode("//season");
+ if (seasonNode == null)
+ {
+ failedCount++;
+ Console.WriteLine($"{episodeFile} & 未找到 season");
+ return;
+ }
+
+ // 读取 1
+ 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 = $"";
+
+ if (titleNode.InnerXml != title)
+ {
+ isUpdate = true;
+ // 写入且不转义
+ titleNode.InnerXml = title;
+ }
+ }
+
+ var plotNode = episodeXml.SelectSingleNode("//plot");
+
+ if (!string.IsNullOrEmpty(overview) && plotNode != null)
+ {
+ 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 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;
+ }
+
+ 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 GetTmdbEpisode(
string path,
int tmdbId,