mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-07 10:14:13 -04:00
Removing most of the things needed for a custom many to many
This commit is contained in:
parent
b2b53f2691
commit
fef6a93a1d
@ -239,6 +239,23 @@ namespace Kyoo
|
|||||||
return types.FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType);
|
return types.FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async IAsyncEnumerable<T2> SelectAsync<T, T2>(this IEnumerable<T> self, Func<T, Task<T2>> mapper)
|
||||||
|
{
|
||||||
|
using IEnumerator<T> enumerator = self.GetEnumerator();
|
||||||
|
|
||||||
|
while (enumerator.MoveNext())
|
||||||
|
yield return await mapper(enumerator.Current);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> self)
|
||||||
|
{
|
||||||
|
List<T> ret = new();
|
||||||
|
|
||||||
|
await foreach(T i in self)
|
||||||
|
ret.Add(i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<T> IfEmpty<T>(this IEnumerable<T> self, Action action)
|
public static IEnumerable<T> IfEmpty<T>(this IEnumerable<T> self, Action action)
|
||||||
{
|
{
|
||||||
using IEnumerator<T> enumerator = self.GetEnumerator();
|
using IEnumerator<T> enumerator = self.GetEnumerator();
|
||||||
|
@ -15,7 +15,7 @@ using Microsoft.EntityFrameworkCore.Metadata;
|
|||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
public abstract class LocalRepository<T>
|
public abstract class LocalRepository<T> : IRepository<T>
|
||||||
where T : class, IResource
|
where T : class, IResource
|
||||||
{
|
{
|
||||||
protected readonly DbContext Database;
|
protected readonly DbContext Database;
|
||||||
@ -53,6 +53,8 @@ namespace Kyoo.Controllers
|
|||||||
return Database.Set<T>().FirstOrDefaultAsync(predicate);
|
return Database.Set<T>().FirstOrDefaultAsync(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract Task<ICollection<T>> Search(string query);
|
||||||
|
|
||||||
public virtual Task<ICollection<T>> GetAll(Expression<Func<T, bool>> where = null,
|
public virtual Task<ICollection<T>> GetAll(Expression<Func<T, bool>> where = null,
|
||||||
Sort<T> sort = default,
|
Sort<T> sort = default,
|
||||||
Pagination limit = default)
|
Pagination limit = default)
|
||||||
@ -256,112 +258,4 @@ namespace Kyoo.Controllers
|
|||||||
await Delete(slug);
|
await Delete(slug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class LocalRepository<T, TInternal> : LocalRepository<TInternal>, IRepository<T>
|
|
||||||
where T : class, IResource
|
|
||||||
where TInternal : class, T, new()
|
|
||||||
{
|
|
||||||
protected LocalRepository(DbContext database) : base(database) { }
|
|
||||||
|
|
||||||
public new Task<T> Get(int id)
|
|
||||||
{
|
|
||||||
return base.Get(id).Cast<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public new Task<T> Get(string slug)
|
|
||||||
{
|
|
||||||
return base.Get(slug).Cast<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<T> Get(Expression<Func<T, bool>> predicate)
|
|
||||||
{
|
|
||||||
return Get(predicate.Convert<Func<TInternal, bool>>()).Cast<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract Task<ICollection<T>> Search(string query);
|
|
||||||
|
|
||||||
public virtual Task<ICollection<T>> GetAll(Expression<Func<T, bool>> where = null,
|
|
||||||
Sort<T> sort = default,
|
|
||||||
Pagination limit = default)
|
|
||||||
{
|
|
||||||
return ApplyFilters(Database.Set<TInternal>(), where, sort, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual async Task<ICollection<T>> ApplyFilters(IQueryable<TInternal> query,
|
|
||||||
Expression<Func<T, bool>> where = null,
|
|
||||||
Sort<T> sort = default,
|
|
||||||
Pagination limit = default)
|
|
||||||
{
|
|
||||||
ICollection<TInternal> items = await ApplyFilters(query,
|
|
||||||
base.Get,
|
|
||||||
DefaultSort,
|
|
||||||
where.Convert<Func<TInternal, bool>>(),
|
|
||||||
sort.To<TInternal>(),
|
|
||||||
limit);
|
|
||||||
|
|
||||||
return items.ToList<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Task<int> GetCount(Expression<Func<T, bool>> where = null)
|
|
||||||
{
|
|
||||||
IQueryable<TInternal> query = Database.Set<TInternal>();
|
|
||||||
if (where != null)
|
|
||||||
query = query.Where(where.Convert<Func<TInternal, bool>>());
|
|
||||||
return query.CountAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
Task<T> IRepository<T>.Create(T item)
|
|
||||||
{
|
|
||||||
if (item == null)
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
TInternal obj = item as TInternal ?? new TInternal();
|
|
||||||
if (!(item is TInternal))
|
|
||||||
Utility.Assign(obj, item);
|
|
||||||
|
|
||||||
return Create(obj).Cast<T>()
|
|
||||||
.Then(x => item.ID = x.ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
Task<T> IRepository<T>.CreateIfNotExists(T item, bool silentFail)
|
|
||||||
{
|
|
||||||
if (item == null)
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
TInternal obj = item as TInternal ?? new TInternal();
|
|
||||||
if (!(item is TInternal))
|
|
||||||
Utility.Assign(obj, item);
|
|
||||||
|
|
||||||
return CreateIfNotExists(obj, silentFail).Cast<T>()
|
|
||||||
.Then(x => item.ID = x.ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<T> Edit(T edited, bool resetOld)
|
|
||||||
{
|
|
||||||
if (edited == null)
|
|
||||||
throw new ArgumentNullException(nameof(edited));
|
|
||||||
if (edited is TInternal intern)
|
|
||||||
return Edit(intern, resetOld).Cast<T>();
|
|
||||||
TInternal obj = new();
|
|
||||||
Utility.Assign(obj, edited);
|
|
||||||
return base.Edit(obj, resetOld).Cast<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract override Task Delete([NotNull] TInternal obj);
|
|
||||||
|
|
||||||
Task IRepository<T>.Delete(T obj)
|
|
||||||
{
|
|
||||||
if (obj == null)
|
|
||||||
throw new ArgumentNullException(nameof(obj));
|
|
||||||
if (obj is TInternal intern)
|
|
||||||
return Delete(intern);
|
|
||||||
TInternal item = new();
|
|
||||||
Utility.Assign(item, obj);
|
|
||||||
return Delete(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteRange(IEnumerable<T> objs)
|
|
||||||
{
|
|
||||||
foreach (T obj in objs)
|
|
||||||
await ((IRepository<T>)this).Delete(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -8,11 +8,11 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
public class CollectionRepository : LocalRepository<Collection, CollectionDE>, ICollectionRepository
|
public class CollectionRepository : LocalRepository<Collection>, ICollectionRepository
|
||||||
{
|
{
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly DatabaseContext _database;
|
private readonly DatabaseContext _database;
|
||||||
protected override Expression<Func<CollectionDE, object>> DefaultSort => x => x.Name;
|
protected override Expression<Func<Collection, object>> DefaultSort => x => x.Name;
|
||||||
|
|
||||||
public CollectionRepository(DatabaseContext database) : base(database)
|
public CollectionRepository(DatabaseContext database) : base(database)
|
||||||
{
|
{
|
||||||
@ -40,10 +40,10 @@ namespace Kyoo.Controllers
|
|||||||
return await _database.Collections
|
return await _database.Collections
|
||||||
.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
|
.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
|
||||||
.Take(20)
|
.Take(20)
|
||||||
.ToListAsync<Collection>();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<CollectionDE> Create(CollectionDE obj)
|
public override async Task<Collection> Create(Collection obj)
|
||||||
{
|
{
|
||||||
await base.Create(obj);
|
await base.Create(obj);
|
||||||
_database.Entry(obj).State = EntityState.Added;
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
@ -51,18 +51,12 @@ namespace Kyoo.Controllers
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Delete(CollectionDE obj)
|
public override async Task Delete(Collection obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
throw new ArgumentNullException(nameof(obj));
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
_database.Entry(obj).State = EntityState.Deleted;
|
_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();
|
await _database.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ namespace Kyoo.Controllers
|
|||||||
&& x.AbsoluteNumber == absoluteNumber);
|
&& x.AbsoluteNumber == absoluteNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ICollection<Episode>> Search(string query)
|
public override async Task<ICollection<Episode>> Search(string query)
|
||||||
{
|
{
|
||||||
return await _database.Episodes
|
return await _database.Episodes
|
||||||
.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
|
.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
|
||||||
|
@ -8,11 +8,11 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
public class GenreRepository : LocalRepository<Genre, GenreDE>, IGenreRepository
|
public class GenreRepository : LocalRepository<Genre>, IGenreRepository
|
||||||
{
|
{
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly DatabaseContext _database;
|
private readonly DatabaseContext _database;
|
||||||
protected override Expression<Func<GenreDE, object>> DefaultSort => x => x.Slug;
|
protected override Expression<Func<Genre, object>> DefaultSort => x => x.Slug;
|
||||||
|
|
||||||
|
|
||||||
public GenreRepository(DatabaseContext database) : base(database)
|
public GenreRepository(DatabaseContext database) : base(database)
|
||||||
@ -41,10 +41,10 @@ namespace Kyoo.Controllers
|
|||||||
return await _database.Genres
|
return await _database.Genres
|
||||||
.Where(genre => EF.Functions.ILike(genre.Name, $"%{query}%"))
|
.Where(genre => EF.Functions.ILike(genre.Name, $"%{query}%"))
|
||||||
.Take(20)
|
.Take(20)
|
||||||
.ToListAsync<Genre>();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<GenreDE> Create(GenreDE obj)
|
public override async Task<Genre> Create(Genre obj)
|
||||||
{
|
{
|
||||||
await base.Create(obj);
|
await base.Create(obj);
|
||||||
_database.Entry(obj).State = EntityState.Added;
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
@ -52,15 +52,12 @@ namespace Kyoo.Controllers
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Delete(GenreDE obj)
|
public override async Task Delete(Genre obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
throw new ArgumentNullException(nameof(obj));
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
_database.Entry(obj).State = EntityState.Deleted;
|
_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();
|
await _database.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
private IQueryable<LibraryItem> ItemsQuery
|
private IQueryable<LibraryItem> ItemsQuery
|
||||||
=> _database.Shows
|
=> _database.Shows
|
||||||
// .Where(x => !_database.CollectionLinks.Any(y => y.ChildID == x.ID))
|
.Where(x => !_database.CollectionLinks.Any(y => y.ChildID == x.ID))
|
||||||
.Select(LibraryItem.FromShow)
|
.Select(LibraryItem.FromShow)
|
||||||
.Concat(_database.Collections
|
.Concat(_database.Collections
|
||||||
.Select(LibraryItem.FromCollection));
|
.Select(LibraryItem.FromCollection));
|
||||||
@ -114,18 +114,17 @@ namespace Kyoo.Controllers
|
|||||||
public override Task Delete(LibraryItem obj) => throw new InvalidOperationException();
|
public override Task Delete(LibraryItem obj) => throw new InvalidOperationException();
|
||||||
|
|
||||||
private IQueryable<LibraryItem> LibraryRelatedQuery(Expression<Func<LibraryLink, bool>> selector)
|
private IQueryable<LibraryItem> LibraryRelatedQuery(Expression<Func<LibraryLink, bool>> selector)
|
||||||
=> throw new NotImplementedException();
|
=> _database.LibraryLinks
|
||||||
// => _database.LibraryLinks
|
.Where(selector)
|
||||||
// .Where(selector)
|
.Select(x => x.Show)
|
||||||
// .Select(x => x.Show)
|
.Where(x => x != null)
|
||||||
// .Where(x => x != null)
|
.Where(x => !_database.CollectionLinks.Any(y => y.ChildID == x.ID))
|
||||||
// .Where(x => !_database.CollectionLinks.Any(y => y.ChildID == x.ID))
|
.Select(LibraryItem.FromShow)
|
||||||
// .Select(LibraryItem.FromShow)
|
.Concat(_database.LibraryLinks
|
||||||
// .Concat(_database.LibraryLinks
|
.Where(selector)
|
||||||
// .Where(selector)
|
.Select(x => x.Collection)
|
||||||
// .Select(x => x.Collection)
|
.Where(x => x != null)
|
||||||
// .Where(x => x != null)
|
.Select(LibraryItem.FromCollection));
|
||||||
// .Select(LibraryItem.FromCollection));
|
|
||||||
|
|
||||||
public async Task<ICollection<LibraryItem>> GetFromLibrary(int id,
|
public async Task<ICollection<LibraryItem>> GetFromLibrary(int id,
|
||||||
Expression<Func<LibraryItem, bool>> where = null,
|
Expression<Func<LibraryItem, bool>> where = null,
|
||||||
|
@ -10,12 +10,12 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
public class LibraryRepository : LocalRepository<Library, LibraryDE>, ILibraryRepository
|
public class LibraryRepository : LocalRepository<Library>, ILibraryRepository
|
||||||
{
|
{
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly DatabaseContext _database;
|
private readonly DatabaseContext _database;
|
||||||
private readonly IProviderRepository _providers;
|
private readonly IProviderRepository _providers;
|
||||||
protected override Expression<Func<LibraryDE, object>> DefaultSort => x => x.ID;
|
protected override Expression<Func<Library, object>> DefaultSort => x => x.ID;
|
||||||
|
|
||||||
|
|
||||||
public LibraryRepository(DatabaseContext database, IProviderRepository providers)
|
public LibraryRepository(DatabaseContext database, IProviderRepository providers)
|
||||||
@ -48,22 +48,18 @@ namespace Kyoo.Controllers
|
|||||||
return await _database.Libraries
|
return await _database.Libraries
|
||||||
.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
|
.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
|
||||||
.Take(20)
|
.Take(20)
|
||||||
.ToListAsync<Library>();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<LibraryDE> Create(LibraryDE obj)
|
public override async Task<Library> Create(Library obj)
|
||||||
{
|
{
|
||||||
await base.Create(obj);
|
await base.Create(obj);
|
||||||
_database.Entry(obj).State = EntityState.Added;
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
if (obj.ProviderLinks != null)
|
|
||||||
foreach (ProviderLink entry in obj.ProviderLinks)
|
|
||||||
_database.Entry(entry).State = EntityState.Added;
|
|
||||||
|
|
||||||
await _database.SaveChangesAsync($"Trying to insert a duplicated library (slug {obj.Slug} already exists).");
|
await _database.SaveChangesAsync($"Trying to insert a duplicated library (slug {obj.Slug} already exists).");
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task Validate(LibraryDE resource)
|
protected override async Task Validate(Library resource)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(resource.Slug))
|
if (string.IsNullOrEmpty(resource.Slug))
|
||||||
throw new ArgumentException("The library's slug must be set and not empty");
|
throw new ArgumentException("The library's slug must be set and not empty");
|
||||||
@ -74,24 +70,17 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
await base.Validate(resource);
|
await base.Validate(resource);
|
||||||
|
|
||||||
if (resource.ProviderLinks != null)
|
resource.Providers = await resource.Providers
|
||||||
foreach (ProviderLink link in resource.ProviderLinks)
|
.SelectAsync(x => _providers.CreateIfNotExists(x, true))
|
||||||
if (ShouldValidate(link))
|
.ToListAsync();
|
||||||
link.Child = await _providers.CreateIfNotExists(link.Child, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Delete(LibraryDE obj)
|
public override async Task Delete(Library obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
throw new ArgumentNullException(nameof(obj));
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
_database.Entry(obj).State = EntityState.Deleted;
|
_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();
|
await _database.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ namespace Kyoo.Controllers
|
|||||||
await _shows.Value.DisposeAsync();
|
await _shows.Value.DisposeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ICollection<People>> Search(string query)
|
public override async Task<ICollection<People>> Search(string query)
|
||||||
{
|
{
|
||||||
return await _database.People
|
return await _database.People
|
||||||
.Where(people => EF.Functions.ILike(people.Name, $"%{query}%"))
|
.Where(people => EF.Functions.ILike(people.Name, $"%{query}%"))
|
||||||
|
@ -19,7 +19,7 @@ namespace Kyoo.Controllers
|
|||||||
_database = database;
|
_database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ICollection<ProviderID>> Search(string query)
|
public override async Task<ICollection<ProviderID>> Search(string query)
|
||||||
{
|
{
|
||||||
return await _database.Providers
|
return await _database.Providers
|
||||||
.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
|
.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
|
||||||
|
@ -74,7 +74,7 @@ namespace Kyoo.Controllers
|
|||||||
&& x.SeasonNumber == seasonNumber);
|
&& x.SeasonNumber == seasonNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ICollection<Season>> Search(string query)
|
public override async Task<ICollection<Season>> Search(string query)
|
||||||
{
|
{
|
||||||
return await _database.Seasons
|
return await _database.Seasons
|
||||||
.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
|
.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
|
||||||
|
@ -9,7 +9,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
public class ShowRepository : LocalRepository<Show, ShowDE>, IShowRepository
|
public class ShowRepository : LocalRepository<Show>, IShowRepository
|
||||||
{
|
{
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly DatabaseContext _database;
|
private readonly DatabaseContext _database;
|
||||||
@ -19,7 +19,7 @@ namespace Kyoo.Controllers
|
|||||||
private readonly IProviderRepository _providers;
|
private readonly IProviderRepository _providers;
|
||||||
private readonly Lazy<ISeasonRepository> _seasons;
|
private readonly Lazy<ISeasonRepository> _seasons;
|
||||||
private readonly Lazy<IEpisodeRepository> _episodes;
|
private readonly Lazy<IEpisodeRepository> _episodes;
|
||||||
protected override Expression<Func<ShowDE, object>> DefaultSort => x => x.Title;
|
protected override Expression<Func<Show, object>> DefaultSort => x => x.Title;
|
||||||
|
|
||||||
public ShowRepository(DatabaseContext database,
|
public ShowRepository(DatabaseContext database,
|
||||||
IStudioRepository studios,
|
IStudioRepository studios,
|
||||||
@ -81,21 +81,11 @@ namespace Kyoo.Controllers
|
|||||||
.ToListAsync<Show>();
|
.ToListAsync<Show>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<ShowDE> Create(ShowDE obj)
|
public override async Task<Show> Create(Show obj)
|
||||||
{
|
{
|
||||||
await base.Create(obj);
|
await base.Create(obj);
|
||||||
_database.Entry(obj).State = EntityState.Added;
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
|
|
||||||
if (obj.GenreLinks != null)
|
|
||||||
{
|
|
||||||
foreach (GenreLink entry in obj.GenreLinks)
|
|
||||||
{
|
|
||||||
if (!(entry.Child is GenreDE))
|
|
||||||
entry.Child = new GenreDE(entry.Child);
|
|
||||||
_database.Entry(entry).State = EntityState.Added;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.People != null)
|
if (obj.People != null)
|
||||||
foreach (PeopleRole entry in obj.People)
|
foreach (PeopleRole entry in obj.People)
|
||||||
_database.Entry(entry).State = EntityState.Added;
|
_database.Entry(entry).State = EntityState.Added;
|
||||||
@ -107,17 +97,16 @@ namespace Kyoo.Controllers
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task Validate(ShowDE resource)
|
protected override async Task Validate(Show resource)
|
||||||
{
|
{
|
||||||
await base.Validate(resource);
|
await base.Validate(resource);
|
||||||
|
|
||||||
if (ShouldValidate(resource.Studio))
|
if (ShouldValidate(resource.Studio))
|
||||||
resource.Studio = await _studios.CreateIfNotExists(resource.Studio, true);
|
resource.Studio = await _studios.CreateIfNotExists(resource.Studio, true);
|
||||||
|
|
||||||
if (resource.GenreLinks != null)
|
resource.Genres = await resource.Genres
|
||||||
foreach (GenreLink link in resource.GenreLinks)
|
.SelectAsync(x => _genres.CreateIfNotExists(x, true))
|
||||||
if (ShouldValidate(link))
|
.ToListAsync();
|
||||||
link.Child = await _genres.CreateIfNotExists(link.Child, true);
|
|
||||||
|
|
||||||
if (resource.People != null)
|
if (resource.People != null)
|
||||||
foreach (PeopleRole link in resource.People)
|
foreach (PeopleRole link in resource.People)
|
||||||
@ -134,32 +123,30 @@ namespace Kyoo.Controllers
|
|||||||
{
|
{
|
||||||
if (collectionID != null)
|
if (collectionID != null)
|
||||||
{
|
{
|
||||||
// await _database.CollectionLinks.AddAsync(new CollectionLink {ParentID = collectionID.Value, ChildID = showID});
|
|
||||||
|
await _database.CollectionLinks.AddAsync(new CollectionLink {ParentID = collectionID.Value, ChildID = showID});
|
||||||
await _database.SaveIfNoDuplicates();
|
await _database.SaveIfNoDuplicates();
|
||||||
}
|
}
|
||||||
if (libraryID != null)
|
if (libraryID != null)
|
||||||
{
|
{
|
||||||
// await _database.LibraryLinks.AddAsync(new LibraryLink {LibraryID = libraryID.Value, ShowID = showID});
|
await _database.LibraryLinks.AddAsync(new LibraryLink {LibraryID = libraryID.Value, ShowID = showID});
|
||||||
await _database.SaveIfNoDuplicates();
|
await _database.SaveIfNoDuplicates();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libraryID != null && collectionID != null)
|
if (libraryID != null && collectionID != null)
|
||||||
{
|
{
|
||||||
// await _database.LibraryLinks.AddAsync(new LibraryLink {LibraryID = libraryID.Value, CollectionID = collectionID.Value});
|
await _database.LibraryLinks.AddAsync(new LibraryLink {LibraryID = libraryID.Value, CollectionID = collectionID.Value});
|
||||||
await _database.SaveIfNoDuplicates();
|
await _database.SaveIfNoDuplicates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Delete(ShowDE obj)
|
public override async Task Delete(Show obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
throw new ArgumentNullException(nameof(obj));
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
_database.Entry(obj).State = EntityState.Deleted;
|
_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)
|
if (obj.People != null)
|
||||||
foreach (PeopleRole entry in obj.People)
|
foreach (PeopleRole entry in obj.People)
|
||||||
@ -169,14 +156,6 @@ namespace Kyoo.Controllers
|
|||||||
foreach (MetadataID entry in obj.ExternalIDs)
|
foreach (MetadataID entry in obj.ExternalIDs)
|
||||||
_database.Entry(entry).State = EntityState.Deleted;
|
_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();
|
await _database.SaveChangesAsync();
|
||||||
|
|
||||||
if (obj.Seasons != null)
|
if (obj.Seasons != null)
|
||||||
|
@ -19,7 +19,7 @@ namespace Kyoo.Controllers
|
|||||||
_database = database;
|
_database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ICollection<Studio>> Search(string query)
|
public override async Task<ICollection<Studio>> Search(string query)
|
||||||
{
|
{
|
||||||
return await _database.Studios
|
return await _database.Studios
|
||||||
.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
|
.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
|
||||||
|
@ -73,7 +73,7 @@ namespace Kyoo.Controllers
|
|||||||
&& x.IsForced == forced);
|
&& x.IsForced == forced);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ICollection<Track>> Search(string query)
|
public override 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.");
|
||||||
}
|
}
|
||||||
|
@ -119,12 +119,6 @@ namespace Kyoo
|
|||||||
modelBuilder.Entity<Episode>()
|
modelBuilder.Entity<Episode>()
|
||||||
.HasIndex(x => new {x.ShowID, x.SeasonNumber, x.EpisodeNumber, x.AbsoluteNumber})
|
.HasIndex(x => new {x.ShowID, x.SeasonNumber, x.EpisodeNumber, x.AbsoluteNumber})
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
modelBuilder.Entity<LibraryLink>()
|
|
||||||
.HasIndex(x => new {x.LibraryID, x.ShowID})
|
|
||||||
.IsUnique();
|
|
||||||
modelBuilder.Entity<LibraryLink>()
|
|
||||||
.HasIndex(x => new {x.LibraryID, x.CollectionID})
|
|
||||||
.IsUnique();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int SaveChanges()
|
public override int SaveChanges()
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
namespace Kyoo.Models
|
|
||||||
{
|
|
||||||
public class CollectionLink : IResourceLink<Collection, Show>
|
|
||||||
{
|
|
||||||
public int ParentID { get; set; }
|
|
||||||
public virtual Collection Parent { get; set; }
|
|
||||||
public int ChildID { get; set; }
|
|
||||||
public virtual Show Child { get; set; }
|
|
||||||
|
|
||||||
public CollectionLink() { }
|
|
||||||
|
|
||||||
public CollectionLink(Collection parent, Show child)
|
|
||||||
{
|
|
||||||
Parent = parent;
|
|
||||||
ParentID = parent.ID;
|
|
||||||
Child = child;
|
|
||||||
ChildID = child.ID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
namespace Kyoo.Models
|
|
||||||
{
|
|
||||||
public class GenreLink : IResourceLink<Show, Genre>
|
|
||||||
{
|
|
||||||
public int ParentID { get; set; }
|
|
||||||
public virtual Show Parent { get; set; }
|
|
||||||
public int ChildID { get; set; }
|
|
||||||
public virtual Genre Child { get; set; }
|
|
||||||
|
|
||||||
public GenreLink() {}
|
|
||||||
|
|
||||||
public GenreLink(Show parent, Genre child)
|
|
||||||
{
|
|
||||||
Parent = parent;
|
|
||||||
Child = child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
namespace Kyoo.Models
|
|
||||||
{
|
|
||||||
public class LibraryLink
|
|
||||||
{
|
|
||||||
public int ID { get; set; }
|
|
||||||
public int LibraryID { get; set; }
|
|
||||||
public virtual Library Library { get; set; }
|
|
||||||
public int? ShowID { get; set; }
|
|
||||||
public virtual Show Show { get; set; }
|
|
||||||
public int? CollectionID { get; set; }
|
|
||||||
public virtual Collection Collection { get; set; }
|
|
||||||
|
|
||||||
public LibraryLink() { }
|
|
||||||
|
|
||||||
public LibraryLink(Library library, Show show)
|
|
||||||
{
|
|
||||||
Library = library;
|
|
||||||
Show = show;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LibraryLink(Library library, Collection collection)
|
|
||||||
{
|
|
||||||
Library = library;
|
|
||||||
Collection = collection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Kyoo.Models
|
|
||||||
{
|
|
||||||
public class ProviderLink : IResourceLink<Library, ProviderID>
|
|
||||||
{
|
|
||||||
[JsonIgnore] public int ParentID { get; set; }
|
|
||||||
[JsonIgnore] public virtual Library Parent { get; set; }
|
|
||||||
[JsonIgnore] public int ChildID { get; set; }
|
|
||||||
[JsonIgnore] public virtual ProviderID Child { get; set; }
|
|
||||||
|
|
||||||
public ProviderLink() { }
|
|
||||||
|
|
||||||
public ProviderLink(ProviderID child, Library parent)
|
|
||||||
{
|
|
||||||
Child = child;
|
|
||||||
Parent = parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
|
|
||||||
namespace Kyoo.Models
|
|
||||||
{
|
|
||||||
public class CollectionDE : Collection
|
|
||||||
{
|
|
||||||
[SerializeIgnore] [NotMergable] public virtual ICollection<CollectionLink> Links { get; set; }
|
|
||||||
[ExpressionRewrite(nameof(Links), nameof(CollectionLink.Child))]
|
|
||||||
public override ICollection<Show> Shows
|
|
||||||
{
|
|
||||||
get => Links?.Select(x => x.Child).ToList();
|
|
||||||
set => Links = value?.Select(x => new CollectionLink(this, x)).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeIgnore] [NotMergable] public virtual ICollection<LibraryLink> LibraryLinks { get; set; }
|
|
||||||
|
|
||||||
[ExpressionRewrite(nameof(LibraryLinks), nameof(GenreLink.Child))]
|
|
||||||
public override ICollection<Library> Libraries
|
|
||||||
{
|
|
||||||
get => LibraryLinks?.Select(x => x.Library).ToList();
|
|
||||||
set => LibraryLinks = value?.Select(x => new LibraryLink(x, this)).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CollectionDE() {}
|
|
||||||
|
|
||||||
public CollectionDE(Collection collection)
|
|
||||||
{
|
|
||||||
Utility.Assign(this, collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
|
|
||||||
namespace Kyoo.Models
|
|
||||||
{
|
|
||||||
public class GenreDE : Genre
|
|
||||||
{
|
|
||||||
[SerializeIgnore] [NotMergable] public virtual ICollection<GenreLink> Links { get; set; }
|
|
||||||
|
|
||||||
[ExpressionRewrite(nameof(Links), nameof(GenreLink.Child))]
|
|
||||||
[SerializeIgnore] [NotMergable] public override ICollection<Show> Shows
|
|
||||||
{
|
|
||||||
get => Links?.Select(x => x.Parent).ToList();
|
|
||||||
set => Links = value?.Select(x => new GenreLink(x, this)).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public GenreDE() {}
|
|
||||||
|
|
||||||
public GenreDE(Genre item)
|
|
||||||
{
|
|
||||||
Utility.Assign(this, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
|
|
||||||
namespace Kyoo.Models
|
|
||||||
{
|
|
||||||
public class LibraryDE : Library
|
|
||||||
{
|
|
||||||
[EditableRelation] [SerializeIgnore] [NotMergable] public virtual ICollection<ProviderLink> ProviderLinks { get; set; }
|
|
||||||
[ExpressionRewrite(nameof(ProviderLinks), nameof(ProviderLink.Child))]
|
|
||||||
public override ICollection<ProviderID> Providers
|
|
||||||
{
|
|
||||||
get => ProviderLinks?.Select(x => x.Child).ToList();
|
|
||||||
set => ProviderLinks = value?.Select(x => new ProviderLink(x, this)).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeIgnore] [NotMergable] public virtual ICollection<LibraryLink> Links { get; set; }
|
|
||||||
[ExpressionRewrite(nameof(Links), nameof(LibraryLink.Show))]
|
|
||||||
public override ICollection<Show> Shows
|
|
||||||
{
|
|
||||||
get => Links?.Where(x => x.Show != null).Select(x => x.Show).ToList();
|
|
||||||
set => Links = Utility.MergeLists(
|
|
||||||
value?.Select(x => new LibraryLink(this, x)),
|
|
||||||
Links?.Where(x => x.Show == null))?.ToList();
|
|
||||||
}
|
|
||||||
[ExpressionRewrite(nameof(Links), nameof(LibraryLink.Collection))]
|
|
||||||
public override ICollection<Collection> Collections
|
|
||||||
{
|
|
||||||
get => Links?.Where(x => x.Collection != null).Select(x => x.Collection).ToList();
|
|
||||||
set => Links = Utility.MergeLists(
|
|
||||||
value?.Select(x => new LibraryLink(this, x)),
|
|
||||||
Links?.Where(x => x.Collection == null))?.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public LibraryDE() {}
|
|
||||||
|
|
||||||
public LibraryDE(Library item)
|
|
||||||
{
|
|
||||||
Utility.Assign(this, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
|
|
||||||
namespace Kyoo.Models
|
|
||||||
{
|
|
||||||
public class ShowDE : Show
|
|
||||||
{
|
|
||||||
[EditableRelation] [SerializeIgnore] [NotMergable] public virtual ICollection<GenreLink> GenreLinks { get; set; }
|
|
||||||
[ExpressionRewrite(nameof(GenreLinks), nameof(GenreLink.Child))]
|
|
||||||
public override ICollection<Genre> Genres
|
|
||||||
{
|
|
||||||
get => GenreLinks?.Select(x => x.Child).ToList();
|
|
||||||
set => GenreLinks = value?.Select(x => new GenreLink(this, x)).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeIgnore] [NotMergable] public virtual ICollection<LibraryLink> LibraryLinks { get; set; }
|
|
||||||
[ExpressionRewrite(nameof(LibraryLinks), nameof(LibraryLink.Library))]
|
|
||||||
public override ICollection<Library> Libraries
|
|
||||||
{
|
|
||||||
get => LibraryLinks?.Select(x => x.Library).ToList();
|
|
||||||
set => LibraryLinks = value?.Select(x => new LibraryLink(x, this)).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeIgnore] [NotMergable] public virtual ICollection<CollectionLink> CollectionLinks { get; set; }
|
|
||||||
[ExpressionRewrite(nameof(CollectionLinks), nameof(CollectionLink.Parent))]
|
|
||||||
public override ICollection<Collection> Collections
|
|
||||||
{
|
|
||||||
get => CollectionLinks?.Select(x => x.Parent).ToList();
|
|
||||||
set => CollectionLinks = value?.Select(x => new CollectionLink(x, this)).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShowDE() {}
|
|
||||||
|
|
||||||
public ShowDE(Show show)
|
|
||||||
{
|
|
||||||
Utility.Assign(this, show);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user