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