mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-11-03 19:17:16 -05:00 
			
		
		
		
	Switch to file scopped namespaces (#349)
This commit is contained in:
		
						commit
						5fedce71a0
					
				@ -1,2 +1,3 @@
 | 
				
			|||||||
7e6e56a366babe17e7891a5897180efbf93c00c5
 | 
					7e6e56a366babe17e7891a5897180efbf93c00c5
 | 
				
			||||||
a5638203a6ecb9f372a5a61e1c8fd443bf3a17fe
 | 
					a5638203a6ecb9f372a5a61e1c8fd443bf3a17fe
 | 
				
			||||||
 | 
					18e301f26acd7f2e97eac26c5f48377fa13956f5
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,8 @@ dotnet_diagnostic.IDE0055.severity = none
 | 
				
			|||||||
dotnet_diagnostic.IDE0058.severity = none
 | 
					dotnet_diagnostic.IDE0058.severity = none
 | 
				
			||||||
dotnet_diagnostic.IDE0130.severity = none
 | 
					dotnet_diagnostic.IDE0130.severity = none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Convert to file-scoped namespace
 | 
				
			||||||
 | 
					csharp_style_namespace_declarations = file_scoped:warning
 | 
				
			||||||
# Sort using and Import directives with System.* appearing first
 | 
					# Sort using and Import directives with System.* appearing first
 | 
				
			||||||
dotnet_sort_system_directives_first = true
 | 
					dotnet_sort_system_directives_first = true
 | 
				
			||||||
csharp_using_directive_placement = outside_namespace:warning
 | 
					csharp_using_directive_placement = outside_namespace:warning
 | 
				
			||||||
 | 
				
			|||||||
@ -18,13 +18,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using Kyoo.Abstractions.Models;
 | 
					using Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An interface to interact with the database. Every repository is mapped through here.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface ILibraryManager
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An interface to interact with the database. Every repository is mapped through here.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public interface ILibraryManager
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	IRepository<T> Repository<T>()
 | 
						IRepository<T> Repository<T>()
 | 
				
			||||||
		where T : IResource, IQuery;
 | 
							where T : IResource, IQuery;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -77,5 +77,4 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// The repository that handle users.
 | 
						/// The repository that handle users.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	IRepository<User> Users { get; }
 | 
						IRepository<User> Users { get; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,13 +19,13 @@
 | 
				
			|||||||
using Kyoo.Abstractions.Models.Permissions;
 | 
					using Kyoo.Abstractions.Models.Permissions;
 | 
				
			||||||
using Microsoft.AspNetCore.Mvc.Filters;
 | 
					using Microsoft.AspNetCore.Mvc.Filters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A service to validate permissions.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface IPermissionValidator
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A service to validate permissions.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public interface IPermissionValidator
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Create an IAuthorizationFilter that will be used to validate permissions.
 | 
						/// Create an IAuthorizationFilter that will be used to validate permissions.
 | 
				
			||||||
	/// This can registered with any lifetime.
 | 
						/// This can registered with any lifetime.
 | 
				
			||||||
@ -43,5 +43,4 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// </param>
 | 
						/// </param>
 | 
				
			||||||
	/// <returns>An authorization filter used to validate the permission.</returns>
 | 
						/// <returns>An authorization filter used to validate the permission.</returns>
 | 
				
			||||||
	IFilterMetadata Create(PartialPermissionAttribute attribute);
 | 
						IFilterMetadata Create(PartialPermissionAttribute attribute);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,17 +21,17 @@ using System.Collections.Generic;
 | 
				
			|||||||
using Autofac;
 | 
					using Autofac;
 | 
				
			||||||
using Microsoft.Extensions.DependencyInjection;
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A common interface used to discord plugins
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <remarks>
 | 
				
			||||||
 | 
					/// You can inject services in the IPlugin constructor.
 | 
				
			||||||
 | 
					/// You should only inject well known services like an ILogger, IConfiguration or IWebHostEnvironment.
 | 
				
			||||||
 | 
					/// </remarks>
 | 
				
			||||||
 | 
					public interface IPlugin
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A common interface used to discord plugins
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	/// <remarks>
 | 
					 | 
				
			||||||
	/// You can inject services in the IPlugin constructor.
 | 
					 | 
				
			||||||
	/// You should only inject well known services like an ILogger, IConfiguration or IWebHostEnvironment.
 | 
					 | 
				
			||||||
	/// </remarks>
 | 
					 | 
				
			||||||
	public interface IPlugin
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The name of the plugin
 | 
						/// The name of the plugin
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -62,5 +62,4 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		// Skipped
 | 
							// Skipped
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,13 +20,13 @@ using System;
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using Kyoo.Abstractions.Models.Exceptions;
 | 
					using Kyoo.Abstractions.Models.Exceptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A manager to load plugins and retrieve information from them.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface IPluginManager
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A manager to load plugins and retrieve information from them.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public interface IPluginManager
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Get a single plugin that match the type and name given.
 | 
						/// Get a single plugin that match the type and name given.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -66,5 +66,4 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// You should not try to put plugins from the plugins directory here as they will get automatically loaded.
 | 
						/// You should not try to put plugins from the plugins directory here as they will get automatically loaded.
 | 
				
			||||||
	/// </param>
 | 
						/// </param>
 | 
				
			||||||
	public void LoadPlugins(params Type[] plugins);
 | 
						public void LoadPlugins(params Type[] plugins);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,15 +23,15 @@ using Kyoo.Abstractions.Models;
 | 
				
			|||||||
using Kyoo.Abstractions.Models.Exceptions;
 | 
					using Kyoo.Abstractions.Models.Exceptions;
 | 
				
			||||||
using Kyoo.Abstractions.Models.Utils;
 | 
					using Kyoo.Abstractions.Models.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// A common repository for every resources.
 | 
					/// A common repository for every resources.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	/// <typeparam name="T">The resource's type that this repository manage.</typeparam>
 | 
					/// <typeparam name="T">The resource's type that this repository manage.</typeparam>
 | 
				
			||||||
	public interface IRepository<T> : IBaseRepository
 | 
					public interface IRepository<T> : IBaseRepository
 | 
				
			||||||
	where T : IResource, IQuery
 | 
						where T : IResource, IQuery
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The event handler type for all events of this repository.
 | 
						/// The event handler type for all events of this repository.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -170,8 +170,7 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	/// <param name="obj">The resource newly created.</param>
 | 
						/// <param name="obj">The resource newly created.</param>
 | 
				
			||||||
	/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 | 
						/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 | 
				
			||||||
		protected static Task OnResourceCreated(T obj) =>
 | 
						protected static Task OnResourceCreated(T obj) => OnCreated?.Invoke(obj) ?? Task.CompletedTask;
 | 
				
			||||||
			OnCreated?.Invoke(obj) ?? Task.CompletedTask;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Edit a resource and replace every property
 | 
						/// Edit a resource and replace every property
 | 
				
			||||||
@ -203,8 +202,7 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	/// <param name="obj">The resource newly edited.</param>
 | 
						/// <param name="obj">The resource newly edited.</param>
 | 
				
			||||||
	/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 | 
						/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 | 
				
			||||||
		protected static Task OnResourceEdited(T obj) =>
 | 
						protected static Task OnResourceEdited(T obj) => OnEdited?.Invoke(obj) ?? Task.CompletedTask;
 | 
				
			||||||
			OnEdited?.Invoke(obj) ?? Task.CompletedTask;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Delete a resource by it's ID
 | 
						/// Delete a resource by it's ID
 | 
				
			||||||
@ -247,25 +245,23 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	/// <param name="obj">The resource newly deleted.</param>
 | 
						/// <param name="obj">The resource newly deleted.</param>
 | 
				
			||||||
	/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 | 
						/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 | 
				
			||||||
		protected static Task OnResourceDeleted(T obj) =>
 | 
						protected static Task OnResourceDeleted(T obj) => OnDeleted?.Invoke(obj) ?? Task.CompletedTask;
 | 
				
			||||||
			OnDeleted?.Invoke(obj) ?? Task.CompletedTask;
 | 
					}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// A base class for repositories. Every service implementing this will be handled by the <see cref="ILibraryManager"/>.
 | 
					/// A base class for repositories. Every service implementing this will be handled by the <see cref="ILibraryManager"/>.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	public interface IBaseRepository
 | 
					public interface IBaseRepository
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The type for witch this repository is responsible or null if non applicable.
 | 
						/// The type for witch this repository is responsible or null if non applicable.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	Type RepositoryType { get; }
 | 
						Type RepositoryType { get; }
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public interface IUserRepository : IRepository<User>
 | 
					public interface IUserRepository : IRepository<User>
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	Task<User?> GetByExternalId(string provider, string id);
 | 
						Task<User?> GetByExternalId(string provider, string id);
 | 
				
			||||||
	Task<User> AddExternalToken(Guid userId, string provider, ExternalToken token);
 | 
						Task<User> AddExternalToken(Guid userId, string provider, ExternalToken token);
 | 
				
			||||||
	Task<User> DeleteExternalToken(Guid userId, string provider);
 | 
						Task<User> DeleteExternalToken(Guid userId, string provider);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,13 +21,13 @@ using System.IO;
 | 
				
			|||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using Kyoo.Abstractions.Models;
 | 
					using Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Download images and retrieve the path of those images for a resource.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface IThumbnailsManager
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Download images and retrieve the path of those images for a resource.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public interface IThumbnailsManager
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Download images of a specified item.
 | 
						/// Download images of a specified item.
 | 
				
			||||||
	/// If no images is available to download, do nothing and silently return.
 | 
						/// If no images is available to download, do nothing and silently return.
 | 
				
			||||||
@ -75,5 +75,4 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// <param name="userId">The id of the user. </param>
 | 
						/// <param name="userId">The id of the user. </param>
 | 
				
			||||||
	/// <param name="image">The byte stream of the image. Null to delete the image.</param>
 | 
						/// <param name="image">The byte stream of the image. Null to delete the image.</param>
 | 
				
			||||||
	Task SetUserImage(Guid userId, Stream? image);
 | 
						Task SetUserImage(Guid userId, Stream? image);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,14 +19,14 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using Microsoft.Extensions.DependencyInjection;
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A list of constant priorities used for <see cref="IStartupAction"/>'s <see cref="IStartupAction.Priority"/>.
 | 
				
			||||||
 | 
					/// It also contains helper methods for creating new <see cref="StartupAction"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class SA
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A list of constant priorities used for <see cref="IStartupAction"/>'s <see cref="IStartupAction.Priority"/>.
 | 
					 | 
				
			||||||
	/// It also contains helper methods for creating new <see cref="StartupAction"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class SA
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The highest predefined priority existing for <see cref="StartupAction"/>.
 | 
						/// The highest predefined priority existing for <see cref="StartupAction"/>.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -102,10 +102,7 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// <typeparam name="T2">A second dependency that this action will use.</typeparam>
 | 
						/// <typeparam name="T2">A second dependency that this action will use.</typeparam>
 | 
				
			||||||
	/// <typeparam name="T3">A third dependency that this action will use.</typeparam>
 | 
						/// <typeparam name="T3">A third dependency that this action will use.</typeparam>
 | 
				
			||||||
	/// <returns>A new <see cref="StartupAction"/></returns>
 | 
						/// <returns>A new <see cref="StartupAction"/></returns>
 | 
				
			||||||
		public static StartupAction<T, T2, T3> New<T, T2, T3>(
 | 
						public static StartupAction<T, T2, T3> New<T, T2, T3>(Action<T, T2, T3> action, int priority)
 | 
				
			||||||
			Action<T, T2, T3> action,
 | 
					 | 
				
			||||||
			int priority
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
		where T : notnull
 | 
							where T : notnull
 | 
				
			||||||
		where T2 : notnull
 | 
							where T2 : notnull
 | 
				
			||||||
		where T3 : notnull => new(action, priority);
 | 
							where T3 : notnull => new(action, priority);
 | 
				
			||||||
@ -249,16 +246,16 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
			);
 | 
								);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// An action executed on kyoo's startup to initialize the asp-net container.
 | 
					/// An action executed on kyoo's startup to initialize the asp-net container.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	/// <remarks>
 | 
					/// <remarks>
 | 
				
			||||||
	/// This is the base interface, see <see cref="SA.StartupAction"/> for a simpler use of this.
 | 
					/// This is the base interface, see <see cref="SA.StartupAction"/> for a simpler use of this.
 | 
				
			||||||
	/// </remarks>
 | 
					/// </remarks>
 | 
				
			||||||
	public interface IStartupAction
 | 
					public interface IStartupAction
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The priority of this action. The actions will be executed on descending priority order.
 | 
						/// The priority of this action. The actions will be executed on descending priority order.
 | 
				
			||||||
	/// If two actions have the same priority, their order is undefined.
 | 
						/// If two actions have the same priority, their order is undefined.
 | 
				
			||||||
@ -270,5 +267,4 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	/// <param name="provider">The service provider containing all services can be used.</param>
 | 
						/// <param name="provider">The service provider containing all services can be used.</param>
 | 
				
			||||||
	void Run(IServiceProvider provider);
 | 
						void Run(IServiceProvider provider);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,13 +23,13 @@ using System.Security.Claims;
 | 
				
			|||||||
using Kyoo.Abstractions.Models.Exceptions;
 | 
					using Kyoo.Abstractions.Models.Exceptions;
 | 
				
			||||||
