mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-11-03 19:17:16 -05: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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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)
 | 
			
		||||
		{
 | 
			
		||||
			using IEnumerator<T> enumerator = self.GetEnumerator();
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ using Microsoft.EntityFrameworkCore.Metadata;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo.Controllers
 | 
			
		||||
{
 | 
			
		||||
	public abstract class LocalRepository<T>
 | 
			
		||||
	public abstract class LocalRepository<T> : IRepository<T>
 | 
			
		||||
		where T : class, IResource
 | 
			
		||||
	{
 | 
			
		||||
		protected readonly DbContext Database;
 | 
			
		||||
@ -53,6 +53,8 @@ namespace Kyoo.Controllers
 | 
			
		||||
			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,
 | 
			
		||||
			Sort<T> sort = default,
 | 
			
		||||
			Pagination limit = default)
 | 
			
		||||
@ -256,112 +258,4 @@ namespace Kyoo.Controllers
 | 
			
		||||
				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
 | 
			
		||||
{
 | 
			
		||||
	public class CollectionRepository : LocalRepository<Collection, CollectionDE>, ICollectionRepository
 | 
			
		||||
	public class CollectionRepository : LocalRepository<Collection>, ICollectionRepository
 | 
			
		||||
	{
 | 
			
		||||
		private bool _disposed;
 | 
			
		||||
		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)
 | 
			
		||||
		{
 | 
			
		||||
@ -40,10 +40,10 @@ namespace Kyoo.Controllers
 | 
			
		||||
			return await _database.Collections
 | 
			
		||||
				.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
 | 
			
		||||
				.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);
 | 
			
		||||
			_database.Entry(obj).State = EntityState.Added;
 | 
			
		||||
@ -51,18 +51,12 @@ namespace Kyoo.Controllers
 | 
			
		||||
			return obj;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override async Task Delete(CollectionDE obj)
 | 
			
		||||
		public override async Task Delete(Collection 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();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
			                                                   && x.AbsoluteNumber == absoluteNumber);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<ICollection<Episode>> Search(string query)
 | 
			
		||||
		public override async Task<ICollection<Episode>> Search(string query)
 | 
			
		||||
		{
 | 
			
		||||
			return await _database.Episodes
 | 
			
		||||
				.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
 | 
			
		||||
 | 
			
		||||
@ -8,11 +8,11 @@ using Microsoft.EntityFrameworkCore;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo.Controllers
 | 
			
		||||
{
 | 
			
		||||
	public class GenreRepository : LocalRepository<Genre, GenreDE>, IGenreRepository
 | 
			
		||||
	public class GenreRepository : LocalRepository<Genre>, IGenreRepository
 | 
			
		||||
	{
 | 
			
		||||
		private bool _disposed;
 | 
			
		||||
		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)
 | 
			
		||||
@ -41,10 +41,10 @@ namespace Kyoo.Controllers
 | 
			
		||||
			return await _database.Genres
 | 
			
		||||
				.Where(genre => EF.Functions.ILike(genre.Name, $"%{query}%"))
 | 
			
		||||
				.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);
 | 
			
		||||
			_database.Entry(obj).State = EntityState.Added;
 | 
			
		||||
@ -52,15 +52,12 @@ namespace Kyoo.Controllers
 | 
			
		||||
			return obj;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override async Task Delete(GenreDE obj)
 | 
			
		||||
		public override async Task Delete(Genre 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();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
 | 
			
		||||
		private IQueryable<LibraryItem> ItemsQuery 
 | 
			
		||||
			=> _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)
 | 
			
		||||
				.Concat(_database.Collections
 | 
			
		||||
					.Select(LibraryItem.FromCollection));
 | 
			
		||||
@ -114,18 +114,17 @@ namespace Kyoo.Controllers
 | 
			
		||||
		public override Task Delete(LibraryItem obj) => throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
		private IQueryable<LibraryItem> LibraryRelatedQuery(Expression<Func<LibraryLink, bool>> selector)
 | 
			
		||||
			=> throw new NotImplementedException();
 | 
			
		||||
			// => _database.LibraryLinks
 | 
			
		||||
			// 	.Where(selector)
 | 
			
		||||
			// 	.Select(x => x.Show)
 | 
			
		||||
			// 	.Where(x => x != null)
 | 
			
		||||
			// 	.Where(x => !_database.CollectionLinks.Any(y => y.ChildID == x.ID))
 | 
			
		||||
			// 	.Select(LibraryItem.FromShow)
 | 
			
		||||
			// 	.Concat(_database.LibraryLinks
 | 
			
		||||
			// 		.Where(selector)
 | 
			
		||||
			// 		.Select(x => x.Collection)
 | 
			
		||||
			// 		.Where(x => x != null)
 | 
			
		||||
			// 		.Select(LibraryItem.FromCollection));
 | 
			
		||||
			=> _database.LibraryLinks
 | 
			
		||||
				.Where(selector)
 | 
			
		||||
				.Select(x => x.Show)
 | 
			
		||||
				.Where(x => x != null)
 | 
			
		||||
				.Where(x => !_database.CollectionLinks.Any(y => y.ChildID == x.ID))
 | 
			
		||||
				.Select(LibraryItem.FromShow)
 | 
			
		||||
				.Concat(_database.LibraryLinks
 | 
			
		||||
					.Where(selector)
 | 
			
		||||
					.Select(x => x.Collection)
 | 
			
		||||
					.Where(x => x != null)
 | 
			
		||||
					.Select(LibraryItem.FromCollection));
 | 
			
		||||
 | 
			
		||||
		public async Task<ICollection<LibraryItem>> GetFromLibrary(int id, 
 | 
			
		||||
			Expression<Func<LibraryItem, bool>> where = null, 
 | 
			
		||||
 | 
			
		||||
@ -10,12 +10,12 @@ using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo.Controllers
 | 
			
		||||
{
 | 
			
		||||
	public class LibraryRepository : LocalRepository<Library, LibraryDE>, ILibraryRepository
 | 
			
		||||
	public class LibraryRepository : LocalRepository<Library>, ILibraryRepository
 | 
			
		||||
	{
 | 
			
		||||
		private bool _disposed;
 | 
			
		||||
		private readonly DatabaseContext _database;
 | 
			
		||||
		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)
 | 
			
		||||
@ -48,22 +48,18 @@ namespace Kyoo.Controllers
 | 
			
		||||
			return await _database.Libraries
 | 
			
		||||
				.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
 | 
			
		||||
				.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);
 | 
			
		||||
			_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).");
 | 
			
		||||
			return obj;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected override async Task Validate(LibraryDE resource)
 | 
			
		||||
		protected override async Task Validate(Library resource)
 | 
			
		||||
		{
 | 
			
		||||
			if (string.IsNullOrEmpty(resource.Slug))
 | 
			
		||||
				throw new ArgumentException("The library's slug must be set and not empty");
 | 
			
		||||
@ -73,25 +69,18 @@ namespace Kyoo.Controllers
 | 
			
		||||
				throw new ArgumentException("The library should have a least one path.");
 | 
			
		||||
			
 | 
			
		||||
			await base.Validate(resource);
 | 
			
		||||
			
 | 
			
		||||
			if (resource.ProviderLinks != null)
 | 
			
		||||
				foreach (ProviderLink link in resource.ProviderLinks)
 | 
			
		||||
					if (ShouldValidate(link))
 | 
			
		||||
						link.Child = await _providers.CreateIfNotExists(link.Child, true);
 | 
			
		||||
 | 
			
		||||
			resource.Providers = await resource.Providers
 | 
			
		||||
				.SelectAsync(x => _providers.CreateIfNotExists(x, true))
 | 
			
		||||
				.ToListAsync();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override async Task Delete(LibraryDE obj)
 | 
			
		||||
		public override async Task Delete(Library 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();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
				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
 | 
			
		||||
				.Where(people => EF.Functions.ILike(people.Name, $"%{query}%"))
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
			_database = database;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<ICollection<ProviderID>> Search(string query)
 | 
			
		||||
		public override async Task<ICollection<ProviderID>> Search(string query)
 | 
			
		||||
		{
 | 
			
		||||
			return await _database.Providers
 | 
			
		||||
				.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
 | 
			
		||||
 | 
			
		||||
@ -74,7 +74,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
			                                                        && x.SeasonNumber == seasonNumber);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<ICollection<Season>> Search(string query)
 | 
			
		||||
		public override async Task<ICollection<Season>> Search(string query)
 | 
			
		||||
		{
 | 
			
		||||
			return await _database.Seasons
 | 
			
		||||
				.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo.Controllers
 | 
			
		||||
{
 | 
			
		||||
	public class ShowRepository : LocalRepository<Show, ShowDE>, IShowRepository
 | 
			
		||||
	public class ShowRepository : LocalRepository<Show>, IShowRepository
 | 
			
		||||
	{
 | 
			
		||||
		private bool _disposed;
 | 
			
		||||
		private readonly DatabaseContext _database;
 | 
			
		||||
@ -19,7 +19,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
		private readonly IProviderRepository _providers;
 | 
			
		||||
		private readonly Lazy<ISeasonRepository> _seasons;
 | 
			
		||||
		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,
 | 
			
		||||
			IStudioRepository studios,
 | 
			
		||||
@ -81,20 +81,10 @@ namespace Kyoo.Controllers
 | 
			
		||||
				.ToListAsync<Show>();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override async Task<ShowDE> Create(ShowDE obj)
 | 
			
		||||
		public override async Task<Show> Create(Show obj)
 | 
			
		||||
		{
 | 
			
		||||
			await base.Create(obj);
 | 
			
		||||
			_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)
 | 
			
		||||
				foreach (PeopleRole entry in obj.People)
 | 
			
		||||
@ -107,17 +97,16 @@ namespace Kyoo.Controllers
 | 
			
		||||
			return obj;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		protected override async Task Validate(ShowDE resource)
 | 
			
		||||
		protected override async Task Validate(Show resource)
 | 
			
		||||
		{
 | 
			
		||||
			await base.Validate(resource);
 | 
			
		||||
			
 | 
			
		||||
			if (ShouldValidate(resource.Studio))
 | 
			
		||||
				resource.Studio = await _studios.CreateIfNotExists(resource.Studio, true);
 | 
			
		||||
			
 | 
			
		||||
			if (resource.GenreLinks != null)
 | 
			
		||||
				foreach (GenreLink link in resource.GenreLinks)
 | 
			
		||||
					if (ShouldValidate(link))
 | 
			
		||||
						link.Child = await _genres.CreateIfNotExists(link.Child, true);
 | 
			
		||||
			resource.Genres = await resource.Genres
 | 
			
		||||
				.SelectAsync(x => _genres.CreateIfNotExists(x, true))
 | 
			
		||||
				.ToListAsync();
 | 
			
		||||
 | 
			
		||||
			if (resource.People != null)
 | 
			
		||||
				foreach (PeopleRole link in resource.People)
 | 
			
		||||
@ -134,32 +123,30 @@ namespace Kyoo.Controllers
 | 
			
		||||
		{
 | 
			
		||||
			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();
 | 
			
		||||
			}
 | 
			
		||||
			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();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			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();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public override async Task Delete(ShowDE obj)
 | 
			
		||||
		public override 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 (PeopleRole entry in obj.People)
 | 
			
		||||
@ -168,14 +155,6 @@ namespace Kyoo.Controllers
 | 
			
		||||
			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();
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
			_database = database;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public async Task<ICollection<Studio>> Search(string query)
 | 
			
		||||
		public override async Task<ICollection<Studio>> Search(string query)
 | 
			
		||||
		{
 | 
			
		||||
			return await _database.Studios
 | 
			
		||||
				.Where(x => EF.Functions.ILike(x.Name, $"%{query}%"))
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
									 && 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.");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -119,12 +119,6 @@ namespace Kyoo
 | 
			
		||||
			modelBuilder.Entity<Episode>()
 | 
			
		||||
				.HasIndex(x => new {x.ShowID, x.SeasonNumber, x.EpisodeNumber, x.AbsoluteNumber})
 | 
			
		||||
				.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()
 | 
			
		||||
 | 
			
		||||
@ -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