Reworking the crawler

This commit is contained in:
Zoe Roux 2020-06-06 21:01:46 +02:00
parent c5b0858d4a
commit 5d96452309
19 changed files with 205 additions and 133 deletions

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Kyoo.Models; using Kyoo.Models;
namespace Kyoo.Controllers namespace Kyoo.Controllers
@ -20,35 +21,40 @@ namespace Kyoo.Controllers
Task<People> GetPeople(string slug); Task<People> GetPeople(string slug);
// Get by relations // Get by relations
Task<IEnumerable<Season>> GetSeasons(long showID); Task<ICollection<Season>> GetSeasons(long showID);
Task<IEnumerable<Season>> GetSeasons(string showSlug); Task<ICollection<Season>> GetSeasons(string showSlug);
Task<IEnumerable<Episode>> GetEpisodes(long showID, long seasonNumber); Task<ICollection<Episode>> GetEpisodes(long showID, long seasonNumber);
Task<IEnumerable<Episode>> GetEpisodes(string showSlug, long seasonNumber); Task<ICollection<Episode>> GetEpisodes(string showSlug, long seasonNumber);
Task<IEnumerable<Episode>> GetEpisodes(long seasonID); Task<ICollection<Episode>> GetEpisodes(long seasonID);
// Helpers
Task<Show> GetShowByPath(string path);
Task AddShowLink(long showID, long? libraryID, long? collectionID);
Task AddShowLink([NotNull] Show show, Library library, Collection collection);
// Get all // Get all
Task<IEnumerable<Library>> GetLibraries(); Task<ICollection<Library>> GetLibraries();
Task<IEnumerable<Collection>> GetCollections(); Task<ICollection<Collection>> GetCollections();
Task<IEnumerable<Show>> GetShows(); Task<ICollection<Show>> GetShows();
Task<IEnumerable<Season>> GetSeasons(); Task<ICollection<Season>> GetSeasons();
Task<IEnumerable<Episode>> GetEpisodes(); Task<ICollection<Episode>> GetEpisodes();
Task<IEnumerable<Track>> GetTracks(); Task<ICollection<Track>> GetTracks();
Task<IEnumerable<Studio>> GetStudios(); Task<ICollection<Studio>> GetStudios();
Task<IEnumerable<People>> GetPeoples(); Task<ICollection<People>> GetPeoples();
Task<IEnumerable<Genre>> GetGenres(); Task<ICollection<Genre>> GetGenres();
Task<IEnumerable<ProviderID>> GetProviders(); Task<ICollection<ProviderID>> GetProviders();
// Search // Search
Task<IEnumerable<Library>> SearchLibraries(string searchQuery); Task<ICollection<Library>> SearchLibraries(string searchQuery);
Task<IEnumerable<Collection>> SearchCollections(string searchQuery); Task<ICollection<Collection>> SearchCollections(string searchQuery);
Task<IEnumerable<Show>> SearchShows(string searchQuery); Task<ICollection<Show>> SearchShows(string searchQuery);
Task<IEnumerable<Season>> SearchSeasons(string searchQuery); Task<ICollection<Season>> SearchSeasons(string searchQuery);
Task<IEnumerable<Episode>> SearchEpisodes(string searchQuery); Task<ICollection<Episode>> SearchEpisodes(string searchQuery);
Task<IEnumerable<Genre>> SearchGenres(string searchQuery); Task<ICollection<Genre>> SearchGenres(string searchQuery);
Task<IEnumerable<Studio>> SearchStudios(string searchQuery); Task<ICollection<Studio>> SearchStudios(string searchQuery);
Task<IEnumerable<People>> SearchPeople(string searchQuery); Task<ICollection<People>> SearchPeople(string searchQuery);
//Register values //Register values
Task RegisterLibrary(Library library); Task RegisterLibrary(Library library);

View File