using Kyoo.Authentication.Models;
 | 
					using Kyoo.Authentication.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication
 | 
					namespace Kyoo.Authentication;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Extension methods.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class Extensions
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Extension methods.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class Extensions
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Get the permissions of an user.
 | 
						/// Get the permissions of an user.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -61,5 +61,4 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
			throw new UnauthorizedException();
 | 
								throw new UnauthorizedException();
 | 
				
			||||||
		return ret.Value;
 | 
							return ret.Value;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,16 +18,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Attributes
 | 
					namespace Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An attribute to specify on apis to specify it's documentation's name and category.
 | 
				
			||||||
 | 
					/// If this is applied on a method, the specified method will be exploded from the controller's page and be
 | 
				
			||||||
 | 
					/// included on the specified tag page.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
 | 
				
			||||||
 | 
					public class ApiDefinitionAttribute : Attribute
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An attribute to specify on apis to specify it's documentation's name and category.
 | 
					 | 
				
			||||||
	/// If this is applied on a method, the specified method will be exploded from the controller's page and be
 | 
					 | 
				
			||||||
	/// included on the specified tag page.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
 | 
					 | 
				
			||||||
	public class ApiDefinitionAttribute : Attribute
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The public name of this api.
 | 
						/// The public name of this api.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -48,5 +48,4 @@ namespace Kyoo.Abstractions.Models.Attributes
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		Name = name;
 | 
							Name = name;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,11 +18,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Attributes
 | 
					namespace Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// An attribute to inform that the property is computed automatically and can't be assigned manually.
 | 
					/// An attribute to inform that the property is computed automatically and can't be assigned manually.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	[AttributeUsage(AttributeTargets.Property)]
 | 
					[AttributeUsage(AttributeTargets.Property)]
 | 
				
			||||||
	public class ComputedAttribute : NotMergeableAttribute { }
 | 
					public class ComputedAttribute : NotMergeableAttribute { }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -18,14 +18,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Attributes
 | 
					namespace Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The targeted relation can be loaded.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[AttributeUsage(AttributeTargets.Property)]
 | 
				
			||||||
 | 
					public class LoadableRelationAttribute : Attribute
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The targeted relation can be loaded.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[AttributeUsage(AttributeTargets.Property)]
 | 
					 | 
				
			||||||
	public class LoadableRelationAttribute : Attribute
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The name of the field containing the related resource's ID.
 | 
						/// The name of the field containing the related resource's ID.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -50,5 +50,4 @@ namespace Kyoo.Abstractions.Models.Attributes
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		RelationID = relationID;
 | 
							RelationID = relationID;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,23 +18,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Attributes
 | 
					namespace Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Specify that a property can't be merged.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[AttributeUsage(AttributeTargets.Property)]
 | 
					 | 
				
			||||||
	public class NotMergeableAttribute : Attribute { }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// An interface with a method called when this object is merged.
 | 
					/// Specify that a property can't be merged.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	public interface IOnMerge
 | 
					[AttributeUsage(AttributeTargets.Property)]
 | 
				
			||||||
	{
 | 
					public class NotMergeableAttribute : Attribute { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An interface with a method called when this object is merged.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface IOnMerge
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// This function is called after the object has been merged.
 | 
						/// This function is called after the object has been merged.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	/// <param name="merged">The object that has been merged with this.</param>
 | 
						/// <param name="merged">The object that has been merged with this.</param>
 | 
				
			||||||
	void OnMerge(object merged);
 | 
						void OnMerge(object merged);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,14 +21,14 @@ using Kyoo.Abstractions.Controllers;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc.Filters;
 | 
					using Microsoft.AspNetCore.Mvc.Filters;
 | 
				
			||||||
using Microsoft.Extensions.DependencyInjection;
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Permissions
 | 
					namespace Kyoo.Abstractions.Models.Permissions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Specify one part of a permissions needed for the API (the kind or the type).
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
 | 
				
			||||||
 | 
					public class PartialPermissionAttribute : Attribute, IFilterFactory
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Specify one part of a permissions needed for the API (the kind or the type).
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
 | 
					 | 
				
			||||||
	public class PartialPermissionAttribute : Attribute, IFilterFactory
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The needed permission type.
 | 
						/// The needed permission type.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -84,5 +84,4 @@ namespace Kyoo.Abstractions.Models.Permissions
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public bool IsReusable => true;
 | 
						public bool IsReusable => true;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,13 +21,13 @@ using Kyoo.Abstractions.Controllers;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc.Filters;
 | 
					using Microsoft.AspNetCore.Mvc.Filters;
 | 
				
			||||||
using Microsoft.Extensions.DependencyInjection;
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Permissions
 | 
					namespace Kyoo.Abstractions.Models.Permissions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The kind of permission needed.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum Kind
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The kind of permission needed.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public enum Kind
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Allow the user to read for this kind of data.
 | 
						/// Allow the user to read for this kind of data.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -52,13 +52,13 @@ namespace Kyoo.Abstractions.Models.Permissions
 | 
				
			|||||||
	/// Allow the user to play this file.
 | 
						/// Allow the user to play this file.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	Play,
 | 
						Play,
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// The group of the permission.
 | 
					/// The group of the permission.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	public enum Group
 | 
					public enum Group
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Default group indicating no value.
 | 
						/// Default group indicating no value.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -73,14 +73,14 @@ namespace Kyoo.Abstractions.Models.Permissions
 | 
				
			|||||||
	/// Allow operation on sensitive items like libraries path, configurations and so on.
 | 
						/// Allow operation on sensitive items like libraries path, configurations and so on.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	Admin
 | 
						Admin
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// Specify permissions needed for the API.
 | 
					/// Specify permissions needed for the API.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
 | 
					[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
 | 
				
			||||||
	public class PermissionAttribute : Attribute, IFilterFactory
 | 
					public class PermissionAttribute : Attribute, IFilterFactory
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The needed permission as string.
 | 
						/// The needed permission as string.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -133,5 +133,4 @@ namespace Kyoo.Abstractions.Models.Permissions
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		return Type;
 | 
							return Type;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,14 +18,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Permissions
 | 
					namespace Kyoo.Abstractions.Models.Permissions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The annotated route can only be accessed by a logged in user.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
 | 
				
			||||||
 | 
					public class UserOnlyAttribute : Attribute
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The annotated route can only be accessed by a logged in user.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
 | 
					 | 
				
			||||||
	public class UserOnlyAttribute : Attribute
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	// TODO: Implement a Filter Attribute to make this work. For now, this attribute is only useful as documentation.
 | 
						// TODO: Implement a Filter Attribute to make this work. For now, this attribute is only useful as documentation.
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,14 +19,14 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Runtime.Serialization;
 | 
					using System.Runtime.Serialization;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Exceptions
 | 
					namespace Kyoo.Abstractions.Models.Exceptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An exception raised when an item already exists in the database.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Serializable]
 | 
				
			||||||
 | 
					public class DuplicatedItemException : Exception
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An exception raised when an item already exists in the database.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Serializable]
 | 
					 | 
				
			||||||
	public class DuplicatedItemException : Exception
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The existing object.
 | 
						/// The existing object.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -49,5 +49,4 @@ namespace Kyoo.Abstractions.Models.Exceptions
 | 
				
			|||||||
	/// <param name="context">The serialization context</param>
 | 
						/// <param name="context">The serialization context</param>
 | 
				
			||||||
	protected DuplicatedItemException(SerializationInfo info, StreamingContext context)
 | 
						protected DuplicatedItemException(SerializationInfo info, StreamingContext context)
 | 
				
			||||||
		: base(info, context) { }
 | 
							: base(info, context) { }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,14 +19,14 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Runtime.Serialization;
 | 
					using System.Runtime.Serialization;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Exceptions
 | 
					namespace Kyoo.Abstractions.Models.Exceptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An exception raised when an item could not be found.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Serializable]
 | 
				
			||||||
 | 
					public class ItemNotFoundException : Exception
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An exception raised when an item could not be found.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Serializable]
 | 
					 | 
				
			||||||
	public class ItemNotFoundException : Exception
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Create a default <see cref="ItemNotFoundException"/> with no message.
 | 
						/// Create a default <see cref="ItemNotFoundException"/> with no message.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -47,5 +47,4 @@ namespace Kyoo.Abstractions.Models.Exceptions
 | 
				
			|||||||
	/// <param name="context">The serialization context</param>
 | 
						/// <param name="context">The serialization context</param>
 | 
				
			||||||
	protected ItemNotFoundException(SerializationInfo info, StreamingContext context)
 | 
						protected ItemNotFoundException(SerializationInfo info, StreamingContext context)
 | 
				
			||||||
		: base(info, context) { }
 | 
							: base(info, context) { }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,11 +19,11 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Runtime.Serialization;
 | 
					using System.Runtime.Serialization;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Exceptions
 | 
					namespace Kyoo.Abstractions.Models.Exceptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Serializable]
 | 
				
			||||||
 | 
					public class UnauthorizedException : Exception
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	[Serializable]
 | 
					 | 
				
			||||||
	public class UnauthorizedException : Exception
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	public UnauthorizedException()
 | 
						public UnauthorizedException()
 | 
				
			||||||
		: base("User not authenticated or token invalid.") { }
 | 
							: base("User not authenticated or token invalid.") { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,5 +32,4 @@ namespace Kyoo.Abstractions.Models.Exceptions
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	protected UnauthorizedException(SerializationInfo info, StreamingContext context)
 | 
						protected UnauthorizedException(SerializationInfo info, StreamingContext context)
 | 
				
			||||||
		: base(info, context) { }
 | 
							: base(info, context) { }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,13 +16,13 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A genre that allow one to specify categories for shows.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum Genre
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A genre that allow one to specify categories for shows.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public enum Genre
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	Action,
 | 
						Action,
 | 
				
			||||||
	Adventure,
 | 
						Adventure,
 | 
				
			||||||
	Animation,
 | 
						Animation,
 | 
				
			||||||
@ -41,5 +41,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	Thriller,
 | 
						Thriller,
 | 
				
			||||||
	War,
 | 
						War,
 | 
				
			||||||
	Western,
 | 
						Western,
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,13 +16,13 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// ID and link of an item on an external provider.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class MetadataId
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// ID and link of an item on an external provider.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class MetadataId
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The ID of the resource on the external provider.
 | 
						/// The ID of the resource on the external provider.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -32,5 +32,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// The URL of the resource on the external provider.
 | 
						/// The URL of the resource on the external provider.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public string? Link { get; set; }
 | 
						public string? Link { get; set; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,15 +20,15 @@ using System.Collections.Generic;
 | 
				
			|||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// A page of resource that contains information about the pagination of resources.
 | 
					/// A page of resource that contains information about the pagination of resources.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	/// <typeparam name="T">The type of resource contained in this page.</typeparam>
 | 
					/// <typeparam name="T">The type of resource contained in this page.</typeparam>
 | 
				
			||||||
	public class Page<T>
 | 
					public class Page<T>
 | 
				
			||||||
	where T : IResource
 | 
						where T : IResource
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The link of the current page.
 | 
						/// The link of the current page.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -67,13 +67,7 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// <param name="previous">The link of the previous page.</param>
 | 
						/// <param name="previous">The link of the previous page.</param>
 | 
				
			||||||
	/// <param name="next">The link of the next page.</param>
 | 
						/// <param name="next">The link of the next page.</param>
 | 
				
			||||||
	/// <param name="first">The link of the first page.</param>
 | 
						/// <param name="first">The link of the first page.</param>
 | 
				
			||||||
		public Page(
 | 
						public Page(ICollection<T> items, string @this, string? previous, string? next, string first)
 | 
				
			||||||
			ICollection<T> items,
 | 
					 | 
				
			||||||
			string @this,
 | 
					 | 
				
			||||||
			string? previous,
 | 
					 | 
				
			||||||
			string? next,
 | 
					 | 
				
			||||||
			string first
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Items = items;
 | 
							Items = items;
 | 
				
			||||||
		This = @this;
 | 
							This = @this;
 | 
				
			||||||
@ -108,5 +102,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
		query.Remove("afterID");
 | 
							query.Remove("afterID");
 | 
				
			||||||
		First = url + query.ToQueryString();
 | 
							First = url + query.ToQueryString();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,13 +23,13 @@ using System.Text.Json.Serialization;
 | 
				
			|||||||
using Kyoo.Abstractions.Controllers;
 | 
					using Kyoo.Abstractions.Controllers;
 | 
				
			||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A class representing collections of <see cref="Show"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Collection : IQuery, IResource, IMetadata, IThumbnails, IAddedDate, ILibraryItem
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A class representing collections of <see cref="Show"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class Collection : IQuery, IResource, IMetadata, IThumbnails, IAddedDate, ILibraryItem
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	public static Sort DefaultSort => new Sort<Collection>.By(nameof(Collection.Name));
 | 
						public static Sort DefaultSort => new Sort<Collection>.By(nameof(Collection.Name));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
@ -87,5 +87,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
			Name = name;
 | 
								Name = name;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,13 +26,13 @@ using EntityFrameworkCore.Projectables;
 | 
				
			|||||||
using Kyoo.Abstractions.Controllers;
 | 
					using Kyoo.Abstractions.Controllers;
 | 
				
			||||||
using Kyoo.Abstractions.Models.Attributes;
 | 
					using Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A class to represent a single show's episode.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Episode : IQuery, IResource, IMetadata, IThumbnails, IAddedDate, INews
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A class to represent a single show's episode.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class Episode : IQuery, IResource, IMetadata, IThumbnails, IAddedDate, INews
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	// Use absolute numbers by default and fallback to season/episodes if it does not exists.
 | 
						// Use absolute numbers by default and fallback to season/episodes if it does not exists.
 | 
				
			||||||
	public static Sort DefaultSort =>
 | 
						public static Sort DefaultSort =>
 | 
				
			||||||
		new Sort<Episode>.Conglomerate(
 | 
							new Sort<Episode>.Conglomerate(
 | 
				
			||||||
@ -52,12 +52,7 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
		get
 | 
							get
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (ShowSlug != null || Show?.Slug != null)
 | 
								if (ShowSlug != null || Show?.Slug != null)
 | 
				
			||||||
					return GetSlug(
 | 
									return GetSlug(ShowSlug ?? Show!.Slug, SeasonNumber, EpisodeNumber, AbsoluteNumber);
 | 
				
			||||||
						ShowSlug ?? Show!.Slug,
 | 
					 | 
				
			||||||
						SeasonNumber,
 | 
					 | 
				
			||||||
						EpisodeNumber,
 | 
					 | 
				
			||||||
						AbsoluteNumber
 | 
					 | 
				
			||||||
					);
 | 
					 | 
				
			||||||
			return GetSlug(ShowId.ToString(), SeasonNumber, EpisodeNumber, AbsoluteNumber);
 | 
								return GetSlug(ShowId.ToString(), SeasonNumber, EpisodeNumber, AbsoluteNumber);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		private set
 | 
							private set
 | 
				
			||||||
@ -301,5 +296,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
			_ => $"{showSlug}-s{seasonNumber}e{episodeNumber}"
 | 
								_ => $"{showSlug}-s{seasonNumber}e{episodeNumber}"
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,16 +18,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An interface applied to resources.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface IAddedDate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An interface applied to resources.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public interface IAddedDate
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The date at which this resource was added to kyoo.
 | 
						/// The date at which this resource was added to kyoo.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public DateTime AddedDate { get; set; }
 | 
						public DateTime AddedDate { get; set; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,16 +18,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An interface applied to resources containing external metadata.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface IMetadata
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An interface applied to resources containing external metadata.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public interface IMetadata
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The link to metadata providers that this show has. See <see cref="MetadataId"/> for more information.
 | 
						/// The link to metadata providers that this show has. See <see cref="MetadataId"/> for more information.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public Dictionary<string, MetadataId> ExternalId { get; set; }
 | 
						public Dictionary<string, MetadataId> ExternalId { get; set; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,13 +20,13 @@ using System;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations;
 | 
					using System.ComponentModel.DataAnnotations;
 | 
				
			||||||
using Kyoo.Abstractions.Controllers;
 | 
					using Kyoo.Abstractions.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An interface to represent a resource that can be retrieved from the database.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface IResource : IQuery
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An interface to represent a resource that can be retrieved from the database.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public interface IResource : IQuery
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// A unique ID for this type of resource. This can't be changed and duplicates are not allowed.
 | 
						/// A unique ID for this type of resource. This can't be changed and duplicates are not allowed.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -46,5 +46,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// </remarks>
 | 
						/// </remarks>
 | 
				
			||||||
	[MaxLength(256)]
 | 
						[MaxLength(256)]
 | 
				
			||||||
	public string Slug { get; }
 | 
						public string Slug { get; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,13 +23,13 @@ using System.Globalization;
 | 
				
			|||||||
using System.Text.Json.Serialization;
 | 
					using System.Text.Json.Serialization;
 | 
				
			||||||
using Kyoo.Abstractions.Models.Attributes;
 | 
					using Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An interface representing items that contains images (like posters, thumbnails, logo, banners...)
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface IThumbnails
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An interface representing items that contains images (like posters, thumbnails, logo, banners...)
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public interface IThumbnails
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// A poster is a 2/3 format image with the cover of the resource.
 | 
						/// A poster is a 2/3 format image with the cover of the resource.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -45,12 +45,12 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// A logo is a small image representing the resource.
 | 
						/// A logo is a small image representing the resource.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public Image? Logo { get; set; }
 | 
						public Image? Logo { get; set; }
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[TypeConverter(typeof(ImageConvertor))]
 | 
					[TypeConverter(typeof(ImageConvertor))]
 | 
				
			||||||
	[SqlFirstColumn(nameof(Source))]
 | 
					[SqlFirstColumn(nameof(Source))]
 | 
				
			||||||
	public class Image
 | 
					public class Image
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The original image from another server.
 | 
						/// The original image from another server.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -94,21 +94,18 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <inheritdoc />
 | 
							/// <inheritdoc />
 | 
				
			||||||
			public override bool CanConvertTo(
 | 
							public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
 | 
				
			||||||
				ITypeDescriptorContext? context,
 | 
					 | 
				
			||||||
				Type? destinationType
 | 
					 | 
				
			||||||
			)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// The quality of an image
 | 
					/// The quality of an image
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	public enum ImageQuality
 | 
					public enum ImageQuality
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Small
 | 
						/// Small
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -123,5 +120,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// Large
 | 
						/// Large
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	High,
 | 
						High,
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,12 +27,12 @@ using Kyoo.Abstractions.Controllers;
 | 
				
			|||||||
using Kyoo.Abstractions.Models.Attributes;
 | 
					using Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// A series or a movie.
 | 
					/// A series or a movie.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	public class Movie
 | 
					public class Movie
 | 
				
			||||||
	: IQuery,
 | 
						: IQuery,
 | 
				
			||||||
		IResource,
 | 
							IResource,
 | 
				
			||||||
		IMetadata,
 | 
							IMetadata,
 | 
				
			||||||
@ -41,7 +41,7 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
		ILibraryItem,
 | 
							ILibraryItem,
 | 
				
			||||||
		INews,
 | 
							INews,
 | 
				
			||||||
		IWatchlist
 | 
							IWatchlist
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	public static Sort DefaultSort => new Sort<Movie>.By(x => x.Name);
 | 
						public static Sort DefaultSort => new Sort<Movie>.By(x => x.Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
@ -185,5 +185,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
			Name = name;
 | 
								Name = name;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,13 +26,13 @@ using EntityFrameworkCore.Projectables;
 | 
				
			|||||||
using Kyoo.Abstractions.Controllers;
 | 
					using Kyoo.Abstractions.Controllers;
 | 
				
			||||||
using Kyoo.Abstractions.Models.Attributes;
 | 
					using Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A season of a <see cref="Show"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Season : IQuery, IResource, IMetadata, IThumbnails, IAddedDate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A season of a <see cref="Show"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class Season : IQuery, IResource, IMetadata, IThumbnails, IAddedDate
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	public static Sort DefaultSort => new Sort<Season>.By(x => x.SeasonNumber);
 | 
						public static Sort DefaultSort => new Sort<Season>.By(x => x.SeasonNumber);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
@ -145,5 +145,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	public int EpisodesCount { get; set; }
 | 
						public int EpisodesCount { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private int _EpisodesCount => Episodes!.Count;
 | 
						private int _EpisodesCount => Episodes!.Count;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,12 +27,12 @@ using Kyoo.Abstractions.Controllers;
 | 
				
			|||||||
using Kyoo.Abstractions.Models.Attributes;
 | 
					using Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// A series or a movie.
 | 
					/// A series or a movie.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	public class Show
 | 
					public class Show
 | 
				
			||||||
	: IQuery,
 | 
						: IQuery,
 | 
				
			||||||
		IResource,
 | 
							IResource,
 | 
				
			||||||
		IMetadata,
 | 
							IMetadata,
 | 
				
			||||||
@ -41,7 +41,7 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
		IAddedDate,
 | 
							IAddedDate,
 | 
				
			||||||
		ILibraryItem,
 | 
							ILibraryItem,
 | 
				
			||||||
		IWatchlist
 | 
							IWatchlist
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	public static Sort DefaultSort => new Sort<Show>.By(x => x.Name);
 | 
						public static Sort DefaultSort => new Sort<Show>.By(x => x.Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
@ -250,13 +250,13 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
			Name = name;
 | 
								Name = name;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// The enum containing show's status.
 | 
					/// The enum containing show's status.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	public enum Status
 | 
					public enum Status
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The status of the show is not known.
 | 
						/// The status of the show is not known.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -276,5 +276,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// This show has not aired yet but has been announced.
 | 
						/// This show has not aired yet but has been announced.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	Planned
 | 
						Planned
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,13 +23,13 @@ using System.Text.Json.Serialization;
 | 
				
			|||||||
using Kyoo.Abstractions.Controllers;
 | 
					using Kyoo.Abstractions.Controllers;
 | 
				
			||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A studio that make shows.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Studio : IQuery, IResource, IMetadata
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A studio that make shows.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class Studio : IQuery, IResource, IMetadata
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	public static Sort DefaultSort => new Sort<Studio>.By(x => x.Name);
 | 
						public static Sort DefaultSort => new Sort<Studio>.By(x => x.Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
@ -77,5 +77,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
			Name = name;
 | 
								Name = name;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,13 +23,13 @@ using System.Text.Json.Serialization;
 | 
				
			|||||||
using Kyoo.Abstractions.Controllers;
 | 
					using Kyoo.Abstractions.Controllers;
 | 
				
			||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A single user of the app.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class User : IQuery, IResource, IAddedDate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A single user of the app.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class User : IQuery, IResource, IAddedDate
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	public static Sort DefaultSort => new Sort<User>.By(x => x.Username);
 | 
						public static Sort DefaultSort => new Sort<User>.By(x => x.Username);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
@ -89,10 +89,10 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
			Username = username;
 | 
								Username = username;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public class ExternalToken
 | 
					public class ExternalToken
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The id of this user on the external service.
 | 
						/// The id of this user on the external service.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -113,5 +113,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// Do not forget to refresh it when using it if necessary.
 | 
						/// Do not forget to refresh it when using it if necessary.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public JwtToken Token { get; set; }
 | 
						public JwtToken Token { get; set; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,13 +20,13 @@ using System;
 | 
				
			|||||||
using System.Text.Json.Serialization;
 | 
					using System.Text.Json.Serialization;
 | 
				
			||||||
using Kyoo.Abstractions.Models.Attributes;
 | 
					using Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Has the user started watching, is it planned?
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum WatchStatus
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Has the user started watching, is it planned?
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public enum WatchStatus
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The user has already watched this.
 | 
						/// The user has already watched this.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -46,14 +46,14 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// The user has not started watching this but plans to.
 | 
						/// The user has not started watching this but plans to.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	Planned,
 | 
						Planned,
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// Metadata of what an user as started/planned to watch.
 | 
					/// Metadata of what an user as started/planned to watch.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	[SqlFirstColumn(nameof(UserId))]
 | 
					[SqlFirstColumn(nameof(UserId))]
 | 
				
			||||||
	public class MovieWatchStatus : IAddedDate
 | 
					public class MovieWatchStatus : IAddedDate
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The ID of the user that started watching this episode.
 | 
						/// The ID of the user that started watching this episode.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -104,11 +104,11 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// Null if the status is not Watching.
 | 
						/// Null if the status is not Watching.
 | 
				
			||||||
	/// </remarks>
 | 
						/// </remarks>
 | 
				
			||||||
	public int? WatchedPercent { get; set; }
 | 
						public int? WatchedPercent { get; set; }
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[SqlFirstColumn(nameof(UserId))]
 | 
					[SqlFirstColumn(nameof(UserId))]
 | 
				
			||||||
	public class EpisodeWatchStatus : IAddedDate
 | 
					public class EpisodeWatchStatus : IAddedDate
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The ID of the user that started watching this episode.
 | 
						/// The ID of the user that started watching this episode.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -159,11 +159,11 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// Null if the status is not Watching or if the next episode is not started.
 | 
						/// Null if the status is not Watching or if the next episode is not started.
 | 
				
			||||||
	/// </remarks>
 | 
						/// </remarks>
 | 
				
			||||||
	public int? WatchedPercent { get; set; }
 | 
						public int? WatchedPercent { get; set; }
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[SqlFirstColumn(nameof(UserId))]
 | 
					[SqlFirstColumn(nameof(UserId))]
 | 
				
			||||||
	public class ShowWatchStatus : IAddedDate
 | 
					public class ShowWatchStatus : IAddedDate
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The ID of the user that started watching this episode.
 | 
						/// The ID of the user that started watching this episode.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -229,5 +229,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// Null if the status is not Watching or if the next episode is not started.
 | 
						/// Null if the status is not Watching or if the next episode is not started.
 | 
				
			||||||
	/// </remarks>
 | 
						/// </remarks>
 | 
				
			||||||
	public int? WatchedPercent { get; set; }
 | 
						public int? WatchedPercent { get; set; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,15 +18,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// Results of a search request.
 | 
					/// Results of a search request.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	/// <typeparam name="T">The search item's type.</typeparam>
 | 
					/// <typeparam name="T">The search item's type.</typeparam>
 | 
				
			||||||
	public class SearchPage<T> : Page<T>
 | 
					public class SearchPage<T> : Page<T>
 | 
				
			||||||
	where T : IResource
 | 
						where T : IResource
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	public SearchPage(
 | 
						public SearchPage(
 | 
				
			||||||
		SearchResult result,
 | 
							SearchResult result,
 | 
				
			||||||
		string @this,
 | 
							string @this,
 | 
				
			||||||
@ -50,5 +50,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		public ICollection<T> Items { get; set; }
 | 
							public ICollection<T> Items { get; set; }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,13 +16,13 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication.Models
 | 
					namespace Kyoo.Authentication.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// List of well known claims of kyoo
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class Claims
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// List of well known claims of kyoo
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class Claims
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The id of the user
 | 
						/// The id of the user
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -52,5 +52,4 @@ namespace Kyoo.Authentication.Models
 | 
				
			|||||||
	/// A guid used to identify a specific refresh token. This is only useful for the server to revokate tokens.
 | 
						/// A guid used to identify a specific refresh token. This is only useful for the server to revokate tokens.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public static string Guid => "guid";
 | 
						public static string Guid => "guid";
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,13 +18,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using Kyoo.Abstractions.Models.Attributes;
 | 
					using Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Utils
 | 
					namespace Kyoo.Abstractions.Models.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A class containing constant numbers.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class Constants
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A class containing constant numbers.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class Constants
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// A property to use on a Microsoft.AspNet.MVC.Route.Order property to mark it as an alternative route
 | 
						/// A property to use on a Microsoft.AspNet.MVC.Route.Order property to mark it as an alternative route
 | 
				
			||||||
	/// that won't be included on the swagger.
 | 
						/// that won't be included on the swagger.
 | 
				
			||||||
@ -56,5 +56,4 @@ namespace Kyoo.Abstractions.Models.Utils
 | 
				
			|||||||
	/// A group name for <see cref="ApiDefinitionAttribute"/>. It should be used for endpoints used by admins.
 | 
						/// A group name for <see cref="ApiDefinitionAttribute"/>. It should be used for endpoints used by admins.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public const string AdminGroup = "4:Admin";
 | 
						public const string AdminGroup = "4:Admin";
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -24,16 +24,16 @@ using System.Linq;
 | 
				
			|||||||
using System.Linq.Expressions;
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Utils
 | 
					namespace Kyoo.Abstractions.Models.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A class that represent a resource. It is made to be used as a parameter in a query and not used somewhere else
 | 
				
			||||||
 | 
					/// on the application.
 | 
				
			||||||
 | 
					/// This class allow routes to be used via ether IDs or Slugs, this is suitable for every <see cref="IResource"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[TypeConverter(typeof(IdentifierConvertor))]
 | 
				
			||||||
 | 
					public class Identifier
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A class that represent a resource. It is made to be used as a parameter in a query and not used somewhere else
 | 
					 | 
				
			||||||
	/// on the application.
 | 
					 | 
				
			||||||
	/// This class allow routes to be used via ether IDs or Slugs, this is suitable for every <see cref="IResource"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[TypeConverter(typeof(IdentifierConvertor))]
 | 
					 | 
				
			||||||
	public class Identifier
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The ID of the resource or null if the slug is specified.
 | 
						/// The ID of the resource or null if the slug is specified.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -162,9 +162,7 @@ namespace Kyoo.Abstractions.Models.Utils
 | 
				
			|||||||
	public Filter<T> IsSame<T>()
 | 
						public Filter<T> IsSame<T>()
 | 
				
			||||||
		where T : IResource
 | 
							where T : IResource
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
			return _id.HasValue
 | 
							return _id.HasValue ? new Filter<T>.Eq("Id", _id.Value) : new Filter<T>.Eq("Slug", _slug!);
 | 
				
			||||||
				? new Filter<T>.Eq("Id", _id.Value)
 | 
					 | 
				
			||||||
				: new Filter<T>.Eq("Slug", _slug!);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public bool Is(Guid uid)
 | 
						public bool Is(Guid uid)
 | 
				
			||||||
@ -244,5 +242,4 @@ namespace Kyoo.Abstractions.Models.Utils
 | 
				
			|||||||
			return Guid.TryParse(slug, out id) ? new Identifier(id) : new Identifier(slug);
 | 
								return Guid.TryParse(slug, out id) ? new Identifier(id) : new Identifier(slug);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,13 +18,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Information about the pagination. How many items should be displayed and where to start.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Pagination
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Information about the pagination. How many items should be displayed and where to start.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class Pagination
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The count of items to return.
 | 
						/// The count of items to return.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -69,5 +69,4 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// <param name="limit">Set the <see cref="Limit"/> value</param>
 | 
						/// <param name="limit">Set the <see cref="Limit"/> value</param>
 | 
				
			||||||
	/// <returns>A new <see cref="Pagination"/> instance</returns>
 | 
						/// <returns>A new <see cref="Pagination"/> instance</returns>
 | 
				
			||||||
	public static implicit operator Pagination(int limit) => new(limit);
 | 
						public static implicit operator Pagination(int limit) => new(limit);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,13 +19,13 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models.Utils
 | 
					namespace Kyoo.Abstractions.Models.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The list of errors that where made in the request.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class RequestError
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The list of errors that where made in the request.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class RequestError
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The list of errors that where made in the request.
 | 
						/// The list of errors that where made in the request.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -50,11 +50,7 @@ namespace Kyoo.Abstractions.Models.Utils
 | 
				
			|||||||
	public RequestError(string[] errors)
 | 
						public RequestError(string[] errors)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (errors == null || !errors.Any())
 | 
							if (errors == null || !errors.Any())
 | 
				
			||||||
				throw new ArgumentException(
 | 
								throw new ArgumentException("Errors must be non null and not empty", nameof(errors));
 | 
				
			||||||
					"Errors must be non null and not empty",
 | 
					 | 
				
			||||||
					nameof(errors)
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
		Errors = errors;
 | 
							Errors = errors;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,13 +16,13 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Information about the pagination. How many items should be displayed and where to start.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class SearchPagination
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Information about the pagination. How many items should be displayed and where to start.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class SearchPagination
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The count of items to return.
 | 
						/// The count of items to return.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -32,5 +32,4 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
	/// Where to start? How many items to skip?
 | 
						/// Where to start? How many items to skip?
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public int? Skip { get; set; }
 | 
						public int? Skip { get; set; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,17 +25,17 @@ using Kyoo.Abstractions.Models;
 | 
				
			|||||||
using Kyoo.Abstractions.Models.Attributes;
 | 
					using Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Controllers
 | 
					namespace Kyoo.Abstractions.Controllers;
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	public record Sort;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					public record Sort;
 | 
				
			||||||
	/// Information about how a query should be sorted. What factor should decide the sort and in which order.
 | 
					
 | 
				
			||||||
	/// </summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// <typeparam name="T">For witch type this sort applies</typeparam>
 | 
					/// Information about how a query should be sorted. What factor should decide the sort and in which order.
 | 
				
			||||||
	public record Sort<T> : Sort
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <typeparam name="T">For witch type this sort applies</typeparam>
 | 
				
			||||||
 | 
					public record Sort<T> : Sort
 | 
				
			||||||
	where T : IQuery
 | 
						where T : IQuery
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Sort by a specific key
 | 
						/// Sort by a specific key
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -117,8 +117,7 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
				)
 | 
									)
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Type[] types =
 | 
							Type[] types = typeof(T).GetCustomAttribute<OneOfAttribute>()?.Types ?? new[] { typeof(T) };
 | 
				
			||||||
				typeof(T).GetCustomAttribute<OneOfAttribute>()?.Types ?? new[] { typeof(T) };
 | 
					 | 
				
			||||||
		PropertyInfo? property = types
 | 
							PropertyInfo? property = types
 | 
				
			||||||
			.Select(x =>
 | 
								.Select(x =>
 | 
				
			||||||
				x.GetProperty(
 | 
									x.GetProperty(
 | 
				
			||||||
@ -131,5 +130,4 @@ namespace Kyoo.Abstractions.Controllers
 | 
				
			|||||||
			throw new ValidationException("The given sort key is not valid.");
 | 
								throw new ValidationException("The given sort key is not valid.");
 | 
				
			||||||
		return new By(property.Name, desendant);
 | 
							return new By(property.Name, desendant);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,13 +16,13 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions.Models
 | 
					namespace Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The links to see a movie or an episode.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class VideoLinks
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The links to see a movie or an episode.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class VideoLinks
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The direct link to the unprocessed video (pristine quality).
 | 
						/// The direct link to the unprocessed video (pristine quality).
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -32,5 +32,4 @@ namespace Kyoo.Abstractions.Models
 | 
				
			|||||||
	/// The link to an HLS master playlist containing all qualities available for this video.
 | 
						/// The link to an HLS master playlist containing all qualities available for this video.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public string Hls { get; set; }
 | 
						public string Hls { get; set; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,13 +21,13 @@ using Autofac.Builder;
 | 
				
			|||||||
using Kyoo.Abstractions.Controllers;
 | 
					using Kyoo.Abstractions.Controllers;
 | 
				
			||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Abstractions
 | 
					namespace Kyoo.Abstractions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A static class with helper functions to setup external modules
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class Module
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A static class with helper functions to setup external modules
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class Module
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Register a new repository to the container.
 | 
						/// Register a new repository to the container.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -72,5 +72,4 @@ namespace Kyoo.Abstractions
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		return builder.RegisterRepository<T2>().AsSelf().As<T>();
 | 
							return builder.RegisterRepository<T2>().AsSelf().As<T>();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,13 +19,13 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Utils
 | 
					namespace Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A set of extensions class for enumerable.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class EnumerableExtensions
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A set of extensions class for enumerable.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class EnumerableExtensions
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// If the enumerable is empty, execute an action.
 | 
						/// If the enumerable is empty, execute an action.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -67,5 +67,4 @@ namespace Kyoo.Utils
 | 
				
			|||||||
		foreach (T i in self)
 | 
							foreach (T i in self)
 | 
				
			||||||
			action(i);
 | 
								action(i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,13 +22,13 @@ using System.Linq;
 | 
				
			|||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
using Kyoo.Abstractions.Models.Attributes;
 | 
					using Kyoo.Abstractions.Models.Attributes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Utils
 | 
					namespace Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A class containing helper methods to merge objects.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class Merger
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A class containing helper methods to merge objects.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class Merger
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Merge two dictionary, if the same key is found on both dictionary, the values of the second one is kept.
 | 
						/// Merge two dictionary, if the same key is found on both dictionary, the values of the second one is kept.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -130,5 +130,4 @@ namespace Kyoo.Utils
 | 
				
			|||||||
			merge.OnMerge(second);
 | 
								merge.OnMerge(second);
 | 
				
			||||||
		return first;
 | 
							return first;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,13 +25,13 @@ using System.Reflection;
 | 
				
			|||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Utils
 | 
					namespace Kyoo.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A set of utility functions that can be used everywhere.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class Utility
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A set of utility functions that can be used everywhere.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class Utility
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Convert a string to snake case. Stollen from
 | 
						/// Convert a string to snake case. Stollen from
 | 
				
			||||||
	/// https://github.com/efcore/EFCore.NamingConventions/blob/main/EFCore.NamingConventions/Internal/SnakeCaseNameRewriter.cs
 | 
						/// https://github.com/efcore/EFCore.NamingConventions/blob/main/EFCore.NamingConventions/Internal/SnakeCaseNameRewriter.cs
 | 
				
			||||||
@ -204,9 +204,7 @@ namespace Kyoo.Utils
 | 
				
			|||||||
			: type.GetInheritanceTree();
 | 
								: type.GetInheritanceTree();
 | 
				
			||||||
		return types
 | 
							return types
 | 
				
			||||||
			.Prepend(type)
 | 
								.Prepend(type)
 | 
				
			||||||
				.FirstOrDefault(x =>
 | 
								.FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType);
 | 
				
			||||||
					x.IsGenericType && x.GetGenericTypeDefinition() == genericType
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
@ -361,5 +359,4 @@ namespace Kyoo.Utils
 | 
				
			|||||||
			return string.Empty;
 | 
								return string.Empty;
 | 
				
			||||||
		return "?" + string.Join('&', query.Select(x => $"{x.Key}={x.Value}"));
 | 
							return "?" + string.Join('&', query.Select(x => $"{x.Key}={x.Value}"));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -32,19 +32,19 @@ using Microsoft.Extensions.Logging;
 | 
				
			|||||||
using Microsoft.Extensions.Primitives;
 | 
					using Microsoft.Extensions.Primitives;
 | 
				
			||||||
using Microsoft.IdentityModel.Tokens;
 | 
					using Microsoft.IdentityModel.Tokens;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication
 | 
					namespace Kyoo.Authentication;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// A module that enable OpenID authentication for Kyoo.
 | 
					/// A module that enable OpenID authentication for Kyoo.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	/// <remarks>
 | 
					/// <remarks>
 | 
				
			||||||
	/// Create a new authentication module instance and use the given configuration.
 | 
					/// Create a new authentication module instance and use the given configuration.
 | 
				
			||||||
	/// </remarks>
 | 
					/// </remarks>
 | 
				
			||||||
	public class AuthenticationModule(
 | 
					public class AuthenticationModule(
 | 
				
			||||||
	IConfiguration configuration,
 | 
						IConfiguration configuration,
 | 
				
			||||||
	ILogger<AuthenticationModule> logger
 | 
						ILogger<AuthenticationModule> logger
 | 
				
			||||||
	) : IPlugin
 | 
					) : IPlugin
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public string Name => "Authentication";
 | 
						public string Name => "Authentication";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,10 +78,7 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
				NewUser = _configuration
 | 
									NewUser = _configuration
 | 
				
			||||||
					.GetValue("DEFAULT_PERMISSIONS", "overall.read,overall.play")!
 | 
										.GetValue("DEFAULT_PERMISSIONS", "overall.read,overall.play")!
 | 
				
			||||||
					.Split(','),
 | 
										.Split(','),
 | 
				
			||||||
					RequireVerification = _configuration.GetValue(
 | 
									RequireVerification = _configuration.GetValue("REQUIRE_ACCOUNT_VERIFICATION", true),
 | 
				
			||||||
						"REQUIRE_ACCOUNT_VERIFICATION",
 | 
					 | 
				
			||||||
						true
 | 
					 | 
				
			||||||
					),
 | 
					 | 
				
			||||||
				PublicUrl =
 | 
									PublicUrl =
 | 
				
			||||||
					_configuration.GetValue<string?>("PUBLIC_URL") ?? "http://localhost:8901",
 | 
										_configuration.GetValue<string?>("PUBLIC_URL") ?? "http://localhost:8901",
 | 
				
			||||||
				ApiKeys = _configuration.GetValue("KYOO_APIKEYS", string.Empty)!.Split(','),
 | 
									ApiKeys = _configuration.GetValue("KYOO_APIKEYS", string.Empty)!.Split(','),
 | 
				
			||||||
@ -154,10 +151,7 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
					{
 | 
										{
 | 
				
			||||||
						string prefix = "Bearer ";
 | 
											string prefix = "Bearer ";
 | 
				
			||||||
						if (
 | 
											if (
 | 
				
			||||||
								ctx.Request.Headers.TryGetValue(
 | 
												ctx.Request.Headers.TryGetValue("Authorization", out StringValues val)
 | 
				
			||||||
									"Authorization",
 | 
					 | 
				
			||||||
									out StringValues val
 | 
					 | 
				
			||||||
								)
 | 
					 | 
				
			||||||
							&& val.ToString() is string auth
 | 
												&& val.ToString() is string auth
 | 
				
			||||||
							&& auth.StartsWith(prefix)
 | 
												&& auth.StartsWith(prefix)
 | 
				
			||||||
						)
 | 
											)
 | 
				
			||||||
@ -185,5 +179,4 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			SA.New<IApplicationBuilder>(app => app.UseAuthentication(), SA.Authentication),
 | 
								SA.New<IApplicationBuilder>(app => app.UseAuthentication(), SA.Authentication),
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,13 +21,13 @@ using System.Threading.Tasks;
 | 
				
			|||||||
using Kyoo.Abstractions.Models;
 | 
					using Kyoo.Abstractions.Models;
 | 
				
			||||||
using Microsoft.IdentityModel.Tokens;
 | 
					using Microsoft.IdentityModel.Tokens;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication
 | 
					namespace Kyoo.Authentication;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The service that controls jwt creation and validation.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public interface ITokenController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The service that controls jwt creation and validation.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public interface ITokenController
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Create a new access token for the given user.
 | 
						/// Create a new access token for the given user.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -50,5 +50,4 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
	/// <exception cref="SecurityTokenException">The given refresh token is not valid.</exception>
 | 
						/// <exception cref="SecurityTokenException">The given refresh token is not valid.</exception>
 | 
				
			||||||
	/// <returns>The id of the token's user.</returns>
 | 
						/// <returns>The id of the token's user.</returns>
 | 
				
			||||||
	Guid GetRefreshTokenUserID(string refreshToken);
 | 
						Guid GetRefreshTokenUserID(string refreshToken);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -32,14 +32,14 @@ using Microsoft.AspNetCore.Mvc;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc.Filters;
 | 
					using Microsoft.AspNetCore.Mvc.Filters;
 | 
				
			||||||
using Microsoft.Extensions.Primitives;
 | 
					using Microsoft.Extensions.Primitives;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication
 | 
					namespace Kyoo.Authentication;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A permission validator to validate permission with user Permission array
 | 
				
			||||||
 | 
					/// or the default array from the configurations if the user is not logged.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class PermissionValidator : IPermissionValidator
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A permission validator to validate permission with user Permission array
 | 
					 | 
				
			||||||
	/// or the default array from the configurations if the user is not logged.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class PermissionValidator : IPermissionValidator
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The permissions options to retrieve default permissions.
 | 
						/// The permissions options to retrieve default permissions.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -126,11 +126,7 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
		/// <param name="partialInfo">The partial permission to validate.</param>
 | 
							/// <param name="partialInfo">The partial permission to validate.</param>
 | 
				
			||||||
		/// <param name="group">The group of the permission.</param>
 | 
							/// <param name="group">The group of the permission.</param>
 | 
				
			||||||
		/// <param name="options">The option containing default values.</param>
 | 
							/// <param name="options">The option containing default values.</param>
 | 
				
			||||||
			public PermissionValidatorFilter(
 | 
							public PermissionValidatorFilter(object partialInfo, Group? group, PermissionOption options)
 | 
				
			||||||
				object partialInfo,
 | 
					 | 
				
			||||||
				Group? group,
 | 
					 | 
				
			||||||
				PermissionOption options
 | 
					 | 
				
			||||||
			)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			switch (partialInfo)
 | 
								switch (partialInfo)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@ -159,11 +155,7 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			if (permission == null || kind == null)
 | 
								if (permission == null || kind == null)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
					if (
 | 
									if (context.HttpContext.Items["PermissionGroup"] is Group group and not Group.None)
 | 
				
			||||||
						context.HttpContext.Items["PermissionGroup"]
 | 
					 | 
				
			||||||
						is Group group
 | 
					 | 
				
			||||||
							and not Group.None
 | 
					 | 
				
			||||||
					)
 | 
					 | 
				
			||||||
					_group = group;
 | 
										_group = group;
 | 
				
			||||||
				else if (_group == Group.None)
 | 
									else if (_group == Group.None)
 | 
				
			||||||
					_group = Group.Overall;
 | 
										_group = Group.Overall;
 | 
				
			||||||
@ -226,10 +218,7 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else if (res.Failure != null)
 | 
								else if (res.Failure != null)
 | 
				
			||||||
					context.Result = _ErrorResult(
 | 
									context.Result = _ErrorResult(res.Failure.Message, StatusCodes.Status403Forbidden);
 | 
				
			||||||
						res.Failure.Message,
 | 
					 | 
				
			||||||
						StatusCodes.Status403Forbidden
 | 
					 | 
				
			||||||
					);
 | 
					 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				context.Result = _ErrorResult(
 | 
									context.Result = _ErrorResult(
 | 
				
			||||||
					"Authentication panic",
 | 
										"Authentication panic",
 | 
				
			||||||
@ -277,9 +266,7 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
			);
 | 
								);
 | 
				
			||||||
			// Change the failure message to make the API nice to use.
 | 
								// Change the failure message to make the API nice to use.
 | 
				
			||||||
			if (ret.Failure != null)
 | 
								if (ret.Failure != null)
 | 
				
			||||||
					return AuthenticateResult.Fail(
 | 
									return AuthenticateResult.Fail("Invalid JWT token. The token may have expired.");
 | 
				
			||||||
						"Invalid JWT token. The token may have expired."
 | 
					 | 
				
			||||||
					);
 | 
					 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -294,5 +281,4 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		return new ObjectResult(new RequestError(error)) { StatusCode = code };
 | 
							return new ObjectResult(new RequestError(error)) { StatusCode = code };
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,13 +27,13 @@ using Kyoo.Abstractions.Models;
 | 
				
			|||||||
using Kyoo.Authentication.Models;
 | 
					using Kyoo.Authentication.Models;
 | 
				
			||||||
using Microsoft.IdentityModel.Tokens;
 | 
					using Microsoft.IdentityModel.Tokens;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication
 | 
					namespace Kyoo.Authentication;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The service that controls jwt creation and validation.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class TokenController : ITokenController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The service that controls jwt creation and validation.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class TokenController : ITokenController
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The options that this controller will use.
 | 
						/// The options that this controller will use.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -131,5 +131,4 @@ namespace Kyoo.Authentication
 | 
				
			|||||||
			return id;
 | 
								return id;
 | 
				
			||||||
		throw new SecurityTokenException("Token not associated to any user.");
 | 
							throw new SecurityTokenException("Token not associated to any user.");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,13 +16,13 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication.Models.DTO
 | 
					namespace Kyoo.Authentication.Models.DTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A model only used on login requests.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class LoginRequest
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A model only used on login requests.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class LoginRequest
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The user's username.
 | 
						/// The user's username.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -43,5 +43,4 @@ namespace Kyoo.Authentication.Models.DTO
 | 
				
			|||||||
		Username = username;
 | 
							Username = username;
 | 
				
			||||||
		Password = password;
 | 
							Password = password;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,13 +21,13 @@ using Kyoo.Abstractions.Models;
 | 
				
			|||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
using BCryptNet = BCrypt.Net.BCrypt;
 | 
					using BCryptNet = BCrypt.Net.BCrypt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication.Models.DTO
 | 
					namespace Kyoo.Authentication.Models.DTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A model only used on register requests.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class RegisterRequest
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A model only used on register requests.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class RegisterRequest
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The user email address
 | 
						/// The user email address
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -73,5 +73,4 @@ namespace Kyoo.Authentication.Models.DTO
 | 
				
			|||||||
			Email = Email,
 | 
								Email = Email,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,13 +16,13 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication.Models
 | 
					namespace Kyoo.Authentication.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The main authentication options.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class AuthenticationOption
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The main authentication options.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class AuthenticationOption
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The path to get this option from the root configuration.
 | 
						/// The path to get this option from the root configuration.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -42,5 +42,4 @@ namespace Kyoo.Authentication.Models
 | 
				
			|||||||
	/// Options for permissions
 | 
						/// Options for permissions
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public PermissionOption Permissions { get; set; } = new();
 | 
						public PermissionOption Permissions { get; set; } = new();
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -35,22 +35,22 @@ using Microsoft.IdentityModel.Tokens;
 | 
				
			|||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
using BCryptNet = BCrypt.Net.BCrypt;
 | 
					using BCryptNet = BCrypt.Net.BCrypt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Authentication.Views
 | 
					namespace Kyoo.Authentication.Views;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// Sign in, Sign up or refresh tokens.
 | 
					/// Sign in, Sign up or refresh tokens.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	[ApiController]
 | 
					[ApiController]
 | 
				
			||||||
	[Route("auth")]
 | 
					[Route("auth")]
 | 
				
			||||||
	[ApiDefinition("Authentication", Group = UsersGroup)]
 | 
					[ApiDefinition("Authentication", Group = UsersGroup)]
 | 
				
			||||||
	public class AuthApi(
 | 
					public class AuthApi(
 | 
				
			||||||
	IUserRepository users,
 | 
						IUserRepository users,
 | 
				
			||||||
	OidcController oidc,
 | 
						OidcController oidc,
 | 
				
			||||||
	ITokenController tokenController,
 | 
						ITokenController tokenController,
 | 
				
			||||||
	IThumbnailsManager thumbs,
 | 
						IThumbnailsManager thumbs,
 | 
				
			||||||
	PermissionOption options
 | 
						PermissionOption options
 | 
				
			||||||
	) : ControllerBase
 | 
					) : ControllerBase
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Create a new Forbidden result from an object.
 | 
						/// Create a new Forbidden result from an object.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -127,12 +127,7 @@ namespace Kyoo.Authentication.Views
 | 
				
			|||||||
	/// <response code="403">The provider gave an error.</response>
 | 
						/// <response code="403">The provider gave an error.</response>
 | 
				
			||||||
	[HttpGet("logged/{provider}")]
 | 
						[HttpGet("logged/{provider}")]
 | 
				
			||||||
	[ProducesResponseType(StatusCodes.Status302Found)]
 | 
						[ProducesResponseType(StatusCodes.Status302Found)]
 | 
				
			||||||
		public ActionResult OauthCodeRedirect(
 | 
						public ActionResult OauthCodeRedirect(string provider, string code, string state, string? error)
 | 
				
			||||||
			string provider,
 | 
					 | 
				
			||||||
			string code,
 | 
					 | 
				
			||||||
			string state,
 | 
					 | 
				
			||||||
			string? error
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return Redirect(
 | 
							return Redirect(
 | 
				
			||||||
			_BuildUrl(
 | 
								_BuildUrl(
 | 
				
			||||||
@ -494,5 +489,4 @@ namespace Kyoo.Authentication.Views
 | 
				
			|||||||
		await thumbs.SetUserImage(User.GetIdOrThrow(), null);
 | 
							await thumbs.SetUserImage(User.GetIdOrThrow(), null);
 | 
				
			||||||
		return NoContent();
 | 
							return NoContent();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,13 +20,13 @@ using Kyoo.Abstractions.Models.Utils;
 | 
				
			|||||||
using Microsoft.AspNetCore.Http;
 | 
					using Microsoft.AspNetCore.Http;
 | 
				
			||||||
using Microsoft.AspNetCore.Routing;
 | 
					using Microsoft.AspNetCore.Routing;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The route constraint that goes with the <see cref="Identifier"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class IdentifierRouteConstraint : IRouteConstraint
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The route constraint that goes with the <see cref="Identifier"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class IdentifierRouteConstraint : IRouteConstraint
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public bool Match(
 | 
						public bool Match(
 | 
				
			||||||
		HttpContext? httpContext,
 | 
							HttpContext? httpContext,
 | 
				
			||||||
@ -38,5 +38,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		return values.ContainsKey(routeKey);
 | 
							return values.ContainsKey(routeKey);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,13 +20,13 @@ using System.Linq;
 | 
				
			|||||||
using Kyoo.Abstractions.Controllers;
 | 
					using Kyoo.Abstractions.Controllers;
 | 
				
			||||||
using Kyoo.Abstractions.Models;
 | 
					using Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An class to interact with the database. Every repository is mapped through here.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class LibraryManager : ILibraryManager
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An class to interact with the database. Every repository is mapped through here.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class LibraryManager : ILibraryManager
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	private readonly IBaseRepository[] _repositories;
 | 
						private readonly IBaseRepository[] _repositories;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public LibraryManager(
 | 
						public LibraryManager(
 | 
				
			||||||
@ -102,5 +102,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		return (IRepository<T>)_repositories.First(x => x.RepositoryType == typeof(T));
 | 
							return (IRepository<T>)_repositories.First(x => x.RepositoryType == typeof(T));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,13 +26,13 @@ using Kyoo.Abstractions.Models.Utils;
 | 
				
			|||||||
using Kyoo.Postgresql;
 | 
					using Kyoo.Postgresql;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A local repository to handle collections
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class CollectionRepository : LocalRepository<Collection>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A local repository to handle collections
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class CollectionRepository : LocalRepository<Collection>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The database handle
 | 
						/// The database handle
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -99,5 +99,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		await _database.SaveChangesAsync();
 | 
							await _database.SaveChangesAsync();
 | 
				
			||||||
		await base.Delete(obj);
 | 
							await base.Delete(obj);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,13 +27,13 @@ using Kyoo.Postgresql;
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using Microsoft.Extensions.DependencyInjection;
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A local repository to handle episodes.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class EpisodeRepository : LocalRepository<Episode>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A local repository to handle episodes.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class EpisodeRepository : LocalRepository<Episode>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The database handle
 | 
						/// The database handle
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -47,8 +47,7 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		IRepository<Show>.OnEdited += async (show) =>
 | 
							IRepository<Show>.OnEdited += async (show) =>
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			await using AsyncServiceScope scope = CoreModule.Services.CreateAsyncScope();
 | 
								await using AsyncServiceScope scope = CoreModule.Services.CreateAsyncScope();
 | 
				
			||||||
				DatabaseContext database =
 | 
								DatabaseContext database = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
 | 
				
			||||||
					scope.ServiceProvider.GetRequiredService<DatabaseContext>();
 | 
					 | 
				
			||||||
			List<Episode> episodes = await database
 | 
								List<Episode> episodes = await database
 | 
				
			||||||
				.Episodes.AsTracking()
 | 
									.Episodes.AsTracking()
 | 
				
			||||||
				.Where(x => x.ShowId == show.Id)
 | 
									.Where(x => x.ShowId == show.Id)
 | 
				
			||||||
@ -152,5 +151,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		if (epCount == 1)
 | 
							if (epCount == 1)
 | 
				
			||||||
			await _shows.Delete(obj.ShowId);
 | 
								await _shows.Delete(obj.ShowId);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,13 +25,13 @@ using Kyoo.Abstractions.Controllers;
 | 
				
			|||||||
using Kyoo.Abstractions.Models;
 | 
					using Kyoo.Abstractions.Models;
 | 
				
			||||||
using Kyoo.Abstractions.Models.Utils;
 | 
					using Kyoo.Abstractions.Models.Utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A local repository to handle library items.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class LibraryItemRepository : DapperRepository<ILibraryItem>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A local repository to handle library items.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class LibraryItemRepository : DapperRepository<ILibraryItem>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	// language=PostgreSQL
 | 
						// language=PostgreSQL
 | 
				
			||||||
	protected override FormattableString Sql =>
 | 
						protected override FormattableString Sql =>
 | 
				
			||||||
		$"""
 | 
							$"""
 | 
				
			||||||
@ -123,5 +123,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
			limit ?? new()
 | 
								limit ?? new()
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -32,15 +32,15 @@ using Kyoo.Postgresql;
 | 
				
			|||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// A base class to create repositories using Entity Framework.
 | 
					/// A base class to create repositories using Entity Framework.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	/// <typeparam name="T">The type of this repository</typeparam>
 | 
					/// <typeparam name="T">The type of this repository</typeparam>
 | 
				
			||||||
	public abstract class LocalRepository<T> : IRepository<T>
 | 
					public abstract class LocalRepository<T> : IRepository<T>
 | 
				
			||||||
	where T : class, IResource, IQuery
 | 
						where T : class, IResource, IQuery
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The Entity Framework's Database handle.
 | 
						/// The Entity Framework's Database handle.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -170,9 +170,7 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		T? ret = await GetOrDefault(filter, include, sortBy, reverse, afterId);
 | 
							T? ret = await GetOrDefault(filter, include, sortBy, reverse, afterId);
 | 
				
			||||||
		if (ret == null)
 | 
							if (ret == null)
 | 
				
			||||||
				throw new ItemNotFoundException(
 | 
								throw new ItemNotFoundException($"No {typeof(T).Name} found with the given predicate.");
 | 
				
			||||||
					$"No {typeof(T).Name} found with the given predicate."
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -244,13 +242,7 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		Pagination? limit = default
 | 
							Pagination? limit = default
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
			IQueryable<T> query = await ApplyFilters(
 | 
							IQueryable<T> query = await ApplyFilters(Database.Set<T>(), filter, sort, limit, include);
 | 
				
			||||||
				Database.Set<T>(),
 | 
					 | 
				
			||||||
				filter,
 | 
					 | 
				
			||||||
				sort,
 | 
					 | 
				
			||||||
				limit,
 | 
					 | 
				
			||||||
				include
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
		return await query.ToListAsync();
 | 
							return await query.ToListAsync();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -435,9 +427,8 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
	protected virtual Task Validate(T resource)
 | 
						protected virtual Task Validate(T resource)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (
 | 
							if (
 | 
				
			||||||
				typeof(T)
 | 
								typeof(T).GetProperty(nameof(resource.Slug))!.GetCustomAttribute<ComputedAttribute>()
 | 
				
			||||||
					.GetProperty(nameof(resource.Slug))!
 | 
								!= null
 | 
				
			||||||
					.GetCustomAttribute<ComputedAttribute>() != null
 | 
					 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
			return Task.CompletedTask;
 | 
								return Task.CompletedTask;
 | 
				
			||||||
		if (string.IsNullOrEmpty(resource.Slug))
 | 
							if (string.IsNullOrEmpty(resource.Slug))
 | 
				
			||||||
@ -446,9 +437,7 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			try
 | 
								try
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
					MethodInfo? setter = typeof(T)
 | 
									MethodInfo? setter = typeof(T).GetProperty(nameof(resource.Slug))!.GetSetMethod();
 | 
				
			||||||
						.GetProperty(nameof(resource.Slug))!
 | 
					 | 
				
			||||||
						.GetSetMethod();
 | 
					 | 
				
			||||||
				if (setter != null)
 | 
									if (setter != null)
 | 
				
			||||||
					setter.Invoke(resource, new object[] { resource.Slug + '!' });
 | 
										setter.Invoke(resource, new object[] { resource.Slug + '!' });
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
@ -495,5 +484,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		foreach (T resource in await GetAll(filter))
 | 
							foreach (T resource in await GetAll(filter))
 | 
				
			||||||
			await Delete(resource);
 | 
								await Delete(resource);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,13 +25,13 @@ using Kyoo.Abstractions.Models.Utils;
 | 
				
			|||||||
using Kyoo.Postgresql;
 | 
					using Kyoo.Postgresql;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A local repository to handle shows
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class MovieRepository : LocalRepository<Movie>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A local repository to handle shows
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class MovieRepository : LocalRepository<Movie>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The database handle
 | 
						/// The database handle
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -105,5 +105,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		await _database.SaveChangesAsync();
 | 
							await _database.SaveChangesAsync();
 | 
				
			||||||
		await base.Delete(obj);
 | 
							await base.Delete(obj);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,13 +22,13 @@ using System.Data.Common;
 | 
				
			|||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
using Kyoo.Abstractions.Models;
 | 
					using Kyoo.Abstractions.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A local repository to handle shows
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class NewsRepository : DapperRepository<INews>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A local repository to handle shows
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class NewsRepository : DapperRepository<INews>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	// language=PostgreSQL
 | 
						// language=PostgreSQL
 | 
				
			||||||
	protected override FormattableString Sql =>
 | 
						protected override FormattableString Sql =>
 | 
				
			||||||
		$"""
 | 
							$"""
 | 
				
			||||||
@ -60,5 +60,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	public NewsRepository(DbConnection database, SqlVariableContext context)
 | 
						public NewsRepository(DbConnection database, SqlVariableContext context)
 | 
				
			||||||
		: base(database, context) { }
 | 
							: base(database, context) { }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -29,13 +29,13 @@ using Kyoo.Postgresql;
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using Microsoft.Extensions.DependencyInjection;
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A local repository to handle seasons.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class SeasonRepository : LocalRepository<Season>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A local repository to handle seasons.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class SeasonRepository : LocalRepository<Season>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The database handle
 | 
						/// The database handle
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -47,8 +47,7 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		IRepository<Show>.OnEdited += async (show) =>
 | 
							IRepository<Show>.OnEdited += async (show) =>
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			await using AsyncServiceScope scope = CoreModule.Services.CreateAsyncScope();
 | 
								await using AsyncServiceScope scope = CoreModule.Services.CreateAsyncScope();
 | 
				
			||||||
				DatabaseContext database =
 | 
								DatabaseContext database = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
 | 
				
			||||||
					scope.ServiceProvider.GetRequiredService<DatabaseContext>();
 | 
					 | 
				
			||||||
			List<Season> seasons = await database
 | 
								List<Season> seasons = await database
 | 
				
			||||||
				.Seasons.AsTracking()
 | 
									.Seasons.AsTracking()
 | 
				
			||||||
				.Where(x => x.ShowId == show.Id)
 | 
									.Where(x => x.ShowId == show.Id)
 | 
				
			||||||
@ -129,5 +128,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		await _database.SaveChangesAsync();
 | 
							await _database.SaveChangesAsync();
 | 
				
			||||||
		await base.Delete(obj);
 | 
							await base.Delete(obj);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,13 +26,13 @@ using Kyoo.Postgresql;
 | 
				
			|||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A local repository to handle shows
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class ShowRepository : LocalRepository<Show>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A local repository to handle shows
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class ShowRepository : LocalRepository<Show>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The database handle
 | 
						/// The database handle
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -106,5 +106,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		await _database.SaveChangesAsync();
 | 
							await _database.SaveChangesAsync();
 | 
				
			||||||
		await base.Delete(obj);
 | 
							await base.Delete(obj);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,13 +26,13 @@ using Kyoo.Postgresql;
 | 
				
			|||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A local repository to handle studios
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class StudioRepository : LocalRepository<Studio>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A local repository to handle studios
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class StudioRepository : LocalRepository<Studio>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The database handle
 | 
						/// The database handle
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -78,5 +78,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		await _database.SaveChangesAsync();
 | 
							await _database.SaveChangesAsync();
 | 
				
			||||||
		await base.Delete(obj);
 | 
							await base.Delete(obj);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -31,19 +31,18 @@ using Kyoo.Abstractions.Models.Exceptions;
 | 
				
			|||||||
using Microsoft.Extensions.Logging;
 | 
					using Microsoft.Extensions.Logging;
 | 
				
			||||||
using SkiaSharp;
 | 
					using SkiaSharp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Controllers
 | 
					namespace Kyoo.Core.Controllers;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// Download images and retrieve the path of those images for a resource.
 | 
					/// Download images and retrieve the path of those images for a resource.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	public class ThumbnailsManager(
 | 
					public class ThumbnailsManager(
 | 
				
			||||||
	IHttpClientFactory clientFactory,
 | 
						IHttpClientFactory clientFactory,
 | 
				
			||||||
	ILogger<ThumbnailsManager> logger,
 | 
						ILogger<ThumbnailsManager> logger,
 | 
				
			||||||
	Lazy<IRepository<User>> users
 | 
						Lazy<IRepository<User>> users
 | 
				
			||||||
	) : IThumbnailsManager
 | 
					) : IThumbnailsManager
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
		private static readonly Dictionary<string, TaskCompletionSource<object>> _downloading =
 | 
						private static readonly Dictionary<string, TaskCompletionSource<object>> _downloading = new();
 | 
				
			||||||
			new();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static async Task _WriteTo(SKBitmap bitmap, string path, int quality)
 | 
						private static async Task _WriteTo(SKBitmap bitmap, string path, int quality)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -264,5 +263,4 @@ namespace Kyoo.Core.Controllers
 | 
				
			|||||||
		Directory.CreateDirectory("/metadata/user");
 | 
							Directory.CreateDirectory("/metadata/user");
 | 
				
			||||||
		await _WriteTo(ret, $"/metadata/user/{userId}.webp", 75);
 | 
							await _WriteTo(ret, $"/metadata/user/{userId}.webp", 75);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,13 +33,13 @@ using Microsoft.AspNetCore.Mvc;
 | 
				
			|||||||
using Microsoft.AspNetCore.Routing;
 | 
					using Microsoft.AspNetCore.Routing;
 | 
				
			||||||
using Microsoft.Extensions.DependencyInjection;
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core
 | 
					namespace Kyoo.Core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The core module containing default implementations
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class CoreModule : IPlugin
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The core module containing default implementations
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class CoreModule : IPlugin
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// A service provider to access services in static context (in events for example).
 | 
						/// A service provider to access services in static context (in events for example).
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -144,5 +144,4 @@ namespace Kyoo.Core
 | 
				
			|||||||
				SA.Endpoint
 | 
									SA.Endpoint
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,17 +25,17 @@ using Microsoft.AspNetCore.Mvc;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc.Filters;
 | 
					using Microsoft.AspNetCore.Mvc.Filters;
 | 
				
			||||||
using Microsoft.Extensions.Logging;
 | 
					using Microsoft.Extensions.Logging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core
 | 
					namespace Kyoo.Core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A middleware to handle errors globally.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <remarks>
 | 
				
			||||||
 | 
					/// Initializes a new instance of the <see cref="ExceptionFilter"/> class.
 | 
				
			||||||
 | 
					/// </remarks>
 | 
				
			||||||
 | 
					/// <param name="logger">The logger used to log errors.</param>
 | 
				
			||||||
 | 
					public class ExceptionFilter(ILogger<ExceptionFilter> logger) : IExceptionFilter
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A middleware to handle errors globally.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	/// <remarks>
 | 
					 | 
				
			||||||
	/// Initializes a new instance of the <see cref="ExceptionFilter"/> class.
 | 
					 | 
				
			||||||
	/// </remarks>
 | 
					 | 
				
			||||||
	/// <param name="logger">The logger used to log errors.</param>
 | 
					 | 
				
			||||||
	public class ExceptionFilter(ILogger<ExceptionFilter> logger) : IExceptionFilter
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <inheritdoc/>
 | 
						/// <inheritdoc/>
 | 
				
			||||||
	public void OnException(ExceptionContext context)
 | 
						public void OnException(ExceptionContext context)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -79,5 +79,4 @@ namespace Kyoo.Core
 | 
				
			|||||||
			StatusCode = StatusCodes.Status500InternalServerError;
 | 
								StatusCode = StatusCodes.Status500InternalServerError;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,16 +22,16 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
 | 
					using Microsoft.Extensions.Diagnostics.HealthChecks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An API endpoint to check the health.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Route("health")]
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[ApiDefinition("Health")]
 | 
				
			||||||
 | 
					public class Health : BaseApi
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An API endpoint to check the health.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Route("health")]
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[ApiDefinition("Health")]
 | 
					 | 
				
			||||||
	public class Health : BaseApi
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	private readonly HealthCheckService _healthCheckService;
 | 
						private readonly HealthCheckService _healthCheckService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
@ -71,5 +71,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
	/// The result of a health operation.
 | 
						/// The result of a health operation.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public record HealthResult(string Status);
 | 
						public record HealthResult(string Status);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,13 +25,13 @@ using Kyoo.Abstractions.Models;
 | 
				
			|||||||
using Kyoo.Utils;
 | 
					using Kyoo.Utils;
 | 
				
			||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A common API containing custom methods to help inheritors.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public abstract class BaseApi : ControllerBase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A common API containing custom methods to help inheritors.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public abstract class BaseApi : ControllerBase
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Construct and return a page from an api.
 | 
						/// Construct and return a page from an api.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -96,5 +96,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return new SearchPage<TResult>(result, self, previous, next, first);
 | 
							return new SearchPage<TResult>(result, self, previous, next, first);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,16 +27,16 @@ using Kyoo.Models;
 | 
				
			|||||||
using Microsoft.AspNetCore.Http;
 | 
					using Microsoft.AspNetCore.Http;
 | 
				
			||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// A base class to handle CRUD operations on a specific resource type <typeparamref name="T"/>.
 | 
					/// A base class to handle CRUD operations on a specific resource type <typeparamref name="T"/>.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	/// <typeparam name="T">The type of resource to make CRUD apis for.</typeparam>
 | 
					/// <typeparam name="T">The type of resource to make CRUD apis for.</typeparam>
 | 
				
			||||||
	[ApiController]
 | 
					[ApiController]
 | 
				
			||||||
	public class CrudApi<T> : BaseApi
 | 
					public class CrudApi<T> : BaseApi
 | 
				
			||||||
	where T : class, IResource, IQuery
 | 
						where T : class, IResource, IQuery
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The repository of the resource, used to retrieve, save and do operations on the baking store.
 | 
						/// The repository of the resource, used to retrieve, save and do operations on the baking store.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -67,10 +67,7 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
	[PartialPermission(Kind.Read)]
 | 
						[PartialPermission(Kind.Read)]
 | 
				
			||||||
	[ProducesResponseType(StatusCodes.Status200OK)]
 | 
						[ProducesResponseType(StatusCodes.Status200OK)]
 | 
				
			||||||
	[ProducesResponseType(StatusCodes.Status404NotFound)]
 | 
						[ProducesResponseType(StatusCodes.Status404NotFound)]
 | 
				
			||||||
		public async Task<ActionResult<T>> Get(
 | 
						public async Task<ActionResult<T>> Get(Identifier identifier, [FromQuery] Include<T>? fields)
 | 
				
			||||||
			Identifier identifier,
 | 
					 | 
				
			||||||
			[FromQuery] Include<T>? fields
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		T? ret = await identifier.Match(
 | 
							T? ret = await identifier.Match(
 | 
				
			||||||
			id => Repository.GetOrDefault(id, fields),
 | 
								id => Repository.GetOrDefault(id, fields),
 | 
				
			||||||
@ -272,5 +269,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
		await Repository.DeleteAll(filter);
 | 
							await Repository.DeleteAll(filter);
 | 
				
			||||||
		return NoContent();
 | 
							return NoContent();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,17 +26,17 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// A base class to handle CRUD operations and services thumbnails for
 | 
					/// A base class to handle CRUD operations and services thumbnails for
 | 
				
			||||||
	/// a specific resource type <typeparamref name="T"/>.
 | 
					/// a specific resource type <typeparamref name="T"/>.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	/// <typeparam name="T">The type of resource to make CRUD and thumbnails apis for.</typeparam>
 | 
					/// <typeparam name="T">The type of resource to make CRUD and thumbnails apis for.</typeparam>
 | 
				
			||||||
	[ApiController]
 | 
					[ApiController]
 | 
				
			||||||
	public class CrudThumbsApi<T> : CrudApi<T>
 | 
					public class CrudThumbsApi<T> : CrudApi<T>
 | 
				
			||||||
	where T : class, IResource, IThumbnails, IQuery
 | 
						where T : class, IResource, IThumbnails, IQuery
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The thumbnail manager used to retrieve images paths.
 | 
						/// The thumbnail manager used to retrieve images paths.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -97,10 +97,7 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
	[PartialPermission(Kind.Read)]
 | 
						[PartialPermission(Kind.Read)]
 | 
				
			||||||
	[ProducesResponseType(StatusCodes.Status200OK)]
 | 
						[ProducesResponseType(StatusCodes.Status200OK)]
 | 
				
			||||||
	[ProducesResponseType(StatusCodes.Status404NotFound)]
 | 
						[ProducesResponseType(StatusCodes.Status404NotFound)]
 | 
				
			||||||
		public Task<IActionResult> GetPoster(
 | 
						public Task<IActionResult> GetPoster(Identifier identifier, [FromQuery] ImageQuality? quality)
 | 
				
			||||||
			Identifier identifier,
 | 
					 | 
				
			||||||
			[FromQuery] ImageQuality? quality
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return _GetImage(identifier, "poster", quality);
 | 
							return _GetImage(identifier, "poster", quality);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -140,12 +137,8 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
	/// </response>
 | 
						/// </response>
 | 
				
			||||||
	[HttpGet("{identifier:id}/thumbnail")]
 | 
						[HttpGet("{identifier:id}/thumbnail")]
 | 
				
			||||||
	[HttpGet("{identifier:id}/backdrop", Order = AlternativeRoute)]
 | 
						[HttpGet("{identifier:id}/backdrop", Order = AlternativeRoute)]
 | 
				
			||||||
		public Task<IActionResult> GetBackdrop(
 | 
						public Task<IActionResult> GetBackdrop(Identifier identifier, [FromQuery] ImageQuality? quality)
 | 
				
			||||||
			Identifier identifier,
 | 
					 | 
				
			||||||
			[FromQuery] ImageQuality? quality
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return _GetImage(identifier, "thumbnail", quality);
 | 
							return _GetImage(identifier, "thumbnail", quality);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -28,18 +28,18 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Information about one or multiple <see cref="Studio"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Route("studios")]
 | 
				
			||||||
 | 
					[Route("studio", Order = AlternativeRoute)]
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[PartialPermission(nameof(Show))]
 | 
				
			||||||
 | 
					[ApiDefinition("Studios", Group = MetadataGroup)]
 | 
				
			||||||
 | 
					public class StudioApi : CrudApi<Studio>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Information about one or multiple <see cref="Studio"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Route("studios")]
 | 
					 | 
				
			||||||
	[Route("studio", Order = AlternativeRoute)]
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[PartialPermission(nameof(Show))]
 | 
					 | 
				
			||||||
	[ApiDefinition("Studios", Group = MetadataGroup)]
 | 
					 | 
				
			||||||
	public class StudioApi : CrudApi<Studio>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The library manager used to modify or retrieve information in the data store.
 | 
						/// The library manager used to modify or retrieve information in the data store.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -99,5 +99,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
			return NotFound();
 | 
								return NotFound();
 | 
				
			||||||
		return Page(resources, pagination.Limit);
 | 
							return Page(resources, pagination.Limit);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -30,18 +30,18 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Information about one or multiple <see cref="Collection"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Route("collections")]
 | 
				
			||||||
 | 
					[Route("collection", Order = AlternativeRoute)]
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[PartialPermission(nameof(Collection))]
 | 
				
			||||||
 | 
					[ApiDefinition("Collections", Group = ResourcesGroup)]
 | 
				
			||||||
 | 
					public class CollectionApi : CrudThumbsApi<Collection>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Information about one or multiple <see cref="Collection"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Route("collections")]
 | 
					 | 
				
			||||||
	[Route("collection", Order = AlternativeRoute)]
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[PartialPermission(nameof(Collection))]
 | 
					 | 
				
			||||||
	[ApiDefinition("Collections", Group = ResourcesGroup)]
 | 
					 | 
				
			||||||
	public class CollectionApi : CrudThumbsApi<Collection>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	private readonly ILibraryManager _libraryManager;
 | 
						private readonly ILibraryManager _libraryManager;
 | 
				
			||||||
	private readonly CollectionRepository _collections;
 | 
						private readonly CollectionRepository _collections;
 | 
				
			||||||
	private readonly LibraryItemRepository _items;
 | 
						private readonly LibraryItemRepository _items;
 | 
				
			||||||
@ -259,5 +259,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
			return NotFound();
 | 
								return NotFound();
 | 
				
			||||||
		return Page(resources, pagination.Limit);
 | 
							return Page(resources, pagination.Limit);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -28,19 +28,19 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// Information about one or multiple <see cref="Episode"/>.
 | 
					/// Information about one or multiple <see cref="Episode"/>.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	[Route("episodes")]
 | 
					[Route("episodes")]
 | 
				
			||||||
	[Route("episode", Order = AlternativeRoute)]
 | 
					[Route("episode", Order = AlternativeRoute)]
 | 
				
			||||||
	[ApiController]
 | 
					[ApiController]
 | 
				
			||||||
	[PartialPermission(nameof(Episode))]
 | 
					[PartialPermission(nameof(Episode))]
 | 
				
			||||||
	[ApiDefinition("Episodes", Group = ResourcesGroup)]
 | 
					[ApiDefinition("Episodes", Group = ResourcesGroup)]
 | 
				
			||||||
	public class EpisodeApi(ILibraryManager libraryManager, IThumbnailsManager thumbnails)
 | 
					public class EpisodeApi(ILibraryManager libraryManager, IThumbnailsManager thumbnails)
 | 
				
			||||||
	: TranscoderApi<Episode>(libraryManager.Episodes, thumbnails)
 | 
						: TranscoderApi<Episode>(libraryManager.Episodes, thumbnails)
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Get episode's show
 | 
						/// Get episode's show
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -195,5 +195,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
		);
 | 
							);
 | 
				
			||||||
		return (path, $"/episodes/{identifier}");
 | 
							return (path, $"/episodes/{identifier}");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,19 +23,19 @@ using Kyoo.Abstractions.Models.Permissions;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Endpoint for items that are not part of a specific library.
 | 
				
			||||||
 | 
					/// An item can ether represent a collection or a show.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Route("items")]
 | 
				
			||||||
 | 
					[Route("item", Order = AlternativeRoute)]
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[PartialPermission("LibraryItem")]
 | 
				
			||||||
 | 
					[ApiDefinition("Items", Group = ResourcesGroup)]
 | 
				
			||||||
 | 
					public class LibraryItemApi : CrudThumbsApi<ILibraryItem>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Endpoint for items that are not part of a specific library.
 | 
					 | 
				
			||||||
	/// An item can ether represent a collection or a show.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Route("items")]
 | 
					 | 
				
			||||||
	[Route("item", Order = AlternativeRoute)]
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[PartialPermission("LibraryItem")]
 | 
					 | 
				
			||||||
	[ApiDefinition("Items", Group = ResourcesGroup)]
 | 
					 | 
				
			||||||
	public class LibraryItemApi : CrudThumbsApi<ILibraryItem>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The library item repository used to modify or retrieve information in the data store.
 | 
						/// The library item repository used to modify or retrieve information in the data store.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -53,5 +53,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		_libraryItems = libraryItems;
 | 
							_libraryItems = libraryItems;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -30,19 +30,19 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
	/// Information about one or multiple <see cref="Movie"/>.
 | 
					/// Information about one or multiple <see cref="Movie"/>.
 | 
				
			||||||
	/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
	[Route("movies")]
 | 
					[Route("movies")]
 | 
				
			||||||
	[Route("movie", Order = AlternativeRoute)]
 | 
					[Route("movie", Order = AlternativeRoute)]
 | 
				
			||||||
	[ApiController]
 | 
					[ApiController]
 | 
				
			||||||
	[PartialPermission(nameof(Show))]
 | 
					[PartialPermission(nameof(Show))]
 | 
				
			||||||
	[ApiDefinition("Shows", Group = ResourcesGroup)]
 | 
					[ApiDefinition("Shows", Group = ResourcesGroup)]
 | 
				
			||||||
	public class MovieApi(ILibraryManager libraryManager, IThumbnailsManager thumbs)
 | 
					public class MovieApi(ILibraryManager libraryManager, IThumbnailsManager thumbs)
 | 
				
			||||||
	: TranscoderApi<Movie>(libraryManager.Movies, thumbs)
 | 
						: TranscoderApi<Movie>(libraryManager.Movies, thumbs)
 | 
				
			||||||
	{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Get studio that made the show
 | 
						/// Get studio that made the show
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -207,5 +207,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
		);
 | 
							);
 | 
				
			||||||
		return (path, $"/movies/{identifier}");
 | 
							return (path, $"/movies/{identifier}");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,19 +23,18 @@ using Kyoo.Abstractions.Models.Permissions;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// List new items added to kyoo.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Route("news")]
 | 
				
			||||||
 | 
					[Route("new", Order = AlternativeRoute)]
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[PartialPermission("LibraryItem")]
 | 
				
			||||||
 | 
					[ApiDefinition("News", Group = ResourcesGroup)]
 | 
				
			||||||
 | 
					public class NewsApi : CrudThumbsApi<INews>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// List new items added to kyoo.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Route("news")]
 | 
					 | 
				
			||||||
	[Route("new", Order = AlternativeRoute)]
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[PartialPermission("LibraryItem")]
 | 
					 | 
				
			||||||
	[ApiDefinition("News", Group = ResourcesGroup)]
 | 
					 | 
				
			||||||
	public class NewsApi : CrudThumbsApi<INews>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	public NewsApi(IRepository<INews> news, IThumbnailsManager thumbs)
 | 
						public NewsApi(IRepository<INews> news, IThumbnailsManager thumbs)
 | 
				
			||||||
		: base(news, thumbs) { }
 | 
							: base(news, thumbs) { }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,17 +26,17 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An endpoint to search for every resources of kyoo. Searching for only a specific type of resource
 | 
				
			||||||
 | 
					/// is available on the said endpoint.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Route("search")]
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[ApiDefinition("Search", Group = ResourcesGroup)]
 | 
				
			||||||
 | 
					public class SearchApi : BaseApi
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An endpoint to search for every resources of kyoo. Searching for only a specific type of resource
 | 
					 | 
				
			||||||
	/// is available on the said endpoint.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Route("search")]
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[ApiDefinition("Search", Group = ResourcesGroup)]
 | 
					 | 
				
			||||||
	public class SearchApi : BaseApi
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	private readonly ISearchManager _searchManager;
 | 
						private readonly ISearchManager _searchManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public SearchApi(ISearchManager searchManager)
 | 
						public SearchApi(ISearchManager searchManager)
 | 
				
			||||||
@ -69,9 +69,7 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
		[FromQuery] Include<Collection> fields
 | 
							[FromQuery] Include<Collection> fields
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
			return SearchPage(
 | 
							return SearchPage(await _searchManager.SearchCollections(q, sortBy, pagination, fields));
 | 
				
			||||||
				await _searchManager.SearchCollections(q, sortBy, pagination, fields)
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
@ -203,5 +201,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		return SearchPage(await _searchManager.SearchStudios(q, sortBy, pagination, fields));
 | 
							return SearchPage(await _searchManager.SearchStudios(q, sortBy, pagination, fields));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -28,18 +28,18 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Information about one or multiple <see cref="Season"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Route("seasons")]
 | 
				
			||||||
 | 
					[Route("season", Order = AlternativeRoute)]
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[PartialPermission(nameof(Season))]
 | 
				
			||||||
 | 
					[ApiDefinition("Seasons", Group = ResourcesGroup)]
 | 
				
			||||||
 | 
					public class SeasonApi : CrudThumbsApi<Season>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Information about one or multiple <see cref="Season"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Route("seasons")]
 | 
					 | 
				
			||||||
	[Route("season", Order = AlternativeRoute)]
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[PartialPermission(nameof(Season))]
 | 
					 | 
				
			||||||
	[ApiDefinition("Seasons", Group = ResourcesGroup)]
 | 
					 | 
				
			||||||
	public class SeasonApi : CrudThumbsApi<Season>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The library manager used to modify or retrieve information in the data store.
 | 
						/// The library manager used to modify or retrieve information in the data store.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -87,10 +87,7 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ICollection<Episode> resources = await _libraryManager.Episodes.GetAll(
 | 
							ICollection<Episode> resources = await _libraryManager.Episodes.GetAll(
 | 
				
			||||||
				Filter.And(
 | 
								Filter.And(filter, identifier.Matcher<Episode>(x => x.SeasonId, x => x.Season!.Slug)),
 | 
				
			||||||
					filter,
 | 
					 | 
				
			||||||
					identifier.Matcher<Episode>(x => x.SeasonId, x => x.Season!.Slug)
 | 
					 | 
				
			||||||
				),
 | 
					 | 
				
			||||||
			sortBy,
 | 
								sortBy,
 | 
				
			||||||
			fields,
 | 
								fields,
 | 
				
			||||||
			pagination
 | 
								pagination
 | 
				
			||||||
@ -131,5 +128,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
			return NotFound();
 | 
								return NotFound();
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -30,18 +30,18 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Information about one or multiple <see cref="Show"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Route("shows")]
 | 
				
			||||||
 | 
					[Route("show", Order = AlternativeRoute)]
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[PartialPermission(nameof(Show))]
 | 
				
			||||||
 | 
					[ApiDefinition("Shows", Group = ResourcesGroup)]
 | 
				
			||||||
 | 
					public class ShowApi : CrudThumbsApi<Show>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Information about one or multiple <see cref="Show"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Route("shows")]
 | 
					 | 
				
			||||||
	[Route("show", Order = AlternativeRoute)]
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[PartialPermission(nameof(Show))]
 | 
					 | 
				
			||||||
	[ApiDefinition("Shows", Group = ResourcesGroup)]
 | 
					 | 
				
			||||||
	public class ShowApi : CrudThumbsApi<Show>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The library manager used to modify or retrieve information in the data store.
 | 
						/// The library manager used to modify or retrieve information in the data store.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -256,10 +256,7 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
	[ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
						[ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
				
			||||||
	[ProducesResponseType(StatusCodes.Status400BadRequest)]
 | 
						[ProducesResponseType(StatusCodes.Status400BadRequest)]
 | 
				
			||||||
	[ProducesResponseType(StatusCodes.Status404NotFound)]
 | 
						[ProducesResponseType(StatusCodes.Status404NotFound)]
 | 
				
			||||||
		public async Task<ShowWatchStatus?> SetWatchStatus(
 | 
						public async Task<ShowWatchStatus?> SetWatchStatus(Identifier identifier, WatchStatus status)
 | 
				
			||||||
			Identifier identifier,
 | 
					 | 
				
			||||||
			WatchStatus status
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Guid id = await identifier.Match(
 | 
							Guid id = await identifier.Match(
 | 
				
			||||||
			id => Task.FromResult(id),
 | 
								id => Task.FromResult(id),
 | 
				
			||||||
@ -290,5 +287,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
		);
 | 
							);
 | 
				
			||||||
		await _libraryManager.WatchStatus.DeleteShowStatus(id, User.GetIdOrThrow());
 | 
							await _libraryManager.WatchStatus.DeleteShowStatus(id, User.GetIdOrThrow());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -29,18 +29,18 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// List new items added to kyoo.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[Route("watchlist")]
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[PartialPermission("LibraryItem")]
 | 
				
			||||||
 | 
					[ApiDefinition("News", Group = ResourcesGroup)]
 | 
				
			||||||
 | 
					[UserOnly]
 | 
				
			||||||
 | 
					public class WatchlistApi(IWatchStatusRepository repository) : BaseApi
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// List new items added to kyoo.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Route("watchlist")]
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[PartialPermission("LibraryItem")]
 | 
					 | 
				
			||||||
	[ApiDefinition("News", Group = ResourcesGroup)]
 | 
					 | 
				
			||||||
	[UserOnly]
 | 
					 | 
				
			||||||
	public class WatchlistApi(IWatchStatusRepository repository) : BaseApi
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Get all
 | 
						/// Get all
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -68,5 +68,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return Page(resources, pagination.Limit);
 | 
							return Page(resources, pagination.Limit);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -28,15 +28,15 @@ using Kyoo.Utils;
 | 
				
			|||||||
using Microsoft.AspNetCore.Http;
 | 
					using Microsoft.AspNetCore.Http;
 | 
				
			||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Core.Api
 | 
					namespace Kyoo.Core.Api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Proxy to other services
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					[ApiController]
 | 
				
			||||||
 | 
					[Obsolete("Use /episode/id/master.m3u8 or routes like that")]
 | 
				
			||||||
 | 
					public class ProxyApi(ILibraryManager library) : Controller
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Proxy to other services
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[ApiController]
 | 
					 | 
				
			||||||
	[Obsolete("Use /episode/id/master.m3u8 or routes like that")]
 | 
					 | 
				
			||||||
	public class ProxyApi(ILibraryManager library) : Controller
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	private Task _Proxy(string route, (string path, string route) info)
 | 
						private Task _Proxy(string route, (string path, string route) info)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		HttpProxyOptions proxyOptions = HttpProxyOptionsBuilder
 | 
							HttpProxyOptions proxyOptions = HttpProxyOptionsBuilder
 | 
				
			||||||
@ -92,5 +92,4 @@ namespace Kyoo.Core.Api
 | 
				
			|||||||
		);
 | 
							);
 | 
				
			||||||
		await _Proxy(rest + query.ToQueryString(), (path, $"{type}/{id}"));
 | 
							await _Proxy(rest + query.ToQueryString(), (path, $"{type}/{id}"));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -37,14 +37,14 @@ using Serilog.Templates;
 | 
				
			|||||||
using Serilog.Templates.Themes;
 | 
					using Serilog.Templates.Themes;
 | 
				
			||||||
using ILogger = Serilog.ILogger;
 | 
					using ILogger = Serilog.ILogger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Host
 | 
					namespace Kyoo.Host;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Hosts of kyoo (main functions) generally only create a new <see cref="Application"/>
 | 
				
			||||||
 | 
					/// and return <see cref="Start(string[])"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Application
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Hosts of kyoo (main functions) generally only create a new <see cref="Application"/>
 | 
					 | 
				
			||||||
	/// and return <see cref="Start(string[])"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class Application
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The environment in witch Kyoo will run (ether "Production" or "Development").
 | 
						/// The environment in witch Kyoo will run (ether "Production" or "Development").
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -124,10 +124,7 @@ namespace Kyoo.Host
 | 
				
			|||||||
				"Version: {Version}",
 | 
									"Version: {Version}",
 | 
				
			||||||
				Assembly.GetExecutingAssembly().GetName().Version.ToString(3)
 | 
									Assembly.GetExecutingAssembly().GetName().Version.ToString(3)
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
				_logger.Information(
 | 
								_logger.Information("Data directory: {DataDirectory}", Environment.CurrentDirectory);
 | 
				
			||||||
					"Data directory: {DataDirectory}",
 | 
					 | 
				
			||||||
					Environment.CurrentDirectory
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
			await host.RunAsync(cancellationToken);
 | 
								await host.RunAsync(cancellationToken);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		catch (Exception ex)
 | 
							catch (Exception ex)
 | 
				
			||||||
@ -157,9 +154,7 @@ namespace Kyoo.Host
 | 
				
			|||||||
					})
 | 
										})
 | 
				
			||||||
					.UseIIS()
 | 
										.UseIIS()
 | 
				
			||||||
					.UseIISIntegration()
 | 
										.UseIISIntegration()
 | 
				
			||||||
						.UseUrls(
 | 
										.UseUrls(Environment.GetEnvironmentVariable("KYOO_BIND_URL") ?? "http://*:5000")
 | 
				
			||||||
							Environment.GetEnvironmentVariable("KYOO_BIND_URL") ?? "http://*:5000"
 | 
					 | 
				
			||||||
						)
 | 
					 | 
				
			||||||
					.UseStartup(host =>
 | 
										.UseStartup(host =>
 | 
				
			||||||
						PluginsStartup.FromWebHost(host, new LoggerFactory().AddSerilog())
 | 
											PluginsStartup.FromWebHost(host, new LoggerFactory().AddSerilog())
 | 
				
			||||||
					)
 | 
										)
 | 
				
			||||||
@ -198,5 +193,4 @@ namespace Kyoo.Host
 | 
				
			|||||||
			.Enrich.WithThreadId()
 | 
								.Enrich.WithThreadId()
 | 
				
			||||||
			.Enrich.FromLogContext();
 | 
								.Enrich.FromLogContext();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,14 +23,14 @@ using Kyoo.Abstractions.Controllers;
 | 
				
			|||||||
using Microsoft.Extensions.DependencyInjection;
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
using Microsoft.Extensions.Logging;
 | 
					using Microsoft.Extensions.Logging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Host.Controllers
 | 
					namespace Kyoo.Host.Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An implementation of <see cref="IPluginManager"/>.
 | 
				
			||||||
 | 
					/// This is used to load plugins and retrieve information from them.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class PluginManager : IPluginManager
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An implementation of <see cref="IPluginManager"/>.
 | 
					 | 
				
			||||||
	/// This is used to load plugins and retrieve information from them.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class PluginManager : IPluginManager
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The service provider. It allow plugin's activation.
 | 
						/// The service provider. It allow plugin's activation.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -86,10 +86,7 @@ namespace Kyoo.Host.Controllers
 | 
				
			|||||||
	public void LoadPlugins(params Type[] plugins)
 | 
						public void LoadPlugins(params Type[] plugins)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		LoadPlugins(
 | 
							LoadPlugins(
 | 
				
			||||||
				plugins
 | 
								plugins.Select(x => (IPlugin)ActivatorUtilities.CreateInstance(_provider, x)).ToArray()
 | 
				
			||||||
					.Select(x => (IPlugin)ActivatorUtilities.CreateInstance(_provider, x))
 | 
					 | 
				
			||||||
					.ToArray()
 | 
					 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,13 +23,13 @@ using Kyoo.Abstractions.Controllers;
 | 
				
			|||||||
using Microsoft.AspNetCore.Builder;
 | 
					using Microsoft.AspNetCore.Builder;
 | 
				
			||||||
using Serilog;
 | 
					using Serilog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Host
 | 
					namespace Kyoo.Host;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A module that registers host controllers and other needed things.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class HostModule : IPlugin
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A module that registers host controllers and other needed things.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class HostModule : IPlugin
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public string Name => "Host";
 | 
						public string Name => "Host";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -57,5 +57,4 @@ namespace Kyoo.Host
 | 
				
			|||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public IEnumerable<IStartupAction> ConfigureSteps =>
 | 
						public IEnumerable<IStartupAction> ConfigureSteps =>
 | 
				
			||||||
		new[] { SA.New<IApplicationBuilder>(app => app.UseSerilogRequestLogging(), SA.Before) };
 | 
							new[] { SA.New<IApplicationBuilder>(app => app.UseSerilogRequestLogging(), SA.Before) };
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -36,13 +36,13 @@ using Microsoft.Extensions.DependencyInjection;
 | 
				
			|||||||
using Microsoft.Extensions.Hosting;
 | 
					using Microsoft.Extensions.Hosting;
 | 
				
			||||||
using Microsoft.Extensions.Logging;
 | 
					using Microsoft.Extensions.Logging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Host
 | 
					namespace Kyoo.Host;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The Startup class is used to configure the AspNet's webhost.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class PluginsStartup
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The Startup class is used to configure the AspNet's webhost.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class PluginsStartup
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// A plugin manager used to load plugins and allow them to configure services / asp net.
 | 
						/// A plugin manager used to load plugins and allow them to configure services / asp net.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -81,8 +81,7 @@ namespace Kyoo.Host
 | 
				
			|||||||
	/// <returns>A new <see cref="PluginsStartup"/>.</returns>
 | 
						/// <returns>A new <see cref="PluginsStartup"/>.</returns>
 | 
				
			||||||
	public static PluginsStartup FromWebHost(WebHostBuilderContext host, ILoggerFactory logger)
 | 
						public static PluginsStartup FromWebHost(WebHostBuilderContext host, ILoggerFactory logger)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
			HostServiceProvider hostProvider =
 | 
							HostServiceProvider hostProvider = new(host.HostingEnvironment, host.Configuration, logger);
 | 
				
			||||||
				new(host.HostingEnvironment, host.Configuration, logger);
 | 
					 | 
				
			||||||
		PluginManager plugins = new(hostProvider, logger.CreateLogger<PluginManager>());
 | 
							PluginManager plugins = new(hostProvider, logger.CreateLogger<PluginManager>());
 | 
				
			||||||
		return new PluginsStartup(plugins);
 | 
							return new PluginsStartup(plugins);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -93,9 +92,7 @@ namespace Kyoo.Host
 | 
				
			|||||||
	/// <param name="services">The service collection to fill.</param>
 | 
						/// <param name="services">The service collection to fill.</param>
 | 
				
			||||||
	public void ConfigureServices(IServiceCollection services)
 | 
						public void ConfigureServices(IServiceCollection services)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
			foreach (
 | 
							foreach (Assembly assembly in _plugins.GetAllPlugins().Select(x => x.GetType().Assembly))
 | 
				
			||||||
				Assembly assembly in _plugins.GetAllPlugins().Select(x => x.GetType().Assembly)
 | 
					 | 
				
			||||||
			)
 | 
					 | 
				
			||||||
			services.AddMvcCore().AddApplicationPart(assembly);
 | 
								services.AddMvcCore().AddApplicationPart(assembly);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		_hostModule.Configure(services);
 | 
							_hostModule.Configure(services);
 | 
				
			||||||
@ -198,5 +195,4 @@ namespace Kyoo.Host
 | 
				
			|||||||
			return null;
 | 
								return null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,13 +19,13 @@
 | 
				
			|||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using Microsoft.AspNetCore.Hosting;
 | 
					using Microsoft.AspNetCore.Hosting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Host
 | 
					namespace Kyoo.Host;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Program entrypoint.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class Program
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Program entrypoint.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class Program
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The string representation of the environment used in <see cref="IWebHostEnvironment"/>.
 | 
						/// The string representation of the environment used in <see cref="IWebHostEnvironment"/>.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -45,5 +45,4 @@ namespace Kyoo.Host
 | 
				
			|||||||
		Application application = new(Environment);
 | 
							Application application = new(Environment);
 | 
				
			||||||
		return application.Start(args);
 | 
							return application.Start(args);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -24,10 +24,10 @@ using Microsoft.Extensions.Configuration;
 | 
				
			|||||||
using Microsoft.Extensions.DependencyInjection;
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
using static System.Text.Json.JsonNamingPolicy;
 | 
					using static System.Text.Json.JsonNamingPolicy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Meiliseach
 | 
					namespace Kyoo.Meiliseach;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class MeilisearchModule : IPlugin
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public class MeilisearchModule : IPlugin
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public string Name => "Meilisearch";
 | 
						public string Name => "Meilisearch";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,11 +64,7 @@ namespace Kyoo.Meiliseach
 | 
				
			|||||||
						CamelCase.ConvertName(nameof(Movie.Rating)),
 | 
											CamelCase.ConvertName(nameof(Movie.Rating)),
 | 
				
			||||||
						CamelCase.ConvertName(nameof(Movie.Runtime)),
 | 
											CamelCase.ConvertName(nameof(Movie.Runtime)),
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
						DisplayedAttributes = new[]
 | 
										DisplayedAttributes = new[] { CamelCase.ConvertName(nameof(Movie.Id)), "kind" },
 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
							CamelCase.ConvertName(nameof(Movie.Id)),
 | 
					 | 
				
			||||||
							"kind"
 | 
					 | 
				
			||||||
						},
 | 
					 | 
				
			||||||
					RankingRules = new[]
 | 
										RankingRules = new[]
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						"words",
 | 
											"words",
 | 
				
			||||||
@ -190,5 +186,4 @@ namespace Kyoo.Meiliseach
 | 
				
			|||||||
		builder.RegisterType<MeiliSync>().AsSelf().SingleInstance().AutoActivate();
 | 
							builder.RegisterType<MeiliSync>().AsSelf().SingleInstance().AutoActivate();
 | 
				
			||||||
		builder.RegisterType<SearchManager>().As<ISearchManager>().InstancePerLifetimeScope();
 | 
							builder.RegisterType<SearchManager>().As<ISearchManager>().InstancePerLifetimeScope();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -31,17 +31,17 @@ using Microsoft.AspNetCore.Http;
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
					using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Postgresql
 | 
					namespace Kyoo.Postgresql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The database handle used for all local repositories.
 | 
				
			||||||
 | 
					/// This is an abstract class. It is meant to be implemented by plugins. This allow the core to be database agnostic.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <remarks>
 | 
				
			||||||
 | 
					/// It should not be used directly, to access the database use a <see cref="ILibraryManager"/> or repositories.
 | 
				
			||||||
 | 
					/// </remarks>
 | 
				
			||||||
 | 
					public abstract class DatabaseContext : DbContext
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The database handle used for all local repositories.
 | 
					 | 
				
			||||||
	/// This is an abstract class. It is meant to be implemented by plugins. This allow the core to be database agnostic.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	/// <remarks>
 | 
					 | 
				
			||||||
	/// It should not be used directly, to access the database use a <see cref="ILibraryManager"/> or repositories.
 | 
					 | 
				
			||||||
	/// </remarks>
 | 
					 | 
				
			||||||
	public abstract class DatabaseContext : DbContext
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	private readonly IHttpContextAccessor _accessor;
 | 
						private readonly IHttpContextAccessor _accessor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
@ -260,10 +260,7 @@ namespace Kyoo.Postgresql
 | 
				
			|||||||
		base.OnModelCreating(modelBuilder);
 | 
							base.OnModelCreating(modelBuilder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		modelBuilder.Entity<Show>().Ignore(x => x.FirstEpisode).Ignore(x => x.AirDate);
 | 
							modelBuilder.Entity<Show>().Ignore(x => x.FirstEpisode).Ignore(x => x.AirDate);
 | 
				
			||||||
			modelBuilder
 | 
							modelBuilder.Entity<Episode>().Ignore(x => x.PreviousEpisode).Ignore(x => x.NextEpisode);
 | 
				
			||||||
				.Entity<Episode>()
 | 
					 | 
				
			||||||
				.Ignore(x => x.PreviousEpisode)
 | 
					 | 
				
			||||||
				.Ignore(x => x.NextEpisode);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		modelBuilder
 | 
							modelBuilder
 | 
				
			||||||
			.Entity<Show>()
 | 
								.Entity<Show>()
 | 
				
			||||||
@ -353,9 +350,7 @@ namespace Kyoo.Postgresql
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		modelBuilder.Entity<MovieWatchStatus>().HasQueryFilter(x => x.UserId == CurrentUserId);
 | 
							modelBuilder.Entity<MovieWatchStatus>().HasQueryFilter(x => x.UserId == CurrentUserId);
 | 
				
			||||||
		modelBuilder.Entity<ShowWatchStatus>().HasQueryFilter(x => x.UserId == CurrentUserId);
 | 
							modelBuilder.Entity<ShowWatchStatus>().HasQueryFilter(x => x.UserId == CurrentUserId);
 | 
				
			||||||
			modelBuilder
 | 
							modelBuilder.Entity<EpisodeWatchStatus>().HasQueryFilter(x => x.UserId == CurrentUserId);
 | 
				
			||||||
				.Entity<EpisodeWatchStatus>()
 | 
					 | 
				
			||||||
				.HasQueryFilter(x => x.UserId == CurrentUserId);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		modelBuilder.Entity<ShowWatchStatus>().Navigation(x => x.NextEpisode).AutoInclude();
 | 
							modelBuilder.Entity<ShowWatchStatus>().Navigation(x => x.NextEpisode).AutoInclude();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -543,9 +538,7 @@ namespace Kyoo.Postgresql
 | 
				
			|||||||
	/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe while waiting for the task to complete</param>
 | 
						/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe while waiting for the task to complete</param>
 | 
				
			||||||
	/// <exception cref="DuplicatedItemException">A duplicated item has been found.</exception>
 | 
						/// <exception cref="DuplicatedItemException">A duplicated item has been found.</exception>
 | 
				
			||||||
	/// <returns>The number of state entries written to the database.</returns>
 | 
						/// <returns>The number of state entries written to the database.</returns>
 | 
				
			||||||
		public override async Task<int> SaveChangesAsync(
 | 
						public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
 | 
				
			||||||
			CancellationToken cancellationToken = default
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		try
 | 
							try
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -635,13 +628,10 @@ namespace Kyoo.Postgresql
 | 
				
			|||||||
	public void DiscardChanges()
 | 
						public void DiscardChanges()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		foreach (
 | 
							foreach (
 | 
				
			||||||
				EntityEntry entry in ChangeTracker
 | 
								EntityEntry entry in ChangeTracker.Entries().Where(x => x.State != EntityState.Detached)
 | 
				
			||||||
					.Entries()
 | 
					 | 
				
			||||||
					.Where(x => x.State != EntityState.Detached)
 | 
					 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			entry.State = EntityState.Detached;
 | 
								entry.State = EntityState.Detached;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,13 +25,13 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
 | 
					using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
 | 
				
			||||||
using Npgsql;
 | 
					using Npgsql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Postgresql
 | 
					namespace Kyoo.Postgresql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A postgresql implementation of <see cref="DatabaseContext"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class PostgresContext : DatabaseContext
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A postgresql implementation of <see cref="DatabaseContext"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class PostgresContext : DatabaseContext
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Is this instance in debug mode?
 | 
						/// Is this instance in debug mode?
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -134,5 +134,4 @@ namespace Kyoo.Postgresql
 | 
				
			|||||||
					or PostgresErrorCodes.ForeignKeyViolation
 | 
										or PostgresErrorCodes.ForeignKeyViolation
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,13 +33,13 @@ using Microsoft.Extensions.DependencyInjection;
 | 
				
			|||||||
using Microsoft.Extensions.Hosting;
 | 
					using Microsoft.Extensions.Hosting;
 | 
				
			||||||
using Npgsql;
 | 
					using Npgsql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Postgresql
 | 
					namespace Kyoo.Postgresql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A module to add postgresql capacity to the app.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class PostgresModule : IPlugin
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A module to add postgresql capacity to the app.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class PostgresModule : IPlugin
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public string Name => "Postgresql";
 | 
						public string Name => "Postgresql";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -137,11 +137,8 @@ namespace Kyoo.Postgresql
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			ServiceLifetime.Transient
 | 
								ServiceLifetime.Transient
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
			services.AddTransient<DbConnection>(
 | 
							services.AddTransient<DbConnection>((_) => new NpgsqlConnection(builder.ConnectionString));
 | 
				
			||||||
				(_) => new NpgsqlConnection(builder.ConnectionString)
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
 | 
							services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,13 +22,13 @@ using Kyoo.Swagger.Models;
 | 
				
			|||||||
using NSwag;
 | 
					using NSwag;
 | 
				
			||||||
using NSwag.Generation.AspNetCore;
 | 
					using NSwag.Generation.AspNetCore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Swagger
 | 
					namespace Kyoo.Swagger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A class to sort apis.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class ApiSorter
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A class to sort apis.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class ApiSorter
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Sort apis by alphabetical orders.
 | 
						/// Sort apis by alphabetical orders.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -62,5 +62,4 @@ namespace Kyoo.Swagger
 | 
				
			|||||||
				.ToList();
 | 
									.ToList();
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,15 +26,15 @@ using NSwag;
 | 
				
			|||||||
using NSwag.Generation.AspNetCore;
 | 
					using NSwag.Generation.AspNetCore;
 | 
				
			||||||
using NSwag.Generation.Processors.Contexts;
 | 
					using NSwag.Generation.Processors.Contexts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Swagger
 | 
					namespace Kyoo.Swagger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A class to handle Api Groups (OpenApi tags and x-tagGroups).
 | 
				
			||||||
 | 
					/// Tags should be specified via <see cref="ApiDefinitionAttribute"/> and this filter will map this to the
 | 
				
			||||||
 | 
					/// <see cref="OpenApiDocument"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class ApiTagsFilter
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A class to handle Api Groups (OpenApi tags and x-tagGroups).
 | 
					 | 
				
			||||||
	/// Tags should be specified via <see cref="ApiDefinitionAttribute"/> and this filter will map this to the
 | 
					 | 
				
			||||||
	/// <see cref="OpenApiDocument"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public static class ApiTagsFilter
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The main operation filter that will map every <see cref="ApiDefinitionAttribute"/>.
 | 
						/// The main operation filter that will map every <see cref="ApiDefinitionAttribute"/>.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -120,5 +120,4 @@ namespace Kyoo.Swagger
 | 
				
			|||||||
		options.AddOperationFilter(OperationFilter);
 | 
							options.AddOperationFilter(OperationFilter);
 | 
				
			||||||
		options.PostProcess += x => x.AddLeftoversToOthersGroup();
 | 
							options.PostProcess += x => x.AddLeftoversToOthersGroup();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -24,19 +24,19 @@ using Kyoo.Utils;
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
 | 
					using Microsoft.AspNetCore.Mvc.ApplicationModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Swagger
 | 
					namespace Kyoo.Swagger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A filter that change <see cref="ProducesResponseTypeAttribute"/>'s
 | 
				
			||||||
 | 
					/// <see cref="ProducesResponseTypeAttribute.Type"/> that where set to <see cref="ActionResult{T}"/> to the
 | 
				
			||||||
 | 
					/// return type of the method.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <remarks>
 | 
				
			||||||
 | 
					/// This is only useful when the return type of the method is a generics type and that can't be specified in the
 | 
				
			||||||
 | 
					/// attribute directly (since attributes don't support generics). This should not be used otherwise.
 | 
				
			||||||
 | 
					/// </remarks>
 | 
				
			||||||
 | 
					public class GenericResponseProvider : IApplicationModelProvider
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A filter that change <see cref="ProducesResponseTypeAttribute"/>'s
 | 
					 | 
				
			||||||
	/// <see cref="ProducesResponseTypeAttribute.Type"/> that where set to <see cref="ActionResult{T}"/> to the
 | 
					 | 
				
			||||||
	/// return type of the method.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	/// <remarks>
 | 
					 | 
				
			||||||
	/// This is only useful when the return type of the method is a generics type and that can't be specified in the
 | 
					 | 
				
			||||||
	/// attribute directly (since attributes don't support generics). This should not be used otherwise.
 | 
					 | 
				
			||||||
	/// </remarks>
 | 
					 | 
				
			||||||
	public class GenericResponseProvider : IApplicationModelProvider
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public int Order => -1;
 | 
						public int Order => -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -65,5 +65,4 @@ namespace Kyoo.Swagger
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,13 +20,13 @@ using System.Collections.Generic;
 | 
				
			|||||||
using Newtonsoft.Json;
 | 
					using Newtonsoft.Json;
 | 
				
			||||||
using NSwag;
 | 
					using NSwag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Swagger.Models
 | 
					namespace Kyoo.Swagger.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A class representing a group of tags in the <see cref="OpenApiDocument"/>
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class TagGroups
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A class representing a group of tags in the <see cref="OpenApiDocument"/>
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class TagGroups
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The name of the tag group.
 | 
						/// The name of the tag group.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
@ -38,5 +38,4 @@ namespace Kyoo.Swagger.Models
 | 
				
			|||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	[JsonProperty(PropertyName = "tags")]
 | 
						[JsonProperty(PropertyName = "tags")]
 | 
				
			||||||
	public List<string> Tags { get; set; }
 | 
						public List<string> Tags { get; set; }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,19 +25,18 @@ using NSwag;
 | 
				
			|||||||
using NSwag.Generation.Processors;
 | 
					using NSwag.Generation.Processors;
 | 
				
			||||||
using NSwag.Generation.Processors.Contexts;
 | 
					using NSwag.Generation.Processors.Contexts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Swagger
 | 
					namespace Kyoo.Swagger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An operation processor that adds permissions information from the <see cref="PermissionAttribute"/> and the
 | 
				
			||||||
 | 
					/// <see cref="PartialPermissionAttribute"/>.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class OperationPermissionProcessor : IOperationProcessor
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An operation processor that adds permissions information from the <see cref="PermissionAttribute"/> and the
 | 
					 | 
				
			||||||
	/// <see cref="PartialPermissionAttribute"/>.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class OperationPermissionProcessor : IOperationProcessor
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public bool Process(OperationProcessorContext context)
 | 
						public bool Process(OperationProcessorContext context)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
			context.OperationDescription.Operation.Security ??=
 | 
							context.OperationDescription.Operation.Security ??= new List<OpenApiSecurityRequirement>();
 | 
				
			||||||
				new List<OpenApiSecurityRequirement>();
 | 
					 | 
				
			||||||
		OpenApiSecurityRequirement perms = context
 | 
							OpenApiSecurityRequirement perms = context
 | 
				
			||||||
			.MethodInfo.GetCustomAttributes<UserOnlyAttribute>()
 | 
								.MethodInfo.GetCustomAttributes<UserOnlyAttribute>()
 | 
				
			||||||
			.Aggregate(
 | 
								.Aggregate(
 | 
				
			||||||
@ -100,5 +99,4 @@ namespace Kyoo.Swagger
 | 
				
			|||||||
			? perms.ToList()
 | 
								? perms.ToList()
 | 
				
			||||||
			: new List<string>();
 | 
								: new List<string>();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -29,13 +29,13 @@ using NSwag;
 | 
				
			|||||||
using NSwag.Generation.AspNetCore;
 | 
					using NSwag.Generation.AspNetCore;
 | 
				
			||||||
using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
					using static Kyoo.Abstractions.Models.Utils.Constants;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Swagger
 | 
					namespace Kyoo.Swagger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A module to enable a swagger interface and an OpenAPI endpoint to document Kyoo.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class SwaggerModule : IPlugin
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// A module to enable a swagger interface and an OpenAPI endpoint to document Kyoo.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public class SwaggerModule : IPlugin
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	/// <inheritdoc />
 | 
						/// <inheritdoc />
 | 
				
			||||||
	public string Name => "Swagger";
 | 
						public string Name => "Swagger";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -127,5 +127,4 @@ namespace Kyoo.Swagger
 | 
				
			|||||||
				SA.Before
 | 
									SA.Before
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user