mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-11-04 03:27:14 -05:00 
			
		
		
		
	Starting to rework related properties loading. (Removing lazy loading)
This commit is contained in:
		
							parent
							
								
									f9e0c23e62
								
							
						
					
					
						commit
						3fe7c83415
					
				@ -61,6 +61,10 @@ namespace Kyoo.Controllers
 | 
			
		||||
		Task<Studio> GetStudio(Expression<Func<Studio, bool>> where);
 | 
			
		||||
		Task<People> GetPerson(Expression<Func<People, bool>> where);
 | 
			
		||||
 | 
			
		||||
		Task Load<T, T2>([NotNull] T obj, Expression<Func<T, T2>> member)
 | 
			
		||||
			where T : class, IResource
 | 
			
		||||
			where T2 : class;
 | 
			
		||||
		
 | 
			
		||||
		// Library Items relations
 | 
			
		||||
		Task<ICollection<LibraryItem>> GetItemsFromLibrary(int id,
 | 
			
		||||
			Expression<Func<LibraryItem, bool>> where = null,
 | 
			
		||||
 | 
			
		||||
@ -33,11 +33,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
			Key = ExpressionRewrite.Rewrite<Func<T, object>>(key);
 | 
			
		||||
			Descendant = descendant;
 | 
			
		||||
			
 | 
			
		||||
			if (Key == null || 
 | 
			
		||||
			    Key.Body is MemberExpression || 
 | 
			
		||||
			    Key.Body.NodeType == ExpressionType.Convert && ((UnaryExpression)Key.Body).Operand is MemberExpression)
 | 
			
		||||
				return;
 | 
			
		||||
				
 | 
			
		||||
			if (!Utility.IsPropertyExpression(Key))
 | 
			
		||||
				throw new ArgumentException("The given sort key is not valid.");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ using Kyoo.Models;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo.Controllers
 | 
			
		||||
{
 | 
			
		||||
	public class LibraryManager : ILibraryManager
 | 
			
		||||
	public abstract class ALibraryManager : ILibraryManager
 | 
			
		||||
	{
 | 
			
		||||
		public ILibraryRepository LibraryRepository { get; }
 | 
			
		||||
		public ILibraryItemRepository LibraryItemRepository { get; }
 | 
			
		||||
@ -20,7 +20,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
		public IPeopleRepository PeopleRepository { get; }
 | 
			
		||||
		public IProviderRepository ProviderRepository { get; }
 | 
			
		||||
		
 | 
			
		||||
		public LibraryManager(ILibraryRepository libraryRepository, 
 | 
			
		||||
		public ALibraryManager(ILibraryRepository libraryRepository, 
 | 
			
		||||
			ILibraryItemRepository libraryItemRepository,
 | 
			
		||||
			ICollectionRepository collectionRepository, 
 | 
			
		||||
			IShowRepository showRepository, 
 | 
			
		||||
@ -235,6 +235,10 @@ namespace Kyoo.Controllers
 | 
			
		||||
			return PeopleRepository.Get(where);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public abstract Task Load<T, T2>(T obj, Expression<Func<T, T2>> member)
 | 
			
		||||
			where T : class, IResource
 | 
			
		||||
			where T2 : class;
 | 
			
		||||
 | 
			
		||||
		public Task<ICollection<Library>> GetLibraries(Expression<Func<Library, bool>> where = null, 
 | 
			
		||||
			Sort<Library> sort = default,
 | 
			
		||||
			Pagination page = default)
 | 
			
		||||
@ -19,7 +19,7 @@
 | 
			
		||||
	</PropertyGroup>
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
		<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
 | 
			
		||||
		<PackageReference Include="JetBrains.Annotations" Version="2020.3.0" />
 | 
			
		||||
		<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.0-beta-20204-02" PrivateAssets="All" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								Kyoo.Common/Models/Attributes/ComposedSlug.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Kyoo.Common/Models/Attributes/ComposedSlug.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo.Models.Attributes
 | 
			
		||||
{
 | 
			
		||||
	[AttributeUsage(AttributeTargets.Class)]
 | 
			
		||||
	public class ComposedSlug : Attribute { }
 | 
			
		||||
}
 | 
			
		||||
@ -4,6 +4,7 @@ using Kyoo.Models.Attributes;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo.Models
 | 
			
		||||
{
 | 
			
		||||
	[ComposedSlug]
 | 
			
		||||
	public class Episode : IResource, IOnMerge
 | 
			
		||||
	{
 | 
			
		||||
		public int ID { get; set; }
 | 
			
		||||
@ -28,7 +29,7 @@ namespace Kyoo.Models
 | 
			
		||||
		[JsonIgnore] public virtual IEnumerable<Track> Tracks { get; set; }
 | 
			
		||||
 | 
			
		||||
		public string ShowTitle => Show.Title;
 | 
			
		||||
		public string Slug => GetSlug(Show.Slug, SeasonNumber, EpisodeNumber);
 | 
			
		||||
		public string Slug => Show != null ? GetSlug(Show.Slug, SeasonNumber, EpisodeNumber) : ID.ToString();
 | 
			
		||||
		public string Thumb
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ using Kyoo.Models.Attributes;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo.Models
 | 
			
		||||
{
 | 
			
		||||
	[ComposedSlug]
 | 
			
		||||
	public class Season : IResource
 | 
			
		||||
	{
 | 
			
		||||
		[JsonIgnore] public int ID  { get; set; }
 | 
			
		||||
@ -10,7 +11,7 @@ namespace Kyoo.Models
 | 
			
		||||
 | 
			
		||||
		public int SeasonNumber { get; set; } = -1;
 | 
			
		||||
 | 
			
		||||
		public string Slug => $"{Show.Slug}-s{SeasonNumber}";
 | 
			
		||||
		public string Slug => Show != null ? $"{Show.Slug}-s{SeasonNumber}" : ID.ToString();
 | 
			
		||||
		public string Title { get; set; }
 | 
			
		||||
		public string Overview { get; set; }
 | 
			
		||||
		public int? Year { get; set; }
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,13 @@ namespace Kyoo
 | 
			
		||||
{
 | 
			
		||||
	public static class Utility
 | 
			
		||||
	{
 | 
			
		||||
		public static bool IsPropertyExpression<T, T2>(Expression<Func<T, T2>> ex)
 | 
			
		||||
		{
 | 
			
		||||
			return ex == null ||
 | 
			
		||||
			       ex.Body is MemberExpression ||
 | 
			
		||||
			       ex.Body.NodeType == ExpressionType.Convert && ((UnaryExpression)ex.Body).Operand is MemberExpression;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public static string ToSlug(string str)
 | 
			
		||||
		{
 | 
			
		||||
			if (str == null)
 | 
			
		||||
 | 
			
		||||
@ -12,10 +12,10 @@
 | 
			
		||||
	</PropertyGroup>
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
	  <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
 | 
			
		||||
	  <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
 | 
			
		||||
	  <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.3" />
 | 
			
		||||
	  <PackageReference Include="Npgsql" Version="4.1.3" />
 | 
			
		||||
	  <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.3" />
 | 
			
		||||
	  <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.3" />
 | 
			
		||||
	  <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
 | 
			
		||||
	  <PackageReference Include="Npgsql" Version="5.0.3" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
 | 
			
		||||
@ -153,6 +153,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
			if (edited == null)
 | 
			
		||||
				throw new ArgumentNullException(nameof(edited));
 | 
			
		||||
 | 
			
		||||
			bool lazyLoading = Database.ChangeTracker.LazyLoadingEnabled;
 | 
			
		||||
			Database.ChangeTracker.LazyLoadingEnabled = false;
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
@ -193,7 +194,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
			}
 | 
			
		||||
			finally
 | 
			
		||||
			{
 | 
			
		||||
				Database.ChangeTracker.LazyLoadingEnabled = true;
 | 
			
		||||
				Database.ChangeTracker.LazyLoadingEnabled = lazyLoading;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -206,7 +207,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
		{
 | 
			
		||||
			if (string.IsNullOrEmpty(resource.Slug))
 | 
			
		||||
				throw new ArgumentException("Resource can't have null as a slug.");
 | 
			
		||||
			if (int.TryParse(resource.Slug, out int _))
 | 
			
		||||
			if (int.TryParse(resource.Slug, out int _) && typeof(T).GetCustomAttribute<ComposedSlug>() == null)
 | 
			
		||||
			{
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
@ -352,7 +353,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
				throw new ArgumentNullException(nameof(edited));
 | 
			
		||||
			if (edited is TInternal intern)
 | 
			
		||||
				return Edit(intern, resetOld).Cast<T>();
 | 
			
		||||
			TInternal obj = new TInternal();
 | 
			
		||||
			TInternal obj = new();
 | 
			
		||||
			Utility.Assign(obj, edited);
 | 
			
		||||
			return base.Edit(obj, resetOld).Cast<T>();
 | 
			
		||||
		}
 | 
			
		||||
@ -365,7 +366,7 @@ namespace Kyoo.Controllers
 | 
			
		||||
				throw new ArgumentNullException(nameof(obj));
 | 
			
		||||
			if (obj is TInternal intern)
 | 
			
		||||
				return Delete(intern);
 | 
			
		||||
			TInternal item = new TInternal();
 | 
			
		||||
			TInternal item = new();
 | 
			
		||||
			Utility.Assign(item, obj);
 | 
			
		||||
			return Delete(item);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										51
									
								
								Kyoo/Controllers/LibraryManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								Kyoo/Controllers/LibraryManager.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Linq.Expressions;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Kyoo.Models;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo.Controllers
 | 
			
		||||
{
 | 
			
		||||
	public class LibaryManager : ALibraryManager
 | 
			
		||||
	{
 | 
			
		||||
		private readonly DatabaseContext _database;
 | 
			
		||||
		
 | 
			
		||||
		public LibaryManager(ILibraryRepository libraryRepository,
 | 
			
		||||
			ILibraryItemRepository libraryItemRepository,
 | 
			
		||||
			ICollectionRepository collectionRepository,
 | 
			
		||||
			IShowRepository showRepository,
 | 
			
		||||
			ISeasonRepository seasonRepository,
 | 
			
		||||
			IEpisodeRepository episodeRepository,
 | 
			
		||||
			ITrackRepository trackRepository,
 | 
			
		||||
			IGenreRepository genreRepository,
 | 
			
		||||
			IStudioRepository studioRepository,
 | 
			
		||||
			IProviderRepository providerRepository,
 | 
			
		||||
			IPeopleRepository peopleRepository,
 | 
			
		||||
			DatabaseContext database)
 | 
			
		||||
			: base(libraryRepository,
 | 
			
		||||
				libraryItemRepository,
 | 
			
		||||
				collectionRepository,
 | 
			
		||||
				showRepository,
 | 
			
		||||
				seasonRepository,
 | 
			
		||||
				episodeRepository,
 | 
			
		||||
				trackRepository,
 | 
			
		||||
				genreRepository,
 | 
			
		||||
				studioRepository,
 | 
			
		||||
				providerRepository,
 | 
			
		||||
				peopleRepository)
 | 
			
		||||
		{
 | 
			
		||||
			_database = database;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public override Task Load<T, T2>(T obj, Expression<Func<T, T2>> member)
 | 
			
		||||
		{
 | 
			
		||||
			if (obj == null)
 | 
			
		||||
				throw new ArgumentNullException(nameof(obj));
 | 
			
		||||
			if (!Utility.IsPropertyExpression(member) || member == null)
 | 
			
		||||
				throw new ArgumentException($"{nameof(member)} is not a property.");
 | 
			
		||||
			if (typeof(IEnumerable).IsAssignableFrom(typeof(T2)))
 | 
			
		||||
				return _database.Entry(obj).Collection(member).LoadAsync();
 | 
			
		||||
			return _database.Entry(obj).Reference(member).LoadAsync();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -20,30 +20,30 @@
 | 
			
		||||
	</PropertyGroup>
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
		<PackageReference Include="IdentityServer4" Version="3.1.2" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4.AspNetIdentity" Version="3.1.2" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4.EntityFramework" Version="3.1.2" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4.EntityFramework.Storage" Version="3.1.2" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4.Storage" Version="3.1.2" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Portable.BouncyCastle" Version="1.8.6.7" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4" Version="4.1.1" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.1" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4.EntityFramework" Version="4.1.1" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4.EntityFramework.Storage" Version="4.1.1" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4.Storage" Version="4.1.1" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.3" />
 | 
			
		||||
		<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
 | 
			
		||||
		<PackageReference Include="Portable.BouncyCastle" Version="1.8.9" />
 | 
			
		||||
		<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj" />
 | 
			
		||||
		<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.3">
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.12" />
 | 
			
		||||
		<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="5.0.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="5.0.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.3">
 | 
			
		||||
		  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
 | 
			
		||||
		  <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
		</PackageReference>
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="5.0.3" />
 | 
			
		||||
		<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.3" />
 | 
			
		||||
		<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
 | 
			
		||||
		<ProjectReference Include="../Kyoo.CommonAPI/Kyoo.CommonAPI.csproj" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
@ -10,6 +11,8 @@ using Npgsql;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo
 | 
			
		||||
{
 | 
			
		||||
	//TODO disable lazy loading a provide a LoadAsync method in the library manager.
 | 
			
		||||
	
 | 
			
		||||
	public class DatabaseContext : DbContext
 | 
			
		||||
	{
 | 
			
		||||
		public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
 | 
			
		||||
@ -41,10 +44,10 @@ namespace Kyoo
 | 
			
		||||
			NpgsqlConnection.GlobalTypeMapper.MapEnum<StreamType>();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		private readonly ValueComparer<IEnumerable<string>> _stringArrayComparer = 
 | 
			
		||||
			new ValueComparer<IEnumerable<string>>(
 | 
			
		||||
		private readonly ValueComparer<IEnumerable<string>> _stringArrayComparer = new(
 | 
			
		||||
			(l1, l2) => l1.SequenceEqual(l2),
 | 
			
		||||
				arr => arr.Aggregate(0, (i, s) => s.GetHashCode()));
 | 
			
		||||
			arr => arr.Aggregate(0, (i, s) => s.GetHashCode())
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		protected override void OnModelCreating(ModelBuilder modelBuilder)
 | 
			
		||||
		{
 | 
			
		||||
@ -266,7 +269,7 @@ namespace Kyoo
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, 
 | 
			
		||||
			CancellationToken cancellationToken = new CancellationToken())
 | 
			
		||||
			CancellationToken cancellationToken = new())
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
@ -281,7 +284,7 @@ namespace Kyoo
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
 | 
			
		||||
		public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new())
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
@ -297,7 +300,7 @@ namespace Kyoo
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public async Task<int> SaveChangesAsync(string duplicateMessage,
 | 
			
		||||
			CancellationToken cancellationToken = new CancellationToken())
 | 
			
		||||
			CancellationToken cancellationToken = new())
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
@ -312,7 +315,7 @@ namespace Kyoo
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public async Task<int> SaveIfNoDuplicates(CancellationToken cancellationToken = new CancellationToken())
 | 
			
		||||
		public async Task<int> SaveIfNoDuplicates(CancellationToken cancellationToken = new())
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
@ -324,13 +327,12 @@ namespace Kyoo
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool IsDuplicateException(DbUpdateException ex)
 | 
			
		||||
		private static bool IsDuplicateException(Exception ex)
 | 
			
		||||
		{
 | 
			
		||||
			return ex.InnerException is PostgresException inner
 | 
			
		||||
			       && inner.SqlState == PostgresErrorCodes.UniqueViolation;
 | 
			
		||||
			return ex.InnerException is PostgresException {SqlState: PostgresErrorCodes.UniqueViolation};
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void DiscardChanges()
 | 
			
		||||
		private void DiscardChanges()
 | 
			
		||||
		{
 | 
			
		||||
			foreach (EntityEntry entry in ChangeTracker.Entries().Where(x => x.State != EntityState.Unchanged
 | 
			
		||||
			                                                                 && x.State != EntityState.Detached))
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,10 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using IdentityServer4.Models;
 | 
			
		||||
 | 
			
		||||
namespace Kyoo
 | 
			
		||||
{
 | 
			
		||||
	public class IdentityContext
 | 
			
		||||
	public static class IdentityContext
 | 
			
		||||
	{
 | 
			
		||||
		public static IEnumerable<IdentityResource> GetIdentityResources()
 | 
			
		||||
		{
 | 
			
		||||
@ -19,7 +20,7 @@ namespace Kyoo
 | 
			
		||||
		{
 | 
			
		||||
			return new List<Client>
 | 
			
		||||
			{
 | 
			
		||||
				new Client
 | 
			
		||||
				new()
 | 
			
		||||
				{
 | 
			
		||||
					ClientId = "kyoo.webapp",
 | 
			
		||||
					
 | 
			
		||||
@ -39,6 +40,38 @@ namespace Kyoo
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static IEnumerable<ApiScope> GetScopes()
 | 
			
		||||
		{
 | 
			
		||||
			return new[]
 | 
			
		||||
			{
 | 
			
		||||
				new ApiScope
 | 
			
		||||
				{
 | 
			
		||||
					Name = "kyoo.read",
 | 
			
		||||
					DisplayName = "Read only access to the API.",
 | 
			
		||||
				},
 | 
			
		||||
				new ApiScope
 | 
			
		||||
				{
 | 
			
		||||
					Name = "kyoo.write",
 | 
			
		||||
					DisplayName = "Read and write access to the public API"
 | 
			
		||||
				},
 | 
			
		||||
				new ApiScope
 | 
			
		||||
				{
 | 
			
		||||
					Name = "kyoo.play",
 | 
			
		||||
					DisplayName = "Allow playback of movies and episodes."
 | 
			
		||||
				},
 | 
			
		||||
				new ApiScope
 | 
			
		||||
				{
 | 
			
		||||
					Name = "kyoo.download",
 | 
			
		||||
					DisplayName = "Allow downloading of episodes and movies from kyoo."
 | 
			
		||||
				},
 | 
			
		||||
				new ApiScope
 | 
			
		||||
				{
 | 
			
		||||
					Name = "kyoo.admin",
 | 
			
		||||
					DisplayName = "Full access to the admin's API and the public API."
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public static IEnumerable<ApiResource> GetApis()
 | 
			
		||||
		{
 | 
			
		||||
			return new[]
 | 
			
		||||
@ -46,34 +79,7 @@ namespace Kyoo
 | 
			
		||||
				new ApiResource
 | 
			
		||||
				{
 | 
			
		||||
					Name = "Kyoo",
 | 
			
		||||
					Scopes =
 | 
			
		||||
					{
 | 
			
		||||
						new Scope
 | 
			
		||||
						{
 | 
			
		||||
							Name = "kyoo.read",
 | 
			
		||||
							DisplayName = "Read only access to the API.",
 | 
			
		||||
						},
 | 
			
		||||
						new Scope
 | 
			
		||||
						{
 | 
			
		||||
							Name = "kyoo.write",
 | 
			
		||||
							DisplayName = "Read and write access to the public API"
 | 
			
		||||
						},
 | 
			
		||||
						new Scope
 | 
			
		||||
						{
 | 
			
		||||
							Name = "kyoo.play",
 | 
			
		||||
							DisplayName = "Allow playback of movies and episodes."
 | 
			
		||||
						},
 | 
			
		||||
						new Scope
 | 
			
		||||
						{
 | 
			
		||||
							Name = "kyoo.download",
 | 
			
		||||
							DisplayName = "Allow downloading of episodes and movies from kyoo."
 | 
			
		||||
						},
 | 
			
		||||
						new Scope
 | 
			
		||||
						{
 | 
			
		||||
							Name = "kyoo.admin",
 | 
			
		||||
							DisplayName = "Full access to the admin's API and the public API."
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					Scopes = GetScopes().Select(x => x.Name).ToArray()
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using IdentityServer4.Extensions;
 | 
			
		||||
using IdentityServer4.Services;
 | 
			
		||||
using Kyoo.Api;
 | 
			
		||||
using Kyoo.Controllers;
 | 
			
		||||
@ -47,8 +48,7 @@ namespace Kyoo
 | 
			
		||||
 | 
			
		||||
			services.AddDbContext<DatabaseContext>(options =>
 | 
			
		||||
			{
 | 
			
		||||
				options.UseLazyLoadingProxies()
 | 
			
		||||
					.UseNpgsql(_configuration.GetConnectionString("Database"));
 | 
			
		||||
				options.UseNpgsql(_configuration.GetConnectionString("Database"));
 | 
			
		||||
					// .EnableSensitiveDataLogging()
 | 
			
		||||
					// .UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole()));
 | 
			
		||||
			}, ServiceLifetime.Transient);
 | 
			
		||||
@ -72,7 +72,6 @@ namespace Kyoo
 | 
			
		||||
			services.AddIdentityServer(options =>
 | 
			
		||||
				{
 | 
			
		||||
					options.IssuerUri = publicUrl;
 | 
			
		||||
					options.PublicOrigin = publicUrl;
 | 
			
		||||
					options.UserInteraction.LoginUrl = publicUrl + "login";
 | 
			
		||||
					options.UserInteraction.ErrorUrl = publicUrl + "error";
 | 
			
		||||
					options.UserInteraction.LogoutUrl = publicUrl + "logout";
 | 
			
		||||
@ -92,6 +91,7 @@ namespace Kyoo
 | 
			
		||||
					options.EnableTokenCleanup = true;
 | 
			
		||||
				})
 | 
			
		||||
				.AddInMemoryIdentityResources(IdentityContext.GetIdentityResources())
 | 
			
		||||
				.AddInMemoryApiScopes(IdentityContext.GetScopes())
 | 
			
		||||
				.AddInMemoryApiResources(IdentityContext.GetApis())
 | 
			
		||||
				.AddProfileService<AccountController>()
 | 
			
		||||
				.AddSigninKeys(_configuration);
 | 
			
		||||
@ -157,7 +157,7 @@ namespace Kyoo
 | 
			
		||||
			services.AddHostedService(provider => (TaskManager)provider.GetService<ITaskManager>());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 | 
			
		||||
		public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 | 
			
		||||
		{
 | 
			
		||||
			if (env.IsDevelopment())
 | 
			
		||||
			{
 | 
			
		||||
@ -186,6 +186,11 @@ namespace Kyoo
 | 
			
		||||
				MinimumSameSitePolicy = SameSiteMode.Strict
 | 
			
		||||
			});
 | 
			
		||||
			app.UseAuthentication();
 | 
			
		||||
			app.Use((ctx, next) =>
 | 
			
		||||
			{
 | 
			
		||||
				ctx.SetIdentityServerOrigin(_configuration.GetValue<string>("public_url"));
 | 
			
		||||
				return next();
 | 
			
		||||
			});
 | 
			
		||||
			app.UseIdentityServer();
 | 
			
		||||
			app.UseAuthorization();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -98,10 +98,9 @@ namespace Kyoo.Tasks
 | 
			
		||||
				await _thumbnails!.Validate(episode, true);
 | 
			
		||||
			if (subs)
 | 
			
		||||
			{
 | 
			
		||||
				// TODO this doesn't work. 
 | 
			
		||||
				IEnumerable<Track> tracks = (await _transcoder!.ExtractInfos(episode.Path))
 | 
			
		||||
				// TODO handle external subtites.
 | 
			
		||||
				episode.Tracks =  (await _transcoder!.ExtractInfos(episode.Path))
 | 
			
		||||
					.Where(x => x.Type != StreamType.Font);
 | 
			
		||||
				episode.Tracks = tracks;
 | 
			
		||||
				await _library.EditEpisode(episode, false);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user