@ -9,31 +9,35 @@ namespace Kyoo.Controllers
{ {
Task<T> Get(long id); Task<T> Get(long id);
Task<T> Get(string slug); Task<T> Get(string slug);
Task<IEnumerable<T>> Search(string query); Task<ICollection<T>> Search(string query);
Task<IEnumerable<T>> GetAll(); Task<ICollection<T>> GetAll();
Task<long> Create([NotNull] T obj); Task<long> Create([NotNull] T obj);
Task<long> CreateIfNotExists([NotNull] T obj); Task<long> CreateIfNotExists([NotNull] T obj);
Task Edit([NotNull] T edited, bool resetOld); Task Edit([NotNull] T edited, bool resetOld);
Task Delete(T obj); Task Delete(T obj);
} }
public interface IShowRepository : IRepository<Show> {} public interface IShowRepository : IRepository<Show>
{
Task<Show> GetByPath(string path);
Task AddShowLink(long showID, long? libraryID, long? collectionID);
}
public interface ISeasonRepository : IRepository<Season> public interface ISeasonRepository : IRepository<Season>
{ {
Task<Season> Get(string showSlug, long seasonNumber); Task<Season> Get(string showSlug, long seasonNumber);
Task<IEnumerable<Season>> GetSeasons(long showID); Task<ICollection<Season>> GetSeasons(long showID);
Task<IEnumerable<Season>> GetSeasons(string showSlug); Task<ICollection<Season>> GetSeasons(string showSlug);
} }
public interface IEpisodeRepository : IRepository<Episode> public interface IEpisodeRepository : IRepository<Episode>
{ {
Task<Episode> Get(string showSlug, long seasonNumber, long episodeNumber); Task<Episode> Get(string showSlug, long seasonNumber, long episodeNumber);
Task<IEnumerable<Episode>> GetEpisodes(long showID, long seasonNumber); Task<ICollection<Episode>> GetEpisodes(long showID, long seasonNumber);
Task<IEnumerable<Episode>> GetEpisodes(string showSlug, long seasonNumber); Task<ICollection<Episode>> GetEpisodes(string showSlug, long seasonNumber);
Task<IEnumerable<Episode>> GetEpisodes(long seasonID); Task<ICollection<Episode>> GetEpisodes(long seasonID);
} }
public interface ITrackRepository : IRepository<Track> public interface ITrackRepository : IRepository<Track>

View File

@ -14,7 +14,7 @@ namespace Kyoo.Models
public bool RunOnStartup { get; } public bool RunOnStartup { get; }
public int Priority { get; } public int Priority { get; }
public Task Run(IServiceProvider serviceProvider, CancellationToken cancellationToken, string arguments = null); public Task Run(IServiceProvider serviceProvider, CancellationToken cancellationToken, string arguments = null);
public IEnumerable<string> GetPossibleParameters(); public Task<IEnumerable<string>> GetPossibleParameters();
public int? Progress(); public int? Progress();
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kyoo.Models; using Kyoo.Models;
@ -86,117 +87,134 @@ namespace Kyoo.Controllers
return _people.Get(slug); return _people.Get(slug);
} }
public Task<IEnumerable<Library>> GetLibraries() public Task<ICollection<Library>> GetLibraries()
{ {
return _libraries.GetAll(); return _libraries.GetAll();
} }
public Task<IEnumerable<Collection>> GetCollections() public Task<ICollection<Collection>> GetCollections()
{ {
return _collections.GetAll(); return _collections.GetAll();
} }
public Task<IEnumerable<Show>> GetShows() public Task<ICollection<Show>> GetShows()
{ {
return _shows.GetAll(); return _shows.GetAll();
} }
public Task<IEnumerable<Season>> GetSeasons() public Task<ICollection<Season>> GetSeasons()
{ {
return _seasons.GetAll(); return _seasons.GetAll();
} }
public Task<IEnumerable<Episode>> GetEpisodes() public Task<ICollection<Episode>> GetEpisodes()
{ {
return _episodes.GetAll(); return _episodes.GetAll();
} }
public Task<IEnumerable<Track>> GetTracks() public Task<ICollection<Track>> GetTracks()
{ {
return _tracks.GetAll(); return _tracks.GetAll();
} }
public Task<IEnumerable<Studio>> GetStudios() public Task<ICollection<Studio>> GetStudios()
{ {
return _studios.GetAll(); return _studios.GetAll();
} }
public Task<IEnumerable<People>> GetPeoples() public Task<ICollection<People>> GetPeoples()
{ {
return _people.GetAll(); return _people.GetAll();
} }
public Task<IEnumerable<Genre>> GetGenres() public Task<ICollection<Genre>> GetGenres()
{ {
return _genres.GetAll(); return _genres.GetAll();
} }
public Task<IEnumerable<ProviderID>> GetProviders() public Task<ICollection<ProviderID>> GetProviders()
{ {
return _providers.GetAll(); return _providers.GetAll();
} }
public Task<IEnumerable<Season>> GetSeasons(long showID) public Task<ICollection<Season>> GetSeasons(long showID)
{ {
return _seasons.GetSeasons(showID); return _seasons.GetSeasons(showID);
} }
public Task<IEnumerable<Season>> GetSeasons(string showSlug) public Task<ICollection<Season>> GetSeasons(string showSlug)
{ {
return _seasons.GetSeasons(showSlug); return _seasons.GetSeasons(showSlug);
} }
public Task<IEnumerable<Episode>> GetEpisodes(long showID, long seasonNumber) public Task<ICollection<Episode>> GetEpisodes(long showID, long seasonNumber)
{ {
return _episodes.GetEpisodes(showID, seasonNumber); return _episodes.GetEpisodes(showID, seasonNumber);
} }
public Task<IEnumerable<Episode>> GetEpisodes(string showSlug, long seasonNumber) public Task<ICollection<Episode>> GetEpisodes(string showSlug, long seasonNumber)
{ {
return _episodes.GetEpisodes(showSlug, seasonNumber); return _episodes.GetEpisodes(showSlug, seasonNumber);
} }
public Task<IEnumerable<Episode>> GetEpisodes(long seasonID) public Task<ICollection<Episode>> GetEpisodes(long seasonID)
{ {
return _episodes.GetEpisodes(seasonID); return _episodes.GetEpisodes(seasonID);
} }
public Task<IEnumerable<Library>> SearchLibraries(string searchQuery) public Task<Show> GetShowByPath(string path)
{
return _shows.GetByPath(path);
}
public Task AddShowLink(long showID, long? libraryID, long? collectionID)
{
return _shows.AddShowLink(showID, libraryID, collectionID);
}
public Task AddShowLink(Show show, Library library, Collection collection)
{
if (show == null)
throw new ArgumentNullException(nameof(show));
return AddShowLink(show.ID, library?.ID, collection?.ID);
}
public Task<ICollection<Library>> SearchLibraries(string searchQuery)
{ {
return _libraries.Search(searchQuery); return _libraries.Search(searchQuery);
} }
public Task<IEnumerable<Collection>> SearchCollections(string searchQuery) public Task<ICollection<Collection>> SearchCollections(string searchQuery)
{ {
return _collections.Search(searchQuery); return _collections.Search(searchQuery);
} }
public Task<IEnumerable<Show>> SearchShows(string searchQuery) public Task<ICollection<Show>> SearchShows(string searchQuery)
{ {
return _shows.Search(searchQuery); return _shows.Search(searchQuery);
} }
public Task<IEnumerable<Season>> SearchSeasons(string searchQuery) public Task<ICollection<Season>> SearchSeasons(string searchQuery)
{ {
return _seasons.Search(searchQuery); return _seasons.Search(searchQuery);
} }
public Task<IEnumerable<Episode>> SearchEpisodes(string searchQuery) public Task<ICollection<Episode>> SearchEpisodes(string searchQuery)
{ {
return _episodes.Search(searchQuery); return _episodes.Search(searchQuery);
} }
public Task<IEnumerable<Genre>> SearchGenres(string searchQuery) public Task<ICollection<Genre>> SearchGenres(string searchQuery)
{ {
return _genres.Search(searchQuery); return _genres.Search(searchQuery);
} }
public Task<IEnumerable<Studio>> SearchStudios(string searchQuery) public Task<ICollection<Studio>> SearchStudios(string searchQuery)
{ {
return _studios.Search(searchQuery); return _studios.Search(searchQuery);
} }
public Task<IEnumerable<People>> SearchPeople(string searchQuery) public Task<ICollection<People>> SearchPeople(string searchQuery)
{ {
return _people.Search(searchQuery); return _people.Search(searchQuery);
} }

