diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs index 705ff12f..caef30a6 100644 --- a/Kyoo.Common/Controllers/IRepository.cs +++ b/Kyoo.Common/Controllers/IRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using JetBrains.Annotations; using Kyoo.Models; @@ -15,9 +16,17 @@ namespace Kyoo.Controllers Task Create([NotNull] T obj); Task CreateIfNotExists([NotNull] T obj); Task Edit([NotNull] T edited, bool resetOld); + Task Delete(int id); Task Delete(string slug); Task Delete([NotNull] T obj); + + Task DeleteRange(params T[] objs) => DeleteRange(objs.AsEnumerable()); + Task DeleteRange(IEnumerable objs); + Task DeleteRange(params int[] ids) => DeleteRange(ids.AsEnumerable()); + Task DeleteRange(IEnumerable ids); + Task DeleteRange(params string[] slugs) => DeleteRange(slugs.AsEnumerable()); + Task DeleteRange(IEnumerable slugs); } public interface IShowRepository : IRepository diff --git a/Kyoo/Controllers/Repositories/CollectionRepository.cs b/Kyoo/Controllers/Repositories/CollectionRepository.cs index 139df7d4..776cc597 100644 --- a/Kyoo/Controllers/Repositories/CollectionRepository.cs +++ b/Kyoo/Controllers/Repositories/CollectionRepository.cs @@ -137,5 +137,23 @@ namespace Kyoo.Controllers _database.Entry(link).State = EntityState.Deleted; await _database.SaveChangesAsync(); } + + public async Task DeleteRange(IEnumerable objs) + { + foreach (Collection obj in objs) + await Delete(obj); + } + + public async Task DeleteRange(IEnumerable ids) + { + foreach (int id in ids) + await Delete(id); + } + + public async Task DeleteRange(IEnumerable slugs) + { + foreach (string slug in slugs) + await Delete(slug); + } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/EpisodeRepository.cs b/Kyoo/Controllers/Repositories/EpisodeRepository.cs index b6924c5c..e4d54134 100644 --- a/Kyoo/Controllers/Repositories/EpisodeRepository.cs +++ b/Kyoo/Controllers/Repositories/EpisodeRepository.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using Kyoo.Models; using Kyoo.Models.Exceptions; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.ChangeTracking; namespace Kyoo.Controllers { @@ -13,14 +12,13 @@ namespace Kyoo.Controllers { private readonly DatabaseContext _database; private readonly IProviderRepository _providers; - private readonly ITrackRepository _tracks; + // private readonly ITrackRepository _tracks; - public EpisodeRepository(DatabaseContext database, IProviderRepository providers, ITrackRepository tracks) + public EpisodeRepository(DatabaseContext database, IProviderRepository providers) { _database = database; _providers = providers; - _tracks = tracks; } public void Dispose() @@ -168,6 +166,23 @@ namespace Kyoo.Controllers } } + public async Task> GetEpisodes(int showID, int seasonNumber) + { + return await _database.Episodes.Where(x => x.ShowID == showID + && x.SeasonNumber == seasonNumber).ToListAsync(); + } + + public async Task> GetEpisodes(string showSlug, int seasonNumber) + { + return await _database.Episodes.Where(x => x.Show.Slug == showSlug + && x.SeasonNumber == seasonNumber).ToListAsync(); + } + + public async Task> GetEpisodes(int seasonID) + { + return await _database.Episodes.Where(x => x.SeasonID == seasonID).ToListAsync(); + } + public async Task Delete(int id) { Episode obj = await Get(id); @@ -195,31 +210,26 @@ namespace Kyoo.Controllers if (obj.ExternalIDs != null) foreach (MetadataID entry in obj.ExternalIDs) _database.Entry(entry).State = EntityState.Deleted; - // Since Tracks & Episodes are on the same database and handled by dotnet-ef, we can't use the repository to delete them. - /*if (obj.Tracks != null) - * foreach (Track entry in obj.Tracks) - * await _tracks.Delete(entry); - */ - await _database.SaveChangesAsync(); } + + public async Task DeleteRange(IEnumerable objs) + { + foreach (Episode obj in objs) + await Delete(obj); + } - public async Task> GetEpisodes(int showID, int seasonNumber) + public async Task DeleteRange(IEnumerable ids) { - return await _database.Episodes.Where(x => x.ShowID == showID - && x.SeasonNumber == seasonNumber).ToListAsync(); + foreach (int id in ids) + await Delete(id); } - - public async Task> GetEpisodes(string showSlug, int seasonNumber) + + public async Task DeleteRange(IEnumerable slugs) { - return await _database.Episodes.Where(x => x.Show.Slug == showSlug - && x.SeasonNumber == seasonNumber).ToListAsync(); - } - - public async Task> GetEpisodes(int seasonID) - { - return await _database.Episodes.Where(x => x.SeasonID == seasonID).ToListAsync(); + foreach (string slug in slugs) + await Delete(slug); } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/GenreRepository.cs b/Kyoo/Controllers/Repositories/GenreRepository.cs index 0da62f6d..9834e37e 100644 --- a/Kyoo/Controllers/Repositories/GenreRepository.cs +++ b/Kyoo/Controllers/Repositories/GenreRepository.cs @@ -134,5 +134,23 @@ namespace Kyoo.Controllers _database.Entry(link).State = EntityState.Deleted; await _database.SaveChangesAsync(); } + + public async Task DeleteRange(IEnumerable objs) + { + foreach (Genre obj in objs) + await Delete(obj); + } + + public async Task DeleteRange(IEnumerable ids) + { + foreach (int id in ids) + await Delete(id); + } + + public async Task DeleteRange(IEnumerable slugs) + { + foreach (string slug in slugs) + await Delete(slug); + } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/LibraryRepository.cs b/Kyoo/Controllers/Repositories/LibraryRepository.cs index 5f29e98e..99e15a0f 100644 --- a/Kyoo/Controllers/Repositories/LibraryRepository.cs +++ b/Kyoo/Controllers/Repositories/LibraryRepository.cs @@ -150,5 +150,23 @@ namespace Kyoo.Controllers _database.Entry(entry).State = EntityState.Deleted; await _database.SaveChangesAsync(); } + + public async Task DeleteRange(IEnumerable objs) + { + foreach (Library obj in objs) + await Delete(obj); + } + + public async Task DeleteRange(IEnumerable ids) + { + foreach (int id in ids) + await Delete(id); + } + + public async Task DeleteRange(IEnumerable slugs) + { + foreach (string slug in slugs) + await Delete(slug); + } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/PeopleRepository.cs b/Kyoo/Controllers/Repositories/PeopleRepository.cs index 60102aff..85664970 100644 --- a/Kyoo/Controllers/Repositories/PeopleRepository.cs +++ b/Kyoo/Controllers/Repositories/PeopleRepository.cs @@ -149,5 +149,23 @@ namespace Kyoo.Controllers _database.Entry(link).State = EntityState.Deleted; await _database.SaveChangesAsync(); } + + public async Task DeleteRange(IEnumerable objs) + { + foreach (People obj in objs) + await Delete(obj); + } + + public async Task DeleteRange(IEnumerable ids) + { + foreach (int id in ids) + await Delete(id); + } + + public async Task DeleteRange(IEnumerable slugs) + { + foreach (string slug in slugs) + await Delete(slug); + } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/ProviderRepository.cs b/Kyoo/Controllers/Repositories/ProviderRepository.cs index 0ed4614d..ec298411 100644 --- a/Kyoo/Controllers/Repositories/ProviderRepository.cs +++ b/Kyoo/Controllers/Repositories/ProviderRepository.cs @@ -131,5 +131,23 @@ namespace Kyoo.Controllers // TODO handle ExternalID deletion when they refer to this providerID. await _database.SaveChangesAsync(); } + + public async Task DeleteRange(IEnumerable objs) + { + foreach (ProviderID obj in objs) + await Delete(obj); + } + + public async Task DeleteRange(IEnumerable ids) + { + foreach (int id in ids) + await Delete(id); + } + + public async Task DeleteRange(IEnumerable slugs) + { + foreach (string slug in slugs) + await Delete(slug); + } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/SeasonRepository.cs b/Kyoo/Controllers/Repositories/SeasonRepository.cs index 7ed56125..df0bdbd2 100644 --- a/Kyoo/Controllers/Repositories/SeasonRepository.cs +++ b/Kyoo/Controllers/Repositories/SeasonRepository.cs @@ -144,6 +144,16 @@ namespace Kyoo.Controllers } } + public async Task> GetSeasons(int showID) + { + return await _database.Seasons.Where(x => x.ShowID == showID).ToListAsync(); + } + + public async Task> GetSeasons(string showSlug) + { + return await _database.Seasons.Where(x => x.Show.Slug == showSlug).ToListAsync(); + } + public async Task Delete(int id) { Season obj = await Get(id); @@ -172,19 +182,26 @@ namespace Kyoo.Controllers foreach (MetadataID entry in obj.ExternalIDs) _database.Entry(entry).State = EntityState.Deleted; if (obj.Episodes != null) - foreach (Episode episode in obj.Episodes) - await _episodes.Delete(episode); + await _episodes.DeleteRange(obj.Episodes); await _database.SaveChangesAsync(); } - public async Task> GetSeasons(int showID) + public async Task DeleteRange(IEnumerable objs) { - return await _database.Seasons.Where(x => x.ShowID == showID).ToListAsync(); + foreach (Season obj in objs) + await Delete(obj); } - - public async Task> GetSeasons(string showSlug) + + public async Task DeleteRange(IEnumerable ids) { - return await _database.Seasons.Where(x => x.Show.Slug == showSlug).ToListAsync(); + foreach (int id in ids) + await Delete(id); + } + + public async Task DeleteRange(IEnumerable slugs) + { + foreach (string slug in slugs) + await Delete(slug); } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/ShowRepository.cs b/Kyoo/Controllers/Repositories/ShowRepository.cs index f355c5cc..60a587ae 100644 --- a/Kyoo/Controllers/Repositories/ShowRepository.cs +++ b/Kyoo/Controllers/Repositories/ShowRepository.cs @@ -162,6 +162,29 @@ namespace Kyoo.Controllers foreach (MetadataID link in obj.ExternalIDs) link.ProviderID = await _providers.CreateIfNotExists(link.Provider); } + + public async Task AddShowLink(int showID, int? libraryID, int? 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); + } + + await _database.SaveChangesAsync(); + } public async Task Delete(int id) { @@ -198,35 +221,28 @@ namespace Kyoo.Controllers _database.Entry(entry).State = EntityState.Deleted; if (obj.Seasons != null) - foreach (Season season in obj.Seasons) - await _seasons.Delete(season); + await _seasons.DeleteRange(obj.Seasons); if (obj.Episodes != null) - foreach (Episode episode in obj.Episodes.Where(x => x.SeasonID == null)) - await _episodes.Delete(episode); + await _episodes.DeleteRange(obj.Episodes); await _database.SaveChangesAsync(); } - public async Task AddShowLink(int showID, int? libraryID, int? collectionID) + public async Task DeleteRange(IEnumerable objs) { - 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); - } - - await _database.SaveChangesAsync(); + foreach (Show obj in objs) + await Delete(obj); + } + + public async Task DeleteRange(IEnumerable ids) + { + foreach (int id in ids) + await Delete(id); + } + + public async Task DeleteRange(IEnumerable slugs) + { + foreach (string slug in slugs) + await Delete(slug); } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/StudioRepository.cs b/Kyoo/Controllers/Repositories/StudioRepository.cs index e6bf7578..69e93e74 100644 --- a/Kyoo/Controllers/Repositories/StudioRepository.cs +++ b/Kyoo/Controllers/Repositories/StudioRepository.cs @@ -133,5 +133,23 @@ namespace Kyoo.Controllers show.StudioID = null; await _database.SaveChangesAsync(); } + + public async Task DeleteRange(IEnumerable objs) + { + foreach (Studio obj in objs) + await Delete(obj); + } + + public async Task DeleteRange(IEnumerable ids) + { + foreach (int id in ids) + await Delete(id); + } + + public async Task DeleteRange(IEnumerable slugs) + { + foreach (string slug in slugs) + await Delete(slug); + } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/TrackRepository.cs b/Kyoo/Controllers/Repositories/TrackRepository.cs index 89284f29..dbc54b01 100644 --- a/Kyoo/Controllers/Repositories/TrackRepository.cs +++ b/Kyoo/Controllers/Repositories/TrackRepository.cs @@ -119,5 +119,23 @@ namespace Kyoo.Controllers _database.Entry(obj).State = EntityState.Deleted; await _database.SaveChangesAsync(); } + + public async Task DeleteRange(IEnumerable objs) + { + foreach (Track obj in objs) + await Delete(obj); + } + + public async Task DeleteRange(IEnumerable ids) + { + foreach (int id in ids) + await Delete(id); + } + + public async Task DeleteRange(IEnumerable slugs) + { + foreach (string slug in slugs) + await Delete(slug); + } } } \ No newline at end of file diff --git a/Kyoo/Startup.cs b/Kyoo/Startup.cs index 0c19d8d7..c59758f0 100644 --- a/Kyoo/Startup.cs +++ b/Kyoo/Startup.cs @@ -46,9 +46,9 @@ namespace Kyoo services.AddDbContext(options => { options.UseLazyLoadingProxies() - .UseNpgsql(_configuration.GetConnectionString("Database")); - //.EnableSensitiveDataLogging() - //.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole())); + .UseNpgsql(_configuration.GetConnectionString("Database")) + .EnableSensitiveDataLogging() + .UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole())); }, ServiceLifetime.Transient); services.AddDbContext(options => diff --git a/Kyoo/Tasks/Crawler.cs b/Kyoo/Tasks/Crawler.cs index c619ad8f..91747974 100644 --- a/Kyoo/Tasks/Crawler.cs +++ b/Kyoo/Tasks/Crawler.cs @@ -59,9 +59,9 @@ namespace Kyoo.Controllers using IServiceScope serviceScope = _serviceProvider.CreateScope(); await using ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService(); - // foreach (Show show in await libraryManager.GetShows()) - // if (!Directory.Exists(show.Path)) - // await libraryManager.DeleteShow(show); + foreach (Show show in await libraryManager.GetShows()) + if (!Directory.Exists(show.Path)) + await libraryManager.DeleteShow(show); ICollection episodes = await libraryManager.GetEpisodes(); ICollection libraries = argument == null