mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-05-27 09:32:35 -04:00
Solving a bug with images and adding unit tests.
This commit is contained in:
+133
-120
@@ -26,7 +26,7 @@ namespace Kyoo.InternalAPI
|
||||
this.libraryManager = libraryManager;
|
||||
this.metadataProvider = metadataProvider;
|
||||
this.transcoder = transcoder;
|
||||
config = configuration;
|
||||
this.config = configuration;
|
||||
|
||||
cancellation = new CancellationTokenSource();
|
||||
}
|
||||
@@ -39,7 +39,7 @@ namespace Kyoo.InternalAPI
|
||||
private Task StartAsync(bool watch, CancellationToken cancellationToken)
|
||||
{
|
||||
Debug.WriteLine("&Crawler started");
|
||||
string[] paths = config.GetSection("libraryPaths").Get<string[]>();
|
||||
IEnumerable<string> paths = libraryManager.GetLibrariesPath();
|
||||
|
||||
foreach (string path in paths)
|
||||
{
|
||||
@@ -65,71 +65,72 @@ namespace Kyoo.InternalAPI
|
||||
return;
|
||||
|
||||
if (IsVideo(file))
|
||||
await TryRegisterEpisode(file);
|
||||
await ExtractEpisodeData(file, folderPath);
|
||||
}
|
||||
}
|
||||
|
||||
public void Watch(string folderPath, CancellationToken cancellationToken)
|
||||
{
|
||||
Debug.WriteLine("&Watching " + folderPath + " for changes");
|
||||
using (FileSystemWatcher watcher = new FileSystemWatcher())
|
||||
{
|
||||
watcher.Path = folderPath;
|
||||
watcher.IncludeSubdirectories = true;
|
||||
watcher.NotifyFilter = NotifyFilters.LastAccess
|
||||
| NotifyFilters.LastWrite
|
||||
| NotifyFilters.FileName
|
||||
| NotifyFilters.Size
|
||||
| NotifyFilters.DirectoryName;
|
||||
|
||||
watcher.Created += FileCreated;
|
||||
watcher.Changed += FileChanged;
|
||||
watcher.Renamed += FileRenamed;
|
||||
watcher.Deleted += FileDeleted;
|
||||
|
||||
|
||||
watcher.EnableRaisingEvents = true;
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested);
|
||||
}
|
||||
}
|
||||
|
||||
private void FileCreated(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("&File Created at " + e.FullPath);
|
||||
if (IsVideo(e.FullPath))
|
||||
{
|
||||
Debug.WriteLine("&Created file is a video");
|
||||
_ = TryRegisterEpisode(e.FullPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void FileChanged(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("&File Changed at " + e.FullPath);
|
||||
}
|
||||
|
||||
private void FileRenamed(object sender, RenamedEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("&File Renamed at " + e.FullPath);
|
||||
}
|
||||
|
||||
private void FileDeleted(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("&File Deleted at " + e.FullPath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async Task TryRegisterEpisode(string path)
|
||||
{
|
||||
if (!libraryManager.IsEpisodeRegistered(path))
|
||||
//Debug.WriteLine("&Watching " + folderPath + " for changes");
|
||||
//using (FileSystemWatcher watcher = new FileSystemWatcher())
|
||||
//{
|
||||
// watcher.Path = folderPath;
|
||||
// watcher.IncludeSubdirectories = true;
|
||||
// watcher.NotifyFilter = NotifyFilters.LastAccess
|
||||
// | NotifyFilters.LastWrite
|
||||
// | NotifyFilters.FileName
|
||||
// | NotifyFilters.Size
|
||||
// | NotifyFilters.DirectoryName;
|
||||
|
||||
// watcher.Created += FileCreated;
|
||||
// watcher.Changed += FileChanged;
|
||||
// watcher.Renamed += FileRenamed;
|
||||
// watcher.Deleted += FileDeleted;
|
||||
|
||||
|
||||
// watcher.EnableRaisingEvents = true;
|
||||
|
||||
// while (!cancellationToken.IsCancellationRequested);
|
||||
//}
|
||||
}
|
||||
|
||||
//private void FileCreated(object sender, FileSystemEventArgs e)
|
||||
//{
|
||||
// Debug.WriteLine("&File Created at " + e.FullPath);
|
||||
// if (IsVideo(e.FullPath))
|
||||
// {
|
||||
// Debug.WriteLine("&Created file is a video");
|
||||
// _ = TryRegisterEpisode(e.FullPath);
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void FileChanged(object sender, FileSystemEventArgs e)
|
||||
//{
|
||||
// Debug.WriteLine("&File Changed at " + e.FullPath);
|
||||
//}
|
||||
|
||||
//private void FileRenamed(object sender, RenamedEventArgs e)
|
||||
//{
|
||||
// Debug.WriteLine("&File Renamed at " + e.FullPath);
|
||||
//}
|
||||
|
||||
//private void FileDeleted(object sender, FileSystemEventArgs e)
|
||||
//{
|
||||
// Debug.WriteLine("&File Deleted at " + e.FullPath);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
private async Task ExtractEpisodeData(string episodePath, string libraryPath)
|
||||
{
|
||||
if (!libraryManager.IsEpisodeRegistered(episodePath))
|
||||
{
|
||||
string relativePath = episodePath.Substring(libraryPath.Length);
|
||||
string patern = config.GetValue<string>("regex");
|
||||
Regex regex = new Regex(patern, RegexOptions.IgnoreCase);
|
||||
Match match = regex.Match(path);
|
||||
Match match = regex.Match(relativePath);
|
||||
|
||||
string showPath = Path.GetDirectoryName(path);
|
||||
string showPath = Path.GetDirectoryName(episodePath);
|
||||
string collectionName = match.Groups["Collection"]?.Value;
|
||||
string showName = match.Groups["ShowTitle"].Value;
|
||||
bool seasonSuccess = long.TryParse(match.Groups["Season"].Value, out long seasonNumber);
|
||||
@@ -143,81 +144,93 @@ namespace Kyoo.InternalAPI
|
||||
episodeNumber = -1;
|
||||
|
||||
regex = new Regex(config.GetValue<string>("absoluteRegex"));
|
||||
match = regex.Match(path);
|
||||
match = regex.Match(relativePath);
|
||||
|
||||
showName = match.Groups["ShowTitle"].Value;
|
||||
bool absoluteSucess = long.TryParse(match.Groups["AbsoluteNumber"].Value, out absoluteNumber);
|
||||
|
||||
if (!absoluteSucess)
|
||||
{
|
||||
Debug.WriteLine("&Couldn't find basic data for the episode (regexs didn't match) at " + path);
|
||||
Debug.WriteLine("&Couldn't find basic data for the episode (regexs didn't match) at " + episodePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
string showProviderIDs;
|
||||
if (!libraryManager.IsShowRegistered(showPath, out long showID))
|
||||
{
|
||||
Show show = await metadataProvider.GetShowFromName(showName, showPath);
|
||||
showProviderIDs = show.ExternalIDs;
|
||||
showID = libraryManager.RegisterShow(show);
|
||||
Show show = await RegisterOrGetShow(collectionName, showName, showPath, libraryPath);
|
||||
await RegisterEpisode(show, seasonNumber, episodeNumber, absoluteNumber, episodePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (collectionName != null)
|
||||
private async Task<Show> RegisterOrGetShow(string collectionName, string showTitle, string showPath, string libraryPath)
|
||||
{
|
||||
string showProviderIDs;
|
||||
|
||||
if (!libraryManager.IsShowRegistered(showPath, out long showID))
|
||||
{
|
||||
Show show = await metadataProvider.GetShowFromName(showTitle, showPath);
|
||||
showProviderIDs = show.ExternalIDs;
|
||||
showID = libraryManager.RegisterShow(show);
|
||||
|
||||
libraryManager.RegisterInLibrary(showID, libraryPath);
|
||||
if (collectionName != null)
|
||||
{
|
||||
if (!libraryManager.IsCollectionRegistered(Slugifier.ToSlug(collectionName), out long collectionID))
|
||||
{
|
||||
if (!libraryManager.IsCollectionRegistered(Slugifier.ToSlug(collectionName), out long collectionID))
|
||||
Collection collection = await metadataProvider.GetCollectionFromName(collectionName);
|
||||
collectionID = libraryManager.RegisterCollection(collection);
|
||||
}
|
||||
libraryManager.AddShowToCollection(showID, collectionID);
|
||||
}
|
||||
|
||||
List<People> actors = await metadataProvider.GetPeople(show.ExternalIDs);
|
||||
libraryManager.RegisterShowPeople(showID, actors);
|
||||
}
|
||||
else
|
||||
showProviderIDs = libraryManager.GetShowExternalIDs(showID);
|
||||
|
||||
return new Show { id = showID, ExternalIDs = showProviderIDs, Title = showTitle };
|
||||
}
|
||||
|
||||
private async Task RegisterEpisode(Show show, long seasonNumber, long episodeNumber, long absoluteNumber, string episodePath)
|
||||
{
|
||||
long seasonID = -1;
|
||||
if (seasonNumber != -1)
|
||||
{
|
||||
if (!libraryManager.IsSeasonRegistered(show.id, seasonNumber, out seasonID))
|
||||
{
|
||||
Season season = await metadataProvider.GetSeason(show.Title, seasonNumber);
|
||||
season.ShowID = show.id;
|
||||
seasonID = libraryManager.RegisterSeason(season);
|
||||
}
|
||||
}
|
||||
|
||||
Episode episode = await metadataProvider.GetEpisode(show.ExternalIDs, seasonNumber, episodeNumber, absoluteNumber, episodePath);
|
||||
episode.ShowID = show.id;
|
||||
|
||||
if (seasonID == -1)
|
||||
{
|
||||
if (!libraryManager.IsSeasonRegistered(show.id, episode.seasonNumber, out seasonID))
|
||||
{
|
||||
Season season = await metadataProvider.GetSeason(show.Title, episode.seasonNumber);
|
||||
season.ShowID = show.id;
|
||||
seasonID = libraryManager.RegisterSeason(season);
|
||||
}
|
||||
}
|
||||
|
||||
episode.SeasonID = seasonID;
|
||||
episode.id = libraryManager.RegisterEpisode(episode);
|
||||
|
||||
if (episode.Path.EndsWith(".mkv"))
|
||||
{
|
||||
if (!FindExtractedSubtitles(episode))
|
||||
{
|
||||
Track[] tracks = transcoder.ExtractSubtitles(episode.Path);
|
||||
if (tracks != null)
|
||||
{
|
||||
foreach (Track track in tracks)
|
||||
{
|
||||
Collection collection = await metadataProvider.GetCollectionFromName(collectionName);
|
||||
collectionID = libraryManager.RegisterCollection(collection);
|
||||
}
|
||||
libraryManager.AddShowToCollection(showID, collectionID);
|
||||
}
|
||||
|
||||
List<People> actors = await metadataProvider.GetPeople(show.ExternalIDs);
|
||||
libraryManager.RegisterShowPeople(showID, actors);
|
||||
}
|
||||
else
|
||||
showProviderIDs = libraryManager.GetShowExternalIDs(showID);
|
||||
|
||||
long seasonID = -1;
|
||||
if (seasonNumber != -1)
|
||||
{
|
||||
if (!libraryManager.IsSeasonRegistered(showID, seasonNumber, out seasonID))
|
||||
{
|
||||
Season season = await metadataProvider.GetSeason(showName, seasonNumber);
|
||||
season.ShowID = showID;
|
||||
seasonID = libraryManager.RegisterSeason(season);
|
||||
}
|
||||
}
|
||||
|
||||
Episode episode = await metadataProvider.GetEpisode(showProviderIDs, seasonNumber, episodeNumber, absoluteNumber, path);
|
||||
episode.ShowID = showID;
|
||||
|
||||
if (seasonID == -1)
|
||||
{
|
||||
if (!libraryManager.IsSeasonRegistered(showID, episode.seasonNumber, out seasonID))
|
||||
{
|
||||
Season season = await metadataProvider.GetSeason(showName, episode.seasonNumber);
|
||||
season.ShowID = showID;
|
||||
seasonID = libraryManager.RegisterSeason(season);
|
||||
}
|
||||
}
|
||||
|
||||
episode.SeasonID = seasonID;
|
||||
long episodeID = libraryManager.RegisterEpisode(episode);
|
||||
episode.id = episodeID;
|
||||
|
||||
if (episode.Path.EndsWith(".mkv"))
|
||||
{
|
||||
if (!FindExtractedSubtitles(episode))
|
||||
{
|
||||
Track[] tracks = transcoder.ExtractSubtitles(episode.Path);
|
||||
if (tracks != null)
|
||||
{
|
||||
foreach (Track track in tracks)
|
||||
{
|
||||
track.episodeID = episode.id;
|
||||
libraryManager.RegisterTrack(track);
|
||||
}
|
||||
track.episodeID = episode.id;
|
||||
libraryManager.RegisterTrack(track);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ namespace Kyoo.InternalAPI
|
||||
List<Season> GetSeasons(long showID);
|
||||
int GetSeasonCount(string showSlug, long seasonNumber);
|
||||
IEnumerable<Show> GetShowsInCollection(long collectionID);
|
||||
IEnumerable<Show> GetShowsByPeople(long peopleID);
|
||||
IEnumerable<string> GetLibrariesPath();
|
||||
|
||||
//Internal HTML read
|
||||
(List<Track> audios, List<Track> subtitles) GetStreams(long episodeID, string showSlug);
|
||||
@@ -55,6 +57,7 @@ namespace Kyoo.InternalAPI
|
||||
|
||||
void RegisterShowPeople(long showID, List<People> actors);
|
||||
void AddShowToCollection(long showID, long collectionID);
|
||||
void RegisterInLibrary(long showID, string libraryPath);
|
||||
|
||||
void ClearSubtitles(long episodeID);
|
||||
}
|
||||
|
||||
@@ -88,12 +88,13 @@ namespace Kyoo.InternalAPI
|
||||
CREATE TABLE libraries(
|
||||
id INTEGER PRIMARY KEY UNIQUE,
|
||||
slug TEXT UNIQUE,
|
||||
name TEXT
|
||||
name TEXT,
|
||||
path TEXT
|
||||
);
|
||||
CREATE TABLE librariesLinks(
|
||||
librarieID INTEGER,
|
||||
libraryID INTEGER,
|
||||
showID INTEGER,
|
||||
FOREIGN KEY(librarieID) REFERENCES libraries(id),
|
||||
FOREIGN KEY(libraryID) REFERENCES libraries(id),
|
||||
FOREIGN KEY(showID) REFERENCES shows(id)
|
||||
);
|
||||
|
||||
@@ -190,6 +191,23 @@ namespace Kyoo.InternalAPI
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetLibrariesPath()
|
||||
{
|
||||
string query = "SELECT path FROM libraries;";
|
||||
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
List<string> libraries = new List<string>();
|
||||
|
||||
while (reader.Read())
|
||||
libraries.Add(reader["path"] as string);
|
||||
|
||||
return libraries;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetShowExternalIDs(long showID)
|
||||
{
|
||||
string query = string.Format("SELECT * FROM shows WHERE id = {0};", showID);
|
||||
@@ -561,6 +579,22 @@ namespace Kyoo.InternalAPI
|
||||
return shows;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Show> GetShowsByPeople(long peopleID)
|
||||
{
|
||||
string query = "SELECT * FROM shows JOIN peopleLinks l ON l.showID = shows.id WHERE l.peopleID = $id;";
|
||||
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("$id", peopleID);
|
||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
List<Show> shows = new List<Show>();
|
||||
while (reader.Read())
|
||||
shows.Add(Show.FromReader(reader));
|
||||
|
||||
return shows;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Check if items exists
|
||||
@@ -726,6 +760,18 @@ namespace Kyoo.InternalAPI
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterInLibrary(long showID, string libraryPath)
|
||||
{
|
||||
string query = "INSERT INTO librariesLinks (libraryID, showID) SELECT id, $showID FROM libraries WHERE libraries.path = $libraryPath;";
|
||||
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("$libraryPath", libraryPath);
|
||||
cmd.Parameters.AddWithValue("$showID", showID);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public long RegisterShow(Show show)
|
||||
{
|
||||
string query = "INSERT INTO shows (slug, title, aliases, path, overview, trailerUrl, startYear, endYear, imgPrimary, imgThumb, imgLogo, imgBackdrop, externalIDs) VALUES($slug, $title, $aliases, $path, $overview, $trailerUrl, $startYear, $endYear, $imgPrimary, $imgThumb, $imgLogo, $imgBackdrop, $externalIDs);";
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace Kyoo.InternalAPI
|
||||
}
|
||||
|
||||
Show show = Merge(datas);
|
||||
return thumbnailsManager.Validate(show);
|
||||
return await thumbnailsManager.Validate(show);
|
||||
}
|
||||
|
||||
public async Task<Season> GetSeason(string showName, long seasonNumber)
|
||||
@@ -151,13 +151,13 @@ namespace Kyoo.InternalAPI
|
||||
|
||||
Episode episode = Merge(datas);
|
||||
episode.Path = episodePath;
|
||||
return thumbnailsManager.Validate(episode);
|
||||
return await thumbnailsManager.Validate(episode);
|
||||
}
|
||||
|
||||
public async Task<List<People>> GetPeople(string id)
|
||||
{
|
||||
List<People> actors = await providers[0].GetPeople(id);
|
||||
return thumbnailsManager.Validate(actors);
|
||||
return await thumbnailsManager.Validate(actors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
using Kyoo.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
{
|
||||
public interface IThumbnailsManager
|
||||
{
|
||||
Show Validate(Show show);
|
||||
List<People> Validate(List<People> actors);
|
||||
Episode Validate(Episode episode);
|
||||
Task<Show> Validate(Show show);
|
||||
Task<List<People>> Validate(List<People> actors);
|
||||
Task<Episode> Validate(Episode episode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
{
|
||||
@@ -17,7 +18,7 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
config = configuration;
|
||||
}
|
||||
|
||||
public Show Validate(Show show)
|
||||
public async Task<Show> Validate(Show show)
|
||||
{
|
||||
string localThumb = Path.Combine(show.Path, "poster.jpg");
|
||||
string localLogo = Path.Combine(show.Path, "logo.png");
|
||||
@@ -30,7 +31,7 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
{
|
||||
using (WebClient client = new WebClient())
|
||||
{
|
||||
client.DownloadFileAsync(new Uri(show.ImgPrimary), localThumb);
|
||||
await client.DownloadFileTaskAsync(new Uri(show.ImgPrimary), localThumb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +42,7 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
{
|
||||
using (WebClient client = new WebClient())
|
||||
{
|
||||
client.DownloadFileAsync(new Uri(show.ImgLogo), localLogo);
|
||||
await client.DownloadFileTaskAsync(new Uri(show.ImgLogo), localLogo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +53,7 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
{
|
||||
using (WebClient client = new WebClient())
|
||||
{
|
||||
client.DownloadFileAsync(new Uri(show.ImgBackdrop), localBackdrop);
|
||||
await client.DownloadFileTaskAsync(new Uri(show.ImgBackdrop), localBackdrop);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +61,7 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
return show;
|
||||
}
|
||||
|
||||
public List<People> Validate(List<People> people)
|
||||
public async Task<List<People>> Validate(List<People> people)
|
||||
{
|
||||
for (int i = 0; i < people?.Count; i++)
|
||||
{
|
||||
@@ -73,7 +74,7 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
using (WebClient client = new WebClient())
|
||||
{
|
||||
Debug.WriteLine("&" + localThumb);
|
||||
client.DownloadFileAsync(new Uri(people[i].imgPrimary), localThumb);
|
||||
await client.DownloadFileTaskAsync(new Uri(people[i].imgPrimary), localThumb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,7 +82,7 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
return people;
|
||||
}
|
||||
|
||||
public Episode Validate(Episode episode)
|
||||
public async Task<Episode> Validate(Episode episode)
|
||||
{
|
||||
//string localThumb = Path.ChangeExtension(episode.Path, "jpg");
|
||||
string localThumb = episode.Path.Replace(Path.GetExtension(episode.Path), "-thumb.jpg");
|
||||
@@ -89,7 +90,7 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
|
||||
{
|
||||
using (WebClient client = new WebClient())
|
||||
{
|
||||
client.DownloadFileAsync(new Uri(episode.ImgPrimary), localThumb);
|
||||
await client.DownloadFileTaskAsync(new Uri(episode.ImgPrimary), localThumb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user