View File

@ -28,7 +28,7 @@ namespace Kyoo.Controllers
return _database.Collections.FirstOrDefaultAsync(x => x.Slug == slug); return _database.Collections.FirstOrDefaultAsync(x => x.Slug == slug);
} }
public async Task<IEnumerable<Collection>> Search(string query) public async Task<ICollection<Collection>> Search(string query)
{ {
return await _database.Collections return await _database.Collections
.Where(x => EF.Functions.Like(x.Name, $"%{query}%")) .Where(x => EF.Functions.Like(x.Name, $"%{query}%"))
@ -36,7 +36,7 @@ namespace Kyoo.Controllers
.ToListAsync(); .ToListAsync();
} }
public async Task<IEnumerable<Collection>> GetAll() public async Task<ICollection<Collection>> GetAll()
{ {
return await _database.Collections.ToListAsync(); return await _database.Collections.ToListAsync();
} }

View File

@ -46,7 +46,7 @@ namespace Kyoo.Controllers
&& x.EpisodeNumber == episodeNumber); && x.EpisodeNumber == episodeNumber);
} }
public async Task<IEnumerable<Episode>> Search(string query) public async Task<ICollection<Episode>> Search(string query)
{ {
return await _database.Episodes return await _database.Episodes
.Where(x => EF.Functions.Like(x.Title, $"%{query}%")) .Where(x => EF.Functions.Like(x.Title, $"%{query}%"))
@ -54,7 +54,7 @@ namespace Kyoo.Controllers
.ToListAsync(); .ToListAsync();
} }
public async Task<IEnumerable<Episode>> GetAll() public async Task<ICollection<Episode>> GetAll()
{ {
return await _database.Episodes.ToListAsync(); return await _database.Episodes.ToListAsync();
} }
@ -64,10 +64,7 @@ namespace Kyoo.Controllers
if (obj == null) if (obj == null)
throw new ArgumentNullException(nameof(obj)); throw new ArgumentNullException(nameof(obj));
obj.Show = null;
obj.Season = null;
await Validate(obj); await Validate(obj);
await _database.Episodes.AddAsync(obj); await _database.Episodes.AddAsync(obj);
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
return obj.ID; return obj.ID;
@ -120,19 +117,19 @@ namespace Kyoo.Controllers
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
} }
public async Task<IEnumerable<Episode>> GetEpisodes(long showID, long seasonNumber) public async Task<ICollection<Episode>> GetEpisodes(long showID, long seasonNumber)
{ {
return await _database.Episodes.Where(x => x.ShowID == showID return await _database.Episodes.Where(x => x.ShowID == showID
&& x.SeasonNumber == seasonNumber).ToListAsync(); && x.SeasonNumber == seasonNumber).ToListAsync();
} }
public async Task<IEnumerable<Episode>> GetEpisodes(string showSlug, long seasonNumber) public async Task<ICollection<Episode>> GetEpisodes(string showSlug, long seasonNumber)
{ {
return await _database.Episodes.Where(x => x.Show.Slug == showSlug return await _database.Episodes.Where(x => x.Show.Slug == showSlug
&& x.SeasonNumber == seasonNumber).ToListAsync(); && x.SeasonNumber == seasonNumber).ToListAsync();
} }
public async Task<IEnumerable<Episode>> GetEpisodes(long seasonID) public async Task<ICollection<Episode>> GetEpisodes(long seasonID)
{ {
return await _database.Episodes.Where(x => x.SeasonID == seasonID).ToListAsync(); return await _database.Episodes.Where(x => x.SeasonID == seasonID).ToListAsync();
} }

