diff --git a/Kyoo.Common/Controllers/ILibraryManager.cs b/Kyoo.Common/Controllers/ILibraryManager.cs index b380608d..1357fc9d 100644 --- a/Kyoo.Common/Controllers/ILibraryManager.cs +++ b/Kyoo.Common/Controllers/ILibraryManager.cs @@ -54,16 +54,12 @@ namespace Kyoo.Controllers long RegisterShow(Show show); long RegisterSeason(Season season); long RegisterEpisode(Episode episode); - void RegisterTrack(Track track); + long RegisterTrack(Track track); + void RegisterShowLinks(Library library, Collection collection, Show show); - long GetOrCreateGenre(Genre genre); - long GetOrCreateStudio(Studio studio); - - void RegisterShowPeople(long showID, IEnumerable actors); - void AddShowToCollection(long showID, long collectionID); - void RegisterInLibrary(long showID, Library library); - - void RemoveEpisode(Episode episode); + void RemoveShow(long showID); + void RemoveSeason(long seasonID); + void RemoveEpisode(long episodeID); void ClearSubtitles(long episodeID); } } diff --git a/Kyoo.Common/Kyoo.Common.csproj b/Kyoo.Common/Kyoo.Common.csproj index 131dda1e..6d446f94 100644 --- a/Kyoo.Common/Kyoo.Common.csproj +++ b/Kyoo.Common/Kyoo.Common.csproj @@ -16,7 +16,6 @@ - diff --git a/Kyoo.Common/Models/Collection.cs b/Kyoo.Common/Models/Collection.cs index 60eeddd2..ada746d0 100644 --- a/Kyoo.Common/Models/Collection.cs +++ b/Kyoo.Common/Models/Collection.cs @@ -1,5 +1,4 @@ -using Kyoo.Controllers; -using Newtonsoft.Json; +using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; @@ -7,7 +6,7 @@ namespace Kyoo.Models { public class Collection : IMergable { - [JsonIgnore] public long ID { get; set; } = -1; + [JsonIgnore] public long ID { get; set; } public string Slug { get; set; } public string Name { get; set; } public string Poster { get; set; } @@ -17,40 +16,22 @@ namespace Kyoo.Models public Collection() { } - public Collection(long id, string slug, string name, string overview, string imgPrimary) + public Collection(string slug, string name, string overview, string imgPrimary) { - ID = id; Slug = slug; Name = name; Overview = overview; ImgPrimary = imgPrimary; } - public static Collection FromReader(System.Data.SQLite.SQLiteDataReader reader) - { - Collection col = new Collection((long) reader["id"], - reader["slug"] as string, - reader["name"] as string, - reader["overview"] as string, - reader["imgPrimary"] as string); - col.Poster = "poster/" + col.Slug; - return col; - } - public Show AsShow() { - return new Show(-1, Slug, Name, null, null, Overview, null, null, null, null, null, null) + return new Show(Slug, Name, null, null, Overview, null, null, null, null, null, null) { IsCollection = true }; } - public Collection SetShows(ILibraryManager libraryManager) - { - Shows = libraryManager.GetShowsInCollection(ID); - return this; - } - public Collection Merge(Collection collection) { if (collection == null) diff --git a/Kyoo.Common/Models/Episode.cs b/Kyoo.Common/Models/Episode.cs index fe386702..f76d5078 100644 --- a/Kyoo.Common/Models/Episode.cs +++ b/Kyoo.Common/Models/Episode.cs @@ -1,5 +1,6 @@ using Newtonsoft.Json; using System; +using System.Collections.Generic; namespace Kyoo.Models { @@ -7,9 +8,9 @@ namespace Kyoo.Models { [JsonIgnore] public long ID { get; set; } [JsonIgnore] public long ShowID { get; set; } - public virtual Show Show { get; set; } + [JsonIgnore] public virtual Show Show { get; set; } [JsonIgnore] public long SeasonID { get; set; } - public virtual Season Season { get; set; } + [JsonIgnore] public virtual Season Season { get; set; } public long SeasonNumber { get; set; } public long EpisodeNumber { get; set; } @@ -24,6 +25,8 @@ namespace Kyoo.Models [JsonIgnore] public string ImgPrimary { get; set; } public string ExternalIDs { get; set; } + public IEnumerable Tracks { get; set; } + public string ShowTitle; //Used in the API response only public string Link; //Used in the API response only public string Thumb; //Used in the API response only @@ -31,20 +34,14 @@ namespace Kyoo.Models public Episode() { - ID = -1; - ShowID = -1; - SeasonID = -1; - SeasonNumber = -1; + SeasonNumber = -1; EpisodeNumber = -1; AbsoluteNumber = -1; } public Episode(long seasonNumber, long episodeNumber, long absoluteNumber, string title, string overview, DateTime? releaseDate, long runtime, string imgPrimary, string externalIDs) { - ID = -1; - ShowID = -1; - SeasonID = -1; - SeasonNumber = seasonNumber; + SeasonNumber = seasonNumber; EpisodeNumber = episodeNumber; AbsoluteNumber = absoluteNumber; Title = title; @@ -55,9 +52,8 @@ namespace Kyoo.Models ExternalIDs = externalIDs; } - public Episode(long id, long showID, long seasonID, long seasonNumber, long episodeNumber, long absoluteNumber, string path, string title, string overview, DateTime? releaseDate, long runtime, string imgPrimary, string externalIDs) + public Episode(long showID, long seasonID, long seasonNumber, long episodeNumber, long absoluteNumber, string path, string title, string overview, DateTime? releaseDate, long runtime, string imgPrimary, string externalIDs) { - ID = id; ShowID = showID; SeasonID = seasonID; SeasonNumber = seasonNumber; @@ -72,37 +68,6 @@ namespace Kyoo.Models ExternalIDs = externalIDs; } - public static Episode FromReader(System.Data.SQLite.SQLiteDataReader reader) - { - return new Episode((long)reader["id"], - (long)reader["showID"], - (long)reader["seasonID"], - (long)reader["seasonNumber"], - (long)reader["episodeNumber"], - (long)reader["absoluteNumber"], - reader["path"] as string, - reader["title"] as string, - reader["overview"] as string, - reader["releaseDate"] as DateTime?, - (long)reader["runtime"], - reader["imgPrimary"] as string, - reader["externalIDs"] as string); - } - - - public Episode SetThumb(string showSlug) - { - Link = GetSlug(showSlug, SeasonNumber, EpisodeNumber); - Thumb = "thumb/" + Link; - return this; - } - - public Episode SetShowTitle(string showTite) - { - ShowTitle = showTite; - return this; - } - public static string GetSlug(string showSlug, long seasonNumber, long episodeNumber) { return showSlug + "-s" + seasonNumber + "e" + episodeNumber; diff --git a/Kyoo.Common/Models/Genre.cs b/Kyoo.Common/Models/Genre.cs index fb0d2dba..550400da 100644 --- a/Kyoo.Common/Models/Genre.cs +++ b/Kyoo.Common/Models/Genre.cs @@ -20,12 +20,5 @@ namespace Kyoo.Models Slug = slug; Name = name; } - - public static Genre FromReader(System.Data.SQLite.SQLiteDataReader reader) - { - return new Genre((long)reader["id"], - reader["slug"] as string, - reader["name"] as string); - } } } diff --git a/Kyoo.Common/Models/Library.cs b/Kyoo.Common/Models/Library.cs index dfe1a584..189a4e39 100644 --- a/Kyoo.Common/Models/Library.cs +++ b/Kyoo.Common/Models/Library.cs @@ -1,11 +1,10 @@ -using System.Collections.Generic; -using Newtonsoft.Json; +using Newtonsoft.Json; namespace Kyoo.Models { public class Library { - [JsonIgnore] public long Id { get; set; } + [JsonIgnore] public long ID { get; set; } public string Slug { get; set; } public string Name { get; set; } public string[] Paths { get; set; } @@ -13,22 +12,12 @@ namespace Kyoo.Models public Library() { } - public Library(long id, string slug, string name, string[] paths, string[] providers) + public Library(string slug, string name, string[] paths, string[] providers) { - Id = id; Slug = slug; Name = name; Paths = paths; Providers = providers; } - - public static Library FromReader(System.Data.SQLite.SQLiteDataReader reader) - { - return new Library((long)reader["id"], - reader["slug"] as string, - reader["name"] as string, - (reader["path"] as string)?.Split('|'), - (reader["providers"] as string)?.Split('|')); - } } } diff --git a/Kyoo.Common/Models/People.cs b/Kyoo.Common/Models/People.cs index ae3408d5..fdceab5d 100644 --- a/Kyoo.Common/Models/People.cs +++ b/Kyoo.Common/Models/People.cs @@ -1,12 +1,11 @@ -using System.Collections; -using System.Collections.Generic; +using System.Collections.Generic; using Newtonsoft.Json; namespace Kyoo.Models { public class People : IMergable { - [JsonIgnore] public long ID { get; set; } = -1; + [JsonIgnore] public long ID { get; set; } public string Slug { get; set; } public string Name { get; set; } public string Role; @@ -18,18 +17,16 @@ namespace Kyoo.Models public People() {} - public People(long id, string slug, string name, string imgPrimary, string externalIDs) + public People(string slug, string name, string imgPrimary, string externalIDs) { - ID = id; Slug = slug; Name = name; ImgPrimary = imgPrimary; ExternalIDs = externalIDs; } - public People(long id, string slug, string name, string role, string type, string imgPrimary, string externalIDs) + public People(string slug, string name, string role, string type, string imgPrimary, string externalIDs) { - ID = id; Slug = slug; Name = name; Role = role; @@ -45,6 +42,19 @@ namespace Kyoo.Models return this; } + public PeopleLink ToLink(Show show) + { + return new PeopleLink + { + People = this, + PeopleID = ID, + Role = Role, + Type = Type, + Show = show, + ShowID = show.ID + }; + } + public People Merge(People other) { if (other == null) diff --git a/Kyoo.Common/Models/Season.cs b/Kyoo.Common/Models/Season.cs index 97d81f7e..1c3877bd 100644 --- a/Kyoo.Common/Models/Season.cs +++ b/Kyoo.Common/Models/Season.cs @@ -1,13 +1,12 @@ -using System.Collections; -using System.Collections.Generic; +using System.Collections.Generic; using Newtonsoft.Json; namespace Kyoo.Models { public class Season : IMergable { - [JsonIgnore] public long ID { get; set; } = -1; - [JsonIgnore] public long ShowID { get; set; } = -1; + [JsonIgnore] public long ID { get; set; } + [JsonIgnore] public long ShowID { get; set; } public long SeasonNumber { get; set; } = -1; public string Title { get; set; } @@ -17,14 +16,13 @@ namespace Kyoo.Models [JsonIgnore] public string ImgPrimary { get; set; } public string ExternalIDs { get; set; } - public virtual Show Show { get; set; } - public virtual IEnumerable Episodes { get; set; } + [JsonIgnore] public virtual Show Show { get; set; } + [JsonIgnore] public virtual IEnumerable Episodes { get; set; } public Season() { } - public Season(long id, long showID, long seasonNumber, string title, string overview, long? year, string imgPrimary, string externalIDs) + public Season(long showID, long seasonNumber, string title, string overview, long? year, string imgPrimary, string externalIDs) { - ID = id; ShowID = showID; SeasonNumber = seasonNumber; Title = title; @@ -34,18 +32,6 @@ namespace Kyoo.Models ExternalIDs = externalIDs; } - public static Season FromReader(System.Data.SQLite.SQLiteDataReader reader) - { - return new Season((long)reader["id"], - (long)reader["showID"], - (long)reader["seasonNumber"], - reader["title"] as string, - reader["overview"] as string, - reader["year"] as long?, - reader["imgPrimary"] as string, - reader["externalIDs"] as string); - } - public Season Merge(Season other) { if (other == null) diff --git a/Kyoo.Common/Models/Show.cs b/Kyoo.Common/Models/Show.cs index 8ed50b6c..cbe40818 100644 --- a/Kyoo.Common/Models/Show.cs +++ b/Kyoo.Common/Models/Show.cs @@ -1,5 +1,4 @@ using System; -using Kyoo.Controllers; using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; @@ -32,9 +31,9 @@ namespace Kyoo.Models public IEnumerable Genres; public virtual Studio Studio { get; set; } - public virtual IEnumerable People { get; set; } - public virtual IEnumerable Seasons { get; set; } - public virtual IEnumerable Episodes { get; set; } + [JsonIgnore] public virtual IEnumerable People { get; set; } + [JsonIgnore] public virtual IEnumerable Seasons { get; set; } + [JsonIgnore] public virtual IEnumerable Episodes { get; set; } public string GetAliases() @@ -50,9 +49,8 @@ namespace Kyoo.Models public Show() { } - public Show(long id, string slug, string title, IEnumerable aliases, string path, string overview, string trailerUrl, IEnumerable genres, Status? status, long? startYear, long? endYear, string externalIDs) + public Show(string slug, string title, IEnumerable aliases, string path, string overview, string trailerUrl, IEnumerable genres, Status? status, long? startYear, long? endYear, string externalIDs) { - ID = id; Slug = slug; Title = title; Aliases = aliases.ToArray(); @@ -67,9 +65,8 @@ namespace Kyoo.Models IsCollection = false; } - public Show(long id, string slug, string title, IEnumerable aliases, string path, string overview, string trailerUrl, Status? status, long? startYear, long? endYear, string imgPrimary, string imgThumb, string imgLogo, string imgBackdrop, string externalIDs) + public Show(string slug, string title, IEnumerable aliases, string path, string overview, string trailerUrl, Status? status, long? startYear, long? endYear, string imgPrimary, string imgThumb, string imgLogo, string imgBackdrop, string externalIDs) { - ID = id; Slug = slug; Title = title; Aliases = aliases.ToArray(); @@ -86,41 +83,7 @@ namespace Kyoo.Models ExternalIDs = externalIDs; IsCollection = false; } - - public static Show FromQueryReader(System.Data.SQLite.SQLiteDataReader reader, bool containsAliases = false) - { - Show show = new Show() - { - Slug = reader["slug"] as string, - Title = reader["title"] as string, - StartYear = reader["startYear"] as long?, - EndYear = reader["endYear"] as long?, - IsCollection = reader["'0'"] as string == "1" - }; - if (containsAliases) - show.Aliases = (reader["aliases"] as string)?.Split('|'); - return show; - } - - public static Show FromReader(System.Data.SQLite.SQLiteDataReader reader) - { - return new Show((long)reader["id"], - reader["slug"] as string, - reader["title"] as string, - (reader["aliases"] as string)?.Split('|'), - reader["path"] as string, - reader["overview"] as string, - reader["trailerUrl"] as string, - reader["status"] as Status?, - reader["startYear"] as long?, - reader["endYear"] as long?, - reader["imgPrimary"] as string, - reader["imgThumb"] as string, - reader["imgLogo"] as string, - reader["imgBackdrop"] as string, - reader["externalIDs"] as string); - } - + public string GetID(string provider) { if (ExternalIDs?.Contains(provider) != true) @@ -130,44 +93,7 @@ namespace Kyoo.Models return ExternalIDs.Substring(startIndex); return ExternalIDs.Substring(startIndex, ExternalIDs.IndexOf('|', startIndex) - startIndex); } - - public Show Set(string slug, string path) - { - Slug = slug; - Path = path; - return this; - } - - public Show SetGenres(ILibraryManager manager) - { - Genres = manager.GetGenreForShow(ID); - return this; - } - - public Show SetStudio(ILibraryManager manager) - { - Studio = manager.GetStudio(ID); - return this; - } - - public Show SetDirectors(ILibraryManager manager) - { - //Directors = manager.GetDirectors(ID); - return this; - } - - public Show SetPeople(ILibraryManager manager) - { - //People = manager.GetPeople(ID); - return this; - } - - public Show SetSeasons(ILibraryManager manager) - { - Seasons = manager.GetSeasons(ID); - return this; - } - + public Show Merge(Show other) { if (other == null) diff --git a/Kyoo.Common/Models/Studio.cs b/Kyoo.Common/Models/Studio.cs index 2fbe2ba4..29c9bfb8 100644 --- a/Kyoo.Common/Models/Studio.cs +++ b/Kyoo.Common/Models/Studio.cs @@ -4,7 +4,7 @@ namespace Kyoo.Models { public class Studio { - [JsonIgnore] public long ID { get; set; } = -1; + [JsonIgnore] public long ID { get; set; } public string Slug { get; set; } public string Name { get; set; } @@ -15,21 +15,7 @@ namespace Kyoo.Models Slug = slug; Name = name; } - - public Studio(long id, string slug, string name) - { - ID = id; - Slug = slug; - Name = name; - } - - public static Studio FromReader(System.Data.SQLite.SQLiteDataReader reader) - { - return new Studio((long)reader["id"], - reader["slug"] as string, - reader["name"] as string); - } - + public static Studio Default() { return new Studio("unknow", "Unknow Studio"); diff --git a/Kyoo.Common/Models/Track.cs b/Kyoo.Common/Models/Track.cs index 8671cdab..2c22bdd1 100644 --- a/Kyoo.Common/Models/Track.cs +++ b/Kyoo.Common/Models/Track.cs @@ -88,18 +88,6 @@ namespace Kyoo.Models IsExternal = false; } - public static Track FromReader(System.Data.SQLite.SQLiteDataReader reader) - { - return new Track((StreamType)Enum.ToObject(typeof(StreamType), reader["streamType"]), - reader["title"] as string, - reader["language"] as string, - reader["isDefault"] as bool? ?? false, - reader["isForced"] as bool? ?? false, - reader["codec"] as string, - reader["isExternal"] as bool? ?? false, - reader["path"] as string); - } - public Track SetLink(string episodeSlug) { if (Type == StreamType.Subtitle) diff --git a/Kyoo/Controllers/Crawler.cs b/Kyoo/Controllers/Crawler.cs index 5037a3c5..53ad2613 100644 --- a/Kyoo/Controllers/Crawler.cs +++ b/Kyoo/Controllers/Crawler.cs @@ -13,50 +13,50 @@ namespace Kyoo.Controllers { public class Crawler : ICrawler { - private bool isRunning; - private readonly CancellationTokenSource cancellation; + private bool _isRunning; + private readonly CancellationTokenSource _cancellation; - private readonly ILibraryManager libraryManager; - private readonly IProviderManager metadataProvider; - private readonly ITranscoder transcoder; - private readonly IConfiguration config; + private readonly ILibraryManager _libraryManager; + private readonly IProviderManager _metadataProvider; + private readonly ITranscoder _transcoder; + private readonly IConfiguration _config; public Crawler(ILibraryManager libraryManager, IProviderManager metadataProvider, ITranscoder transcoder, IConfiguration configuration) { - this.libraryManager = libraryManager; - this.metadataProvider = metadataProvider; - this.transcoder = transcoder; - config = configuration; - cancellation = new CancellationTokenSource(); + _libraryManager = libraryManager; + _metadataProvider = metadataProvider; + _transcoder = transcoder; + _config = configuration; + _cancellation = new CancellationTokenSource(); } public void Start() { - if (isRunning) + if (_isRunning) return; - isRunning = true; - StartAsync(cancellation.Token); + _isRunning = true; + StartAsync(_cancellation.Token); } public void Cancel() { - if (!isRunning) + if (!_isRunning) return; - isRunning = false; - cancellation.Cancel(); + _isRunning = false; + _cancellation.Cancel(); } private async void StartAsync(CancellationToken cancellationToken) { try { - IEnumerable episodes = libraryManager.GetAllEpisodes(); - IEnumerable libraries = libraryManager.GetLibraries(); + IEnumerable episodes = _libraryManager.GetAllEpisodes(); + IEnumerable libraries = _libraryManager.GetLibraries(); foreach (Episode episode in episodes) { if (!File.Exists(episode.Path)) - libraryManager.RemoveEpisode(episode); + _libraryManager.RemoveEpisode(episode.ID); } foreach (Library library in libraries) @@ -66,7 +66,7 @@ namespace Kyoo.Controllers { Console.Error.WriteLine($"Unknown exception thrown durring libraries scan.\nException: {ex.Message}"); } - isRunning = false; + _isRunning = false; Console.WriteLine("Scan finished!"); } @@ -79,7 +79,7 @@ namespace Kyoo.Controllers { if (cancellationToken.IsCancellationRequested) return; - if (!IsVideo(file)) + if (!IsVideo(file) || _libraryManager.IsEpisodeRegistered(file, out long _)) continue; string relativePath = file.Substring(path.Length); await RegisterFile(file, relativePath, library); @@ -89,136 +89,96 @@ namespace Kyoo.Controllers private async Task RegisterFile(string path, string relativePath, Library library) { - if (!libraryManager.IsEpisodeRegistered(path, out long _)) + string patern = _config.GetValue("regex"); + Regex regex = new Regex(patern, RegexOptions.IgnoreCase); + Match match = regex.Match(relativePath); + + string showPath = Path.GetDirectoryName(path); + string collectionName = match.Groups["Collection"]?.Value; + string showName = match.Groups["ShowTitle"].Value; + bool seasonSuccess = long.TryParse(match.Groups["Season"].Value, out long seasonNumber); + bool episodeSucess = long.TryParse(match.Groups["Episode"].Value, out long episodeNumber); + long absoluteNumber = -1; + + Console.WriteLine("Registering episode at: " + path); + if (!seasonSuccess || !episodeSucess) { - string patern = config.GetValue("regex"); - Regex regex = new Regex(patern, RegexOptions.IgnoreCase); - Match match = regex.Match(relativePath); + //Considering that the episode is using absolute path. + seasonNumber = -1; + episodeNumber = -1; - string showPath = Path.GetDirectoryName(path); - string collectionName = match.Groups["Collection"]?.Value; - string showName = match.Groups["ShowTitle"].Value; - bool seasonSuccess = long.TryParse(match.Groups["Season"].Value, out long seasonNumber); - bool episodeSucess = long.TryParse(match.Groups["Episode"].Value, out long episodeNumber); - long absoluteNumber = -1; + regex = new Regex(_config.GetValue("absoluteRegex")); + match = regex.Match(relativePath); - Console.WriteLine("Registering episode at: " + path); - if (!seasonSuccess || !episodeSucess) + showName = match.Groups["ShowTitle"].Value; + bool absoluteSucess = long.TryParse(match.Groups["AbsoluteNumber"].Value, out absoluteNumber); + + if (!absoluteSucess) { - //Considering that the episode is using absolute path. - seasonNumber = -1; - episodeNumber = -1; - - regex = new Regex(config.GetValue("absoluteRegex")); - match = regex.Match(relativePath); - - showName = match.Groups["ShowTitle"].Value; - bool absoluteSucess = long.TryParse(match.Groups["AbsoluteNumber"].Value, out absoluteNumber); - - if (!absoluteSucess) - { - Console.Error.WriteLine("Couldn't find basic data for the episode (regexs didn't match) " + relativePath); - return; - } + Console.Error.WriteLine("Couldn't find basic data for the episode (regexs didn't match) " + relativePath); + return; } - - Show show = await RegisterOrGetShow(collectionName, showName, showPath, library); - if (show != null) - await RegisterEpisode(show, seasonNumber, episodeNumber, absoluteNumber, path, library); - else - Console.Error.WriteLine($"Coudld not get informations about the show {showName}."); } + + Collection collection = await GetCollection(collectionName, library); + Show show = await GetShow(showName, showPath, library); + Season season = await GetSeason(show, seasonNumber, library); + Episode episode = await GetEpisode(show, season, episodeNumber, absoluteNumber, path, library); + _libraryManager.RegisterEpisode(episode); + _libraryManager.RegisterShowLinks(library, collection, show); } - private async Task RegisterOrGetShow(string collectionName, string showTitle, string showPath, Library library) + private async Task GetCollection(string collectionName, Library library) { - string showProviderIDs; - - if (!libraryManager.IsShowRegistered(showPath, out long showID)) - { - Show show = await metadataProvider.GetShowFromName(showTitle, showPath, library); - showProviderIDs = show.ExternalIDs; - showID = libraryManager.RegisterShow(show); - - if (showID == -1) - return null; - - libraryManager.RegisterInLibrary(showID, library); - if (!string.IsNullOrEmpty(collectionName)) - { - if (!libraryManager.IsCollectionRegistered(Utility.ToSlug(collectionName), out long collectionID)) - { - Collection collection = await metadataProvider.GetCollectionFromName(collectionName, library); - collectionID = libraryManager.RegisterCollection(collection); - } - libraryManager.AddShowToCollection(showID, collectionID); - } - - IEnumerable actors = await metadataProvider.GetPeople(show, library); - libraryManager.RegisterShowPeople(showID, actors); - } - else - showProviderIDs = libraryManager.GetShowExternalIDs(showID); - - return new Show { ID = showID, ExternalIDs = showProviderIDs, Title = showTitle }; - } - - private async Task RegisterSeason(Show show, long seasonNumber, Library library) - { - if (libraryManager.IsSeasonRegistered(show.ID, seasonNumber, out long seasonID)) - return seasonID; - - Season season = await metadataProvider.GetSeason(show, seasonNumber, library); - seasonID = libraryManager.RegisterSeason(season); - return seasonID; + if (string.IsNullOrEmpty(collectionName)) + return await Task.FromResult(null); + if (_libraryManager.IsCollectionRegistered(Utility.ToSlug(collectionName), out long collectionID)) + return new Collection {ID = collectionID}; + return await _metadataProvider.GetCollectionFromName(collectionName, library); } - private async Task RegisterEpisode(Show show, long seasonNumber, long episodeNumber, long absoluteNumber, string episodePath, Library library) + private async Task GetShow(string showTitle, string showPath, Library library) { - long seasonID = -1; - if (seasonNumber != -1) - seasonID = await RegisterSeason(show, seasonNumber, library); - - Episode episode = await metadataProvider.GetEpisode(show, episodePath, seasonNumber, episodeNumber, absoluteNumber, library); - if (seasonID == -1) - seasonID = await RegisterSeason(show, seasonNumber, library); - episode.SeasonID = seasonID; - episode.ID = libraryManager.RegisterEpisode(episode); - - Track[] tracks = await transcoder.GetTrackInfo(episode.Path); - int subcount = 0; - foreach (Track track in tracks) - { - if (track.Type == StreamType.Subtitle) - { - subcount++; - continue; - } - track.EpisodeID = episode.ID; - libraryManager.RegisterTrack(track); - } - - if (episode.Path.EndsWith(".mkv") && CountExtractedSubtitles(episode) != subcount) - { - Track[] subtitles = await transcoder.ExtractSubtitles(episode.Path); - if (subtitles != null) - { - foreach (Track track in subtitles) - { - track.EpisodeID = episode.ID; - libraryManager.RegisterTrack(track); - } - } - } + if (_libraryManager.IsShowRegistered(showPath, out long showID)) + return new Show { ID = showID, Title = showTitle, ExternalIDs = _libraryManager.GetShowExternalIDs(showID) }; + Show show = await _metadataProvider.GetShowFromName(showTitle, showPath, library); + show.People = from people in await _metadataProvider.GetPeople(show, library) select people.ToLink(show); + return show; } - private int CountExtractedSubtitles(Episode episode) + private async Task GetSeason(Show show, long seasonNumber, Library library) + { + if (_libraryManager.IsSeasonRegistered(show.ID, seasonNumber, out long seasonID)) + return await Task.FromResult(new Season {ID = seasonID, ShowID = show.ID, Show = show}); + Season season = await _metadataProvider.GetSeason(show, seasonNumber, library); + season.Show = show; + season.ShowID = show.ID; + return season; + } + + private async Task GetEpisode(Show show, Season season, long episodeNumber, long absoluteNumber, string episodePath, Library library) + { + Episode episode = await _metadataProvider.GetEpisode(show, episodePath, season.SeasonNumber, episodeNumber, absoluteNumber, library); + episode.ShowID = show.ID; + episode.Show = show; + episode.SeasonID = season.ID; + episode.Season = season; + + IEnumerable tracks = await _transcoder.GetTrackInfo(episode.Path); + List epTracks = tracks.Where(x => x.Type != StreamType.Subtitle).Concat(GetExtractedSubtitles(episode)).ToList(); + if (epTracks.Count(x => !x.IsExternal) < tracks.Count()) + epTracks.AddRange(await _transcoder.ExtractSubtitles(episode.Path)); + episode.Tracks = epTracks; + return episode; + } + + private static IEnumerable GetExtractedSubtitles(Episode episode) { string path = Path.Combine(Path.GetDirectoryName(episode.Path), "Subtitles"); - int subcount = 0; + List tracks = new List(); if (!Directory.Exists(path)) - return 0; + return tracks; foreach (string sub in Directory.EnumerateFiles(path, "", SearchOption.AllDirectories)) { string episodeLink = Path.GetFileNameWithoutExtension(episode.Path); @@ -236,10 +196,9 @@ namespace Kyoo.Controllers track.Codec = "subrip"; else track.Codec = null; - libraryManager.RegisterTrack(track); - subcount++; + tracks.Add(track); } - return subcount; + return tracks; } private static readonly string[] VideoExtensions = { ".webm", ".mkv", ".flv", ".vob", ".ogg", ".ogv", ".avi", ".mts", ".m2ts", ".ts", ".mov", ".qt", ".asf", ".mp4", ".m4p", ".m4v", ".mpg", ".mp2", ".mpeg", ".mpe", ".mpv", ".m2v", ".3gp", ".3g2" }; @@ -252,7 +211,7 @@ namespace Kyoo.Controllers public Task StopAsync() { - cancellation.Cancel(); + _cancellation.Cancel(); return null; } } diff --git a/Kyoo/Controllers/LibraryManager.cs b/Kyoo/Controllers/LibraryManager.cs index e91b891d..c28e7d02 100644 --- a/Kyoo/Controllers/LibraryManager.cs +++ b/Kyoo/Controllers/LibraryManager.cs @@ -1,8 +1,6 @@ using Kyoo.Models; using Kyoo.Models.Watch; -using System; using System.Collections.Generic; -using System.Data.SQLite; using System.Linq; namespace Kyoo.Controllers @@ -10,7 +8,6 @@ namespace Kyoo.Controllers public class LibraryManager : ILibraryManager { private readonly DatabaseContext _database; - private readonly SQLiteConnection sqlConnection; public LibraryManager(DatabaseContext database) @@ -63,9 +60,8 @@ namespace Kyoo.Controllers public IEnumerable GetShows() { - return (from show in _database.Shows join link in _database.CollectionLinks on show equals link.Show into gj - from l in gj.DefaultIfEmpty() - where l.CollectionID == null select l.Show).AsEnumerable().Union( + return (from show in _database.Shows from l in _database.CollectionLinks.DefaultIfEmpty() + where l.CollectionID == null select show).AsEnumerable().Union( from collection in _database.Collections select collection.AsShow()).OrderBy(x => x.Title); } @@ -303,43 +299,9 @@ namespace Kyoo.Controllers #region Write Into The Database public long RegisterCollection(Collection collection) { - // string query = "INSERT INTO collections (slug, name, overview, imgPrimary) VALUES($slug, $name, $overview, $imgPrimary);"; - // - // using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) - // { - // try - // { - // cmd.Parameters.AddWithValue("$slug", collection.Slug); - // cmd.Parameters.AddWithValue("$name", collection.Name); - // cmd.Parameters.AddWithValue("$overview", collection.Overview); - // cmd.Parameters.AddWithValue("$imgPrimary", collection.ImgPrimary); - // cmd.ExecuteNonQuery(); - // - // cmd.CommandText = "SELECT LAST_INSERT_ROWID()"; - // return (long)cmd.ExecuteScalar(); - // } - // catch - // { - // Console.Error.WriteLine("SQL error while trying to create a collection. Collection probably already registered."); - // cmd.CommandText = "SELECT * FROM collections WHERE slug = $slug"; - // cmd.Parameters.AddWithValue("$slug", collection.Slug); - // return (long)cmd.ExecuteScalar(); - // } - // } - return -1; - } - - public void RegisterInLibrary(long showID, Library library) - { - // string query = - // "INSERT INTO librariesLinks (libraryID, showID) SELECT id, $showID FROM libraries WHERE libraries.id = $libraryID;"; - // - // using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) - // { - // cmd.Parameters.AddWithValue("$libraryID", library.Id); - // cmd.Parameters.AddWithValue("$showID", showID); - // cmd.ExecuteNonQuery(); - // } + _database.Collections.Add(collection); + _database.SaveChanges(); + return collection.ID; } public long RegisterShow(Show show) @@ -351,167 +313,54 @@ namespace Kyoo.Controllers public long RegisterSeason(Season season) { - string query = "INSERT INTO seasons (showID, seasonNumber, title, overview, year, imgPrimary, externalIDs) VALUES($showID, $seasonNumber, $title, $overview, $year, $imgPrimary, $externalIDs);"; - using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) - { - try - { - cmd.Parameters.AddWithValue("$showID", season.ShowID); - cmd.Parameters.AddWithValue("$seasonNumber", season.SeasonNumber); - cmd.Parameters.AddWithValue("$title", season.Title); - cmd.Parameters.AddWithValue("$overview", season.Overview); - cmd.Parameters.AddWithValue("$year", season.Year); - cmd.Parameters.AddWithValue("$imgPrimary", season.ImgPrimary); - cmd.Parameters.AddWithValue("$externalIDs", season.ExternalIDs); - cmd.ExecuteNonQuery(); - - cmd.CommandText = "SELECT LAST_INSERT_ROWID()"; - return (long)cmd.ExecuteScalar(); - } - catch - { - Console.Error.WriteLine("SQL error while trying to insert a season ({0}), season probably already registered.", season.Title); - cmd.CommandText = "SELECT * FROM seasons WHERE showID = $showID AND seasonNumber = $seasonNumber"; - cmd.Parameters.AddWithValue("$showID", season.ShowID); - cmd.Parameters.AddWithValue("$seasonNumber", season.SeasonNumber); - return (long)cmd.ExecuteScalar(); - } - } + _database.Seasons.Add(season); + _database.SaveChanges(); + return season.ID; } public long RegisterEpisode(Episode episode) { - string query = "INSERT INTO episodes (showID, seasonID, seasonNumber, episodeNumber, absoluteNumber, path, title, overview, releaseDate, runtime, imgPrimary, externalIDs) VALUES($showID, $seasonID, $seasonNumber, $episodeNumber, $absoluteNumber, $path, $title, $overview, $releaseDate, $runtime, $imgPrimary, $externalIDs);"; - using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) - { - try - { - cmd.Parameters.AddWithValue("$showID", episode.ShowID); - cmd.Parameters.AddWithValue("$seasonID", episode.SeasonID); - cmd.Parameters.AddWithValue("$seasonNUmber", episode.SeasonNumber); - cmd.Parameters.AddWithValue("$episodeNumber", episode.EpisodeNumber); - cmd.Parameters.AddWithValue("$absoluteNumber", episode.AbsoluteNumber); - cmd.Parameters.AddWithValue("$path", episode.Path); - cmd.Parameters.AddWithValue("$title", episode.Title); - cmd.Parameters.AddWithValue("$overview", episode.Overview); - cmd.Parameters.AddWithValue("$releaseDate", episode.ReleaseDate); - cmd.Parameters.AddWithValue("$runtime", episode.Runtime); - cmd.Parameters.AddWithValue("$imgPrimary", episode.ImgPrimary); - cmd.Parameters.AddWithValue("$externalIDs", episode.ExternalIDs); - cmd.ExecuteNonQuery(); - - cmd.CommandText = "SELECT LAST_INSERT_ROWID()"; - return (long)cmd.ExecuteScalar(); - } - catch - { - Console.Error.WriteLine("SQL error while trying to insert an episode ({0}), episode probably already registered.", episode.Link); - cmd.CommandText = "SELECT * FROM episodes WHERE showID = $showID AND seasonNumber = $seasonNumber AND episodeNumber = $episodeNumber"; - cmd.Parameters.AddWithValue("$showID", episode.ShowID); - cmd.Parameters.AddWithValue("$seasonNumber", episode.SeasonNumber); - cmd.Parameters.AddWithValue("$episodeNumber", episode.EpisodeNumber); - return (long)cmd.ExecuteScalar(); - } - } + _database.Episodes.Add(episode); + _database.SaveChanges(); + return episode.ID; } - public void RegisterTrack(Track track) + public long RegisterTrack(Track track) { - string query = "INSERT INTO tracks (episodeID, streamType, title, language, codec, isDefault, isForced, isExternal, path) VALUES($episodeID, $streamType, $title, $language, $codec, $isDefault, $isForced, $isExternal, $path);"; - using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) - { - cmd.Parameters.AddWithValue("$episodeID", track.EpisodeID); - cmd.Parameters.AddWithValue("$streamType", track.Type); - cmd.Parameters.AddWithValue("$title", track.Title); - cmd.Parameters.AddWithValue("$language", track.Language); - cmd.Parameters.AddWithValue("$codec", track.Codec); - cmd.Parameters.AddWithValue("$isDefault", track.IsDefault); - cmd.Parameters.AddWithValue("$isForced", track.IsForced); - cmd.Parameters.AddWithValue("$isExternal", track.IsExternal); - cmd.Parameters.AddWithValue("$path", track.Path); - cmd.ExecuteNonQuery(); - } + _database.Tracks.Add(track); + _database.SaveChanges(); + return track.ID; } - public void RegisterShowPeople(long showID, IEnumerable people) + public void RegisterShowLinks(Library library, Collection collection, Show show) { - if (people == null) - return; - - string linkQuery = "INSERT INTO peopleLinks (peopleID, showID, role, type) VALUES($peopleID, $showID, $role, $type);"; - - foreach (People peop in people) + if (collection != null) { - using (SQLiteCommand cmd = new SQLiteCommand(linkQuery, sqlConnection)) - { - cmd.Parameters.AddWithValue("$peopleID", GetOrCreatePeople(peop)); - cmd.Parameters.AddWithValue("$showID", showID); - cmd.Parameters.AddWithValue("$role", peop.Role); - cmd.Parameters.AddWithValue("$type", peop.Type); - cmd.ExecuteNonQuery(); - } + _database.LibraryLinks.Add(new LibraryLink {LibraryID = library.ID, CollectionID = collection.ID}); + _database.CollectionLinks.Add(new CollectionLink { CollectionID = collection.ID, ShowID = show.ID}); } + _database.LibraryLinks.Add(new LibraryLink {LibraryID = library.ID, ShowID = show.ID}); + _database.SaveChanges(); } - - public void AddShowToCollection(long showID, long collectionID) - { - string linkQuery = "INSERT INTO collectionsLinks (collectionID, showID) VALUES($collectionID, $showID);"; - - using (SQLiteCommand cmd = new SQLiteCommand(linkQuery, sqlConnection)) - { - cmd.Parameters.AddWithValue("$collectionID", collectionID); - cmd.Parameters.AddWithValue("$showID", showID); - cmd.ExecuteNonQuery(); - } - } - + public void RemoveShow(long showID) { - string query = "DELETE FROM shows WHERE id = $showID;"; - - using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) - { - cmd.Parameters.AddWithValue("$showID", showID); - cmd.ExecuteNonQuery(); - } + _database.Shows.Remove(new Show {ID = showID}); } - public void RemoveSeason(long showID, long seasonID) + public void RemoveSeason(long seasonID) { - string query = "DELETE FROM seasons WHERE id = $seasonID;"; - - using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) - { - cmd.Parameters.AddWithValue("$seasonID", seasonID); - cmd.ExecuteNonQuery(); - } - if (GetSeasons(showID).Count() == 0) - RemoveShow(showID); + _database.Seasons.Remove(new Season {ID = seasonID}); } - public void RemoveEpisode(Episode episode) + public void RemoveEpisode(long episodeID) { - string query = "DELETE FROM episodes WHERE id = $episodeID;"; - - using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) - { - cmd.Parameters.AddWithValue("$episodeID", episode.ID); - cmd.ExecuteNonQuery(); - } - - if (GetEpisodes(episode.ShowID, episode.SeasonNumber).Count() == 0) - RemoveSeason(episode.ShowID, episode.SeasonID); + _database.Episodes.Remove(new Episode {ID = episodeID}); } public void ClearSubtitles(long episodeID) { - string query = "DELETE FROM tracks WHERE episodeID = $episodeID;"; - - using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) - { - cmd.Parameters.AddWithValue("$episodeID", episodeID); - cmd.ExecuteNonQuery(); - } + _database.Tracks.RemoveRange(_database.Tracks.Where(x => x.EpisodeID == episodeID)); } #endregion } diff --git a/Kyoo/HtmlAPI/LibrariesAPI.cs b/Kyoo/HtmlAPI/LibrariesAPI.cs index 9654a154..fa466b5d 100644 --- a/Kyoo/HtmlAPI/LibrariesAPI.cs +++ b/Kyoo/HtmlAPI/LibrariesAPI.cs @@ -31,7 +31,7 @@ namespace Kyoo.Controllers if (library == null) return NotFound(); - return _libraryManager.GetShowsInLibrary(library.Id).ToList(); + return _libraryManager.GetShowsInLibrary(library.ID).ToList(); } } } \ No newline at end of file diff --git a/Kyoo/HtmlAPI/PeopleAPI.cs b/Kyoo/HtmlAPI/PeopleAPI.cs index bd133892..4fae762b 100644 --- a/Kyoo/HtmlAPI/PeopleAPI.cs +++ b/Kyoo/HtmlAPI/PeopleAPI.cs @@ -23,7 +23,7 @@ namespace Kyoo.Controllers if (people == null) return NotFound(); - Collection collection = new Collection(0, people.Slug, people.Name, null, null) + Collection collection = new Collection(people.Slug, people.Name, null, null) { Shows = libraryManager.GetShowsByPeople(people.ID), Poster = "peopleimg/" + people.Slug