mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Merge branch 'master' of https://github.com/AnonymusRaccoon/Kyoo
This commit is contained in:
commit
d3a126bf03
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models;
|
||||
@ -15,7 +16,17 @@ namespace Kyoo.Controllers
|
||||
Task<int> Create([NotNull] T obj);
|
||||
Task<int> CreateIfNotExists([NotNull] T obj);
|
||||
Task Edit([NotNull] T edited, bool resetOld);
|
||||
Task Delete(T obj);
|
||||
|
||||
Task Delete(int id);
|
||||
Task Delete(string slug);
|
||||
Task Delete([NotNull] T obj);
|
||||
|
||||
Task DeleteRange(params T[] objs) => DeleteRange(objs.AsEnumerable());
|
||||
Task DeleteRange(IEnumerable<T> objs);
|
||||
Task DeleteRange(params int[] ids) => DeleteRange(ids.AsEnumerable());
|
||||
Task DeleteRange(IEnumerable<int> ids);
|
||||
Task DeleteRange(params string[] slugs) => DeleteRange(slugs.AsEnumerable());
|
||||
Task DeleteRange(IEnumerable<string> slugs);
|
||||
}
|
||||
|
||||
public interface IShowRepository : IRepository<Show>
|
||||
@ -27,6 +38,7 @@ namespace Kyoo.Controllers
|
||||
public interface ISeasonRepository : IRepository<Season>
|
||||
{
|
||||
Task<Season> Get(string showSlug, int seasonNumber);
|
||||
Task Delete(string showSlug, int seasonNumber);
|
||||
|
||||
Task<ICollection<Season>> GetSeasons(int showID);
|
||||
Task<ICollection<Season>> GetSeasons(string showSlug);
|
||||
@ -35,6 +47,7 @@ namespace Kyoo.Controllers
|
||||
public interface IEpisodeRepository : IRepository<Episode>
|
||||
{
|
||||
Task<Episode> Get(string showSlug, int seasonNumber, int episodeNumber);
|
||||
Task Delete(string showSlug, int seasonNumber, int episodeNumber);
|
||||
|
||||
Task<ICollection<Episode>> GetEpisodes(int showID, int seasonNumber);
|
||||
Task<ICollection<Episode>> GetEpisodes(string showSlug, int seasonNumber);
|
||||
|
@ -19,6 +19,14 @@ namespace Kyoo.Models
|
||||
get => Links.Select(x => x.Show);
|
||||
set => Links = value.Select(x => new CollectionLink(this, x));
|
||||
}
|
||||
|
||||
[NotMergable] [JsonIgnore] public virtual IEnumerable<LibraryLink> LibraryLinks { get; set; }
|
||||
|
||||
[NotMergable] [JsonIgnore] public IEnumerable<Library> Libraries
|
||||
{
|
||||
get => LibraryLinks?.Select(x => x.Library);
|
||||
set => LibraryLinks = value?.Select(x => new LibraryLink(x, this));
|
||||
}
|
||||
|
||||
public Collection() { }
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Kyoo.Models
|
||||
{
|
||||
@ -8,7 +11,13 @@ namespace Kyoo.Models
|
||||
public string Slug { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// public IEnumerable<Show> Shows { get; set; }
|
||||
[NotMergable] [JsonIgnore] public virtual IEnumerable<GenreLink> Links { get; set; }
|
||||
|
||||
[NotMergable] [JsonIgnore] public IEnumerable<Show> Shows
|
||||
{
|
||||
get => Links.Select(x => x.Show);
|
||||
set => Links = value?.Select(x => new GenreLink(x, this));
|
||||
}
|
||||
|
||||
public Genre() {}
|
||||
|
||||
|
@ -41,6 +41,22 @@ namespace Kyoo.Models
|
||||
[JsonIgnore] public virtual IEnumerable<PeopleLink> People { get; set; }
|
||||
[JsonIgnore] public virtual IEnumerable<Season> Seasons { get; set; }
|
||||
[JsonIgnore] public virtual IEnumerable<Episode> Episodes { get; set; }
|
||||
|
||||
[NotMergable] [JsonIgnore] public virtual IEnumerable<LibraryLink> LibraryLinks { get; set; }
|
||||
|
||||
[NotMergable] [JsonIgnore] public IEnumerable<Library> Libraries
|
||||
{
|
||||
get => LibraryLinks?.Select(x => x.Library);
|
||||
set => LibraryLinks = value?.Select(x => new LibraryLink(x, this));
|
||||
}
|
||||
|
||||
[NotMergable] [JsonIgnore] public virtual IEnumerable<CollectionLink> CollectionLinks { get; set; }
|
||||
|
||||
[NotMergable] [JsonIgnore] public IEnumerable<Collection> Collections
|
||||
{
|
||||
get => CollectionLinks.Select(x => x.Collection);
|
||||
set => CollectionLinks = value?.Select(x => new CollectionLink(x, this));
|
||||
}
|
||||
|
||||
public Show() { }
|
||||
|
||||
|
@ -111,10 +111,49 @@ namespace Kyoo.Controllers
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
Collection obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
Collection obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(Collection obj)
|
||||
{
|
||||
_database.Collections.Remove(obj);
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
if (obj.Links != null)
|
||||
foreach (CollectionLink link in obj.Links)
|
||||
_database.Entry(link).State = EntityState.Deleted;
|
||||
if (obj.LibraryLinks != null)
|
||||
foreach (LibraryLink link in obj.LibraryLinks)
|
||||
_database.Entry(link).State = EntityState.Deleted;
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<Collection> objs)
|
||||
{
|
||||
foreach (Collection obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ namespace Kyoo.Controllers
|
||||
{
|
||||
private readonly DatabaseContext _database;
|
||||
private readonly IProviderRepository _providers;
|
||||
// private readonly ITrackRepository _tracks;
|
||||
|
||||
|
||||
public EpisodeRepository(DatabaseContext database, IProviderRepository providers)
|
||||
@ -83,10 +84,12 @@ namespace Kyoo.Controllers
|
||||
if (obj.ExternalIDs != null)
|
||||
foreach (MetadataID entry in obj.ExternalIDs)
|
||||
_database.Entry(entry).State = EntityState.Added;
|
||||
|
||||
// Since Episodes & Tracks are on the same DB, using a single commit is quicker.
|
||||
if (obj.Tracks != null)
|
||||
foreach (Track entry in obj.Tracks)
|
||||
_database.Entry(entry).State = EntityState.Added;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
await _database.SaveChangesAsync();
|
||||
@ -99,6 +102,16 @@ namespace Kyoo.Controllers
|
||||
throw new DuplicatedItemException($"Trying to insert a duplicated episode (slug {obj.Slug} already exists).");
|
||||
throw;
|
||||
}
|
||||
|
||||
// Since Episodes & Tracks are on the same DB, using a single commit is quicker.
|
||||
/*if (obj.Tracks != null)
|
||||
* foreach (Track track in obj.Tracks)
|
||||
* {
|
||||
* track.EpisodeID = obj.ID;
|
||||
* await _tracks.Create(track);
|
||||
* }
|
||||
*/
|
||||
|
||||
return obj.ID;
|
||||
}
|
||||
|
||||
@ -153,16 +166,10 @@ namespace Kyoo.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Delete(Episode obj)
|
||||
{
|
||||
_database.Episodes.Remove(obj);
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<ICollection<Episode>> GetEpisodes(int showID, int seasonNumber)
|
||||
{
|
||||
return await _database.Episodes.Where(x => x.ShowID == showID
|
||||
&& x.SeasonNumber == seasonNumber).ToListAsync();
|
||||
&& x.SeasonNumber == seasonNumber).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<ICollection<Episode>> GetEpisodes(string showSlug, int seasonNumber)
|
||||
@ -175,5 +182,54 @@ namespace Kyoo.Controllers
|
||||
{
|
||||
return await _database.Episodes.Where(x => x.SeasonID == seasonID).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
Episode obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
Episode obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string showSlug, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
Episode obj = await Get(showSlug, seasonNumber, episodeNumber);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(Episode obj)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
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.
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<Episode> objs)
|
||||
{
|
||||
foreach (Episode obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -56,7 +56,7 @@ namespace Kyoo.Controllers
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
await _database.Genres.AddAsync(obj);
|
||||
_database.Entry(obj).State = EntityState.Added;
|
||||
|
||||
try
|
||||
{
|
||||
@ -110,11 +110,47 @@ namespace Kyoo.Controllers
|
||||
Utility.Merge(old, edited);
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
Genre obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
Genre obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(Genre obj)
|
||||
{
|
||||
_database.Genres.Remove(obj);
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
if (obj.Links != null)
|
||||
foreach (GenreLink link in obj.Links)
|
||||
_database.Entry(link).State = EntityState.Deleted;
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<Genre> objs)
|
||||
{
|
||||
foreach (Genre obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -124,10 +124,49 @@ namespace Kyoo.Controllers
|
||||
link.ProviderID = await _providers.CreateIfNotExists(link.Provider);
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
Library obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
Library obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(Library obj)
|
||||
{
|
||||
_database.Libraries.Remove(obj);
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
if (obj.ProviderLinks != null)
|
||||
foreach (ProviderLink entry in obj.ProviderLinks)
|
||||
_database.Entry(entry).State = EntityState.Deleted;
|
||||
if (obj.Links != null)
|
||||
foreach (LibraryLink entry in obj.Links)
|
||||
_database.Entry(entry).State = EntityState.Deleted;
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<Library> objs)
|
||||
{
|
||||
foreach (Library obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -122,11 +122,50 @@ namespace Kyoo.Controllers
|
||||
foreach (MetadataID link in obj.ExternalIDs)
|
||||
link.ProviderID = await _providers.CreateIfNotExists(link.Provider);
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
People obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
People obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(People obj)
|
||||
{
|
||||
_database.Peoples.Remove(obj);
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
if (obj.ExternalIDs != null)
|
||||
foreach (MetadataID entry in obj.ExternalIDs)
|
||||
_database.Entry(entry).State = EntityState.Deleted;
|
||||
if (obj.Roles != null)
|
||||
foreach (PeopleLink link in obj.Roles)
|
||||
_database.Entry(link).State = EntityState.Deleted;
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<People> objs)
|
||||
{
|
||||
foreach (People obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -110,10 +110,44 @@ namespace Kyoo.Controllers
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
ProviderID obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
ProviderID obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(ProviderID obj)
|
||||
{
|
||||
_database.Providers.Remove(obj);
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
// TODO handle ExternalID deletion when they refer to this providerID.
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<ProviderID> objs)
|
||||
{
|
||||
foreach (ProviderID obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -12,12 +12,14 @@ namespace Kyoo.Controllers
|
||||
{
|
||||
private readonly DatabaseContext _database;
|
||||
private readonly IProviderRepository _providers;
|
||||
private readonly IEpisodeRepository _episodes;
|
||||
|
||||
|
||||
public SeasonRepository(DatabaseContext database, IProviderRepository providers)
|
||||
public SeasonRepository(DatabaseContext database, IProviderRepository providers, IEpisodeRepository episodes)
|
||||
{
|
||||
_database = database;
|
||||
_providers = providers;
|
||||
_episodes = episodes;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@ -141,12 +143,6 @@ namespace Kyoo.Controllers
|
||||
link.ProviderID = await _providers.CreateIfNotExists(link.Provider);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Delete(Season obj)
|
||||
{
|
||||
_database.Seasons.Remove(obj);
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<ICollection<Season>> GetSeasons(int showID)
|
||||
{
|
||||
@ -157,5 +153,58 @@ namespace Kyoo.Controllers
|
||||
{
|
||||
return await _database.Seasons.Where(x => x.Show.Slug == showSlug).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
Season obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
Season obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string showSlug, int seasonNumber)
|
||||
{
|
||||
Season obj = await Get(showSlug, seasonNumber);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(Season obj)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
|
||||
if (obj.ExternalIDs != null)
|
||||
foreach (MetadataID entry in obj.ExternalIDs)
|
||||
_database.Entry(entry).State = EntityState.Deleted;
|
||||
|
||||
await _database.SaveChangesAsync();
|
||||
|
||||
if (obj.Episodes != null)
|
||||
await _episodes.DeleteRange(obj.Episodes);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<Season> objs)
|
||||
{
|
||||
foreach (Season obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,18 +15,24 @@ namespace Kyoo.Controllers
|
||||
private readonly IPeopleRepository _people;
|
||||
private readonly IGenreRepository _genres;
|
||||
private readonly IProviderRepository _providers;
|
||||
private readonly ISeasonRepository _seasons;
|
||||
private readonly IEpisodeRepository _episodes;
|
||||
|
||||
public ShowRepository(DatabaseContext database,
|
||||
IStudioRepository studios,
|
||||
IPeopleRepository people,
|
||||
IGenreRepository genres,
|
||||
IProviderRepository providers)
|
||||
IProviderRepository providers,
|
||||
ISeasonRepository seasons,
|
||||
IEpisodeRepository episodes)
|
||||
{
|
||||
_database = database;
|
||||
_studios = studios;
|
||||
_people = people;
|
||||
_genres = genres;
|
||||
_providers = providers;
|
||||
_seasons = seasons;
|
||||
_episodes = episodes;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@ -40,19 +46,19 @@ namespace Kyoo.Controllers
|
||||
await Task.WhenAll(_database.DisposeAsync().AsTask(), _studios.DisposeAsync().AsTask());
|
||||
}
|
||||
|
||||
public async Task<Show> Get(int id)
|
||||
public Task<Show> Get(int id)
|
||||
{
|
||||
return await _database.Shows.FirstOrDefaultAsync(x => x.ID == id);
|
||||
return _database.Shows.FirstOrDefaultAsync(x => x.ID == id);
|
||||
}
|
||||
|
||||
public async Task<Show> Get(string slug)
|
||||
public Task<Show> Get(string slug)
|
||||
{
|
||||
return await _database.Shows.FirstOrDefaultAsync(x => x.Slug == slug);
|
||||
return _database.Shows.FirstOrDefaultAsync(x => x.Slug == slug);
|
||||
}
|
||||
|
||||
public async Task<Show> GetByPath(string path)
|
||||
public Task<Show> GetByPath(string path)
|
||||
{
|
||||
return await _database.Shows.FirstOrDefaultAsync(x => x.Path == path);
|
||||
return _database.Shows.FirstOrDefaultAsync(x => x.Path == path);
|
||||
}
|
||||
|
||||
public async Task<ICollection<Show>> Search(string query)
|
||||
@ -145,28 +151,16 @@ namespace Kyoo.Controllers
|
||||
obj.StudioID = await _studios.CreateIfNotExists(obj.Studio);
|
||||
|
||||
if (obj.GenreLinks != null)
|
||||
{
|
||||
foreach (GenreLink link in obj.GenreLinks)
|
||||
link.GenreID = await _genres.CreateIfNotExists(link.Genre);
|
||||
}
|
||||
|
||||
if (obj.People != null)
|
||||
{
|
||||
foreach (PeopleLink link in obj.People)
|
||||
link.PeopleID = await _people.CreateIfNotExists(link.People);
|
||||
}
|
||||
|
||||
if (obj.ExternalIDs != null)
|
||||
{
|
||||
foreach (MetadataID link in obj.ExternalIDs)
|
||||
link.ProviderID = await _providers.CreateIfNotExists(link.Provider);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Delete(Show show)
|
||||
{
|
||||
_database.Shows.Remove(show);
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task AddShowLink(int showID, int? libraryID, int? collectionID)
|
||||
@ -191,5 +185,71 @@ namespace Kyoo.Controllers
|
||||
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
Show obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
Show obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(Show obj)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
|
||||
if (obj.GenreLinks != null)
|
||||
foreach (GenreLink entry in obj.GenreLinks)
|
||||
_database.Entry(entry).State = EntityState.Deleted;
|
||||
|
||||
if (obj.People != null)
|
||||
foreach (PeopleLink entry in obj.People)
|
||||
_database.Entry(entry).State = EntityState.Deleted;
|
||||
|
||||
if (obj.ExternalIDs != null)
|
||||
foreach (MetadataID entry in obj.ExternalIDs)
|
||||
_database.Entry(entry).State = EntityState.Deleted;
|
||||
|
||||
if (obj.CollectionLinks != null)
|
||||
foreach (CollectionLink entry in obj.CollectionLinks)
|
||||
_database.Entry(entry).State = EntityState.Deleted;
|
||||
|
||||
if (obj.LibraryLinks != null)
|
||||
foreach (LibraryLink entry in obj.LibraryLinks)
|
||||
_database.Entry(entry).State = EntityState.Deleted;
|
||||
|
||||
await _database.SaveChangesAsync();
|
||||
|
||||
if (obj.Seasons != null)
|
||||
await _seasons.DeleteRange(obj.Seasons);
|
||||
|
||||
if (obj.Episodes != null)
|
||||
await _episodes.DeleteRange(obj.Episodes);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<Show> objs)
|
||||
{
|
||||
foreach (Show obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -109,10 +109,47 @@ namespace Kyoo.Controllers
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
Studio obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
Studio obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(Studio obj)
|
||||
{
|
||||
_database.Studios.Remove(obj);
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
|
||||
// Using Dotnet-EF change discovery service to remove references to this studio on shows.
|
||||
foreach (Show show in obj.Shows)
|
||||
show.StudioID = null;
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<Studio> objs)
|
||||
{
|
||||
foreach (Studio obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -99,10 +99,43 @@ namespace Kyoo.Controllers
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
Track obj = await Get(id);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(string slug)
|
||||
{
|
||||
Track obj = await Get(slug);
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task Delete(Track obj)
|
||||
{
|
||||
_database.Tracks.Remove(obj);
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
_database.Entry(obj).State = EntityState.Deleted;
|
||||
await _database.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<Track> objs)
|
||||
{
|
||||
foreach (Track obj in objs)
|
||||
await Delete(obj);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<int> ids)
|
||||
{
|
||||
foreach (int id in ids)
|
||||
await Delete(id);
|
||||
}
|
||||
|
||||
public async Task DeleteRange(IEnumerable<string> slugs)
|
||||
{
|
||||
foreach (string slug in slugs)
|
||||
await Delete(slug);
|
||||
}
|
||||
}
|
||||
}
|
@ -113,16 +113,40 @@ namespace Kyoo
|
||||
.Ignore(x => x.Providers);
|
||||
|
||||
modelBuilder.Entity<Collection>()
|
||||
.Ignore(x => x.Shows);
|
||||
.Ignore(x => x.Shows)
|
||||
.Ignore(x => x.Libraries);
|
||||
|
||||
modelBuilder.Entity<Show>()
|
||||
.Ignore(x => x.Genres);
|
||||
|
||||
.Ignore(x => x.Genres)
|
||||
.Ignore(x => x.Libraries)
|
||||
.Ignore(x => x.Collections);
|
||||
|
||||
modelBuilder.Entity<PeopleLink>()
|
||||
.Ignore(x => x.Slug)
|
||||
.Ignore(x => x.Name)
|
||||
.Ignore(x => x.ExternalIDs);
|
||||
|
||||
modelBuilder.Entity<Genre>()
|
||||
.Ignore(x => x.Shows);
|
||||
|
||||
|
||||
modelBuilder.Entity<MetadataID>()
|
||||
.HasOne(x => x.Show)
|
||||
.WithMany(x => x.ExternalIDs)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
modelBuilder.Entity<MetadataID>()
|
||||
.HasOne(x => x.Season)
|
||||
.WithMany(x => x.ExternalIDs)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
modelBuilder.Entity<MetadataID>()
|
||||
.HasOne(x => x.Episode)
|
||||
.WithMany(x => x.ExternalIDs)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
modelBuilder.Entity<MetadataID>()
|
||||
.HasOne(x => x.People)
|
||||
.WithMany(x => x.ExternalIDs)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
|
||||
modelBuilder.Entity<Collection>()
|
||||
.HasIndex(x => x.Slug)
|
||||
|
@ -10,7 +10,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
{
|
||||
[DbContext(typeof(DatabaseContext))]
|
||||
[Migration("20200618133537_Initial")]
|
||||
[Migration("20200623000428_Initial")]
|
||||
partial class Initial
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
@ -506,7 +506,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
.HasForeignKey("CollectionID");
|
||||
|
||||
b.HasOne("Kyoo.Models.Show", "Show")
|
||||
.WithMany()
|
||||
.WithMany("CollectionLinks")
|
||||
.HasForeignKey("ShowID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
@ -528,7 +528,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
modelBuilder.Entity("Kyoo.Models.GenreLink", b =>
|
||||
{
|
||||
b.HasOne("Kyoo.Models.Genre", "Genre")
|
||||
.WithMany()
|
||||
.WithMany("Links")
|
||||
.HasForeignKey("GenreID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
@ -543,7 +543,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
modelBuilder.Entity("Kyoo.Models.LibraryLink", b =>
|
||||
{
|
||||
b.HasOne("Kyoo.Models.Collection", "Collection")
|
||||
.WithMany()
|
||||
.WithMany("LibraryLinks")
|
||||
.HasForeignKey("CollectionID");
|
||||
|
||||
b.HasOne("Kyoo.Models.Library", "Library")
|
||||
@ -553,7 +553,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Kyoo.Models.Show", "Show")
|
||||
.WithMany()
|
||||
.WithMany("LibraryLinks")
|
||||
.HasForeignKey("ShowID");
|
||||
});
|
||||
|
||||
@ -561,11 +561,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
{
|
||||
b.HasOne("Kyoo.Models.Episode", "Episode")
|
||||
.WithMany("ExternalIDs")
|
||||
.HasForeignKey("EpisodeID");
|
||||
.HasForeignKey("EpisodeID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Kyoo.Models.People", "People")
|
||||
.WithMany("ExternalIDs")
|
||||
.HasForeignKey("PeopleID");
|
||||
.HasForeignKey("PeopleID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Kyoo.Models.ProviderID", "Provider")
|
||||
.WithMany()
|
||||
@ -575,11 +577,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
|
||||
b.HasOne("Kyoo.Models.Season", "Season")
|
||||
.WithMany("ExternalIDs")
|
||||
.HasForeignKey("SeasonID");
|
||||
.HasForeignKey("SeasonID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Kyoo.Models.Show", "Show")
|
||||
.WithMany("ExternalIDs")
|
||||
.HasForeignKey("ShowID");
|
||||
.HasForeignKey("ShowID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Kyoo.Models.PeopleLink", b =>
|
@ -347,13 +347,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
column: x => x.EpisodeID,
|
||||
principalTable: "Episodes",
|
||||
principalColumn: "ID",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_MetadataIds_Peoples_PeopleID",
|
||||
column: x => x.PeopleID,
|
||||
principalTable: "Peoples",
|
||||
principalColumn: "ID",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_MetadataIds_Providers_ProviderID",
|
||||
column: x => x.ProviderID,
|
||||
@ -365,13 +365,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
column: x => x.SeasonID,
|
||||
principalTable: "Seasons",
|
||||
principalColumn: "ID",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_MetadataIds_Shows_ShowID",
|
||||
column: x => x.ShowID,
|
||||
principalTable: "Shows",
|
||||
principalColumn: "ID",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
@ -504,7 +504,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
.HasForeignKey("CollectionID");
|
||||
|
||||
b.HasOne("Kyoo.Models.Show", "Show")
|
||||
.WithMany()
|
||||
.WithMany("CollectionLinks")
|
||||
.HasForeignKey("ShowID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
@ -526,7 +526,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
modelBuilder.Entity("Kyoo.Models.GenreLink", b =>
|
||||
{
|
||||
b.HasOne("Kyoo.Models.Genre", "Genre")
|
||||
.WithMany()
|
||||
.WithMany("Links")
|
||||
.HasForeignKey("GenreID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
@ -541,7 +541,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
modelBuilder.Entity("Kyoo.Models.LibraryLink", b =>
|
||||
{
|
||||
b.HasOne("Kyoo.Models.Collection", "Collection")
|
||||
.WithMany()
|
||||
.WithMany("LibraryLinks")
|
||||
.HasForeignKey("CollectionID");
|
||||
|
||||
b.HasOne("Kyoo.Models.Library", "Library")
|
||||
@ -551,7 +551,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Kyoo.Models.Show", "Show")
|
||||
.WithMany()
|
||||
.WithMany("LibraryLinks")
|
||||
.HasForeignKey("ShowID");
|
||||
});
|
||||
|
||||
@ -559,11 +559,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
{
|
||||
b.HasOne("Kyoo.Models.Episode", "Episode")
|
||||
.WithMany("ExternalIDs")
|
||||
.HasForeignKey("EpisodeID");
|
||||
.HasForeignKey("EpisodeID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Kyoo.Models.People", "People")
|
||||
.WithMany("ExternalIDs")
|
||||
.HasForeignKey("PeopleID");
|
||||
.HasForeignKey("PeopleID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Kyoo.Models.ProviderID", "Provider")
|
||||
.WithMany()
|
||||
@ -573,11 +575,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||
|
||||
b.HasOne("Kyoo.Models.Season", "Season")
|
||||
.WithMany("ExternalIDs")
|
||||
.HasForeignKey("SeasonID");
|
||||
.HasForeignKey("SeasonID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Kyoo.Models.Show", "Show")
|
||||
.WithMany("ExternalIDs")
|
||||
.HasForeignKey("ShowID");
|
||||
.HasForeignKey("ShowID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Kyoo.Models.PeopleLink", b =>
|
||||
|
@ -46,8 +46,8 @@ namespace Kyoo
|
||||
services.AddDbContext<DatabaseContext>(options =>
|
||||
{
|
||||
options.UseLazyLoadingProxies()
|
||||
.UseNpgsql(_configuration.GetConnectionString("Database"))
|
||||
.EnableSensitiveDataLogging();
|
||||
.UseNpgsql(_configuration.GetConnectionString("Database"));
|
||||
// .EnableSensitiveDataLogging()
|
||||
// .UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole()));
|
||||
}, ServiceLifetime.Transient);
|
||||
|
||||
|
@ -58,6 +58,11 @@ namespace Kyoo.Controllers
|
||||
|
||||
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||
await using ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
|
||||
|
||||
foreach (Show show in await libraryManager.GetShows())
|
||||
if (!Directory.Exists(show.Path))
|
||||
await libraryManager.DeleteShow(show);
|
||||
|
||||
ICollection<Episode> episodes = await libraryManager.GetEpisodes();
|
||||
ICollection<Library> libraries = argument == null
|
||||
? await libraryManager.GetLibraries()
|
||||
@ -135,12 +140,12 @@ namespace Kyoo.Controllers
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
try
|
||||
|
||||
try
|
||||
{
|
||||
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||
await using ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
|
||||
|
||||
|
||||
string patern = _config.GetValue<string>("regex");
|
||||
Regex regex = new Regex(patern, RegexOptions.IgnoreCase);
|
||||
Match match = regex.Match(relativePath);
|
||||
@ -160,12 +165,12 @@ namespace Kyoo.Controllers
|
||||
else
|
||||
{
|
||||
Season season = await GetSeason(libraryManager, show, seasonNumber, library);
|
||||
Episode episode = await GetEpisode(libraryManager,
|
||||
show,
|
||||
season,
|
||||
episodeNumber,
|
||||
Episode episode = await GetEpisode(libraryManager,
|
||||
show,
|
||||
season,
|
||||
episodeNumber,
|
||||
absoluteNumber,
|
||||
path,
|
||||
path,
|
||||
library);
|
||||
await libraryManager.RegisterEpisode(episode);
|
||||
}
|
||||
@ -173,6 +178,10 @@ namespace Kyoo.Controllers
|
||||
await libraryManager.AddShowLink(show, library, collection);
|
||||
Console.WriteLine($"Episode at {path} registered.");
|
||||
}
|
||||
catch (DuplicatedItemException ex)
|
||||
{
|
||||
await Console.Error.WriteLineAsync($"{path}: {ex.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Console.Error.WriteLineAsync($"Unknown exception thrown while registering episode at {path}." +
|
||||
|
Loading…
x
Reference in New Issue
Block a user