View File

@ -28,7 +28,7 @@ namespace Kyoo.Controllers
return await _database.Genres.FirstOrDefaultAsync(x => x.Slug == slug); return await _database.Genres.FirstOrDefaultAsync(x => x.Slug == slug);
} }
public async Task<IEnumerable<Genre>> Search(string query) public async Task<ICollection<Genre>> Search(string query)
{ {
return await _database.Genres return await _database.Genres
.Where(genre => EF.Functions.Like(genre.Name, $"%{query}%")) .Where(genre => EF.Functions.Like(genre.Name, $"%{query}%"))
@ -36,7 +36,7 @@ namespace Kyoo.Controllers
.ToListAsync(); .ToListAsync();
} }
public async Task<IEnumerable<Genre>> GetAll() public async Task<ICollection<Genre>> GetAll()
{ {
return await _database.Genres.ToListAsync(); return await _database.Genres.ToListAsync();
} }

View File

@ -30,7 +30,7 @@ namespace Kyoo.Controllers
return _database.Libraries.FirstOrDefaultAsync(x => x.Name == slug); return _database.Libraries.FirstOrDefaultAsync(x => x.Name == slug);
} }
public async Task<IEnumerable<Library>> Search(string query) public async Task<ICollection<Library>> Search(string query)
{ {
return await _database.Libraries return await _database.Libraries
.Where(x => EF.Functions.Like(x.Name, $"%{query}%")) .Where(x => EF.Functions.Like(x.Name, $"%{query}%"))
@ -38,7 +38,7 @@ namespace Kyoo.Controllers
.ToListAsync(); .ToListAsync();
} }
public async Task<IEnumerable<Library>> GetAll() public async Task<ICollection<Library>> GetAll()
{ {
return await _database.Libraries.ToListAsync(); return await _database.Libraries.ToListAsync();
} }

View File

@ -29,7 +29,7 @@ namespace Kyoo.Controllers
return _database.Peoples.FirstOrDefaultAsync(x => x.Slug == slug); return _database.Peoples.FirstOrDefaultAsync(x => x.Slug == slug);
} }
public async Task<IEnumerable<People>> Search(string query) public async Task<ICollection<People>> Search(string query)
{ {
return await _database.Peoples return await _database.Peoples
.Where(people => EF.Functions.Like(people.Name, $"%{query}%")) .Where(people => EF.Functions.Like(people.Name, $"%{query}%"))
@ -37,7 +37,7 @@ namespace Kyoo.Controllers
.ToListAsync(); .ToListAsync();
} }
public async Task<IEnumerable<People>> GetAll() public async Task<ICollection<People>> GetAll()
{ {
return await _database.Peoples.ToListAsync(); return await _database.Peoples.ToListAsync();
} }

