226 lines
7.0 KiB
C#
226 lines
7.0 KiB
C#
using System.Net;
|
|
using Newtonsoft.Json;
|
|
using TMDbLib.Client;
|
|
|
|
namespace ConsoleApp1;
|
|
|
|
public class ShowSession
|
|
{
|
|
public string session;
|
|
public List<EpisodeInfo> extras = new List<EpisodeInfo>();
|
|
public List<EpisodeInfo> episodes = new List<EpisodeInfo>();
|
|
}
|
|
|
|
public class Show
|
|
{
|
|
public string rawTitle;
|
|
public string title;
|
|
public string year;
|
|
public string tmdbId;
|
|
public List<ShowSession> sessions = new List<ShowSession>();
|
|
}
|
|
|
|
public class ShowsManager
|
|
{
|
|
private List<Show> _shows = new List<Show>();
|
|
|
|
private TMDbClient _client;
|
|
|
|
public ShowsManager()
|
|
{
|
|
_client = new TMDbClient("991107af25913562cfa06622a52873e1", proxy: new WebProxy("http://127.0.0.1:7897"));
|
|
}
|
|
|
|
private static Show FindOrCreateShow(List<Show> shows, string rawTitle)
|
|
{
|
|
foreach (var show in shows)
|
|
{
|
|
if (show.rawTitle == rawTitle)
|
|
{
|
|
return show;
|
|
}
|
|
}
|
|
|
|
var result = new Show();
|
|
result.rawTitle = rawTitle;
|
|
shows.Add(result);
|
|
return result;
|
|
}
|
|
|
|
private static ShowSession FindOrCreateShowSession(List<ShowSession> sessions, string sessionNumber)
|
|
{
|
|
foreach (var session in sessions)
|
|
{
|
|
if (session.session == sessionNumber)
|
|
{
|
|
return session;
|
|
}
|
|
}
|
|
var result = new ShowSession();
|
|
result.session = sessionNumber;
|
|
sessions.Add(result);
|
|
return result;
|
|
}
|
|
|
|
private static string LCP(string str1, string str2)
|
|
{
|
|
if (string.IsNullOrEmpty(str1) || string.IsNullOrEmpty(str2))
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
int minLength = Math.Min(str1.Length, str2.Length);
|
|
int i = 0;
|
|
|
|
while (i < minLength && str1[i] == str2[i])
|
|
{
|
|
i++;
|
|
}
|
|
|
|
return str1.Substring(0, i);
|
|
}
|
|
|
|
public static string CalcBasePathOfSessionExtras(ShowSession session)
|
|
{
|
|
if(session.extras.Count == 0) return string.Empty;
|
|
var result = session.extras[0].path;
|
|
foreach (var extra in session.extras)
|
|
{
|
|
result = LCP(result, extra.path);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public void AppendEpisodeFromFile(string path)
|
|
{
|
|
var resultsJson = File.ReadAllText(path);
|
|
var results = JsonConvert.DeserializeObject<List<EpisodeInfo>>(resultsJson);
|
|
foreach (var episode in results)
|
|
{
|
|
AppendEpisode(episode);
|
|
}
|
|
}
|
|
|
|
public void AppendEpisode(EpisodeInfo episode)
|
|
{
|
|
var show = FindOrCreateShow(_shows, episode.name);
|
|
var session = FindOrCreateShowSession(show.sessions, episode.session);
|
|
if (episode.type == "others")
|
|
{
|
|
session.extras.Add(episode);
|
|
}
|
|
else
|
|
{
|
|
session.episodes.Add(episode);
|
|
}
|
|
}
|
|
|
|
public async Task QueryTMDB(Dictionary<string, string> mapping)
|
|
{
|
|
int current = 0;
|
|
foreach (var show in _shows)
|
|
{
|
|
current++;
|
|
Console.WriteLine($"{current}/{_shows.Count}");
|
|
var title = show.rawTitle;
|
|
if(mapping.TryGetValue(title, out var value)) title = value;
|
|
var result = await _client.SearchTvShowAsync(title, language:"zh-CN");
|
|
if (result == null || result.Results.Count == 0) continue;
|
|
var tv = result.Results[0];
|
|
show.title = tv.Name;
|
|
show.year = tv.FirstAirDate.Value.Year.ToString();
|
|
show.tmdbId = tv.Id.ToString();
|
|
}
|
|
}
|
|
|
|
public void Dump(string path)
|
|
{
|
|
var result = JsonConvert.SerializeObject(_shows, Formatting.Indented);
|
|
File.WriteAllText(path, result);
|
|
}
|
|
|
|
public void Load(string path)
|
|
{
|
|
var json = File.ReadAllText(path);
|
|
_shows = JsonConvert.DeserializeObject<List<Show>>(json);
|
|
}
|
|
|
|
private string AddZero(string s)
|
|
{
|
|
if(s.Length == 1) return $"0{s}";
|
|
return s;
|
|
}
|
|
|
|
private string AddNumberToFileName(string path, int n)
|
|
{
|
|
return Path.Combine(Path.GetDirectoryName(path)??"",
|
|
Path.GetFileNameWithoutExtension(path) + $"({n})" + Path.GetExtension(path));
|
|
}
|
|
|
|
public void MoveFiles(string basePath, string targetBasePath)
|
|
{
|
|
HashSet<string> files = new HashSet<string>();
|
|
Queue<(string, string)> moves = new Queue<(string, string)>();
|
|
|
|
foreach (var show in _shows)
|
|
{
|
|
foreach (var session in show.sessions)
|
|
{
|
|
foreach (var episode in session.episodes)
|
|
{
|
|
var oldPath = Path.Combine(basePath, episode.path);
|
|
var newSubPath = $"{show.title} ({show.year})/Season {session.session}/{show.title} ({show.year}) S{AddZero(episode.session)}E{AddZero(episode.episode)} [{episode.group}]";
|
|
if (episode.type == "subtitle" && !string.IsNullOrEmpty(episode.language))
|
|
{
|
|
newSubPath += $".{episode.language}";
|
|
}
|
|
newSubPath += Path.GetExtension(episode.path);
|
|
var newPath = Path.Combine(targetBasePath, newSubPath);
|
|
|
|
var testPath = newPath;
|
|
int n = 0;
|
|
while (files.Contains(testPath))
|
|
{
|
|
testPath = AddNumberToFileName(newPath, ++n);
|
|
}
|
|
newPath = testPath;
|
|
|
|
files.Add(newPath);
|
|
moves.Enqueue((oldPath, newPath));
|
|
Console.WriteLine($"{oldPath} -> {newPath}");
|
|
}
|
|
|
|
|
|
var extraPath = CalcBasePathOfSessionExtras(session);
|
|
foreach (var episode in session.extras)
|
|
{
|
|
var oldPath = Path.Combine(basePath, episode.path);
|
|
var newSubPath = $"{show.title} ({show.year})/Season {session.session}/extras";
|
|
var subPath = episode.path.Substring(extraPath.Length);
|
|
var newPath = Path.Combine(targetBasePath, newSubPath, subPath);
|
|
|
|
var testPath = newPath;
|
|
int n = 0;
|
|
while (files.Contains(testPath))
|
|
{
|
|
testPath = AddNumberToFileName(newPath, ++n);
|
|
}
|
|
newPath = testPath;
|
|
|
|
files.Add(newPath);
|
|
moves.Enqueue((oldPath, newPath));
|
|
Console.WriteLine($"{oldPath} -> {newPath}");
|
|
}
|
|
}
|
|
}
|
|
|
|
while (moves.Count > 0)
|
|
{
|
|
var move = moves.Dequeue();
|
|
if (!File.Exists(move.Item1)) continue;
|
|
Directory.CreateDirectory(Path.GetDirectoryName(move.Item2));
|
|
File.Move(move.Item1, move.Item2);
|
|
Console.WriteLine($"{move.Item1} -> {move.Item2}");
|
|
}
|
|
}
|
|
} |