diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 484d5036..b4a233cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,12 +31,12 @@ jobs: workflow: build.yml path: ./artifacts github_token: ${{secrets.GITHUB_TOKEN}} - - name: Public the common to nuget + - name: Public the abstractions to nuget id: publish_nuget uses: rohith/publish-nuget@v2 with: - PROJECT_FILE_PATH: Kyoo.Common/Kyoo.Common.csproj - PACKAGE_NAME: Kyoo.Common + PROJECT_FILE_PATH: Kyoo.Abstractions/Kyoo.Abstractions.csproj + PACKAGE_NAME: Kyoo.Abstractions VERSION_REGEX: ^\s*(.*)<\/PackageVersion>\s*$ NUGET_KEY: ${{secrets.NUGET_API_KEY}} INCLUDE_SYMBOLS: true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7c86b7b0..63b6d701 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,7 @@ jobs: - name: Build run: | dotnet build --no-restore '-p:SkipWebApp=true;SkipTranscoder=true' -p:CopyLocalLockFileAssemblies=true - cp ./Kyoo.Common/bin/Debug/net5.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll ./tests/Kyoo.Tests/bin/Debug/net5.0/ + cp ./Kyoo.Abstractions/bin/Debug/net5.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll ./tests/Kyoo.Tests/bin/Debug/net5.0/ - name: Test run: dotnet test --no-build '-p:CollectCoverage=true;CoverletOutputFormat=opencover' env: diff --git a/.gitmodules b/.gitmodules index 616ea2bb..3085af6a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,6 +3,6 @@ url = ../Kyoo.Transcoder.git branch = master [submodule "WebApp"] - path = Kyoo.WebApp + path = Kyoo.WebApp/Front url = ../Kyoo.WebApp.git branch = master diff --git a/Dockerfile b/Dockerfile index 8764c7df..9158d2a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ RUN cmake . && make -j FROM node:alpine as webapp WORKDIR /webapp COPY Kyoo.WebApp . +WORKDIR /webapp/Front RUN npm install RUN npm run build -- --prod @@ -19,6 +20,6 @@ RUN apt-get update && apt-get install -y libavutil-dev libavcodec-dev libavforma EXPOSE 5000 COPY --from=builder /opt/kyoo /usr/lib/kyoo COPY --from=transcoder /transcoder/libtranscoder.so /usr/lib/kyoo -COPY --from=webapp /webapp/dist/* /usr/lib/kyoo/wwwroot/ +COPY --from=webapp /webapp/Front/dist/* /usr/lib/kyoo/wwwroot/ CMD ["/usr/lib/kyoo/Kyoo", "/var/lib/kyoo"] diff --git a/Kyoo.Common/.gitignore b/Kyoo.Abstractions/.gitignore similarity index 100% rename from Kyoo.Common/.gitignore rename to Kyoo.Abstractions/.gitignore diff --git a/Kyoo.Common/Controllers/IConfigurationManager.cs b/Kyoo.Abstractions/Controllers/IConfigurationManager.cs similarity index 79% rename from Kyoo.Common/Controllers/IConfigurationManager.cs rename to Kyoo.Abstractions/Controllers/IConfigurationManager.cs index 02430b10..73c649d1 100644 --- a/Kyoo.Common/Controllers/IConfigurationManager.cs +++ b/Kyoo.Abstractions/Controllers/IConfigurationManager.cs @@ -1,9 +1,10 @@ using System; using System.Threading.Tasks; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using JetBrains.Annotations; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { /// /// A class to ease configuration management. This work WITH Microsoft's package, you can still use IOptions patterns @@ -26,6 +27,15 @@ namespace Kyoo.Controllers /// /// The root path of the editable configuration. It should not be a nested type. void AddUntyped(string path); + + /// + /// An helper method of and . + /// This register a typed value if is not null and registers an untyped type + /// if is null. + /// + /// The root path of the editable configuration. It should not be a nested type. + /// The type of the configuration or null. + void Register(string path, [CanBeNull] Type type); /// /// Get the value of a setting using it's path. diff --git a/Kyoo.Common/Controllers/IFileSystem.cs b/Kyoo.Abstractions/Controllers/IFileSystem.cs similarity index 89% rename from Kyoo.Common/Controllers/IFileSystem.cs rename to Kyoo.Abstractions/Controllers/IFileSystem.cs index 92e951b7..36c5dd3b 100644 --- a/Kyoo.Common/Controllers/IFileSystem.cs +++ b/Kyoo.Abstractions/Controllers/IFileSystem.cs @@ -2,25 +2,11 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using JetBrains.Annotations; +using Kyoo.Abstractions.Models; using Microsoft.AspNetCore.Mvc; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { - /// - /// A class wrapping a value that will be set after the completion of the task it is related to. - /// - /// - /// This class replace the use of an out parameter on a task since tasks and out can't be combined. - /// - /// The type of the value - public class AsyncRef - { - /// - /// The value that will be set before the completion of the task. - /// - public T Value { get; set; } - } - /// /// A service to abstract the file system to allow custom file systems (like distant file systems or external providers) /// diff --git a/Kyoo.Common/Controllers/IIdentifier.cs b/Kyoo.Abstractions/Controllers/IIdentifier.cs similarity index 90% rename from Kyoo.Common/Controllers/IIdentifier.cs rename to Kyoo.Abstractions/Controllers/IIdentifier.cs index 5d11c53b..8a9d07ed 100644 --- a/Kyoo.Common/Controllers/IIdentifier.cs +++ b/Kyoo.Abstractions/Controllers/IIdentifier.cs @@ -1,8 +1,8 @@ using System.Threading.Tasks; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { /// /// An interface to identify episodes, shows and metadata based on the episode file. diff --git a/Kyoo.Common/Controllers/ILibraryManager.cs b/Kyoo.Abstractions/Controllers/ILibraryManager.cs similarity index 99% rename from Kyoo.Common/Controllers/ILibraryManager.cs rename to Kyoo.Abstractions/Controllers/ILibraryManager.cs index 8c3442e3..856becb7 100644 --- a/Kyoo.Common/Controllers/ILibraryManager.cs +++ b/Kyoo.Abstractions/Controllers/ILibraryManager.cs @@ -4,10 +4,10 @@ using System.Linq.Expressions; using System.Runtime.InteropServices; using System.Threading.Tasks; using JetBrains.Annotations; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { /// /// An interface to interract with the database. Every repository is mapped through here. diff --git a/Kyoo.Common/Controllers/IMetadataProvider.cs b/Kyoo.Abstractions/Controllers/IMetadataProvider.cs similarity index 97% rename from Kyoo.Common/Controllers/IMetadataProvider.cs rename to Kyoo.Abstractions/Controllers/IMetadataProvider.cs index ed6ab40d..c04ac906 100644 --- a/Kyoo.Common/Controllers/IMetadataProvider.cs +++ b/Kyoo.Abstractions/Controllers/IMetadataProvider.cs @@ -1,9 +1,9 @@ -using Kyoo.Models; +using Kyoo.Abstractions.Models; using System.Collections.Generic; using System.Threading.Tasks; using JetBrains.Annotations; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { /// /// An interface to automatically retrieve metadata from external providers. diff --git a/Kyoo.Abstractions/Controllers/IPlugin.cs b/Kyoo.Abstractions/Controllers/IPlugin.cs new file mode 100644 index 00000000..0ff6c932 --- /dev/null +++ b/Kyoo.Abstractions/Controllers/IPlugin.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using Autofac; +using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; + +namespace Kyoo.Abstractions.Controllers +{ + /// + /// A common interface used to discord plugins + /// + /// + /// You can inject services in the IPlugin constructor. + /// You should only inject well known services like an ILogger, IConfiguration or IWebHostEnvironment. + /// + [UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)] + public interface IPlugin + { + /// + /// A slug to identify this plugin in queries. + /// + string Slug { get; } + + /// + /// The name of the plugin + /// + string Name { get; } + + /// + /// The description of this plugin. This will be displayed on the "installed plugins" page. + /// + string Description { get; } + + /// + /// true if the plugin should be enabled, false otherwise. + /// If a plugin is not enabled, no configure method will be called. + /// This allow one to enable a plugin if a specific configuration value is set or if the environment contains + /// the right settings. + /// + /// + /// By default, a plugin is always enabled. This method can be overriden to change this behavior. + /// + virtual bool Enabled => true; + + /// + /// A list of types that will be available via the IOptions interfaces and will be listed inside + /// an IConfiguration. + /// + /// If a field should be loosely typed, or null + /// can be specified. + /// WARNING: null means an unmanaged type that won't be editable. This can be used + /// for external libraries or variable arguments. + /// + /// + /// All use of the configuration must be specified here and not registered elsewhere, if a type is registered + /// elsewhere the configuration won't be editable via the and all values + /// will be discarded on edit. + /// + Dictionary Configuration { get; } + + /// + /// An optional configuration step to allow a plugin to change asp net configurations. + /// + /// + virtual IEnumerable ConfigureSteps => ArraySegment.Empty; + + /// + /// A configure method that will be run on plugin's startup. + /// + /// The autofac service container to register services. + void Configure(ContainerBuilder builder) + { + // Skipped + } + + /// + /// A configure method that will be run on plugin's startup. + /// This is available for libraries that build upon a , for more precise + /// configuration use . + /// + /// A service container to register new services. + void Configure(IServiceCollection services) + { + // Skipped + } + + /// + /// An optional function to execute and initialize your plugin. + /// It can be used to initialize a database connection, fill initial data or anything. + /// + /// A service provider to request services + void Initialize(IServiceProvider provider) + { + // Skipped + } + + /// + /// An optional callback function called when the startups ends and this plugin has been flagged has disabled. + /// It allow a plugin to log an error or warning message to inform why it has been disabled. + /// + void Disabled() + { + // Skipped + } + } +} \ No newline at end of file diff --git a/Kyoo.Common/Controllers/IPluginManager.cs b/Kyoo.Abstractions/Controllers/IPluginManager.cs similarity index 64% rename from Kyoo.Common/Controllers/IPluginManager.cs rename to Kyoo.Abstractions/Controllers/IPluginManager.cs index 04d308f3..795339a4 100644 --- a/Kyoo.Common/Controllers/IPluginManager.cs +++ b/Kyoo.Abstractions/Controllers/IPluginManager.cs @@ -1,10 +1,8 @@ +using System; using System.Collections.Generic; -using Autofac; -using Kyoo.Models.Exceptions; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; +using Kyoo.Abstractions.Models.Exceptions; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { /// /// A manager to load plugins and retrieve information from them. @@ -41,23 +39,14 @@ namespace Kyoo.Controllers /// You should not try to put plugins from the plugins directory here as they will get automatically loaded. /// public void LoadPlugins(ICollection plugins); - - /// - /// Configure container adding or removing services as the plugins wants. - /// - /// The container to populate - void ConfigureContainer(ContainerBuilder builder); /// - /// Configure services via the microsoft way. This allow libraries to add their services. + /// Load plugins and their dependencies from the plugin directory. /// - /// The service collection to populate - public void ConfigureServices(IServiceCollection services); - - /// - /// Configure an asp net application applying plugins policies. - /// - /// The asp net application to configure - public void ConfigureAspnet(IApplicationBuilder app); + /// + /// An initial plugin list to use. + /// You should not try to put plugins from the plugins directory here as they will get automatically loaded. + /// + public void LoadPlugins(params Type[] plugins); } } \ No newline at end of file diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Abstractions/Controllers/IRepository.cs similarity index 96% rename from Kyoo.Common/Controllers/IRepository.cs rename to Kyoo.Abstractions/Controllers/IRepository.cs index c5fe7a7c..3a7dee05 100644 --- a/Kyoo.Common/Controllers/IRepository.cs +++ b/Kyoo.Abstractions/Controllers/IRepository.cs @@ -4,10 +4,10 @@ using System.Linq.Expressions; using System.Runtime.InteropServices; using System.Threading.Tasks; using JetBrains.Annotations; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { /// /// Information about the pagination. How many items should be displayed and where to start. @@ -106,7 +106,7 @@ namespace Kyoo.Controllers } /// - /// A base class for repositories. Every service implementing this will be handled by the . + /// A base class for repositories. Every service implementing this will be handled by the . /// public interface IBaseRepository { @@ -309,20 +309,20 @@ namespace Kyoo.Controllers Task Get(string showSlug, int seasonNumber); /// - /// Get a season from it's showID and it's seasonNumber or null if it is not found. - /// - /// The id of the show - /// The season's number - /// The season found - Task GetOrDefault(int showID, int seasonNumber); - - /// - /// Get a season from it's show slug and it's seasonNumber or null if it is not found. - /// - /// The slug of the show - /// The season's number - /// The season found - Task GetOrDefault(string showSlug, int seasonNumber); + /// Get a season from it's showID and it's seasonNumber or null if it is not found. + /// + /// The id of the show + /// The season's number + /// The season found + Task GetOrDefault(int showID, int seasonNumber); + + /// + /// Get a season from it's show slug and it's seasonNumber or null if it is not found. + /// + /// The slug of the show + /// The season's number + /// The season found + Task GetOrDefault(string showSlug, int seasonNumber); } /// diff --git a/Kyoo.Common/Controllers/ITask.cs b/Kyoo.Abstractions/Controllers/ITask.cs similarity index 92% rename from Kyoo.Common/Controllers/ITask.cs rename to Kyoo.Abstractions/Controllers/ITask.cs index e8d07000..79c8c778 100644 --- a/Kyoo.Common/Controllers/ITask.cs +++ b/Kyoo.Abstractions/Controllers/ITask.cs @@ -4,11 +4,10 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; -using Kyoo.Models; -using Kyoo.Models.Attributes; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { /// /// A single task parameter. This struct contains metadata to display and utility functions to get them in the task. @@ -55,7 +54,7 @@ namespace Kyoo.Controllers /// A new task parameter. public static TaskParameter Create(string name, string description) { - return new() + return new TaskParameter { Name = name, Description = description, @@ -72,7 +71,7 @@ namespace Kyoo.Controllers /// A new task parameter. public static TaskParameter CreateRequired(string name, string description) { - return new() + return new TaskParameter { Name = name, Description = description, @@ -182,11 +181,6 @@ namespace Kyoo.Controllers /// A token to request the task's cancellation. /// If this task is not cancelled quickly, it might be killed by the runner. /// - /// - /// Your task can have any service as a public field and use the , - /// they will be set to an available service from the service container before calling this method. - /// They also will be removed after this method return (or throw) to prevent dangling services. - /// /// /// An exception meaning that the task has failed for handled reasons like invalid arguments, /// invalid environment, missing plugins or failures not related to a default in the code. diff --git a/Kyoo.Common/Controllers/ITaskManager.cs b/Kyoo.Abstractions/Controllers/ITaskManager.cs similarity index 95% rename from Kyoo.Common/Controllers/ITaskManager.cs rename to Kyoo.Abstractions/Controllers/ITaskManager.cs index 37b40f12..2a999aad 100644 --- a/Kyoo.Common/Controllers/ITaskManager.cs +++ b/Kyoo.Abstractions/Controllers/ITaskManager.cs @@ -2,10 +2,10 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Threading; -using Kyoo.Common.Models.Attributes; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models.Exceptions; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { /// /// A service to handle long running tasks. diff --git a/Kyoo.Common/Controllers/IThumbnailsManager.cs b/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs similarity index 94% rename from Kyoo.Common/Controllers/IThumbnailsManager.cs rename to Kyoo.Abstractions/Controllers/IThumbnailsManager.cs index 61fe5345..54e5be0a 100644 --- a/Kyoo.Common/Controllers/IThumbnailsManager.cs +++ b/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs @@ -1,8 +1,8 @@ -using Kyoo.Models; +using Kyoo.Abstractions.Models; using System.Threading.Tasks; using JetBrains.Annotations; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { /// /// Download images and retrieve the path of those images for a resource. diff --git a/Kyoo.Common/Controllers/ITranscoder.cs b/Kyoo.Abstractions/Controllers/ITranscoder.cs similarity index 75% rename from Kyoo.Common/Controllers/ITranscoder.cs rename to Kyoo.Abstractions/Controllers/ITranscoder.cs index 4fc109d1..d076b9f2 100644 --- a/Kyoo.Common/Controllers/ITranscoder.cs +++ b/Kyoo.Abstractions/Controllers/ITranscoder.cs @@ -1,7 +1,7 @@ -using Kyoo.Models; +using Kyoo.Abstractions.Models; using System.Threading.Tasks; -namespace Kyoo.Controllers +namespace Kyoo.Abstractions.Controllers { public interface ITranscoder { diff --git a/Kyoo.Abstractions/Controllers/StartupAction.cs b/Kyoo.Abstractions/Controllers/StartupAction.cs new file mode 100644 index 00000000..fb2b29a5 --- /dev/null +++ b/Kyoo.Abstractions/Controllers/StartupAction.cs @@ -0,0 +1,221 @@ +using System; +using Microsoft.Extensions.DependencyInjection; + +namespace Kyoo.Abstractions.Controllers +{ + /// + /// A list of constant priorities used for 's . + /// It also contains helper methods for creating new . + /// + public static class SA + { + public const int Before = 5000; + public const int Routing = 4000; + public const int StaticFiles = 3000; + public const int Authentication = 2000; + public const int Authorization = 1000; + public const int Endpoint = 0; + public const int After = -1000; + + /// + /// Create a new . + /// + /// The action to run + /// The priority of the new action + /// A new + public static StartupAction New(Action action, int priority) + => new(action, priority); + + /// + /// Create a new . + /// + /// The action to run + /// The priority of the new action + /// A dependency that this action will use. + /// A new + public static StartupAction New(Action action, int priority) + => new(action, priority); + + /// + /// Create a new . + /// + /// The action to run + /// The priority of the new action + /// A dependency that this action will use. + /// A second dependency that this action will use. + /// A new + public static StartupAction New(Action action, int priority) + => new(action, priority); + + /// + /// Create a new . + /// + /// The action to run + /// The priority of the new action + /// A dependency that this action will use. + /// A second dependency that this action will use. + /// A third dependency that this action will use. + /// A new + public static StartupAction New(Action action, int priority) + => new(action, priority); + } + + + /// + /// An action executed on kyoo's startup to initialize the asp-net container. + /// + /// + /// This is the base interface, see for a simpler use of this. + /// + public interface IStartupAction + { + /// + /// 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. + /// + int Priority { get; } + + /// + /// Run this action to configure the container, a service provider containing all services can be used. + /// + /// The service provider containing all services can be used. + void Run(IServiceProvider provider); + } + + /// + /// A with no dependencies. + /// + public class StartupAction : IStartupAction + { + /// + /// The action to execute at startup. + /// + private readonly Action _action; + + /// + public int Priority { get; } + + /// + /// Create a new . + /// + /// The action to execute on startup. + /// The priority of this action (see ). + public StartupAction(Action action, int priority) + { + _action = action; + Priority = priority; + } + + /// + public void Run(IServiceProvider provider) + { + _action.Invoke(); + } + } + + /// + /// A with one dependencies. + /// + /// The dependency to use. + public class StartupAction : IStartupAction + { + /// + /// The action to execute at startup. + /// + private readonly Action _action; + + /// + public int Priority { get; } + + /// + /// Create a new . + /// + /// The action to execute on startup. + /// The priority of this action (see ). + public StartupAction(Action action, int priority) + { + _action = action; + Priority = priority; + } + + /// + public void Run(IServiceProvider provider) + { + _action.Invoke(provider.GetRequiredService()); + } + } + + /// + /// A with two dependencies. + /// + /// The dependency to use. + /// The second dependency to use. + public class StartupAction : IStartupAction + { + /// + /// The action to execute at startup. + /// + private readonly Action _action; + + /// + public int Priority { get; } + + /// + /// Create a new . + /// + /// The action to execute on startup. + /// The priority of this action (see ). + public StartupAction(Action action, int priority) + { + _action = action; + Priority = priority; + } + + /// + public void Run(IServiceProvider provider) + { + _action.Invoke( + provider.GetRequiredService(), + provider.GetRequiredService() + ); + } + } + + /// + /// A with three dependencies. + /// + /// The dependency to use. + /// The second dependency to use. + /// The third dependency to use. + public class StartupAction : IStartupAction + { + /// + /// The action to execute at startup. + /// + private readonly Action _action; + + /// + public int Priority { get; } + + /// + /// Create a new . + /// + /// The action to execute on startup. + /// The priority of this action (see ). + public StartupAction(Action action, int priority) + { + _action = action; + Priority = priority; + } + + /// + public void Run(IServiceProvider provider) + { + _action.Invoke( + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService() + ); + } + } +} \ No newline at end of file diff --git a/Kyoo.Common/Kyoo.Common.csproj b/Kyoo.Abstractions/Kyoo.Abstractions.csproj similarity index 91% rename from Kyoo.Common/Kyoo.Common.csproj rename to Kyoo.Abstractions/Kyoo.Abstractions.csproj index ec328eab..9831afb3 100644 --- a/Kyoo.Common/Kyoo.Common.csproj +++ b/Kyoo.Abstractions/Kyoo.Abstractions.csproj @@ -3,7 +3,7 @@ net5.0 true - Kyoo.Common + Kyoo.Abstractions Zoe Roux Base package to create plugins for Kyoo. https://github.com/AnonymusRaccoon/Kyoo @@ -12,10 +12,11 @@ SDG GPL-3.0-or-later true - 1.0.25 + 1.0.0 true snupkg default + Kyoo.Abstractions diff --git a/Kyoo.Abstractions/Models/AsyncRef.cs b/Kyoo.Abstractions/Models/AsyncRef.cs new file mode 100644 index 00000000..26885f56 --- /dev/null +++ b/Kyoo.Abstractions/Models/AsyncRef.cs @@ -0,0 +1,17 @@ +namespace Kyoo.Abstractions.Models +{ + /// + /// A class wrapping a value that will be set after the completion of the task it is related to. + /// + /// + /// This class replace the use of an out parameter on a task since tasks and out can't be combined. + /// + /// The type of the value + public class AsyncRef + { + /// + /// The value that will be set before the completion of the task. + /// + public T Value { get; set; } + } +} \ No newline at end of file diff --git a/Kyoo.Common/Models/Attributes/ComputedAttribute.cs b/Kyoo.Abstractions/Models/Attributes/ComputedAttribute.cs similarity index 84% rename from Kyoo.Common/Models/Attributes/ComputedAttribute.cs rename to Kyoo.Abstractions/Models/Attributes/ComputedAttribute.cs index b7f07048..dbdfa09b 100644 --- a/Kyoo.Common/Models/Attributes/ComputedAttribute.cs +++ b/Kyoo.Abstractions/Models/Attributes/ComputedAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace Kyoo.Models.Attributes +namespace Kyoo.Abstractions.Models.Attributes { /// /// An attribute to inform that the property is computed automatically and can't be assigned manually. diff --git a/Kyoo.Common/Models/Attributes/FileSystemMetadataAttribute.cs b/Kyoo.Abstractions/Models/Attributes/FileSystemMetadataAttribute.cs similarity index 95% rename from Kyoo.Common/Models/Attributes/FileSystemMetadataAttribute.cs rename to Kyoo.Abstractions/Models/Attributes/FileSystemMetadataAttribute.cs index d2b997a5..afab7bc1 100644 --- a/Kyoo.Common/Models/Attributes/FileSystemMetadataAttribute.cs +++ b/Kyoo.Abstractions/Models/Attributes/FileSystemMetadataAttribute.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.ComponentModel.Composition; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; -namespace Kyoo.Common.Models.Attributes +namespace Kyoo.Abstractions.Models.Attributes { /// /// An attribute to inform how a works. diff --git a/Kyoo.Common/Models/Attributes/MergeAttributes.cs b/Kyoo.Abstractions/Models/Attributes/MergeAttributes.cs similarity index 92% rename from Kyoo.Common/Models/Attributes/MergeAttributes.cs rename to Kyoo.Abstractions/Models/Attributes/MergeAttributes.cs index 54d49d52..1cfc8e13 100644 --- a/Kyoo.Common/Models/Attributes/MergeAttributes.cs +++ b/Kyoo.Abstractions/Models/Attributes/MergeAttributes.cs @@ -1,6 +1,6 @@ using System; -namespace Kyoo.Models.Attributes +namespace Kyoo.Abstractions.Models.Attributes { /// /// Specify that a property can't be merged. diff --git a/Kyoo.Common/Models/Attributes/PermissionAttribute.cs b/Kyoo.Abstractions/Models/Attributes/PermissionAttribute.cs similarity index 99% rename from Kyoo.Common/Models/Attributes/PermissionAttribute.cs rename to Kyoo.Abstractions/Models/Attributes/PermissionAttribute.cs index 24de7950..b343547a 100644 --- a/Kyoo.Common/Models/Attributes/PermissionAttribute.cs +++ b/Kyoo.Abstractions/Models/Attributes/PermissionAttribute.cs @@ -2,7 +2,7 @@ using System; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; -namespace Kyoo.Models.Permissions +namespace Kyoo.Abstractions.Models.Permissions { /// /// The kind of permission needed. diff --git a/Kyoo.Common/Models/Attributes/RelationAttributes.cs b/Kyoo.Abstractions/Models/Attributes/RelationAttributes.cs similarity index 92% rename from Kyoo.Common/Models/Attributes/RelationAttributes.cs rename to Kyoo.Abstractions/Models/Attributes/RelationAttributes.cs index ef84f5e5..943bd1fe 100644 --- a/Kyoo.Common/Models/Attributes/RelationAttributes.cs +++ b/Kyoo.Abstractions/Models/Attributes/RelationAttributes.cs @@ -1,7 +1,7 @@ using System; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; -namespace Kyoo.Models.Attributes +namespace Kyoo.Abstractions.Models.Attributes { /// /// The targeted relation can be edited via calls to the repository's method. diff --git a/Kyoo.Common/Models/Attributes/SerializeAttribute.cs b/Kyoo.Abstractions/Models/Attributes/SerializeAttribute.cs similarity index 97% rename from Kyoo.Common/Models/Attributes/SerializeAttribute.cs rename to Kyoo.Abstractions/Models/Attributes/SerializeAttribute.cs index a7958c91..d2f2eb68 100644 --- a/Kyoo.Common/Models/Attributes/SerializeAttribute.cs +++ b/Kyoo.Abstractions/Models/Attributes/SerializeAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace Kyoo.Models.Attributes +namespace Kyoo.Abstractions.Models.Attributes { /// /// Remove an property from the serialization pipeline. It will simply be skipped. diff --git a/Kyoo.Common/Models/Attributes/TaskMetadataAttribute.cs b/Kyoo.Abstractions/Models/Attributes/TaskMetadataAttribute.cs similarity index 96% rename from Kyoo.Common/Models/Attributes/TaskMetadataAttribute.cs rename to Kyoo.Abstractions/Models/Attributes/TaskMetadataAttribute.cs index 0ebe7a34..18cf7802 100644 --- a/Kyoo.Common/Models/Attributes/TaskMetadataAttribute.cs +++ b/Kyoo.Abstractions/Models/Attributes/TaskMetadataAttribute.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.ComponentModel.Composition; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; -namespace Kyoo.Common.Models.Attributes +namespace Kyoo.Abstractions.Models.Attributes { /// /// An attribute to inform how a works. diff --git a/Kyoo.Common/Models/Chapter.cs b/Kyoo.Abstractions/Models/Chapter.cs similarity index 97% rename from Kyoo.Common/Models/Chapter.cs rename to Kyoo.Abstractions/Models/Chapter.cs index 51ccc231..4605e7b4 100644 --- a/Kyoo.Common/Models/Chapter.cs +++ b/Kyoo.Abstractions/Models/Chapter.cs @@ -1,4 +1,4 @@ -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A chapter to split an episode in multiple parts. diff --git a/Kyoo.Common/Models/ConfigurationReference.cs b/Kyoo.Abstractions/Models/ConfigurationReference.cs similarity index 98% rename from Kyoo.Common/Models/ConfigurationReference.cs rename to Kyoo.Abstractions/Models/ConfigurationReference.cs index 00d20b4c..8b1064dd 100644 --- a/Kyoo.Common/Models/ConfigurationReference.cs +++ b/Kyoo.Abstractions/Models/ConfigurationReference.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Reflection; using JetBrains.Annotations; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A class given information about a strongly typed configuration. diff --git a/Kyoo.Common/Models/Exceptions/DuplicatedItemException.cs b/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs similarity index 95% rename from Kyoo.Common/Models/Exceptions/DuplicatedItemException.cs rename to Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs index b0d26bf0..248ea2ba 100644 --- a/Kyoo.Common/Models/Exceptions/DuplicatedItemException.cs +++ b/Kyoo.Abstractions/Models/Exceptions/DuplicatedItemException.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.Serialization; -namespace Kyoo.Models.Exceptions +namespace Kyoo.Abstractions.Models.Exceptions { /// /// An exception raised when an item already exists in the database. diff --git a/Kyoo.Common/Models/Exceptions/IdentificationFailedException.cs b/Kyoo.Abstractions/Models/Exceptions/IdentificationFailedException.cs similarity index 92% rename from Kyoo.Common/Models/Exceptions/IdentificationFailedException.cs rename to Kyoo.Abstractions/Models/Exceptions/IdentificationFailedException.cs index 7c820f5a..05740b42 100644 --- a/Kyoo.Common/Models/Exceptions/IdentificationFailedException.cs +++ b/Kyoo.Abstractions/Models/Exceptions/IdentificationFailedException.cs @@ -1,8 +1,8 @@ using System; using System.Runtime.Serialization; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; -namespace Kyoo.Models.Exceptions +namespace Kyoo.Abstractions.Models.Exceptions { /// /// An exception raised when an failed. diff --git a/Kyoo.Common/Models/Exceptions/ItemNotFoundException.cs b/Kyoo.Abstractions/Models/Exceptions/ItemNotFoundException.cs similarity index 95% rename from Kyoo.Common/Models/Exceptions/ItemNotFoundException.cs rename to Kyoo.Abstractions/Models/Exceptions/ItemNotFoundException.cs index d05882b1..5a16e62e 100644 --- a/Kyoo.Common/Models/Exceptions/ItemNotFoundException.cs +++ b/Kyoo.Abstractions/Models/Exceptions/ItemNotFoundException.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.Serialization; -namespace Kyoo.Models.Exceptions +namespace Kyoo.Abstractions.Models.Exceptions { /// /// An exception raised when an item could not be found. diff --git a/Kyoo.Common/Models/Exceptions/TaskFailedException.cs b/Kyoo.Abstractions/Models/Exceptions/TaskFailedException.cs similarity index 93% rename from Kyoo.Common/Models/Exceptions/TaskFailedException.cs rename to Kyoo.Abstractions/Models/Exceptions/TaskFailedException.cs index 5fe65f7c..eebc784e 100644 --- a/Kyoo.Common/Models/Exceptions/TaskFailedException.cs +++ b/Kyoo.Abstractions/Models/Exceptions/TaskFailedException.cs @@ -1,8 +1,8 @@ using System; using System.Runtime.Serialization; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; -namespace Kyoo.Models.Exceptions +namespace Kyoo.Abstractions.Models.Exceptions { /// /// An exception raised when an failed. diff --git a/Kyoo.Common/Models/LibraryItem.cs b/Kyoo.Abstractions/Models/LibraryItem.cs similarity index 98% rename from Kyoo.Common/Models/LibraryItem.cs rename to Kyoo.Abstractions/Models/LibraryItem.cs index 18680b9e..802e98a3 100644 --- a/Kyoo.Common/Models/LibraryItem.cs +++ b/Kyoo.Abstractions/Models/LibraryItem.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// The type of item, ether a show, a movie or a collection. diff --git a/Kyoo.Common/Models/MetadataID.cs b/Kyoo.Abstractions/Models/MetadataID.cs similarity index 93% rename from Kyoo.Common/Models/MetadataID.cs rename to Kyoo.Abstractions/Models/MetadataID.cs index cda4ce11..5cdf08ea 100644 --- a/Kyoo.Common/Models/MetadataID.cs +++ b/Kyoo.Abstractions/Models/MetadataID.cs @@ -1,8 +1,8 @@ using System; using System.Linq.Expressions; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// ID and link of an item on an external provider. diff --git a/Kyoo.Common/Models/Page.cs b/Kyoo.Abstractions/Models/Page.cs similarity index 98% rename from Kyoo.Common/Models/Page.cs rename to Kyoo.Abstractions/Models/Page.cs index 1c8cff69..eb8898d2 100644 --- a/Kyoo.Common/Models/Page.cs +++ b/Kyoo.Abstractions/Models/Page.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A page of resource that contains information about the pagination of resources. diff --git a/Kyoo.Common/Models/PeopleRole.cs b/Kyoo.Abstractions/Models/PeopleRole.cs similarity index 97% rename from Kyoo.Common/Models/PeopleRole.cs rename to Kyoo.Abstractions/Models/PeopleRole.cs index daf9c7cd..934daf7d 100644 --- a/Kyoo.Common/Models/PeopleRole.cs +++ b/Kyoo.Abstractions/Models/PeopleRole.cs @@ -1,4 +1,4 @@ -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A role a person played for a show. It can be an actor, musician, voice actor, director, writer... diff --git a/Kyoo.Common/Models/Resources/Collection.cs b/Kyoo.Abstractions/Models/Resources/Collection.cs similarity index 95% rename from Kyoo.Common/Models/Resources/Collection.cs rename to Kyoo.Abstractions/Models/Resources/Collection.cs index 20cc481b..faa7ac9f 100644 --- a/Kyoo.Common/Models/Resources/Collection.cs +++ b/Kyoo.Abstractions/Models/Resources/Collection.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A class representing collections of . diff --git a/Kyoo.Common/Models/Resources/Episode.cs b/Kyoo.Abstractions/Models/Resources/Episode.cs similarity index 97% rename from Kyoo.Common/Models/Resources/Episode.cs rename to Kyoo.Abstractions/Models/Resources/Episode.cs index dd1f62e1..65e1bd29 100644 --- a/Kyoo.Common/Models/Resources/Episode.cs +++ b/Kyoo.Abstractions/Models/Resources/Episode.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using System.Text.RegularExpressions; using JetBrains.Annotations; -using Kyoo.Controllers; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A class to represent a single show's episode. diff --git a/Kyoo.Common/Models/Resources/Genre.cs b/Kyoo.Abstractions/Models/Resources/Genre.cs similarity index 92% rename from Kyoo.Common/Models/Resources/Genre.cs rename to Kyoo.Abstractions/Models/Resources/Genre.cs index e5fcbed8..b346381f 100644 --- a/Kyoo.Common/Models/Resources/Genre.cs +++ b/Kyoo.Abstractions/Models/Resources/Genre.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A genre that allow one to specify categories for shows. diff --git a/Kyoo.Common/Models/Resources/Interfaces/IMetadata.cs b/Kyoo.Abstractions/Models/Resources/Interfaces/IMetadata.cs similarity index 97% rename from Kyoo.Common/Models/Resources/Interfaces/IMetadata.cs rename to Kyoo.Abstractions/Models/Resources/Interfaces/IMetadata.cs index ef1e6bbc..b28d893a 100644 --- a/Kyoo.Common/Models/Resources/Interfaces/IMetadata.cs +++ b/Kyoo.Abstractions/Models/Resources/Interfaces/IMetadata.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// An interface applied to resources containing external metadata. diff --git a/Kyoo.Common/Models/Resources/Interfaces/IResource.cs b/Kyoo.Abstractions/Models/Resources/Interfaces/IResource.cs similarity index 92% rename from Kyoo.Common/Models/Resources/Interfaces/IResource.cs rename to Kyoo.Abstractions/Models/Resources/Interfaces/IResource.cs index 4867bc0a..bde5aef6 100644 --- a/Kyoo.Common/Models/Resources/Interfaces/IResource.cs +++ b/Kyoo.Abstractions/Models/Resources/Interfaces/IResource.cs @@ -1,6 +1,6 @@ -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// An interface to represent a resource that can be retrieved from the database. diff --git a/Kyoo.Common/Models/Resources/Interfaces/IThumbnails.cs b/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs similarity index 95% rename from Kyoo.Common/Models/Resources/Interfaces/IThumbnails.cs rename to Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs index ba4999de..670dbb51 100644 --- a/Kyoo.Common/Models/Resources/Interfaces/IThumbnails.cs +++ b/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// An interface representing items that contains images (like posters, thumbnails, logo, banners...) diff --git a/Kyoo.Common/Models/Resources/Library.cs b/Kyoo.Abstractions/Models/Resources/Library.cs similarity index 93% rename from Kyoo.Common/Models/Resources/Library.cs rename to Kyoo.Abstractions/Models/Resources/Library.cs index 6580f988..fad1156e 100644 --- a/Kyoo.Common/Models/Resources/Library.cs +++ b/Kyoo.Abstractions/Models/Resources/Library.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A library containing and . diff --git a/Kyoo.Common/Models/Resources/People.cs b/Kyoo.Abstractions/Models/Resources/People.cs similarity index 94% rename from Kyoo.Common/Models/Resources/People.cs rename to Kyoo.Abstractions/Models/Resources/People.cs index 7bd59620..ce46c6a7 100644 --- a/Kyoo.Common/Models/Resources/People.cs +++ b/Kyoo.Abstractions/Models/Resources/People.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// An actor, voice actor, writer, animator, somebody who worked on a . diff --git a/Kyoo.Common/Models/Resources/Provider.cs b/Kyoo.Abstractions/Models/Resources/Provider.cs similarity index 93% rename from Kyoo.Common/Models/Resources/Provider.cs rename to Kyoo.Abstractions/Models/Resources/Provider.cs index 31b87f3f..61726100 100644 --- a/Kyoo.Common/Models/Resources/Provider.cs +++ b/Kyoo.Abstractions/Models/Resources/Provider.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using Kyoo.Controllers; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// This class contains metadata about . diff --git a/Kyoo.Common/Models/Resources/Season.cs b/Kyoo.Abstractions/Models/Resources/Season.cs similarity index 96% rename from Kyoo.Common/Models/Resources/Season.cs rename to Kyoo.Abstractions/Models/Resources/Season.cs index 2c5d59eb..d60da6d8 100644 --- a/Kyoo.Common/Models/Resources/Season.cs +++ b/Kyoo.Abstractions/Models/Resources/Season.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using System.Text.RegularExpressions; using JetBrains.Annotations; -using Kyoo.Controllers; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A season of a . diff --git a/Kyoo.Common/Models/Resources/Show.cs b/Kyoo.Abstractions/Models/Resources/Show.cs similarity index 97% rename from Kyoo.Common/Models/Resources/Show.cs rename to Kyoo.Abstractions/Models/Resources/Show.cs index 03c86e5e..77f18d99 100644 --- a/Kyoo.Common/Models/Resources/Show.cs +++ b/Kyoo.Abstractions/Models/Resources/Show.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using Kyoo.Controllers; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A series or a movie. diff --git a/Kyoo.Common/Models/Resources/Studio.cs b/Kyoo.Abstractions/Models/Resources/Studio.cs similarity index 92% rename from Kyoo.Common/Models/Resources/Studio.cs rename to Kyoo.Abstractions/Models/Resources/Studio.cs index 03ec04df..f0e14567 100644 --- a/Kyoo.Common/Models/Resources/Studio.cs +++ b/Kyoo.Abstractions/Models/Resources/Studio.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A studio that make shows. diff --git a/Kyoo.Common/Models/Resources/Track.cs b/Kyoo.Abstractions/Models/Resources/Track.cs similarity index 94% rename from Kyoo.Common/Models/Resources/Track.cs rename to Kyoo.Abstractions/Models/Resources/Track.cs index d82cdbe1..4f94b7f3 100644 --- a/Kyoo.Common/Models/Resources/Track.cs +++ b/Kyoo.Abstractions/Models/Resources/Track.cs @@ -3,9 +3,9 @@ using System.Globalization; using System.Linq; using System.Text.RegularExpressions; using JetBrains.Annotations; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models.Attributes; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// The list of available stream types. @@ -60,9 +60,9 @@ namespace Kyoo.Models } /// - /// The slug of the episode that contain this track. If this is not set, this track is ill-formed. - /// - [SerializeIgnore] public string EpisodeSlug { private get; set; } + /// The slug of the episode that contain this track. If this is not set, this track is ill-formed. + /// + [SerializeIgnore] public string EpisodeSlug { private get; set; } /// /// The title of the stream. diff --git a/Kyoo.Common/Models/Resources/User.cs b/Kyoo.Abstractions/Models/Resources/User.cs similarity index 98% rename from Kyoo.Common/Models/Resources/User.cs rename to Kyoo.Abstractions/Models/Resources/User.cs index 3400df62..8e61cb64 100644 --- a/Kyoo.Common/Models/Resources/User.cs +++ b/Kyoo.Abstractions/Models/Resources/User.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A single user of the app. diff --git a/Kyoo.Common/Models/SearchResult.cs b/Kyoo.Abstractions/Models/SearchResult.cs similarity index 96% rename from Kyoo.Common/Models/SearchResult.cs rename to Kyoo.Abstractions/Models/SearchResult.cs index 9ec2bc37..9b1b5006 100644 --- a/Kyoo.Common/Models/SearchResult.cs +++ b/Kyoo.Abstractions/Models/SearchResult.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// Results of a search request. diff --git a/Kyoo.Common/Models/WatchItem.cs b/Kyoo.Abstractions/Models/WatchItem.cs similarity index 98% rename from Kyoo.Common/Models/WatchItem.cs rename to Kyoo.Abstractions/Models/WatchItem.cs index 158563a8..3f48a636 100644 --- a/Kyoo.Common/Models/WatchItem.cs +++ b/Kyoo.Abstractions/Models/WatchItem.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Attributes; using PathIO = System.IO.Path; -namespace Kyoo.Models +namespace Kyoo.Abstractions.Models { /// /// A watch item give information useful for playback. diff --git a/Kyoo.Common/Module.cs b/Kyoo.Abstractions/Module.cs similarity index 98% rename from Kyoo.Common/Module.cs rename to Kyoo.Abstractions/Module.cs index 7fb9bdbc..f4594387 100644 --- a/Kyoo.Common/Module.cs +++ b/Kyoo.Abstractions/Module.cs @@ -1,9 +1,9 @@ using Autofac; using Autofac.Builder; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; using Microsoft.Extensions.Configuration; -namespace Kyoo +namespace Kyoo.Abstractions { /// /// A static class with helper functions to setup external modules diff --git a/Kyoo.Common/Utility/EnumerableExtensions.cs b/Kyoo.Abstractions/Utility/EnumerableExtensions.cs similarity index 100% rename from Kyoo.Common/Utility/EnumerableExtensions.cs rename to Kyoo.Abstractions/Utility/EnumerableExtensions.cs diff --git a/Kyoo.Common/Utility/Merger.cs b/Kyoo.Abstractions/Utility/Merger.cs similarity index 99% rename from Kyoo.Common/Utility/Merger.cs rename to Kyoo.Abstractions/Utility/Merger.cs index 32441c1d..c59f47a1 100644 --- a/Kyoo.Common/Utility/Merger.cs +++ b/Kyoo.Abstractions/Utility/Merger.cs @@ -5,8 +5,8 @@ using System.ComponentModel; using System.Linq; using System.Reflection; using JetBrains.Annotations; -using Kyoo.Models; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; namespace Kyoo { diff --git a/Kyoo.Common/MethodOfUtils.cs b/Kyoo.Abstractions/Utility/MethodOfUtils.cs similarity index 100% rename from Kyoo.Common/MethodOfUtils.cs rename to Kyoo.Abstractions/Utility/MethodOfUtils.cs diff --git a/Kyoo.Common/Utility/TaskUtils.cs b/Kyoo.Abstractions/Utility/TaskUtils.cs similarity index 54% rename from Kyoo.Common/Utility/TaskUtils.cs rename to Kyoo.Abstractions/Utility/TaskUtils.cs index 78332cc9..a0d04b03 100644 --- a/Kyoo.Common/Utility/TaskUtils.cs +++ b/Kyoo.Abstractions/Utility/TaskUtils.cs @@ -21,17 +21,17 @@ namespace Kyoo /// /// The source task has been canceled. public static Task Then(this Task task, Action then) - { - return task.ContinueWith(x => - { - if (x.IsFaulted) - x.Exception!.InnerException!.ReThrow(); - if (x.IsCanceled) - throw new TaskCanceledException(); - then(x.Result); - return x.Result; - }, TaskContinuationOptions.ExecuteSynchronously); - } + { + return task.ContinueWith(x => + { + if (x.IsFaulted) + x.Exception!.InnerException!.ReThrow(); + if (x.IsCanceled) + throw new TaskCanceledException(); + then(x.Result); + return x.Result; + }, TaskContinuationOptions.ExecuteSynchronously); + } /// /// Map the result of a task to another result. @@ -42,28 +42,28 @@ namespace Kyoo /// The resulting task after the mapping method /// A task wrapping the initial task and mapping the initial result. /// The source task has been canceled. - public static Task Map(this Task task, Func map) - { - return task.ContinueWith(x => - { - if (x.IsFaulted) - x.Exception!.InnerException!.ReThrow(); - if (x.IsCanceled) - throw new TaskCanceledException(); - return map(x.Result); - }, TaskContinuationOptions.ExecuteSynchronously); - } + public static Task Map(this Task task, Func map) + { + return task.ContinueWith(x => + { + if (x.IsFaulted) + x.Exception!.InnerException!.ReThrow(); + if (x.IsCanceled) + throw new TaskCanceledException(); + return map(x.Result); + }, TaskContinuationOptions.ExecuteSynchronously); + } - /// - /// A method to return the a default value from a task if the initial task is null. - /// - /// The initial task - /// The type that the task will return - /// A non-null task. - [NotNull] - public static Task DefaultIfNull([CanBeNull] Task value) - { - return value ?? Task.FromResult(default); - } + /// + /// A method to return the a default value from a task if the initial task is null. + /// + /// The initial task + /// The type that the task will return + /// A non-null task. + [NotNull] + public static Task DefaultIfNull([CanBeNull] Task value) + { + return value ?? Task.FromResult(default); + } } } \ No newline at end of file diff --git a/Kyoo.Common/Utility/Utility.cs b/Kyoo.Abstractions/Utility/Utility.cs similarity index 98% rename from Kyoo.Common/Utility/Utility.cs rename to Kyoo.Abstractions/Utility/Utility.cs index 72d25fd5..ab4fc92d 100644 --- a/Kyoo.Common/Utility/Utility.cs +++ b/Kyoo.Abstractions/Utility/Utility.cs @@ -155,7 +155,8 @@ namespace Kyoo IEnumerable types = genericType.IsInterface ? type.GetInterfaces() : type.GetInheritanceTree(); - return types.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType); + return types.Prepend(type) + .Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType); } /// @@ -179,7 +180,8 @@ namespace Kyoo IEnumerable types = genericType.IsInterface ? type.GetInterfaces() : type.GetInheritanceTree(); - return types.FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType); + return types.Prepend(type) + .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType); } /// diff --git a/Kyoo.Authentication/AuthenticationModule.cs b/Kyoo.Authentication/AuthenticationModule.cs index 1e9dcd01..61f3d929 100644 --- a/Kyoo.Authentication/AuthenticationModule.cs +++ b/Kyoo.Authentication/AuthenticationModule.cs @@ -3,14 +3,15 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using Autofac; using IdentityServer4.Extensions; using IdentityServer4.Models; using IdentityServer4.Services; +using Kyoo.Abstractions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Authentication.Models; using Kyoo.Authentication.Views; -using Kyoo.Controllers; -using Kyoo.Models.Attributes; -using Kyoo.Models.Permissions; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -37,58 +38,61 @@ namespace Kyoo.Authentication /// public string Description => "Enable OpenID authentication for Kyoo."; - + /// - public ICollection Provides => ArraySegment.Empty; - - /// - public ICollection ConditionalProvides => ArraySegment.Empty; - - /// - public ICollection Requires => new [] + public Dictionary Configuration => new() { - typeof(IUserRepository) + { AuthenticationOption.Path, typeof(AuthenticationOption) }, + { PermissionOption.Path, typeof(PermissionOption) }, + { CertificateOption.Path, typeof(CertificateOption) } }; - - + + /// /// The configuration to use. /// private readonly IConfiguration _configuration; /// - /// A logger factory to allow IdentityServer to log things. + /// The logger used to allow IdentityServer to log things. /// - private readonly ILoggerFactory _loggerFactory; + private readonly ILogger _logger; /// /// The environment information to check if the app runs in debug mode /// private readonly IWebHostEnvironment _environment; - - /// - /// The configuration manager used to register typed/untyped implementations. - /// - [Injected] public IConfigurationManager ConfigurationManager { private get; set; } /// /// Create a new authentication module instance and use the given configuration and environment. /// /// The configuration to use - /// The logger factory to allow IdentityServer to log things + /// The logger used to allow IdentityServer to log things /// The environment information to check if the app runs in debug mode public AuthenticationModule(IConfiguration configuration, - ILoggerFactory loggerFactory, + ILogger logger, IWebHostEnvironment environment) { _configuration = configuration; - _loggerFactory = loggerFactory; + _logger = logger; _environment = environment; } /// - public void Configure(IServiceCollection services, ICollection availableTypes) + public void Configure(ContainerBuilder builder) + { + builder.RegisterType().As().SingleInstance(); + + DefaultCorsPolicyService cors = new(_logger) + { + AllowedOrigins = { new Uri(_configuration.GetPublicUrl()).GetLeftPart(UriPartial.Authority) } + }; + builder.RegisterInstance(cors).As().SingleInstance(); + } + + /// + public void Configure(IServiceCollection services) { string publicUrl = _configuration.GetPublicUrl(); @@ -100,10 +104,6 @@ namespace Kyoo.Authentication // TODO handle direct-videos with bearers (probably add a cookie and a app.Use to translate that for videos) // TODO Check if tokens should be stored. - - services.Configure(_configuration.GetSection(PermissionOption.Path)); - services.Configure(_configuration.GetSection(CertificateOption.Path)); - services.Configure(_configuration.GetSection(AuthenticationOption.Path)); List clients = new(); _configuration.GetSection("authentication:clients").Bind(clients); @@ -131,47 +131,46 @@ namespace Kyoo.Authentication options.Audience = "kyoo"; options.RequireHttpsMetadata = false; }); - services.AddSingleton(); - - DefaultCorsPolicyService cors = new(_loggerFactory.CreateLogger()) - { - AllowedOrigins = {new Uri(publicUrl).GetLeftPart(UriPartial.Authority)} - }; - services.AddSingleton(cors); } /// - public void ConfigureAspNet(IApplicationBuilder app) + public IEnumerable ConfigureSteps => new IStartupAction[] { - ConfigurationManager.AddTyped(AuthenticationOption.Path); - - app.UseCookiePolicy(new CookiePolicyOptions + SA.New(app => { - MinimumSameSitePolicy = SameSiteMode.Strict - }); - app.UseAuthentication(); - app.Use((ctx, next) => + PhysicalFileProvider provider = new(Path.Combine( + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, + "login")); + app.UseDefaultFiles(new DefaultFilesOptions + { + RequestPath = new PathString("/login"), + FileProvider = provider, + RedirectToAppendTrailingSlash = true + }); + app.UseStaticFiles(new StaticFileOptions + { + RequestPath = new PathString("/login"), + FileProvider = provider + }); + }, SA.StaticFiles), + SA.New(app => { - ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl()); - return next(); - }); - app.UseIdentityServer(); - app.UseAuthorization(); - - PhysicalFileProvider provider = new(Path.Combine( - Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, - "login")); - app.UseDefaultFiles(new DefaultFilesOptions + app.UseCookiePolicy(new CookiePolicyOptions + { + MinimumSameSitePolicy = SameSiteMode.Strict + }); + app.UseAuthentication(); + }, SA.Authentication), + SA.New(app => { - RequestPath = new PathString("/login"), - FileProvider = provider, - RedirectToAppendTrailingSlash = true - }); - app.UseStaticFiles(new StaticFileOptions - { - RequestPath = new PathString("/login"), - FileProvider = provider - }); - } + app.Use((ctx, next) => + { + ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl()); + return next(); + }); + app.UseIdentityServer(); + }, SA.Endpoint), + SA.New(app => app.UseAuthorization(), SA.Authorization) + }; } } \ No newline at end of file diff --git a/Kyoo.Authentication/Controllers/Certificates.cs b/Kyoo.Authentication/Controllers/Certificates.cs index 3aaab9b8..906890c4 100644 --- a/Kyoo.Authentication/Controllers/Certificates.cs +++ b/Kyoo.Authentication/Controllers/Certificates.cs @@ -34,7 +34,7 @@ namespace Kyoo.Authentication X509Certificate2 certificate = GetCertificate(options); builder.AddSigningCredential(certificate); - if (certificate.NotAfter.AddDays(7) <= DateTime.UtcNow) + if (certificate.NotAfter.AddDays(-7) <= DateTime.UtcNow) { Console.WriteLine("Signin certificate will expire soon, renewing it."); if (File.Exists(options.OldFile)) @@ -67,7 +67,7 @@ namespace Kyoo.Authentication /// The loaded certificate private static X509Certificate2 GetExistingCredential(string file, string password) { - return new(file, password, + return new X509Certificate2(file, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable diff --git a/Kyoo.Authentication/Controllers/PremissionValidator.cs b/Kyoo.Authentication/Controllers/PremissionValidator.cs index ca3102ed..d34f5e57 100644 --- a/Kyoo.Authentication/Controllers/PremissionValidator.cs +++ b/Kyoo.Authentication/Controllers/PremissionValidator.cs @@ -2,8 +2,8 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Authentication.Models; -using Kyoo.Models.Permissions; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Http; diff --git a/Kyoo.Authentication/Extensions.cs b/Kyoo.Authentication/Extensions.cs index 718a7a44..ca37cd09 100644 --- a/Kyoo.Authentication/Extensions.cs +++ b/Kyoo.Authentication/Extensions.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Security.Claims; using IdentityModel; using IdentityServer4; -using Kyoo.Models; +using Kyoo.Abstractions.Models; namespace Kyoo.Authentication { diff --git a/Kyoo.Authentication/Kyoo.Authentication.csproj b/Kyoo.Authentication/Kyoo.Authentication.csproj index 2cde6c7e..080795b2 100644 --- a/Kyoo.Authentication/Kyoo.Authentication.csproj +++ b/Kyoo.Authentication/Kyoo.Authentication.csproj @@ -2,18 +2,12 @@ net5.0 - ../Kyoo/bin/$(Configuration)/$(TargetFramework)/plugins/authentication - false - false - false - false - true - + ../Kyoo.WebLogin/ + SDG Zoe Roux https://github.com/AnonymusRaccoon/Kyoo default - ../Kyoo.WebLogin/ @@ -23,28 +17,14 @@ - - all - false - runtime - + - + + + login/%(RecursiveDir)%(Filename)%(Extension) + Always + - - - - - login/%(LoginFiles.RecursiveDir)%(LoginFiles.Filename)%(LoginFiles.Extension) - PreserveNewest - true - - - - - - - diff --git a/Kyoo.Authentication/Models/DTO/RegisterRequest.cs b/Kyoo.Authentication/Models/DTO/RegisterRequest.cs index ad556f6d..e10967fd 100644 --- a/Kyoo.Authentication/Models/DTO/RegisterRequest.cs +++ b/Kyoo.Authentication/Models/DTO/RegisterRequest.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using Kyoo.Models; +using Kyoo.Abstractions.Models; namespace Kyoo.Authentication.Models.DTO { @@ -34,7 +34,7 @@ namespace Kyoo.Authentication.Models.DTO /// public User ToUser() { - return new() + return new User { Slug = Utility.ToSlug(Username), Username = Username, diff --git a/Kyoo.Authentication/Views/AccountApi.cs b/Kyoo.Authentication/Views/AccountApi.cs index 4288250e..1e369e31 100644 --- a/Kyoo.Authentication/Views/AccountApi.cs +++ b/Kyoo.Authentication/Views/AccountApi.cs @@ -8,11 +8,11 @@ using System.Threading.Tasks; using IdentityServer4.Extensions; using IdentityServer4.Models; using IdentityServer4.Services; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; using Kyoo.Authentication.Models; using Kyoo.Authentication.Models.DTO; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; diff --git a/Kyoo.Common/Controllers/IPlugin.cs b/Kyoo.Common/Controllers/IPlugin.cs deleted file mode 100644 index ea072c39..00000000 --- a/Kyoo.Common/Controllers/IPlugin.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Autofac; -using JetBrains.Annotations; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; - -namespace Kyoo.Controllers -{ - /// - /// A common interface used to discord plugins - /// - /// - /// You can inject services in the IPlugin constructor. - /// You should only inject well known services like an ILogger, IConfiguration or IWebHostEnvironment. - /// - [UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)] - public interface IPlugin - { - /// - /// A slug to identify this plugin in queries. - /// - string Slug { get; } - - /// - /// The name of the plugin - /// - string Name { get; } - - /// - /// The description of this plugin. This will be displayed on the "installed plugins" page. - /// - string Description { get; } - - /// - /// A list of services that are provided by this service. This allow other plugins to declare dependencies - /// - /// - /// You should put the type's interface that will be register in configure. - /// - ICollection Provides { get; } - - /// - /// A list of types that will be provided only if a condition is met. The condition can be an arbitrary method or - /// a condition based on other type availability. For more information, see . - /// - ICollection ConditionalProvides { get; } - - /// - /// A list of services that are required by this plugin. - /// You can put services that you provide conditionally here if you want. - /// Kyoo will warn the user that this plugin can't be loaded if a required service is not found. - /// - /// - /// Put here the most complete type that are needed for your plugin to work. If you need a LibraryManager, - /// put typeof(ILibraryManager). - /// - ICollection Requires { get; } - - /// - /// A configure method that will be run on plugin's startup. - /// - /// The autofac service container to register services. - void Configure(ContainerBuilder builder) - { - // Skipped - } - - /// - /// A configure method that will be run on plugin's startup. - /// - /// A service container to register new services. - /// The list of types that are available for this instance. This can be used - /// for conditional type. See - /// or > - /// You can't simply check on the service collection because some dependencies might be registered after your plugin. - /// - void Configure(IServiceCollection services, ICollection availableTypes) - { - // Skipped - } - - - /// - /// An optional configuration step to allow a plugin to change asp net configurations. - /// WARNING: This is only called on Kyoo's startup so you must restart the app to apply this changes. - /// - /// - /// The Asp.Net application builder. On most case it is not needed but you can use it to - /// add asp net functionalities. - /// - void ConfigureAspNet(IApplicationBuilder app) - { - // Skipped - } - - /// - /// An optional function to execute and initialize your plugin. - /// It can be used to initialize a database connection, fill initial data or anything. - /// - /// A service provider to request services - void Initialize(IServiceProvider provider) - { - // Skipped - } - } - - /// - /// A type that will only be provided if a special condition is met. To check that your condition is met, - /// you can check the class. - /// - public class ConditionalProvide : Tuple - { - /// - /// Get the type that may be provided - /// - public Type Type => Item1; - - /// - /// Get the condition. - /// - public ProviderCondition Condition => Item2; - - /// - /// Create a from a type and a condition. - /// - /// The type to provide - /// The condition - public ConditionalProvide(Type type, ProviderCondition condition) - : base(type, condition) - { } - - /// - /// Create a from a tuple of (Type, ProviderCondition). - /// - /// The tuple to convert - public ConditionalProvide((Type type, ProviderCondition condition) tuple) - : base(tuple.type, tuple.condition) - { } - - /// - /// Implicitly convert a tuple to a . - /// - /// The tuple to convert - /// A new based on the given tuple. - public static implicit operator ConditionalProvide((Type, Type) tuple) => new (tuple); - } - - /// - /// A condition for a conditional type. - /// - public class ProviderCondition - { - /// - /// The condition as a method. If true is returned, the type will be provided. - /// - public Func Condition { get; } = () => true; - /// - /// The list of types that this method needs. - /// - public ICollection Needed { get; } = ArraySegment.Empty; - - - /// - /// Create a new from a raw function. - /// - /// The predicate that will be used as condition - public ProviderCondition(Func condition) - { - Condition = condition; - } - - /// - /// Create a new from a type. This allow you to inform that a type will - /// only be available if a dependency is met. - /// - /// The type that you need - public ProviderCondition(Type needed) - { - Needed = new[] {needed}; - } - - /// - /// Create a new from a list of type. This allow you to inform that a type will - /// only be available if a list of dependencies are met. - /// - /// The types that you need - public ProviderCondition(ICollection needed) - { - Needed = needed; - } - - /// - /// Create a new with a list of types as dependencies and a predicate - /// for arbitrary conditions. - /// - /// The list of dependencies - /// An arbitrary condition - public ProviderCondition(ICollection needed, Func condition) - { - Needed = needed; - Condition = condition; - } - - - /// - /// Implicitly convert a type to a . - /// - /// The type dependency - /// A that will return true if the given type is available. - public static implicit operator ProviderCondition(Type type) => new(type); - - /// - /// Implicitly convert a list of type to a . - /// - /// The list of type dependencies - /// A that will return true if the given types are available. - public static implicit operator ProviderCondition(Type[] types) => new(types); - - /// - public static implicit operator ProviderCondition(List types) => new(types); - - - /// - /// Check if a type is available. - /// - /// The type to check - /// The list of types - /// True if the dependency is met, false otherwise - public static bool Has(Type needed, ICollection available) - { - return available.Contains(needed); - } - - /// - /// Check if a list of type are available. - /// - /// The list of types to check - /// The list of types - /// True if the dependencies are met, false otherwise - public static bool Has(ICollection needed, ICollection available) - { - return needed.All(x => Has(x, available)); - } - } -} \ No newline at end of file diff --git a/Kyoo.Common/Models/Attributes/InjectedAttribute.cs b/Kyoo.Common/Models/Attributes/InjectedAttribute.cs deleted file mode 100644 index d517300f..00000000 --- a/Kyoo.Common/Models/Attributes/InjectedAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using JetBrains.Annotations; -using Kyoo.Controllers; - -namespace Kyoo.Models.Attributes -{ - /// - /// An attribute to inform that the service will be injected automatically by a service provider. - /// - /// - /// It should only be used on and it will be injected before - /// calling . - /// - [AttributeUsage(AttributeTargets.Property)] - [MeansImplicitUse(ImplicitUseKindFlags.Assign)] - public class InjectedAttribute : Attribute { } -} \ No newline at end of file diff --git a/Kyoo.CommonAPI/DatabaseContext.cs b/Kyoo.Database/DatabaseContext.cs similarity index 99% rename from Kyoo.CommonAPI/DatabaseContext.cs rename to Kyoo.Database/DatabaseContext.cs index ad96ff78..282cb93c 100644 --- a/Kyoo.CommonAPI/DatabaseContext.cs +++ b/Kyoo.Database/DatabaseContext.cs @@ -5,13 +5,13 @@ using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; -namespace Kyoo +namespace Kyoo.Database { /// /// The database handle used for all local repositories. diff --git a/Kyoo.CommonAPI/Extensions.cs b/Kyoo.Database/Extensions.cs similarity index 58% rename from Kyoo.CommonAPI/Extensions.cs rename to Kyoo.Database/Extensions.cs index dfb2d4d8..43031638 100644 --- a/Kyoo.CommonAPI/Extensions.cs +++ b/Kyoo.Database/Extensions.cs @@ -11,16 +11,26 @@ namespace Kyoo /// /// Get a connection string from the Configuration's section "Database" /// - /// The IConfiguration instance to load. + /// The IConfiguration instance to use. /// The database's name. /// A parsed connection string public static string GetDatabaseConnection(this IConfiguration config, string database) { DbConnectionStringBuilder builder = new(); - IConfigurationSection section = config.GetSection("Database").GetSection(database); + IConfigurationSection section = config.GetSection("database:configurations").GetSection(database); foreach (IConfigurationSection child in section.GetChildren()) builder[child.Key] = child.Value; return builder.ConnectionString; } + + /// + /// Get the name of the selected database. + /// + /// The IConfiguration instance to use. + /// The name of the selected database. + public static string GetSelectedDatabase(this IConfiguration config) + { + return config.GetValue("database:enabled"); + } } } \ No newline at end of file diff --git a/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj b/Kyoo.Database/Kyoo.Database.csproj similarity index 78% rename from Kyoo.CommonAPI/Kyoo.CommonAPI.csproj rename to Kyoo.Database/Kyoo.Database.csproj index 451c387d..9a64194a 100644 --- a/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj +++ b/Kyoo.Database/Kyoo.Database.csproj @@ -2,9 +2,8 @@ net5.0 - Kyoo.CommonApi - Kyoo.CommonApi - Kyoo.CommonApi + Kyoo.Database + Kyoo.Database Zoe Roux https://github.com/AnonymusRaccoon/Kyoo Library @@ -19,7 +18,7 @@ - + diff --git a/Kyoo.Postgresql/Kyoo.Postgresql.csproj b/Kyoo.Postgresql/Kyoo.Postgresql.csproj index a53ba3b7..e356ba8a 100644 --- a/Kyoo.Postgresql/Kyoo.Postgresql.csproj +++ b/Kyoo.Postgresql/Kyoo.Postgresql.csproj @@ -18,9 +18,7 @@ - - - - + + diff --git a/Kyoo.Postgresql/Migrations/20210801171613_Initial.Designer.cs b/Kyoo.Postgresql/Migrations/20210801171613_Initial.Designer.cs index 20b6f7bd..958d1951 100644 --- a/Kyoo.Postgresql/Migrations/20210801171613_Initial.Designer.cs +++ b/Kyoo.Postgresql/Migrations/20210801171613_Initial.Designer.cs @@ -1,7 +1,7 @@ // using System; using System.Collections.Generic; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using Kyoo.Postgresql; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; diff --git a/Kyoo.Postgresql/Migrations/20210801171613_Initial.cs b/Kyoo.Postgresql/Migrations/20210801171613_Initial.cs index 395d9e27..1f336f4e 100644 --- a/Kyoo.Postgresql/Migrations/20210801171613_Initial.cs +++ b/Kyoo.Postgresql/Migrations/20210801171613_Initial.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; diff --git a/Kyoo.Postgresql/Migrations/20210801171641_Triggers.Designer.cs b/Kyoo.Postgresql/Migrations/20210801171641_Triggers.Designer.cs index fd13824a..02738ac0 100644 --- a/Kyoo.Postgresql/Migrations/20210801171641_Triggers.Designer.cs +++ b/Kyoo.Postgresql/Migrations/20210801171641_Triggers.Designer.cs @@ -1,7 +1,7 @@ // using System; using System.Collections.Generic; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using Kyoo.Postgresql; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; diff --git a/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs b/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs index cd338b2f..a3b33778 100644 --- a/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs +++ b/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs @@ -1,7 +1,7 @@ // using System; using System.Collections.Generic; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using Kyoo.Postgresql; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; diff --git a/Kyoo.Postgresql/PostgresContext.cs b/Kyoo.Postgresql/PostgresContext.cs index 36f12a8c..cbefb849 100644 --- a/Kyoo.Postgresql/PostgresContext.cs +++ b/Kyoo.Postgresql/PostgresContext.cs @@ -3,7 +3,8 @@ using System.Globalization; using System.Linq.Expressions; using System.Reflection; using EFCore.NamingConventions.Internal; -using Kyoo.Models; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; using Npgsql; diff --git a/Kyoo.Postgresql/PostgresModule.cs b/Kyoo.Postgresql/PostgresModule.cs index 6b84bd93..295faf96 100644 --- a/Kyoo.Postgresql/PostgresModule.cs +++ b/Kyoo.Postgresql/PostgresModule.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; +using Kyoo.Database; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -23,19 +24,12 @@ namespace Kyoo.Postgresql /// public string Description => "A database context for postgresql."; + + /// + public Dictionary Configuration => new(); /// - public ICollection Provides => new[] - { - typeof(DatabaseContext) - }; - - /// - public ICollection ConditionalProvides => ArraySegment.Empty; - - /// - public ICollection Requires => ArraySegment.Empty; - + public bool Enabled => _configuration.GetSelectedDatabase() == "postgres"; /// /// The configuration to use. The database connection string is pulled from it. @@ -59,7 +53,7 @@ namespace Kyoo.Postgresql } /// - public void Configure(IServiceCollection services, ICollection availableTypes) + public void Configure(IServiceCollection services) { services.AddDbContext(x => { diff --git a/Kyoo.SqLite/Kyoo.SqLite.csproj b/Kyoo.SqLite/Kyoo.SqLite.csproj index cdedc4ca..f689dbe8 100644 --- a/Kyoo.SqLite/Kyoo.SqLite.csproj +++ b/Kyoo.SqLite/Kyoo.SqLite.csproj @@ -18,9 +18,7 @@ - - - - + + diff --git a/Kyoo.SqLite/SqLiteContext.cs b/Kyoo.SqLite/SqLiteContext.cs index cbd44659..123de717 100644 --- a/Kyoo.SqLite/SqLiteContext.cs +++ b/Kyoo.SqLite/SqLiteContext.cs @@ -2,7 +2,8 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; -using Kyoo.Models; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; diff --git a/Kyoo.SqLite/SqLiteModule.cs b/Kyoo.SqLite/SqLiteModule.cs index 96c29836..9a1dc76b 100644 --- a/Kyoo.SqLite/SqLiteModule.cs +++ b/Kyoo.SqLite/SqLiteModule.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; +using Kyoo.Database; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -22,20 +23,14 @@ namespace Kyoo.SqLite /// public string Description => "A database context for sqlite."; + + /// + public Dictionary Configuration => new(); + + /// + public bool Enabled => _configuration.GetSelectedDatabase() == "sqlite"; + - /// - public ICollection Provides => new[] - { - typeof(DatabaseContext) - }; - - /// - public ICollection ConditionalProvides => ArraySegment.Empty; - - /// - public ICollection Requires => ArraySegment.Empty; - - /// /// The configuration to use. The database connection string is pulled from it. /// @@ -59,7 +54,7 @@ namespace Kyoo.SqLite /// - public void Configure(IServiceCollection services, ICollection availableTypes) + public void Configure(IServiceCollection services) { services.AddDbContext(x => { diff --git a/Kyoo.TheMovieDb/Convertors/CollectionConvertors.cs b/Kyoo.TheMovieDb/Convertors/CollectionConvertors.cs index 3fe71a89..3c1460f2 100644 --- a/Kyoo.TheMovieDb/Convertors/CollectionConvertors.cs +++ b/Kyoo.TheMovieDb/Convertors/CollectionConvertors.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using TMDbLib.Objects.Search; namespace Kyoo.TheMovieDb diff --git a/Kyoo.TheMovieDb/Convertors/EpisodeConvertors.cs b/Kyoo.TheMovieDb/Convertors/EpisodeConvertors.cs index 75129af3..efee43df 100644 --- a/Kyoo.TheMovieDb/Convertors/EpisodeConvertors.cs +++ b/Kyoo.TheMovieDb/Convertors/EpisodeConvertors.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using TMDbLib.Objects.TvShows; namespace Kyoo.TheMovieDb diff --git a/Kyoo.TheMovieDb/Convertors/MovieConvertors.cs b/Kyoo.TheMovieDb/Convertors/MovieConvertors.cs index 450f6934..f859c489 100644 --- a/Kyoo.TheMovieDb/Convertors/MovieConvertors.cs +++ b/Kyoo.TheMovieDb/Convertors/MovieConvertors.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using System.Linq; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using TMDbLib.Objects.Movies; using TMDbLib.Objects.Search; diff --git a/Kyoo.TheMovieDb/Convertors/PeopleConvertors.cs b/Kyoo.TheMovieDb/Convertors/PeopleConvertors.cs index 861f21e0..32a0cbaf 100644 --- a/Kyoo.TheMovieDb/Convertors/PeopleConvertors.cs +++ b/Kyoo.TheMovieDb/Convertors/PeopleConvertors.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using TMDbLib.Objects.General; using TMDbLib.Objects.People; using TMDbLib.Objects.Search; -using Images = Kyoo.Models.Images; +using Images = Kyoo.Abstractions.Models.Images; using TvCast = TMDbLib.Objects.TvShows.Cast; using MovieCast = TMDbLib.Objects.Movies.Cast; @@ -15,11 +15,11 @@ namespace Kyoo.TheMovieDb public static partial class Convertors { /// - /// Convert a to a . + /// Convert a to a . /// /// An internal TheMovieDB cast. /// The provider that represent TheMovieDB inside Kyoo. - /// A representing the movie cast. + /// A representing the movie cast. public static PeopleRole ToPeople(this MovieCast cast, Provider provider) { return new PeopleRole diff --git a/Kyoo.TheMovieDb/Convertors/SeasonConvertors.cs b/Kyoo.TheMovieDb/Convertors/SeasonConvertors.cs index a1aa4e51..8c5dc7a1 100644 --- a/Kyoo.TheMovieDb/Convertors/SeasonConvertors.cs +++ b/Kyoo.TheMovieDb/Convertors/SeasonConvertors.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using TMDbLib.Objects.TvShows; namespace Kyoo.TheMovieDb diff --git a/Kyoo.TheMovieDb/Convertors/ShowConvertors.cs b/Kyoo.TheMovieDb/Convertors/ShowConvertors.cs index 946a8aea..a47b62c5 100644 --- a/Kyoo.TheMovieDb/Convertors/ShowConvertors.cs +++ b/Kyoo.TheMovieDb/Convertors/ShowConvertors.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using System.Linq; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using TMDbLib.Objects.Search; using TMDbLib.Objects.TvShows; diff --git a/Kyoo.TheMovieDb/Convertors/StudioConvertors.cs b/Kyoo.TheMovieDb/Convertors/StudioConvertors.cs index 9839d784..42290c73 100644 --- a/Kyoo.TheMovieDb/Convertors/StudioConvertors.cs +++ b/Kyoo.TheMovieDb/Convertors/StudioConvertors.cs @@ -1,4 +1,4 @@ -using Kyoo.Models; +using Kyoo.Abstractions.Models; using TMDbLib.Objects.Companies; using TMDbLib.Objects.Search; diff --git a/Kyoo.TheMovieDb/Kyoo.TheMovieDb.csproj b/Kyoo.TheMovieDb/Kyoo.TheMovieDb.csproj index 72b8bdec..7b841c4a 100644 --- a/Kyoo.TheMovieDb/Kyoo.TheMovieDb.csproj +++ b/Kyoo.TheMovieDb/Kyoo.TheMovieDb.csproj @@ -17,7 +17,6 @@ - - + diff --git a/Kyoo.TheMovieDb/PluginTmdb.cs b/Kyoo.TheMovieDb/PluginTmdb.cs index aaf5aa9c..6fb94e23 100644 --- a/Kyoo.TheMovieDb/PluginTmdb.cs +++ b/Kyoo.TheMovieDb/PluginTmdb.cs @@ -1,12 +1,9 @@ using System; using System.Collections.Generic; using Autofac; -using Kyoo.Controllers; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions; +using Kyoo.Abstractions.Controllers; using Kyoo.TheMovieDb.Models; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; namespace Kyoo.TheMovieDb { @@ -25,55 +22,15 @@ namespace Kyoo.TheMovieDb public string Description => "A metadata provider for TheMovieDB."; /// - public ICollection Provides => new [] + public Dictionary Configuration => new() { - typeof(IMetadataProvider) + { TheMovieDbOptions.Path, typeof(TheMovieDbOptions) } }; - - /// - public ICollection ConditionalProvides => ArraySegment.Empty; - - /// - public ICollection Requires => ArraySegment.Empty; - - - /// - /// The configuration to use. - /// - private readonly IConfiguration _configuration; - - /// - /// The configuration manager used to register typed/untyped implementations. - /// - [Injected] public IConfigurationManager ConfigurationManager { private get; set; } - - - /// - /// Create a new tmdb module instance and use the given configuration. - /// - /// The configuration to use - public PluginTmdb(IConfiguration configuration) - { - _configuration = configuration; - } - - + /// public void Configure(ContainerBuilder builder) { builder.RegisterProvider(); } - - /// - public void Configure(IServiceCollection services, ICollection availableTypes) - { - services.Configure(_configuration.GetSection(TheMovieDbOptions.Path)); - } - - /// - public void ConfigureAspNet(IApplicationBuilder app) - { - ConfigurationManager.AddTyped(TheMovieDbOptions.Path); - } } } \ No newline at end of file diff --git a/Kyoo.TheMovieDb/ProviderTmdb.cs b/Kyoo.TheMovieDb/ProviderTmdb.cs index b04d3f03..7d8c4057 100644 --- a/Kyoo.TheMovieDb/ProviderTmdb.cs +++ b/Kyoo.TheMovieDb/ProviderTmdb.cs @@ -2,8 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Kyoo.TheMovieDb.Models; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/Kyoo.TheTvdb/Convertors.cs b/Kyoo.TheTvdb/Convertors.cs index 69ee4c26..20413570 100644 --- a/Kyoo.TheTvdb/Convertors.cs +++ b/Kyoo.TheTvdb/Convertors.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using TvDbSharper.Dto; namespace Kyoo.TheTvdb diff --git a/Kyoo.TheTvdb/Kyoo.TheTvdb.csproj b/Kyoo.TheTvdb/Kyoo.TheTvdb.csproj index 9553bef5..29995a3c 100644 --- a/Kyoo.TheTvdb/Kyoo.TheTvdb.csproj +++ b/Kyoo.TheTvdb/Kyoo.TheTvdb.csproj @@ -16,7 +16,6 @@ - - + diff --git a/Kyoo.TheTvdb/PluginTvdb.cs b/Kyoo.TheTvdb/PluginTvdb.cs index e0b697ea..8d43cb81 100644 --- a/Kyoo.TheTvdb/PluginTvdb.cs +++ b/Kyoo.TheTvdb/PluginTvdb.cs @@ -1,12 +1,9 @@ using System; using System.Collections.Generic; using Autofac; -using Kyoo.Controllers; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions; +using Kyoo.Abstractions.Controllers; using Kyoo.TheTvdb.Models; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; using TvDbSharper; namespace Kyoo.TheTvdb @@ -24,58 +21,18 @@ namespace Kyoo.TheTvdb /// public string Description => "A metadata provider for The TVDB."; - + /// - public ICollection Provides => new [] + public Dictionary Configuration => new() { - typeof(IMetadataProvider) + { TvdbOption.Path, typeof(TvdbOption) } }; - - /// - public ICollection ConditionalProvides => ArraySegment.Empty; - - /// - public ICollection Requires => ArraySegment.Empty; - - - /// - /// The configuration to use. - /// - private readonly IConfiguration _configuration; - - /// - /// The configuration manager used to register typed/untyped implementations. - /// - [Injected] public IConfigurationManager ConfigurationManager { private get; set; } - - - /// - /// Create a new tvdb module instance and use the given configuration. - /// - /// The configuration to use - public PluginTvdb(IConfiguration configuration) - { - _configuration = configuration; - } - - + /// public void Configure(ContainerBuilder builder) { builder.RegisterType().As(); builder.RegisterProvider(); } - - /// - public void Configure(IServiceCollection services, ICollection availableTypes) - { - services.Configure(_configuration.GetSection(TvdbOption.Path)); - } - - /// - public void ConfigureAspNet(IApplicationBuilder app) - { - ConfigurationManager.AddTyped(TvdbOption.Path); - } } } \ No newline at end of file diff --git a/Kyoo.TheTvdb/ProviderTvdb.cs b/Kyoo.TheTvdb/ProviderTvdb.cs index 01411d1d..ae983720 100644 --- a/Kyoo.TheTvdb/ProviderTvdb.cs +++ b/Kyoo.TheTvdb/ProviderTvdb.cs @@ -3,8 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using JetBrains.Annotations; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Kyoo.TheTvdb.Models; using Microsoft.Extensions.Options; using TvDbSharper; diff --git a/Kyoo.WebApp b/Kyoo.WebApp/Front similarity index 100% rename from Kyoo.WebApp rename to Kyoo.WebApp/Front diff --git a/Kyoo.WebApp/Kyoo.WebApp.csproj b/Kyoo.WebApp/Kyoo.WebApp.csproj new file mode 100644 index 00000000..73d2fdef --- /dev/null +++ b/Kyoo.WebApp/Kyoo.WebApp.csproj @@ -0,0 +1,62 @@ + + + net5.0 + true + Latest + false + $(DefaultItemExcludes);$(SpaRoot)node_modules/** + Front/ + + + false + + SDG + Zoe Roux + https://github.com/AnonymusRaccoon/Kyoo + default + + + + + + + + + + + + + + wwwroot/%(RecursiveDir)%(Filename)%(Extension) + Always + + + + + wwwroot/%(RecursiveDir)%(Filename)%(Extension) + Always + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Kyoo.WebApp/WebAppModule.cs b/Kyoo.WebApp/WebAppModule.cs new file mode 100644 index 00000000..dc17c899 --- /dev/null +++ b/Kyoo.WebApp/WebAppModule.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Kyoo.Abstractions.Controllers; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.SpaServices.AngularCli; +using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Kyoo.WebApp +{ + /// + /// A module to enable the web-app (the front-end of kyoo). + /// + public class WebAppModule : IPlugin + { + /// + public string Slug => "webapp"; + + /// + public string Name => "WebApp"; + + /// + public string Description => "A module to enable the web-app (the front-end of kyoo)."; + + /// + public Dictionary Configuration => new(); + + /// + public bool Enabled => Directory.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot")); + + + /// + /// A logger only used to inform the user if the webapp could not be enabled. + /// + private readonly ILogger _logger; + + /// + /// Create a new . + /// + /// A logger only used to inform the user if the webapp could not be enabled. + public WebAppModule(ILogger logger) + { + _logger = logger; + } + + /// + public void Disabled() + { + _logger.LogError("The web app files could not be found, it will be disabled. " + + "If you cloned the project, you probably forgot to use the --recurse flag"); + } + + /// + public void Configure(IServiceCollection services) + { + services.AddSpaStaticFiles(x => + { + x.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"); + }); + } + + /// + public IEnumerable ConfigureSteps => new IStartupAction[] + { + SA.New((app, env) => + { + if (!env.IsDevelopment()) + app.UseSpaStaticFiles(); + }, SA.StaticFiles), + SA.New((app, contentTypeProvider) => + { + app.UseStaticFiles(new StaticFileOptions + { + ContentTypeProvider = contentTypeProvider, + FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot")) + }); + }, SA.StaticFiles), + SA.New(app => + { + app.Use((ctx, next) => + { + ctx.Response.Headers.Remove("X-Powered-By"); + ctx.Response.Headers.Remove("Server"); + ctx.Response.Headers.Add("Feature-Policy", "autoplay 'self'; fullscreen"); + ctx.Response.Headers.Add("Content-Security-Policy", "default-src 'self' blob:; script-src 'self' blob: 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self'"); + ctx.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN"); + ctx.Response.Headers.Add("Referrer-Policy", "no-referrer"); + ctx.Response.Headers.Add("Access-Control-Allow-Origin", "null"); + ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff"); + return next(); + }); + }, SA.Endpoint - 499), + SA.New((app, env) => + { + app.UseSpa(spa => + { + spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp", "Front"); + + if (env.IsDevelopment()) + spa.UseAngularCliServer("start"); + }); + }, SA.Endpoint - 500) + }; + } +} \ No newline at end of file diff --git a/Kyoo.sln b/Kyoo.sln index fdb1f643..701d760b 100644 --- a/Kyoo.sln +++ b/Kyoo.sln @@ -1,9 +1,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kyoo", "Kyoo\Kyoo.csproj", "{0F8275B6-C7DD-42DF-A168-755C81B1C329}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Common", "Kyoo.Common\Kyoo.Common.csproj", "{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Abstractions", "Kyoo.Abstractions\Kyoo.Abstractions.csproj", "{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.CommonAPI", "Kyoo.CommonAPI\Kyoo.CommonAPI.csproj", "{6F91B645-F785-46BB-9C4F-1EFC83E489B6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Database", "Kyoo.Database\Kyoo.Database.csproj", "{6F91B645-F785-46BB-9C4F-1EFC83E489B6}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Postgresql", "Kyoo.Postgresql\Kyoo.Postgresql.csproj", "{3213C96D-0BF3-460B-A8B5-B9977229408A}" EndProject @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.TheMovieDb", "Kyoo.The EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Tests", "tests\Kyoo.Tests\Kyoo.Tests.csproj", "{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.WebApp", "Kyoo.WebApp\Kyoo.WebApp.csproj", "{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -59,5 +61,9 @@ Global {0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Debug|Any CPU.Build.0 = Debug|Any CPU {0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.ActiveCfg = Release|Any CPU {0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.Build.0 = Release|Any CPU + {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Kyoo/Controllers/ConfigurationManager.cs b/Kyoo/Controllers/ConfigurationManager.cs index 32b2e7f7..c6476551 100644 --- a/Kyoo/Controllers/ConfigurationManager.cs +++ b/Kyoo/Controllers/ConfigurationManager.cs @@ -5,9 +5,10 @@ using System.Dynamic; using System.IO; using System.Linq; using System.Threading.Tasks; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; using Kyoo.Api; -using Kyoo.Models; -using Kyoo.Models.Exceptions; using Microsoft.Extensions.Configuration; using Newtonsoft.Json.Linq; @@ -50,6 +51,21 @@ namespace Kyoo.Controllers ConfigurationReference config = ConfigurationReference.CreateUntyped(path); _references.Add(config.Path, config.Type); } + + /// + public void Register(string path, Type type) + { + if (type == null) + { + ConfigurationReference config = ConfigurationReference.CreateUntyped(path); + _references.Add(config.Path, config.Type); + } + else + { + foreach (ConfigurationReference confRef in ConfigurationReference.CreateReference(path, type)) + _references.Add(confRef.Path, confRef.Type); + } + } /// /// Get the type of the resource at the given path diff --git a/Kyoo/Controllers/FileSystems/FileSystemComposite.cs b/Kyoo/Controllers/FileSystems/FileSystemComposite.cs index b3f4f66a..bab7167d 100644 --- a/Kyoo/Controllers/FileSystems/FileSystemComposite.cs +++ b/Kyoo/Controllers/FileSystems/FileSystemComposite.cs @@ -6,8 +6,9 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using Autofac.Features.Metadata; using JetBrains.Annotations; -using Kyoo.Common.Models.Attributes; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models; using Kyoo.Models.Options; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; diff --git a/Kyoo/Controllers/FileSystems/HttpFileSystem.cs b/Kyoo/Controllers/FileSystems/HttpFileSystem.cs index c7954db8..8bd3d62f 100644 --- a/Kyoo/Controllers/FileSystems/HttpFileSystem.cs +++ b/Kyoo/Controllers/FileSystems/HttpFileSystem.cs @@ -4,7 +4,9 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net.Http; using System.Threading.Tasks; -using Kyoo.Common.Models.Attributes; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; using Microsoft.AspNetCore.Mvc; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/FileSystems/LocalFileSystem.cs b/Kyoo/Controllers/FileSystems/LocalFileSystem.cs index 87575e0a..3c4da8a0 100644 --- a/Kyoo/Controllers/FileSystems/LocalFileSystem.cs +++ b/Kyoo/Controllers/FileSystems/LocalFileSystem.cs @@ -2,8 +2,9 @@ using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; -using Kyoo.Common.Models.Attributes; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; using Kyoo.Models.Options; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.StaticFiles; @@ -20,7 +21,7 @@ namespace Kyoo.Controllers /// /// An extension provider to get content types from files extensions. /// - private FileExtensionContentTypeProvider _provider; + private readonly IContentTypeProvider _provider; /// /// Options to check if the metadata should be kept in the show directory or in a kyoo's directory. @@ -31,9 +32,11 @@ namespace Kyoo.Controllers /// Create a new with the specified options. /// /// The options to use. - public LocalFileSystem(IOptionsMonitor options) + /// An extension provider to get content types from files extensions. + public LocalFileSystem(IOptionsMonitor options, IContentTypeProvider provider) { _options = options; + _provider = provider; } /// @@ -44,15 +47,6 @@ namespace Kyoo.Controllers /// The content type of the file private string _GetContentType(string path) { - if (_provider == null) - { - _provider = new FileExtensionContentTypeProvider(); - _provider.Mappings[".mkv"] = "video/x-matroska"; - _provider.Mappings[".ass"] = "text/x-ssa"; - _provider.Mappings[".srt"] = "application/x-subrip"; - _provider.Mappings[".m3u8"] = "application/x-mpegurl"; - } - if (_provider.TryGetContentType(path, out string contentType)) return contentType; throw new NotImplementedException($"Can't get the content type of the file at: {path}"); diff --git a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs b/Kyoo/Controllers/LibraryManager.cs similarity index 99% rename from Kyoo.Common/Controllers/Implementations/LibraryManager.cs rename to Kyoo/Controllers/LibraryManager.cs index 08475c32..2b396ed5 100644 --- a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs +++ b/Kyoo/Controllers/LibraryManager.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; namespace Kyoo.Controllers { diff --git a/Kyoo/Controllers/PassthroughPermissionValidator.cs b/Kyoo/Controllers/PassthroughPermissionValidator.cs index d6d2f334..5b623008 100644 --- a/Kyoo/Controllers/PassthroughPermissionValidator.cs +++ b/Kyoo/Controllers/PassthroughPermissionValidator.cs @@ -1,4 +1,4 @@ -using Kyoo.Models.Permissions; +using Kyoo.Abstractions.Models.Permissions; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Logging; diff --git a/Kyoo/Controllers/PluginManager.cs b/Kyoo/Controllers/PluginManager.cs index 46185f16..3b60e83f 100644 --- a/Kyoo/Controllers/PluginManager.cs +++ b/Kyoo/Controllers/PluginManager.cs @@ -4,9 +4,8 @@ using System.IO; using System.Linq; using System.Reflection; using System.Runtime.Loader; -using Autofac; +using Kyoo.Abstractions.Controllers; using Kyoo.Models.Options; -using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -26,7 +25,7 @@ namespace Kyoo.Controllers /// /// The configuration to get the plugin's directory. /// - private readonly IOptionsMonitor _options; + private readonly IOptions _options; /// /// The logger used by this class. /// @@ -44,7 +43,7 @@ namespace Kyoo.Controllers /// The configuration instance, to get the plugin's directory path. /// The logger used by this class. public PluginManager(IServiceProvider provider, - IOptionsMonitor options, + IOptions options, ILogger logger) { _provider = provider; @@ -106,28 +105,21 @@ namespace Kyoo.Controllers /// public void LoadPlugins(ICollection plugins) { - string pluginFolder = _options.CurrentValue.PluginPath; + string pluginFolder = _options.Value.PluginPath; if (!Directory.Exists(pluginFolder)) Directory.CreateDirectory(pluginFolder); _logger.LogTrace("Loading new plugins..."); string[] pluginsPaths = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories); - plugins = plugins.Concat(pluginsPaths.SelectMany(LoadPlugin)) + IPlugin[] newPlugins = plugins + .Concat(pluginsPaths.SelectMany(LoadPlugin)) .GroupBy(x => x.Name) .Select(x => x.First()) - .ToList(); - - ICollection available = GetProvidedTypes(plugins); - _plugins.AddRange(plugins.Where(plugin => - { - Type missing = plugin.Requires.FirstOrDefault(x => available.All(y => !y.IsAssignableTo(x))); - if (missing == null) - return true; - - _logger.LogCritical("No {Dependency} available in Kyoo but the plugin {Plugin} requires it", - missing.Name, plugin.Name); - return false; - })); + .ToArray(); + _plugins.AddRange(newPlugins.Where(x => x.Enabled)); + + foreach (IPlugin plugin in newPlugins.Where(x => !x.Enabled)) + plugin.Disabled(); if (!_plugins.Any()) _logger.LogInformation("No plugin enabled"); @@ -136,78 +128,13 @@ namespace Kyoo.Controllers } /// - public void ConfigureContainer(ContainerBuilder builder) + public void LoadPlugins(params Type[] plugins) { - foreach (IPlugin plugin in _plugins) - plugin.Configure(builder); + LoadPlugins(plugins + .Select(x => (IPlugin)ActivatorUtilities.CreateInstance(_provider, x)) + .ToArray() + ); } - - /// - public void ConfigureServices(IServiceCollection services) - { - ICollection available = GetProvidedTypes(_plugins); - foreach (IPlugin plugin in _plugins) - plugin.Configure(services, available); - } - - /// - public void ConfigureAspnet(IApplicationBuilder app) - { - foreach (IPlugin plugin in _plugins) - { - using IServiceScope scope = _provider.CreateScope(); - Helper.InjectServices(plugin, x => scope.ServiceProvider.GetRequiredService(x)); - plugin.ConfigureAspNet(app); - Helper.InjectServices(plugin, _ => null); - } - } - - /// - /// Get the list of types provided by the currently loaded plugins. - /// - /// The list of plugins that will be used as a plugin pool to get provided types. - /// The list of types available. - private ICollection GetProvidedTypes(ICollection plugins) - { - List available = plugins.SelectMany(x => x.Provides).ToList(); - List conditionals = plugins - .SelectMany(x => x.ConditionalProvides) - .Where(x => x.Condition.Condition()) - .ToList(); - - bool IsAvailable(ConditionalProvide conditional, bool log = false) - { - if (!conditional.Condition.Condition()) - return false; - - ICollection needed = conditional.Condition.Needed - .Where(y => !available.Contains(y)) - .ToList(); - // TODO handle circular dependencies, actually it might stack overflow. - needed = needed.Where(x => !conditionals - .Where(y => y.Type == x) - .Any(y => IsAvailable(y))) - .ToList(); - if (!needed.Any()) - return true; - if (log && available.All(x => x != conditional.Type)) - { - _logger.LogWarning("The type {Type} is not available, {Dependencies} could not be met", - conditional.Type.Name, - needed.Select(x => x.Name)); - } - return false; - } - - // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator - foreach (ConditionalProvide conditional in conditionals) - { - if (IsAvailable(conditional, true)) - available.Add(conditional.Type); - } - return available; - } - /// /// A custom to load plugin's dependency if they are on the same folder. diff --git a/Kyoo/Controllers/ProviderComposite.cs b/Kyoo/Controllers/ProviderComposite.cs index 2474016c..dd9ecb41 100644 --- a/Kyoo/Controllers/ProviderComposite.cs +++ b/Kyoo/Controllers/ProviderComposite.cs @@ -1,8 +1,9 @@ using System; -using Kyoo.Models; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Microsoft.Extensions.Logging; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/RegexIdentifier.cs b/Kyoo/Controllers/RegexIdentifier.cs index c25e3e4f..41a6e0d8 100644 --- a/Kyoo/Controllers/RegexIdentifier.cs +++ b/Kyoo/Controllers/RegexIdentifier.cs @@ -4,8 +4,9 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; using Kyoo.Models.Options; using Kyoo.Models.Watch; using Microsoft.Extensions.Options; diff --git a/Kyoo/Controllers/Repositories/CollectionRepository.cs b/Kyoo/Controllers/Repositories/CollectionRepository.cs index e4250c8f..cdb0740a 100644 --- a/Kyoo/Controllers/Repositories/CollectionRepository.cs +++ b/Kyoo/Controllers/Repositories/CollectionRepository.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/EpisodeRepository.cs b/Kyoo/Controllers/Repositories/EpisodeRepository.cs index 92a573a4..d31e97cc 100644 --- a/Kyoo/Controllers/Repositories/EpisodeRepository.cs +++ b/Kyoo/Controllers/Repositories/EpisodeRepository.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/GenreRepository.cs b/Kyoo/Controllers/Repositories/GenreRepository.cs index fe9444f5..b791f627 100644 --- a/Kyoo/Controllers/Repositories/GenreRepository.cs +++ b/Kyoo/Controllers/Repositories/GenreRepository.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/LibraryItemRepository.cs b/Kyoo/Controllers/Repositories/LibraryItemRepository.cs index b0ec916e..172c7ab6 100644 --- a/Kyoo/Controllers/Repositories/LibraryItemRepository.cs +++ b/Kyoo/Controllers/Repositories/LibraryItemRepository.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/LibraryRepository.cs b/Kyoo/Controllers/Repositories/LibraryRepository.cs index 06f57fc1..e532d4e0 100644 --- a/Kyoo/Controllers/Repositories/LibraryRepository.cs +++ b/Kyoo/Controllers/Repositories/LibraryRepository.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo.CommonAPI/LocalRepository.cs b/Kyoo/Controllers/Repositories/LocalRepository.cs similarity index 98% rename from Kyoo.CommonAPI/LocalRepository.cs rename to Kyoo/Controllers/Repositories/LocalRepository.cs index 67a75e12..14d4cb40 100644 --- a/Kyoo.CommonAPI/LocalRepository.cs +++ b/Kyoo/Controllers/Repositories/LocalRepository.cs @@ -4,10 +4,11 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Models; -using Kyoo.Models.Attributes; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Api; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/PeopleRepository.cs b/Kyoo/Controllers/Repositories/PeopleRepository.cs index 3b6d3f87..10ca820b 100644 --- a/Kyoo/Controllers/Repositories/PeopleRepository.cs +++ b/Kyoo/Controllers/Repositories/PeopleRepository.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/ProviderRepository.cs b/Kyoo/Controllers/Repositories/ProviderRepository.cs index f555f5a5..a1f00608 100644 --- a/Kyoo/Controllers/Repositories/ProviderRepository.cs +++ b/Kyoo/Controllers/Repositories/ProviderRepository.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/SeasonRepository.cs b/Kyoo/Controllers/Repositories/SeasonRepository.cs index 0ac7e759..f63f37e2 100644 --- a/Kyoo/Controllers/Repositories/SeasonRepository.cs +++ b/Kyoo/Controllers/Repositories/SeasonRepository.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/ShowRepository.cs b/Kyoo/Controllers/Repositories/ShowRepository.cs index 3ef8747c..1605eab6 100644 --- a/Kyoo/Controllers/Repositories/ShowRepository.cs +++ b/Kyoo/Controllers/Repositories/ShowRepository.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/StudioRepository.cs b/Kyoo/Controllers/Repositories/StudioRepository.cs index 2c807375..42b98b44 100644 --- a/Kyoo/Controllers/Repositories/StudioRepository.cs +++ b/Kyoo/Controllers/Repositories/StudioRepository.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/TrackRepository.cs b/Kyoo/Controllers/Repositories/TrackRepository.cs index a462ca23..b7c29c47 100644 --- a/Kyoo/Controllers/Repositories/TrackRepository.cs +++ b/Kyoo/Controllers/Repositories/TrackRepository.cs @@ -2,7 +2,9 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/Repositories/UserRepository.cs b/Kyoo/Controllers/Repositories/UserRepository.cs index 5ebd4d2b..896b8480 100644 --- a/Kyoo/Controllers/Repositories/UserRepository.cs +++ b/Kyoo/Controllers/Repositories/UserRepository.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; namespace Kyoo.Controllers diff --git a/Kyoo/Controllers/TaskManager.cs b/Kyoo/Controllers/TaskManager.cs index 8b5650a6..df89f290 100644 --- a/Kyoo/Controllers/TaskManager.cs +++ b/Kyoo/Controllers/TaskManager.cs @@ -7,8 +7,9 @@ using System.Threading.Tasks; using Autofac.Features.Metadata; using Autofac.Features.OwnedInstances; using JetBrains.Annotations; -using Kyoo.Common.Models.Attributes; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models.Exceptions; using Kyoo.Models.Options; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; diff --git a/Kyoo/Controllers/ThumbnailsManager.cs b/Kyoo/Controllers/ThumbnailsManager.cs index 23469dcf..274b655f 100644 --- a/Kyoo/Controllers/ThumbnailsManager.cs +++ b/Kyoo/Controllers/ThumbnailsManager.cs @@ -1,8 +1,9 @@ -using Kyoo.Models; -using System; +using System; using System.IO; using System.Linq; using System.Threading.Tasks; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.Logging; diff --git a/Kyoo/Controllers/Transcoder.cs b/Kyoo/Controllers/Transcoder.cs index 5942cbd2..a8adc9d1 100644 --- a/Kyoo/Controllers/Transcoder.cs +++ b/Kyoo/Controllers/Transcoder.cs @@ -2,7 +2,8 @@ using System; using System.IO; using System.Runtime.InteropServices; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Kyoo.Models.Options; using Microsoft.Extensions.Options; using Stream = Kyoo.Models.Watch.Stream; diff --git a/Kyoo/CoreModule.cs b/Kyoo/CoreModule.cs index 51f4f94c..b6445b3d 100644 --- a/Kyoo/CoreModule.cs +++ b/Kyoo/CoreModule.cs @@ -1,19 +1,23 @@ using System; using System.Collections.Generic; -using System.IO; using Autofac; using Autofac.Core; using Autofac.Core.Registration; +using Autofac.Extras.AttributeMetadata; +using Kyoo.Abstractions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Permissions; +using Kyoo.Api; using Kyoo.Controllers; -using Kyoo.Models.Attributes; +using Kyoo.Database; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Kyoo.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Hosting; +using IMetadataProvider = Kyoo.Abstractions.Controllers.IMetadataProvider; namespace Kyoo { @@ -32,63 +36,22 @@ namespace Kyoo public string Description => "The core module containing default implementations."; /// - public ICollection Provides => new[] + public Dictionary Configuration => new() { - typeof(IFileSystem), - typeof(ITranscoder), - typeof(IThumbnailsManager), - typeof(IMetadataProvider), - typeof(ITaskManager), - typeof(ILibraryManager), - typeof(IIdentifier), - typeof(AProviderComposite) + { BasicOptions.Path, typeof(BasicOptions) }, + { TaskOptions.Path, typeof(TaskOptions) }, + { MediaOptions.Path, typeof(MediaOptions) }, + { "database", null }, + { "logging", null } }; - /// - public ICollection ConditionalProvides => new ConditionalProvide[] - { - (typeof(ILibraryRepository), typeof(DatabaseContext)), - (typeof(ILibraryItemRepository), typeof(DatabaseContext)), - (typeof(ICollectionRepository), typeof(DatabaseContext)), - (typeof(IShowRepository), typeof(DatabaseContext)), - (typeof(ISeasonRepository), typeof(DatabaseContext)), - (typeof(IEpisodeRepository), typeof(DatabaseContext)), - (typeof(ITrackRepository), typeof(DatabaseContext)), - (typeof(IPeopleRepository), typeof(DatabaseContext)), - (typeof(IStudioRepository), typeof(DatabaseContext)), - (typeof(IGenreRepository), typeof(DatabaseContext)), - (typeof(IProviderRepository), typeof(DatabaseContext)), - (typeof(IUserRepository), typeof(DatabaseContext)) - }; - /// - public ICollection Requires => new [] - { - typeof(ILibraryRepository), - typeof(ILibraryItemRepository), - typeof(ICollectionRepository), - typeof(IShowRepository), - typeof(ISeasonRepository), - typeof(IEpisodeRepository), - typeof(ITrackRepository), - typeof(IPeopleRepository), - typeof(IStudioRepository), - typeof(IGenreRepository), - typeof(IProviderRepository) - }; - - /// /// The configuration to use. /// private readonly IConfiguration _configuration; - - /// - /// The configuration manager used to register typed/untyped implementations. - /// - [Injected] public IConfigurationManager ConfigurationManager { private get; set; } - + /// /// Create a new core module instance and use the given configuration. /// @@ -101,6 +64,8 @@ namespace Kyoo /// public void Configure(ContainerBuilder builder) { + builder.RegisterModule(); + builder.RegisterComposite().InstancePerLifetimeScope(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); @@ -139,17 +104,24 @@ namespace Kyoo builder.RegisterType().As() .IfNotRegistered(typeof(IPermissionValidator)); + + builder.RegisterType().As().SingleInstance() + .OnActivating(x => + { + x.Instance.Mappings[".data"] = "application/octet-stream"; + x.Instance.Mappings[".mkv"] = "video/x-matroska"; + x.Instance.Mappings[".ass"] = "text/x-ssa"; + x.Instance.Mappings[".srt"] = "application/x-subrip"; + x.Instance.Mappings[".m3u8"] = "application/x-mpegurl"; + }); } /// - public void Configure(IServiceCollection services, ICollection availableTypes) + public void Configure(IServiceCollection services) { string publicUrl = _configuration.GetPublicUrl(); - services.Configure(_configuration.GetSection(BasicOptions.Path)); - services.Configure(_configuration.GetSection(TaskOptions.Path)); - services.Configure(_configuration.GetSection(MediaOptions.Path)); - + services.AddMvc().AddControllersAsServices(); services.AddControllers() .AddNewtonsoftJson(x => { @@ -157,30 +129,32 @@ namespace Kyoo x.SerializerSettings.Converters.Add(new PeopleRoleConverter()); }); + services.AddResponseCompression(x => + { + x.EnableForHttps = true; + }); + + services.AddHttpClient(); + services.AddHostedService(x => x.GetService() as TaskManager); } /// - public void ConfigureAspNet(IApplicationBuilder app) + public IEnumerable ConfigureSteps => new IStartupAction[] { - ConfigurationManager.AddTyped(BasicOptions.Path); - ConfigurationManager.AddTyped(TaskOptions.Path); - ConfigurationManager.AddTyped(MediaOptions.Path); - ConfigurationManager.AddUntyped("database"); - ConfigurationManager.AddUntyped("logging"); - - FileExtensionContentTypeProvider contentTypeProvider = new(); - contentTypeProvider.Mappings[".data"] = "application/octet-stream"; - app.UseStaticFiles(new StaticFileOptions + SA.New((app, env) => { - ContentTypeProvider = contentTypeProvider, - FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot")) - }); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } + if (env.IsDevelopment()) + app.UseDeveloperExceptionPage(); + else + { + app.UseExceptionHandler("/error"); + app.UseHsts(); + } + }, SA.Before), + SA.New(app => app.UseResponseCompression(), SA.Routing + 1), + SA.New(app => app.UseRouting(), SA.Routing), + SA.New(app => app.UseEndpoints(x => x.MapControllers()), SA.Endpoint) + }; } } \ No newline at end of file diff --git a/Kyoo/Helper.cs b/Kyoo/Helper.cs index 244f6eec..ad8a6dfb 100644 --- a/Kyoo/Helper.cs +++ b/Kyoo/Helper.cs @@ -1,32 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; using System.Net.Http; -using System.Reflection; using System.Threading.Tasks; -using JetBrains.Annotations; -using Kyoo.Models.Attributes; using Newtonsoft.Json; namespace Kyoo { public static class Helper { - /// - /// Inject services into the marked properties of the given object. - /// - /// The object to inject - /// The function used to retrieve services. (The function is called immediately) - public static void InjectServices(object obj, [InstantHandle] Func retrieve) - { - IEnumerable properties = obj.GetType().GetProperties() - .Where(x => x.GetCustomAttribute() != null) - .Where(x => x.CanWrite); - - foreach (PropertyInfo property in properties) - property.SetValue(obj, retrieve(property.PropertyType)); - } - /// /// An helper method to get json content from an http server. This is a temporary thing and will probably be /// replaced by a call to the function of the same name in the System.Net.Http.Json namespace when .net6 diff --git a/Kyoo/Kyoo.csproj b/Kyoo/Kyoo.csproj index 0185da01..e76cf005 100644 --- a/Kyoo/Kyoo.csproj +++ b/Kyoo/Kyoo.csproj @@ -2,15 +2,7 @@ net5.0 - true - Latest - false - ../Kyoo.WebApp/ ../Kyoo.Transcoder/ - $(DefaultItemExcludes);$(SpaRoot)node_modules/** - - - false SDG Zoe Roux @@ -33,107 +25,34 @@ - - - - - - - + - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - wwwroot/%(DistFiles.Filename)%(DistFiles.Extension) - PreserveNewest - true - - - - - - - - wwwroot/%(StaticFiles.RecursiveDir)%(StaticFiles.Filename)%(StaticFiles.Extension) - PreserveNewest - true - - - - - - - - - - - - - - - - - + PreserveNewest false - - - - - ../Kyoo.WebLogin/ - - - - - - - - login/%(LoginFiles.RecursiveDir)%(LoginFiles.Filename)%(LoginFiles.Extension) - PreserveNewest - true - - - - - - diff --git a/Kyoo/Models/Options/BasicOptions.cs b/Kyoo/Models/Options/BasicOptions.cs index 2754e0d9..ca018fd4 100644 --- a/Kyoo/Models/Options/BasicOptions.cs +++ b/Kyoo/Models/Options/BasicOptions.cs @@ -1,3 +1,4 @@ +using Kyoo.Abstractions.Models; using System; namespace Kyoo.Models.Options diff --git a/Kyoo/Models/Stream.cs b/Kyoo/Models/Stream.cs index 3639a4a6..6d2b4a3c 100644 --- a/Kyoo/Models/Stream.cs +++ b/Kyoo/Models/Stream.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; namespace Kyoo.Models.Watch { diff --git a/Kyoo/PluginsStartup.cs b/Kyoo/PluginsStartup.cs new file mode 100644 index 00000000..4bcd362f --- /dev/null +++ b/Kyoo/PluginsStartup.cs @@ -0,0 +1,216 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Autofac; +using Kyoo.Abstractions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Authentication; +using Kyoo.Controllers; +using Kyoo.Models.Options; +using Kyoo.Postgresql; +using Kyoo.SqLite; +using Kyoo.Tasks; +using Kyoo.TheMovieDb; +using Kyoo.TheTvdb; +using Kyoo.WebApp; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Kyoo +{ + /// + /// The Startup class is used to configure the AspNet's webhost. + /// + public class PluginsStartup + { + /// + /// A plugin manager used to load plugins and allow them to configure services / asp net. + /// + private readonly IPluginManager _plugins; + + /// + /// The configuration used to register and so on for plugin's specified types. + /// + private readonly IConfiguration _configuration; + + /// + /// Created from the DI container, those services are needed to load information and instantiate plugins.s + /// + /// The plugin manager to use to load new plugins and configure the host. + /// + /// The configuration used to register and so on for plugin's specified types. + /// + public PluginsStartup(IPluginManager plugins, IConfiguration configuration) + { + _plugins = plugins; + _configuration = configuration; + _plugins.LoadPlugins( + typeof(CoreModule), + typeof(WebAppModule), + typeof(AuthenticationModule), + typeof(PostgresModule), + typeof(SqLiteModule), + typeof(PluginTvdb), + typeof(PluginTmdb) + ); + } + + /// + /// Configure the services context via the . + /// + /// The service collection to fill. + public void ConfigureServices(IServiceCollection services) + { + foreach (IPlugin plugin in _plugins.GetAllPlugins()) + plugin.Configure(services); + + IEnumerable> configTypes = _plugins.GetAllPlugins() + .SelectMany(x => x.Configuration) + .Where(x => x.Value != null); + foreach ((string path, Type type) in configTypes) + { + Utility.RunGenericMethod( + typeof(OptionsConfigurationServiceCollectionExtensions), + nameof(OptionsConfigurationServiceCollectionExtensions.Configure), + type, + services, _configuration.GetSection(path) + ); + } + } + + /// + /// Configure the autofac container via the . + /// + /// The builder to configure. + public void ConfigureContainer(ContainerBuilder builder) + { + builder.RegisterInstance(_plugins).As().ExternallyOwned(); + builder.RegisterTask(); + + foreach (IPlugin plugin in _plugins.GetAllPlugins()) + plugin.Configure(builder); + } + + /// + /// Configure the asp net host. + /// + /// The asp net host to configure + /// An autofac container used to create a new scope to configure asp-net. + /// The configuration manager used to register strongly typed config. + public void Configure(IApplicationBuilder app, ILifetimeScope container, IConfigurationManager config) + { + IEnumerable steps = _plugins.GetAllPlugins() + .SelectMany(x => x.ConfigureSteps) + .OrderByDescending(x => x.Priority); + + using ILifetimeScope scope = container.BeginLifetimeScope(x => + x.RegisterInstance(app).SingleInstance().ExternallyOwned()); + IServiceProvider provider = scope.Resolve(); + foreach (IStartupAction step in steps) + step.Run(provider); + + IEnumerable> pluginConfig = _plugins.GetAllPlugins() + .SelectMany(x => x.Configuration) + .GroupBy(x => x.Key.Split(':').First()) + .Select(x => x + .OrderBy(y => y.Key.Length) + .First() + ); + foreach ((string path, Type type) in pluginConfig) + config.Register(path, type); + } + + + /// + /// Create a new from a webhost. + /// This is meant to be used from . + /// + /// The context of the web host. + /// + /// The method used to configure the logger factory used by the plugin manager and plugins during startup. + /// + /// A new . + public static PluginsStartup FromWebHost(WebHostBuilderContext host, + Action loggingConfiguration) + { + HostBuilderContext genericHost = new(new Dictionary()) + { + Configuration = host.Configuration, + HostingEnvironment = host.HostingEnvironment + }; + ILoggerFactory logger = LoggerFactory.Create(builder => loggingConfiguration(genericHost, builder)); + HostServiceProvider hostProvider = new(host.HostingEnvironment, host.Configuration, logger); + PluginManager plugins = new( + hostProvider, + Options.Create(host.Configuration.GetSection(BasicOptions.Path).Get()), + logger.CreateLogger() + ); + return new PluginsStartup(plugins, host.Configuration); + } + + /// + /// A simple host service provider used to activate plugins instance. + /// The same services as a generic host are available and an has been added. + /// + private class HostServiceProvider : IServiceProvider + { + /// + /// The host environment that could be used by plugins to configure themself. + /// + private readonly IWebHostEnvironment _hostEnvironment; + + /// + /// The configuration context. + /// + private readonly IConfiguration _configuration; + + /// + /// A logger factory used to create a logger for the plugin manager. + /// + private readonly ILoggerFactory _loggerFactory; + + + /// + /// Create a new that will return given services when asked. + /// + /// + /// The host environment that could be used by plugins to configure themself. + /// + /// The configuration context + /// A logger factory used to create a logger for the plugin manager. + public HostServiceProvider(IWebHostEnvironment hostEnvironment, + IConfiguration configuration, + ILoggerFactory loggerFactory) + { + _hostEnvironment = hostEnvironment; + _configuration = configuration; + _loggerFactory = loggerFactory; + } + + /// + public object GetService(Type serviceType) + { + if (serviceType == typeof(IWebHostEnvironment) || serviceType == typeof(IHostEnvironment)) + return _hostEnvironment; + if (serviceType == typeof(IConfiguration)) + return _configuration; + if (serviceType.GetGenericTypeDefinition() == typeof(ILogger<>)) + { + return Utility.RunGenericMethod( + typeof(LoggerFactoryExtensions), + nameof(LoggerFactoryExtensions.CreateLogger), + serviceType.GetGenericArguments().First(), + _loggerFactory + ); + } + + return null; + } + } + } +} diff --git a/Kyoo/Program.cs b/Kyoo/Program.cs index f1adfb40..e9f21a0b 100644 --- a/Kyoo/Program.cs +++ b/Kyoo/Program.cs @@ -1,13 +1,11 @@ using System; -using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading.Tasks; -using Autofac; using Autofac.Extensions.DependencyInjection; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace Kyoo @@ -21,52 +19,38 @@ namespace Kyoo /// The path of the json configuration of the application. /// public const string JsonConfigPath = "./settings.json"; + + /// + /// The string representation of the environment used in . + /// +#if DEBUG + private const string Environment = "Development"; +#else + private const string Environment = "Production"; +#endif /// /// Main function of the program /// /// Command line arguments - [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse")] public static async Task Main(string[] args) { - if (!File.Exists("./settings.json")) - File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "settings.json"), "settings.json"); + if (!File.Exists(JsonConfigPath)) + File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, JsonConfigPath), JsonConfigPath); - IWebHostBuilder builder = CreateWebHostBuilder(args); + IHost host = CreateWebHostBuilder(args) + .UseEnvironment(Environment) + .Build(); - bool? debug = Environment.GetEnvironmentVariable("ENVIRONMENT")?.ToLowerInvariant() switch - { - "d" => true, - "dev" => true, - "debug" => true, - "development" => true, - "p" => false, - "prod" => false, - "production" => false, - _ => null - }; - - if (debug == null && Environment.GetEnvironmentVariable("ENVIRONMENT") != null) - { - Console.WriteLine( - $"Invalid ENVIRONMENT variable. Supported values are \"debug\" and \"prod\". Ignoring..."); - } - - #if DEBUG - debug ??= true; - #endif - - if (debug != null) - builder = builder.UseEnvironment(debug == true ? "Development" : "Production"); - try { - Console.WriteLine($"Running as {Environment.UserName}."); - await builder.Build().RunAsync(); + host.Services.GetRequiredService>() + .LogInformation("Running as {Name}", System.Environment.UserName); + await host.RunAsync(); } catch (Exception ex) { - await Console.Error.WriteLineAsync($"Unhandled exception: {ex}"); + host.Services.GetRequiredService>().LogCritical(ex, "Unhandled exception"); } } @@ -78,45 +62,60 @@ namespace Kyoo /// The modified configuration builder private static IConfigurationBuilder SetupConfig(IConfigurationBuilder builder, string[] args) { - return builder.AddJsonFile(JsonConfigPath, false, true) + return builder.SetBasePath(System.Environment.CurrentDirectory) + .AddJsonFile(JsonConfigPath, false, true) .AddEnvironmentVariables() .AddCommandLine(args); } + /// + /// Configure the logging. + /// + /// The host context that contains the configuration + /// The logger builder to configure. + private static void _ConfigureLogging(HostBuilderContext context, ILoggingBuilder builder) + { + builder.AddConfiguration(context.Configuration.GetSection("logging")) + .AddSimpleConsole(x => + { + x.TimestampFormat = "[hh:mm:ss] "; + }) + .AddDebug() + .AddEventSourceLogger(); + } + /// /// Create a a web host /// /// Command line parameters that can be handled by kestrel + /// + /// An action to configure the logging. If it is null, will be used. + /// /// A new web host instance - private static IWebHostBuilder CreateWebHostBuilder(string[] args) + public static IHostBuilder CreateWebHostBuilder(string[] args, + Action loggingConfiguration = null) { IConfiguration configuration = SetupConfig(new ConfigurationBuilder(), args).Build(); + loggingConfiguration ??= _ConfigureLogging; - return new WebHostBuilder() - .ConfigureServices(x => - { - AutofacServiceProviderFactory factory = new(); - x.Replace(ServiceDescriptor.Singleton>(factory)); - }) + return new HostBuilder() + .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .UseContentRoot(AppDomain.CurrentDomain.BaseDirectory) - .UseConfiguration(configuration) .ConfigureAppConfiguration(x => SetupConfig(x, args)) - .ConfigureLogging((context, builder) => - { - builder.AddConfiguration(context.Configuration.GetSection("logging")) - .AddSimpleConsole(x => - { - x.TimestampFormat = "[hh:mm:ss] "; - }) - .AddDebug() - .AddEventSourceLogger(); - }) + .ConfigureLogging(loggingConfiguration) .ConfigureServices(x => x.AddRouting()) - .UseKestrel(options => { options.AddServerHeader = false; }) - .UseIIS() - .UseIISIntegration() - .UseUrls(configuration.GetValue("basics:url")) - .UseStartup(); + .ConfigureWebHost(x => x + .UseKestrel(options => { options.AddServerHeader = false; }) + .UseIIS() + .UseIISIntegration() + .UseUrls(configuration.GetValue("basics:url")) + .UseStartup(host => PluginsStartup.FromWebHost(host, loggingConfiguration)) + ); } + + /// + /// An useless class only used to have a logger in the main. + /// + private class Application {} } } diff --git a/Kyoo/Startup.cs b/Kyoo/Startup.cs deleted file mode 100644 index 804a08f0..00000000 --- a/Kyoo/Startup.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.IO; -using Autofac; -using Autofac.Extras.AttributeMetadata; -using Kyoo.Authentication; -using Kyoo.Controllers; -using Kyoo.Models.Options; -using Kyoo.Postgresql; -using Kyoo.Tasks; -using Kyoo.TheMovieDb; -using Kyoo.TheTvdb; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.SpaServices.AngularCli; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace Kyoo -{ - /// - /// The Startup class is used to configure the AspNet's webhost. - /// - public class Startup - { - /// - /// A plugin manager used to load plugins and allow them to configure services / asp net. - /// - private readonly IPluginManager _plugins; - - - /// - /// Created from the DI container, those services are needed to load information and instantiate plugins.s - /// - /// - /// The ServiceProvider used to create this instance. - /// The host provider that contains only well-known services that are Kyoo independent. - /// This is used to instantiate plugins that might need a logger, a configuration or an host environment. - /// - /// The configuration context - /// A logger factory used to create a logger for the plugin manager. - public Startup(IServiceProvider hostProvider, IConfiguration configuration, ILoggerFactory loggerFactory, IWebHostEnvironment host) - { - IOptionsMonitor options = hostProvider.GetService>(); - _plugins = new PluginManager(hostProvider, options, loggerFactory.CreateLogger()); - - // TODO remove postgres from here and load it like a normal plugin. - _plugins.LoadPlugins(new IPlugin[] { - new CoreModule(configuration), - new PostgresModule(configuration, host), - // new SqLiteModule(configuration, host), - new AuthenticationModule(configuration, loggerFactory, host), - new PluginTvdb(configuration), - new PluginTmdb(configuration) - }); - } - - /// - /// Configure the WebApp services context. - /// - /// The service collection to fill. - public void ConfigureServices(IServiceCollection services) - { - services.AddMvc().AddControllersAsServices(); - - services.AddSpaStaticFiles(configuration => - { - configuration.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"); - }); - services.AddResponseCompression(x => - { - x.EnableForHttps = true; - }); - - services.AddHttpClient(); - - _plugins.ConfigureServices(services); - } - - public void ConfigureContainer(ContainerBuilder builder) - { - builder.RegisterModule(); - builder.RegisterInstance(_plugins).As().ExternallyOwned(); - builder.RegisterTask(); - _plugins.ConfigureContainer(builder); - } - - /// - /// Configure the asp net host. - /// - /// The asp net host to configure - /// The host environment (is the app in development mode?) - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider provider) - { - if (env.IsDevelopment()) - app.UseDeveloperExceptionPage(); - else - { - app.UseExceptionHandler("/error"); - app.UseHsts(); - } - - if (!env.IsDevelopment()) - app.UseSpaStaticFiles(); - - app.UseRouting(); - app.Use((ctx, next) => - { - ctx.Response.Headers.Remove("X-Powered-By"); - ctx.Response.Headers.Remove("Server"); - ctx.Response.Headers.Add("Feature-Policy", "autoplay 'self'; fullscreen"); - ctx.Response.Headers.Add("Content-Security-Policy", "default-src 'self' blob:; script-src 'self' blob: 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self' https://www.youtube.com"); - ctx.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN"); - ctx.Response.Headers.Add("Referrer-Policy", "no-referrer"); - ctx.Response.Headers.Add("Access-Control-Allow-Origin", "null"); - ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff"); - return next(); - }); - app.UseResponseCompression(); - - if (_plugins is PluginManager manager) - manager.SetProvider(provider); - _plugins.ConfigureAspnet(app); - - app.UseSpa(spa => - { - spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp"); - - if (env.IsDevelopment()) - spa.UseAngularCliServer("start"); - }); - } - } -} diff --git a/Kyoo/Tasks/Crawler.cs b/Kyoo/Tasks/Crawler.cs index 333710a3..cc2762c4 100644 --- a/Kyoo/Tasks/Crawler.cs +++ b/Kyoo/Tasks/Crawler.cs @@ -1,12 +1,12 @@ using System; -using Kyoo.Models; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using Kyoo.Common.Models.Attributes; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; using Kyoo.Models.Watch; using Microsoft.Extensions.Logging; diff --git a/Kyoo/Tasks/Housekeeping.cs b/Kyoo/Tasks/Housekeeping.cs index b98989f5..1724b0e7 100644 --- a/Kyoo/Tasks/Housekeeping.cs +++ b/Kyoo/Tasks/Housekeeping.cs @@ -1,9 +1,9 @@ using System; using System.Threading; using System.Threading.Tasks; -using Kyoo.Common.Models.Attributes; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; using Microsoft.Extensions.Logging; namespace Kyoo.Tasks diff --git a/Kyoo/Tasks/MetadataProviderLoader.cs b/Kyoo/Tasks/MetadataProviderLoader.cs index 42342434..3c9163c4 100644 --- a/Kyoo/Tasks/MetadataProviderLoader.cs +++ b/Kyoo/Tasks/MetadataProviderLoader.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Kyoo.Common.Models.Attributes; -using Kyoo.Controllers; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models.Exceptions; namespace Kyoo.Tasks { diff --git a/Kyoo/Tasks/PluginInitializer.cs b/Kyoo/Tasks/PluginInitializer.cs index c9f814a6..7f9e5171 100644 --- a/Kyoo/Tasks/PluginInitializer.cs +++ b/Kyoo/Tasks/PluginInitializer.cs @@ -2,8 +2,8 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Kyoo.Common.Models.Attributes; -using Kyoo.Controllers; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Attributes; namespace Kyoo.Tasks { diff --git a/Kyoo/Tasks/RegisterEpisode.cs b/Kyoo/Tasks/RegisterEpisode.cs index c7c7c3e3..851d658d 100644 --- a/Kyoo/Tasks/RegisterEpisode.cs +++ b/Kyoo/Tasks/RegisterEpisode.cs @@ -2,10 +2,10 @@ using System; using System.Linq; using System.Threading; using System.Threading.Tasks; -using Kyoo.Common.Models.Attributes; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models.Exceptions; namespace Kyoo.Tasks { diff --git a/Kyoo/Tasks/RegisterSubtitle.cs b/Kyoo/Tasks/RegisterSubtitle.cs index 6c36ea58..2ace1f0b 100644 --- a/Kyoo/Tasks/RegisterSubtitle.cs +++ b/Kyoo/Tasks/RegisterSubtitle.cs @@ -1,10 +1,10 @@ using System; using System.Threading; using System.Threading.Tasks; -using Kyoo.Common.Models.Attributes; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; +using Kyoo.Abstractions.Models.Exceptions; namespace Kyoo.Tasks { diff --git a/Kyoo/Views/CollectionApi.cs b/Kyoo/Views/CollectionApi.cs index 9c26a65c..b6cada95 100644 --- a/Kyoo/Views/CollectionApi.cs +++ b/Kyoo/Views/CollectionApi.cs @@ -1,14 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; -using Kyoo.Controllers; -using Kyoo.Models; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.Extensions.Options; namespace Kyoo.Api diff --git a/Kyoo/Views/ConfigurationApi.cs b/Kyoo/Views/ConfigurationApi.cs index 7830d786..1abef5bf 100644 --- a/Kyoo/Views/ConfigurationApi.cs +++ b/Kyoo/Views/ConfigurationApi.cs @@ -1,8 +1,8 @@ using System; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models.Exceptions; -using Kyoo.Models.Permissions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Microsoft.AspNetCore.Mvc; namespace Kyoo.Api diff --git a/Kyoo/Views/EpisodeApi.cs b/Kyoo/Views/EpisodeApi.cs index e98f1f6a..f225c0b7 100644 --- a/Kyoo/Views/EpisodeApi.cs +++ b/Kyoo/Views/EpisodeApi.cs @@ -1,14 +1,13 @@ using System; -using Kyoo.Models; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Controllers; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.Extensions.Options; namespace Kyoo.Api diff --git a/Kyoo/Views/GenreApi.cs b/Kyoo/Views/GenreApi.cs index e494665d..3076fca2 100644 --- a/Kyoo/Views/GenreApi.cs +++ b/Kyoo/Views/GenreApi.cs @@ -2,11 +2,10 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; diff --git a/Kyoo.CommonAPI/ApiHelper.cs b/Kyoo/Views/Helper/ApiHelper.cs similarity index 98% rename from Kyoo.CommonAPI/ApiHelper.cs rename to Kyoo/Views/Helper/ApiHelper.cs index d3d8d951..f2650942 100644 --- a/Kyoo.CommonAPI/ApiHelper.cs +++ b/Kyoo/Views/Helper/ApiHelper.cs @@ -4,9 +4,9 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; -using Kyoo.Models; +using Kyoo.Abstractions.Models; -namespace Kyoo.CommonApi +namespace Kyoo.Api { public static class ApiHelper { diff --git a/Kyoo.CommonAPI/CrudApi.cs b/Kyoo/Views/Helper/CrudApi.cs similarity index 95% rename from Kyoo.CommonAPI/CrudApi.cs rename to Kyoo/Views/Helper/CrudApi.cs index 9b7e7c39..eba42b1d 100644 --- a/Kyoo.CommonAPI/CrudApi.cs +++ b/Kyoo/Views/Helper/CrudApi.cs @@ -2,13 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; -using Kyoo.Models.Permissions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Microsoft.AspNetCore.Mvc; -namespace Kyoo.CommonApi +namespace Kyoo.Api { [ApiController] [ResourceView] @@ -82,7 +82,7 @@ namespace Kyoo.CommonApi protected Page Page(ICollection resources, int limit) where TResult : IResource { - return new Page(resources, + return new Page(resources, new Uri(BaseURL, Request.Path), Request.Query.ToDictionary(x => x.Key, x => x.Value.ToString(), StringComparer.InvariantCultureIgnoreCase), limit); diff --git a/Kyoo.CommonAPI/JsonSerializer.cs b/Kyoo/Views/Helper/JsonSerializer.cs similarity index 88% rename from Kyoo.CommonAPI/JsonSerializer.cs rename to Kyoo/Views/Helper/JsonSerializer.cs index 3a2caac7..c5b91b03 100644 --- a/Kyoo.CommonAPI/JsonSerializer.cs +++ b/Kyoo/Views/Helper/JsonSerializer.cs @@ -4,13 +4,13 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; -using Kyoo.Models; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; -namespace Kyoo.Controllers +namespace Kyoo.Api { public class JsonPropertyIgnorer : CamelCasePropertyNamesContractResolver { @@ -26,7 +26,7 @@ namespace Kyoo.Controllers { JsonProperty property = base.CreateProperty(member, memberSerialization); - LoadableRelationAttribute relation = member?.GetCustomAttribute(); + LoadableRelationAttribute relation = member.GetCustomAttribute(); if (relation != null) { if (relation.RelationID == null) @@ -42,14 +42,14 @@ namespace Kyoo.Controllers }; } - if (member?.GetCustomAttribute() != null) + if (member.GetCustomAttribute() != null) property.ShouldSerialize = _ => false; - if (member?.GetCustomAttribute() != null) + if (member.GetCustomAttribute() != null) property.ShouldDeserialize = _ => false; // TODO use http context to disable serialize as. // TODO check https://stackoverflow.com/questions/53288633/net-core-api-custom-json-resolver-based-on-request-values - SerializeAsAttribute serializeAs = member?.GetCustomAttribute(); + SerializeAsAttribute serializeAs = member.GetCustomAttribute(); if (serializeAs != null) property.ValueProvider = new SerializeAsProvider(serializeAs.Format, _host); return property; @@ -81,7 +81,7 @@ namespace Kyoo.Controllers if (value.People != null) value.People.Roles = null; - JObject obj = JObject.FromObject(value.ForPeople ? value.People : value.Show, serializer); + JObject obj = JObject.FromObject((value.ForPeople ? value.People : value.Show)!, serializer); obj.Add("role", value.Role); obj.Add("type", value.Type); obj.WriteTo(writer); diff --git a/Kyoo.CommonAPI/ResourceViewAttribute.cs b/Kyoo/Views/Helper/ResourceViewAttribute.cs similarity index 96% rename from Kyoo.CommonAPI/ResourceViewAttribute.cs rename to Kyoo/Views/Helper/ResourceViewAttribute.cs index 487373c4..386dc60c 100644 --- a/Kyoo.CommonAPI/ResourceViewAttribute.cs +++ b/Kyoo/Views/Helper/ResourceViewAttribute.cs @@ -3,15 +3,15 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; -namespace Kyoo.CommonApi +namespace Kyoo.Api { public class ResourceViewAttribute : ActionFilterAttribute { diff --git a/Kyoo/Views/LibraryApi.cs b/Kyoo/Views/LibraryApi.cs index 83d0e712..69203926 100644 --- a/Kyoo/Views/LibraryApi.cs +++ b/Kyoo/Views/LibraryApi.cs @@ -1,13 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; -using Kyoo.Controllers; -using Kyoo.Models; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; -using Kyoo.CommonApi; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.Extensions.Options; namespace Kyoo.Api diff --git a/Kyoo/Views/LibraryItemApi.cs b/Kyoo/Views/LibraryItemApi.cs index c35ec412..0c801a5c 100644 --- a/Kyoo/Views/LibraryItemApi.cs +++ b/Kyoo/Views/LibraryItemApi.cs @@ -2,12 +2,11 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; @@ -44,7 +43,7 @@ namespace Kyoo.Api new Pagination(limit, afterID)); return new Page(resources, - new Uri(_baseURL + Request.Path), + new Uri(_baseURL, Request.Path), Request.Query.ToDictionary(x => x.Key, x => x.Value.ToString(), StringComparer.InvariantCultureIgnoreCase), limit); } diff --git a/Kyoo/Views/PeopleApi.cs b/Kyoo/Views/PeopleApi.cs index bd25491e..06ce4df7 100644 --- a/Kyoo/Views/PeopleApi.cs +++ b/Kyoo/Views/PeopleApi.cs @@ -1,12 +1,11 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; diff --git a/Kyoo/Views/ProviderApi.cs b/Kyoo/Views/ProviderApi.cs index 5651f4f7..04f999a1 100644 --- a/Kyoo/Views/ProviderApi.cs +++ b/Kyoo/Views/ProviderApi.cs @@ -1,9 +1,8 @@ using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; diff --git a/Kyoo/Views/SearchApi.cs b/Kyoo/Views/SearchApi.cs index b78aa683..5abe1467 100644 --- a/Kyoo/Views/SearchApi.cs +++ b/Kyoo/Views/SearchApi.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Permissions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Permissions; using Microsoft.AspNetCore.Mvc; namespace Kyoo.Api diff --git a/Kyoo/Views/SeasonApi.cs b/Kyoo/Views/SeasonApi.cs index fdf98959..6979b47b 100644 --- a/Kyoo/Views/SeasonApi.cs +++ b/Kyoo/Views/SeasonApi.cs @@ -1,13 +1,12 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Controllers; -using Kyoo.Models; using Microsoft.AspNetCore.Mvc; using System.Linq; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.Extensions.Options; namespace Kyoo.Api diff --git a/Kyoo/Views/ShowApi.cs b/Kyoo/Views/ShowApi.cs index 0c8dde65..1c3c3fa5 100644 --- a/Kyoo/Views/ShowApi.cs +++ b/Kyoo/Views/ShowApi.cs @@ -1,15 +1,14 @@ using System; -using Kyoo.Models; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Controllers; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.Extensions.Options; namespace Kyoo.Api diff --git a/Kyoo/Views/StudioApi.cs b/Kyoo/Views/StudioApi.cs index a6957e33..5474d1f5 100644 --- a/Kyoo/Views/StudioApi.cs +++ b/Kyoo/Views/StudioApi.cs @@ -2,11 +2,10 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; diff --git a/Kyoo/Views/SubtitleApi.cs b/Kyoo/Views/SubtitleApi.cs index 89d036aa..e4f94887 100644 --- a/Kyoo/Views/SubtitleApi.cs +++ b/Kyoo/Views/SubtitleApi.cs @@ -1,11 +1,11 @@ -using Kyoo.Models; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models.Permissions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Permissions; namespace Kyoo.Api { diff --git a/Kyoo/Views/TaskApi.cs b/Kyoo/Views/TaskApi.cs index dfad76da..25097411 100644 --- a/Kyoo/Views/TaskApi.cs +++ b/Kyoo/Views/TaskApi.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Microsoft.AspNetCore.Mvc; -using Kyoo.Controllers; -using Kyoo.Models.Exceptions; -using Kyoo.Models.Permissions; namespace Kyoo.Api { diff --git a/Kyoo/Views/TrackApi.cs b/Kyoo/Views/TrackApi.cs index 07df38ce..a6a1b6cb 100644 --- a/Kyoo/Views/TrackApi.cs +++ b/Kyoo/Views/TrackApi.cs @@ -1,11 +1,10 @@ using System.Linq; using System.Threading.Tasks; -using Kyoo.CommonApi; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; diff --git a/Kyoo/Views/VideoApi.cs b/Kyoo/Views/VideoApi.cs index cbc2937b..2badb6dd 100644 --- a/Kyoo/Views/VideoApi.cs +++ b/Kyoo/Views/VideoApi.cs @@ -1,11 +1,11 @@ using System.IO; -using Kyoo.Controllers; -using Kyoo.Models; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Kyoo.Models.Options; -using Kyoo.Models.Permissions; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Options; diff --git a/Kyoo/Views/WatchApi.cs b/Kyoo/Views/WatchApi.cs index 38e65e21..d4a46e8a 100644 --- a/Kyoo/Views/WatchApi.cs +++ b/Kyoo/Views/WatchApi.cs @@ -1,8 +1,8 @@ using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; -using Kyoo.Models.Permissions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Abstractions.Models.Permissions; using Microsoft.AspNetCore.Mvc; namespace Kyoo.Api diff --git a/Kyoo/settings.json b/Kyoo/settings.json index 1ddc8cf1..a3d90396 100644 --- a/Kyoo/settings.json +++ b/Kyoo/settings.json @@ -10,19 +10,22 @@ }, "database": { - "sqlite": { - "data Source": "kyoo.db", - "cache": "Shared" - }, - "postgres": { - "server": "127.0.0.1", - "port": "5432", - "database": "kyooDB", - "user ID": "kyoo", - "password": "kyooPassword", - "pooling": "true", - "maxPoolSize": "95", - "timeout": "30" + "enabled": "sqlite", + "configurations": { + "sqlite": { + "data Source": "kyoo.db", + "cache": "Shared" + }, + "postgres": { + "server": "127.0.0.1", + "port": "5432", + "database": "kyooDB", + "user ID": "kyoo", + "password": "kyooPassword", + "pooling": "true", + "maxPoolSize": "95", + "timeout": "30" + } } }, diff --git a/tests/Kyoo.Tests/Database/RepositoryActivator.cs b/tests/Kyoo.Tests/Database/RepositoryActivator.cs index 8e543546..92addd86 100644 --- a/tests/Kyoo.Tests/Database/RepositoryActivator.cs +++ b/tests/Kyoo.Tests/Database/RepositoryActivator.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Kyoo.Abstractions.Controllers; using Kyoo.Controllers; +using Kyoo.Database; using Xunit.Abstractions; namespace Kyoo.Tests diff --git a/tests/Kyoo.Tests/Database/RepositoryTests.cs b/tests/Kyoo.Tests/Database/RepositoryTests.cs index 4cc72b4c..536673b3 100644 --- a/tests/Kyoo.Tests/Database/RepositoryTests.cs +++ b/tests/Kyoo.Tests/Database/RepositoryTests.cs @@ -3,9 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; +using Kyoo.Database; using Xunit; namespace Kyoo.Tests @@ -64,7 +65,7 @@ namespace Kyoo.Tests [Fact] public async Task GetByFakeSlugTest() { - await Assert.ThrowsAsync(() => _repository.Get("non-existent")); + await Assert.ThrowsAsync(() => _repository.Get("non-existent")); } [Fact] diff --git a/tests/Kyoo.Tests/Database/SpecificTests/CollectionsTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/CollectionsTests.cs index f1f773ad..f28cef94 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/CollectionsTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/CollectionsTests.cs @@ -2,8 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/EpisodeTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/EpisodeTests.cs index 8a477100..0aff5ec7 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/EpisodeTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/EpisodeTests.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/GenreTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/GenreTests.cs index dc820187..0b5d8489 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/GenreTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/GenreTests.cs @@ -1,5 +1,5 @@ -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/LibraryItemTest.cs b/tests/Kyoo.Tests/Database/SpecificTests/LibraryItemTest.cs index f3e031b2..d370996a 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/LibraryItemTest.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/LibraryItemTest.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/LibraryTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/LibraryTests.cs index 79277f61..20b7defe 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/LibraryTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/LibraryTests.cs @@ -2,8 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/PeopleTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/PeopleTests.cs index 3de88edf..669f6f91 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/PeopleTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/PeopleTests.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/ProviderTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/ProviderTests.cs index 9c022875..06edde1b 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/ProviderTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/ProviderTests.cs @@ -1,5 +1,5 @@ -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/SanityTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/SanityTests.cs index a071ee2b..efbdbd26 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/SanityTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/SanityTests.cs @@ -1,7 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/SeasonTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/SeasonTests.cs index ae56415c..54d164a9 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/SeasonTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/SeasonTests.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/ShowTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/ShowTests.cs index d3111f75..c46aaa26 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/ShowTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/ShowTests.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using FluentAssertions; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Database; using Microsoft.EntityFrameworkCore; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/StudioTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/StudioTests.cs index c727f67a..8b64bded 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/StudioTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/StudioTests.cs @@ -1,5 +1,5 @@ -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/TrackTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/TrackTests.cs index 0ff0c156..2bf7cc17 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/TrackTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/TrackTests.cs @@ -1,6 +1,6 @@ using System.Threading.Tasks; -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/SpecificTests/UserTests.cs b/tests/Kyoo.Tests/Database/SpecificTests/UserTests.cs index 24bfc789..a9f7b0bc 100644 --- a/tests/Kyoo.Tests/Database/SpecificTests/UserTests.cs +++ b/tests/Kyoo.Tests/Database/SpecificTests/UserTests.cs @@ -1,5 +1,5 @@ -using Kyoo.Controllers; -using Kyoo.Models; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Xunit; using Xunit.Abstractions; diff --git a/tests/Kyoo.Tests/Database/TestContext.cs b/tests/Kyoo.Tests/Database/TestContext.cs index fa2935b8..79d873c4 100644 --- a/tests/Kyoo.Tests/Database/TestContext.cs +++ b/tests/Kyoo.Tests/Database/TestContext.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Kyoo.Database; using Kyoo.Postgresql; using Kyoo.SqLite; using Microsoft.Data.Sqlite; diff --git a/tests/Kyoo.Tests/Database/TestSample.cs b/tests/Kyoo.Tests/Database/TestSample.cs index 6f9a69ff..2cf72abd 100644 --- a/tests/Kyoo.Tests/Database/TestSample.cs +++ b/tests/Kyoo.Tests/Database/TestSample.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; -using Kyoo.Models; +using Kyoo.Abstractions.Models; +using Kyoo.Database; namespace Kyoo.Tests { diff --git a/tests/Kyoo.Tests/Identifier/IdentifierTests.cs b/tests/Kyoo.Tests/Identifier/IdentifierTests.cs index 36ad94b9..93f6c345 100644 --- a/tests/Kyoo.Tests/Identifier/IdentifierTests.cs +++ b/tests/Kyoo.Tests/Identifier/IdentifierTests.cs @@ -1,7 +1,8 @@ using System.Threading.Tasks; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Exceptions; using Kyoo.Controllers; -using Kyoo.Models; -using Kyoo.Models.Exceptions; using Kyoo.Models.Options; using Microsoft.Extensions.Options; using Moq; diff --git a/tests/Kyoo.Tests/Identifier/ProviderTests.cs b/tests/Kyoo.Tests/Identifier/ProviderTests.cs index c49ca3b2..0d9eb34a 100644 --- a/tests/Kyoo.Tests/Identifier/ProviderTests.cs +++ b/tests/Kyoo.Tests/Identifier/ProviderTests.cs @@ -2,8 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Kyoo.Abstractions.Controllers; +using Kyoo.Abstractions.Models; using Kyoo.Controllers; -using Kyoo.Models; using Microsoft.Extensions.Logging; using Moq; using Xunit; diff --git a/tests/Kyoo.Tests/Identifier/Tvdb/ConvertorTests.cs b/tests/Kyoo.Tests/Identifier/Tvdb/ConvertorTests.cs index a761ab9e..48e6cf56 100644 --- a/tests/Kyoo.Tests/Identifier/Tvdb/ConvertorTests.cs +++ b/tests/Kyoo.Tests/Identifier/Tvdb/ConvertorTests.cs @@ -1,6 +1,6 @@ using System; using System.Linq; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using Kyoo.TheTvdb; using TvDbSharper.Dto; using Xunit; diff --git a/tests/Kyoo.Tests/Kyoo.Tests.csproj b/tests/Kyoo.Tests/Kyoo.Tests.csproj index f174bc55..7568e9d5 100644 --- a/tests/Kyoo.Tests/Kyoo.Tests.csproj +++ b/tests/Kyoo.Tests/Kyoo.Tests.csproj @@ -32,8 +32,8 @@ - - + + diff --git a/tests/Kyoo.Tests/Utility/MergerTests.cs b/tests/Kyoo.Tests/Utility/MergerTests.cs index de9d3b04..a378ebb7 100644 --- a/tests/Kyoo.Tests/Utility/MergerTests.cs +++ b/tests/Kyoo.Tests/Utility/MergerTests.cs @@ -3,8 +3,8 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using JetBrains.Annotations; -using Kyoo.Models; -using Kyoo.Models.Attributes; +using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; using Xunit; namespace Kyoo.Tests.Utility diff --git a/tests/Kyoo.Tests/Utility/UtilityTests.cs b/tests/Kyoo.Tests/Utility/UtilityTests.cs index f6f279aa..5c01069c 100644 --- a/tests/Kyoo.Tests/Utility/UtilityTests.cs +++ b/tests/Kyoo.Tests/Utility/UtilityTests.cs @@ -1,7 +1,7 @@ using System; using System.Linq.Expressions; using System.Reflection; -using Kyoo.Models; +using Kyoo.Abstractions.Models; using Xunit; using Utils = Kyoo.Utility;