View File

@ -28,7 +28,7 @@ namespace Kyoo.Controllers
return await _database.Providers.FirstOrDefaultAsync(x => x.Name == slug); return await _database.Providers.FirstOrDefaultAsync(x => x.Name == slug);
} }
public async Task<IEnumerable<ProviderID>> Search(string query) public async Task<ICollection<ProviderID>> Search(string query)
{ {
return await _database.Providers return await _database.Providers
.Where(x => EF.Functions.Like(x.Name, $"%{query}%")) .Where(x => EF.Functions.Like(x.Name, $"%{query}%"))
@ -36,7 +36,7 @@ namespace Kyoo.Controllers
.ToListAsync(); .ToListAsync();
} }
public async Task<IEnumerable<ProviderID>> GetAll() public async Task<ICollection<ProviderID>> GetAll()
{ {
return await _database.Providers.ToListAsync(); return await _database.Providers.ToListAsync();
} }

View File

@ -42,7 +42,7 @@ namespace Kyoo.Controllers
&& x.SeasonNumber == seasonNumber); && x.SeasonNumber == seasonNumber);
} }
public async Task<IEnumerable<Season>> Search(string query) public async Task<ICollection<Season>> Search(string query)
{ {
return await _database.Seasons return await _database.Seasons
.Where(x => EF.Functions.Like(x.Title, $"%{query}%")) .Where(x => EF.Functions.Like(x.Title, $"%{query}%"))
@ -50,7 +50,7 @@ namespace Kyoo.Controllers
.ToListAsync(); .ToListAsync();
} }
public async Task<IEnumerable<Season>> GetAll() public async Task<ICollection<Season>> GetAll()
{ {
return await _database.Seasons.ToListAsync(); return await _database.Seasons.ToListAsync();
} }
@ -116,12 +116,12 @@ namespace Kyoo.Controllers
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
} }
public async Task<IEnumerable<Season>> GetSeasons(long showID) public async Task<ICollection<Season>> GetSeasons(long showID)
{ {
return await _database.Seasons.Where(x => x.ShowID == showID).ToListAsync(); return await _database.Seasons.Where(x => x.ShowID == showID).ToListAsync();
} }
public async Task<IEnumerable<Season>> GetSeasons(string showSlug) public async Task<ICollection<Season>> GetSeasons(string showSlug)
{ {
return await _database.Seasons.Where(x => x.Show.Slug == showSlug).ToListAsync(); return await _database.Seasons.Where(x => x.Show.Slug == showSlug).ToListAsync();
} }

View File

@ -39,7 +39,12 @@ namespace Kyoo.Controllers
return await _database.Shows.FirstOrDefaultAsync(x => x.Slug == slug); return await _database.Shows.FirstOrDefaultAsync(x => x.Slug == slug);
} }
public async Task<IEnumerable<Show>> Search(string query) public async Task<Show> GetByPath(string path)
{
return await _database.Shows.FirstOrDefaultAsync(x => x.Path == path);
}
public async Task<ICollection<Show>> Search(string query)
{ {
return await _database.Shows return await _database.Shows
.FromSqlInterpolated($@"SELECT * FROM Shows WHERE Shows.Title LIKE {$"%{query}%"} .FromSqlInterpolated($@"SELECT * FROM Shows WHERE Shows.Title LIKE {$"%{query}%"}
@ -48,7 +53,7 @@ namespace Kyoo.Controllers
.ToListAsync(); .ToListAsync();
} }
public async Task<IEnumerable<Show>> GetAll() public async Task<ICollection<Show>> GetAll()
{ {
return await _database.Shows.ToListAsync(); return await _database.Shows.ToListAsync();
} }
@ -121,5 +126,28 @@ namespace Kyoo.Controllers
_database.Shows.Remove(show); _database.Shows.Remove(show);
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
} }
public Task AddShowLink(long showID, long? libraryID, long? collectionID)
{
if (collectionID != null)
{
_database.CollectionLinks.AddIfNotExist(new CollectionLink { CollectionID = collectionID, ShowID = showID},
x => x.CollectionID == collectionID && x.ShowID == showID);
}
if (libraryID != null)
{
_database.LibraryLinks.AddIfNotExist(new LibraryLink {LibraryID = libraryID.Value, ShowID = showID},
x => x.LibraryID == libraryID.Value && x.CollectionID == null && x.ShowID == showID);
}
if (libraryID != null && collectionID != null)
{
_database.LibraryLinks.AddIfNotExist(
new LibraryLink {LibraryID = libraryID.Value, CollectionID = collectionID.Value},
x => x.LibraryID == libraryID && x.CollectionID == collectionID && x.ShowID == null);
}
return Task.CompletedTask;
}
} }
} }

View File

@ -28,7 +28,7 @@ namespace Kyoo.Controllers
return await _database.Studios.FirstOrDefaultAsync(x => x.Name == slug); return await _database.Studios.FirstOrDefaultAsync(x => x.Name == slug);
} }
public async Task<IEnumerable<Studio>> Search(string query) public async Task<ICollection<Studio>> Search(string query)
{ {
return await _database.Studios return await _database.Studios
.Where(x => EF.Functions.Like(x.Name, $"%{query}%")) .Where(x => EF.Functions.Like(x.Name, $"%{query}%"))
@ -36,7 +36,7 @@ namespace Kyoo.Controllers
.ToListAsync(); .ToListAsync();
} }
public async Task<IEnumerable<Studio>> GetAll() public async Task<ICollection<Studio>> GetAll()
{ {
return await _database.Studios.ToListAsync(); return await _database.Studios.ToListAsync();
} }

View File

@ -34,12 +34,12 @@ namespace Kyoo.Controllers
&& x.IsForced == isForced); && x.IsForced == isForced);
} }
public Task<IEnumerable<Track>> Search(string query) public Task<ICollection<Track>> Search(string query)
{ {
throw new InvalidOperationException("Tracks do not support the search method."); throw new InvalidOperationException("Tracks do not support the search method.");
} }
public async Task<IEnumerable<Track>> GetAll() public async Task<ICollection<Track>> GetAll()
{ {
return await _database.Tracks.ToListAsync(); return await _database.Tracks.ToListAsync();
} }

View File

@ -8,7 +8,6 @@ using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kyoo.Models.Watch; using Kyoo.Models.Watch;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace Kyoo.Controllers namespace Kyoo.Controllers
@ -28,11 +27,11 @@ namespace Kyoo.Controllers
private ITranscoder _transcoder; private ITranscoder _transcoder;
private IConfiguration _config; private IConfiguration _config;
public IEnumerable<string> GetPossibleParameters() public async Task<IEnumerable<string>> GetPossibleParameters()
{ {
using IServiceScope serviceScope = _serviceProvider.CreateScope(); using IServiceScope serviceScope = _serviceProvider.CreateScope();
ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>(); ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
return libraryManager.GetLibraries().Select(x => x.Slug); return (await libraryManager.GetLibraries()).Select(x => x.Slug);
} }
public int? Progress() public int? Progress()
@ -53,28 +52,27 @@ namespace Kyoo.Controllers
{ {
using IServiceScope serviceScope = _serviceProvider.CreateScope(); using IServiceScope serviceScope = _serviceProvider.CreateScope();
ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>(); ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
IEnumerable<Episode> episodes = libraryManager.GetEpisodes(); ICollection<Episode> episodes = await libraryManager.GetEpisodes();
IEnumerable<Library> libraries = argument == null ICollection<Library> libraries = argument == null
? libraryManager.GetLibraries() ? await libraryManager.GetLibraries()
: new [] {libraryManager.GetLibrary(argument)}; : new [] { await libraryManager.GetLibrary(argument)};
foreach (Episode episode in episodes) foreach (Episode episode in episodes)
{ {
if (!File.Exists(episode.Path)) if (!File.Exists(episode.Path))
libraryManager.RemoveEpisode(episode); await libraryManager.DeleteEpisode(episode);
} }
await libraryManager.SaveChanges();
await Task.WhenAll(libraries.ToList().Select(x => Scan(x, libraryManager, cancellationToken))); await Task.WhenAll(libraries.Select(x => Scan(x, episodes, cancellationToken)));
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.Error.WriteLine($"Unknown exception thrown durring libraries scan.\nException: {ex.Message}"); await Console.Error.WriteLineAsync($"Unknown exception thrown durring libraries scan.\nException: {ex.Message}");
} }
Console.WriteLine("Scan finished!"); Console.WriteLine("Scan finished!");
} }
private Task Scan(Library library, ILibraryManager libraryManager, CancellationToken cancellationToken) private Task Scan(Library library, ICollection<Episode> episodes, CancellationToken cancellationToken)
{ {
Console.WriteLine($"Scanning library {library.Name} at {string.Join(", ", library.Paths)}."); Console.WriteLine($"Scanning library {library.Name} at {string.Join(", ", library.Paths)}.");
return Task.WhenAll(library.Paths.Select(async path => return Task.WhenAll(library.Paths.Select(async path =>
@ -89,29 +87,29 @@ namespace Kyoo.Controllers
} }
catch (DirectoryNotFoundException) catch (DirectoryNotFoundException)
{ {
Console.Error.WriteLine($"The library's directory {path} could not be found (library slug: {library.Slug})"); await Console.Error.WriteLineAsync($"The library's directory {path} could not be found (library slug: {library.Slug})");
return Task.CompletedTask; return Task.CompletedTask;
} }
catch (PathTooLongException) catch (PathTooLongException)
{ {
Console.Error.WriteLine($"The library's directory {path} is too long for this system. (library slug: {library.Slug})"); await Console.Error.WriteLineAsync($"The library's directory {path} is too long for this system. (library slug: {library.Slug})");
return Task.CompletedTask; return Task.CompletedTask;
} }
catch (ArgumentException) catch (ArgumentException)
{ {
Console.Error.WriteLine($"The library's directory {path} is invalid. (library slug: {library.Slug})"); await Console.Error.WriteLineAsync($"The library's directory {path} is invalid. (library slug: {library.Slug})");
return Task.CompletedTask; return Task.CompletedTask;
} }
catch (UnauthorizedAccessException) catch (UnauthorizedAccessException)
{ {
Console.Error.WriteLine($"Permission denied: can't access library's directory at {path}. (library slug: {library.Slug})"); await Console.Error.WriteLineAsync($"Permission denied: can't access library's directory at {path}. (library slug: {library.Slug})");
return Task.CompletedTask; return Task.CompletedTask;
} }
// return Task.WhenAll(files.Select(file => // return Task.WhenAll(files.Select(file =>
foreach (string file in files) foreach (string file in files)
{ {
if (!IsVideo(file) || libraryManager.GetEpisodes().Any(x => x.Path == file)) if (!IsVideo(file) || episodes.Any(x => x.Path == file))
continue; //return Task.CompletedTask; continue; //return Task.CompletedTask;
string relativePath = file.Substring(path.Length); string relativePath = file.Substring(path.Length);
/*return*/ await RegisterFile(file, relativePath, library, cancellationToken); /*return*/ await RegisterFile(file, relativePath, library, cancellationToken);
@ -128,7 +126,6 @@ namespace Kyoo.Controllers
using IServiceScope serviceScope = _serviceProvider.CreateScope(); using IServiceScope serviceScope = _serviceProvider.CreateScope();
ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>(); ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
((DbSet<Library>)libraryManager.GetLibraries()).Attach(library);
string patern = _config.GetValue<string>("regex"); string patern = _config.GetValue<string>("regex");
Regex regex = new Regex(patern, RegexOptions.IgnoreCase); Regex regex = new Regex(patern, RegexOptions.IgnoreCase);
@ -145,66 +142,88 @@ namespace Kyoo.Controllers
bool isMovie = seasonNumber == -1 && episodeNumber == -1 && absoluteNumber == -1; bool isMovie = seasonNumber == -1 && episodeNumber == -1 && absoluteNumber == -1;
Show show = await GetShow(libraryManager, showName, showPath, isMovie, library); Show show = await GetShow(libraryManager, showName, showPath, isMovie, library);
if (isMovie) if (isMovie)
libraryManager.Register(await GetMovie(show, path)); await libraryManager.RegisterEpisode(await GetMovie(show, path));
else else
{ {
Season season = await GetSeason(libraryManager, show, seasonNumber, library); Season season = await GetSeason(libraryManager, show, seasonNumber, library);
Episode episode = await GetEpisode(libraryManager, show, season, episodeNumber, absoluteNumber, path, library); Episode episode = await GetEpisode(libraryManager, show, season, episodeNumber, absoluteNumber, path, library);
libraryManager.Register(episode); await libraryManager.RegisterEpisode(episode);
} }
if (collection != null)
libraryManager.Register(collection); await libraryManager.AddShowLink(show, library, collection);
libraryManager.RegisterShowLinks(library, collection, show); Console.WriteLine($"Episode at {path} registered.");
Console.WriteLine($"Registering episode at: {path}");
await libraryManager.SaveChanges();
} }
private async Task<Collection> GetCollection(ILibraryManager libraryManager, string collectionName, Library library) private async Task<Collection> GetCollection(ILibraryManager libraryManager,
string collectionName,
Library library)
{ {
if (string.IsNullOrEmpty(collectionName)) if (string.IsNullOrEmpty(collectionName))
return await Task.FromResult<Collection>(null); return null;
Collection name = libraryManager.GetCollection(Utility.ToSlug(collectionName)); Collection collection = await libraryManager.GetCollection(Utility.ToSlug(collectionName));
if (name != null) if (collection != null)
return name; return collection;
return await _metadataProvider.GetCollectionFromName(collectionName, library); collection = await _metadataProvider.GetCollectionFromName(collectionName, library);
await libraryManager.RegisterCollection(collection);
return collection;
} }
private async Task<Show> GetShow(ILibraryManager libraryManager, string showTitle, string showPath, bool isMovie, Library library) private async Task<Show> GetShow(ILibraryManager libraryManager,
string showTitle,
string showPath,
bool isMovie,
Library library)
{ {
Show show = libraryManager.GetShowByPath(showPath); Show show = await libraryManager.GetShowByPath(showPath);
if (show != null) if (show != null)
return show; return show;
show = await _metadataProvider.SearchShow(showTitle, isMovie, library); show = await _metadataProvider.SearchShow(showTitle, isMovie, library);
show.Path = showPath; show.Path = showPath;
show.People = await _metadataProvider.GetPeople(show, library); show.People = await _metadataProvider.GetPeople(show, library);
await libraryManager.RegisterShow(show);
await _thumbnailsManager.Validate(show.People); await _thumbnailsManager.Validate(show.People);
await _thumbnailsManager.Validate(show); await _thumbnailsManager.Validate(show);
return show; return show;
} }
private async Task<Season> GetSeason(ILibraryManager libraryManager, Show show, long seasonNumber, Library library) private async Task<Season> GetSeason(ILibraryManager libraryManager,
Show show,
long seasonNumber,
Library library)
{ {
if (seasonNumber == -1) if (seasonNumber == -1)
return default; return default;
Season season = libraryManager.GetSeason(show.Slug, seasonNumber); Season season = await libraryManager.GetSeason(show.Slug, seasonNumber);
if (season == null) if (season == null)
{ {
season = await _metadataProvider.GetSeason(show, seasonNumber, library); season = await _metadataProvider.GetSeason(show, seasonNumber, library);
await libraryManager.RegisterSeason(season);
await _thumbnailsManager.Validate(season); await _thumbnailsManager.Validate(season);
} }
season.Show = show; season.Show = show;
return season; return season;
} }
private async Task<Episode> GetEpisode(ILibraryManager libraryManager, Show show, Season season, long episodeNumber, long absoluteNumber, string episodePath, Library library) private async Task<Episode> GetEpisode(ILibraryManager libraryManager,
Show show,
Season season,
long episodeNumber,
long absoluteNumber,
string episodePath,
Library library)
{ {
Episode episode = await _metadataProvider.GetEpisode(show, episodePath, season?.SeasonNumber ?? -1, episodeNumber, absoluteNumber, library); Episode episode = await _metadataProvider.GetEpisode(show,
if (season == null) episodePath,
season = await GetSeason(libraryManager, show, episode.SeasonNumber, library); season?.SeasonNumber ?? -1,
episodeNumber,
absoluteNumber,
library);
season ??= await GetSeason(libraryManager, show, episode.SeasonNumber, library);
episode.Season = season; episode.Season = season;
if (season == null) if (season == null)
{ {
await Console.Error.WriteLineAsync("\tError: You don't have any provider that support absolute epiode numbering. Install one and try again."); await Console.Error.WriteLineAsync("Error: You don't have any provider that support absolute epiode numbering. Install one and try again.");
return default; return default;
} }

View File

@ -58,9 +58,9 @@ namespace Kyoo.Tasks
return Task.CompletedTask; return Task.CompletedTask;
} }
public IEnumerable<string> GetPossibleParameters() public Task<IEnumerable<string>> GetPossibleParameters()
{ {
return null; return Task.FromResult<IEnumerable<string>>(null);
} }
public int? Progress() public int? Progress()

View File

@ -28,9 +28,9 @@ namespace Kyoo.Tasks
return Task.CompletedTask; return Task.CompletedTask;
} }
public IEnumerable<string> GetPossibleParameters() public Task<IEnumerable<string>> GetPossibleParameters()
{ {
return null; return Task.FromResult<IEnumerable<string>>(null);
} }
public int? Progress() public int? Progress()

View File

@ -24,9 +24,9 @@ namespace Kyoo.Tasks
return Task.CompletedTask; return Task.CompletedTask;
} }
public IEnumerable<string> GetPossibleParameters() public Task<IEnumerable<string>> GetPossibleParameters()
{ {
return null; return Task.FromResult<IEnumerable<string>>(null);
} }
public int? Progress() public int? Progress()

View File

@ -114,9 +114,9 @@ namespace Kyoo.Tasks
await _thumbnailsManager.Validate(edited, true); await _thumbnailsManager.Validate(edited, true);
} }
public IEnumerable<string> GetPossibleParameters() public Task<IEnumerable<string>> GetPossibleParameters()
{ {
return default; return Task.FromResult<IEnumerable<string>>(null);
} }
public int? Progress() public int? Progress()