mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Delete usless plugin/startup handling
This commit is contained in:
parent
13ad35a9ac
commit
9bd1e50de3
@ -8,7 +8,6 @@ COPY src/Directory.Build.props src/Directory.Build.props
|
|||||||
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
||||||
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
||||||
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
||||||
COPY src/Kyoo.Host/Kyoo.Host.csproj src/Kyoo.Host/Kyoo.Host.csproj
|
|
||||||
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||||
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
||||||
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
||||||
|
@ -8,7 +8,6 @@ COPY src/Directory.Build.props src/Directory.Build.props
|
|||||||
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
||||||
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
||||||
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
||||||
COPY src/Kyoo.Host/Kyoo.Host.csproj src/Kyoo.Host/Kyoo.Host.csproj
|
|
||||||
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||||
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
||||||
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
||||||
|
@ -11,7 +11,6 @@ COPY src/Directory.Build.props src/Directory.Build.props
|
|||||||
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
||||||
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
||||||
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
||||||
COPY src/Kyoo.Host/Kyoo.Host.csproj src/Kyoo.Host/Kyoo.Host.csproj
|
|
||||||
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||||
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
||||||
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
||||||
|
@ -10,8 +10,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Authentication", "src\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Swagger", "src\Kyoo.Swagger\Kyoo.Swagger.csproj", "{7D1A7596-73F6-4D35-842E-A5AD9C620596}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Swagger", "src\Kyoo.Swagger\Kyoo.Swagger.csproj", "{7D1A7596-73F6-4D35-842E-A5AD9C620596}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Host", "src\Kyoo.Host\Kyoo.Host.csproj", "{0938459E-2E2B-457F-8120-7D8CA93866A6}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Meilisearch", "src\Kyoo.Meilisearch\Kyoo.Meilisearch.csproj", "{F8E6018A-FD51-40EB-99FF-A26BA59F2762}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Meilisearch", "src\Kyoo.Meilisearch\Kyoo.Meilisearch.csproj", "{F8E6018A-FD51-40EB-99FF-A26BA59F2762}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.RabbitMq", "src\Kyoo.RabbitMq\Kyoo.RabbitMq.csproj", "{B97AD4A8-E6E6-41CD-87DF-5F1326FD7198}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.RabbitMq", "src\Kyoo.RabbitMq\Kyoo.RabbitMq.csproj", "{B97AD4A8-E6E6-41CD-87DF-5F1326FD7198}"
|
||||||
@ -54,10 +52,6 @@ Global
|
|||||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{0938459E-2E2B-457F-8120-7D8CA93866A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{0938459E-2E2B-457F-8120-7D8CA93866A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{0938459E-2E2B-457F-8120-7D8CA93866A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{0938459E-2E2B-457F-8120-7D8CA93866A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
@ -1,4 +1,2 @@
|
|||||||
--project
|
--project
|
||||||
src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||||
--msbuildprojectextensionspath
|
|
||||||
out/obj/Kyoo.Postgresql
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<LangVersion>default</LangVersion>
|
<LangVersion>default</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
<Company>Kyoo</Company>
|
<Company>Kyoo</Company>
|
||||||
<Authors>Kyoo</Authors>
|
<Authors>Kyoo</Authors>
|
||||||
<Copyright>Copyright (c) Kyoo</Copyright>
|
<Copyright>Copyright (c) Kyoo</Copyright>
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Autofac;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Controllers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A common interface used to discord plugins
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// You can inject services in the IPlugin constructor.
|
|
||||||
/// You should only inject well known services like an ILogger, IConfiguration or IWebHostEnvironment.
|
|
||||||
/// </remarks>
|
|
||||||
public interface IPlugin
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The name of the plugin
|
|
||||||
/// </summary>
|
|
||||||
string Name { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An optional configuration step to allow a plugin to change asp net configurations.
|
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="SA"/>
|
|
||||||
IEnumerable<IStartupAction> ConfigureSteps => ArraySegment<IStartupAction>.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A configure method that will be run on plugin's startup.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The autofac service container to register services.</param>
|
|
||||||
void Configure(ContainerBuilder builder)
|
|
||||||
{
|
|
||||||
// Skipped
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A configure method that will be run on plugin's startup.
|
|
||||||
/// This is available for libraries that build upon a <see cref="IServiceCollection"/>, for more precise
|
|
||||||
/// configuration use <see cref="Configure(Autofac.ContainerBuilder)"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="services">A service container to register new services.</param>
|
|
||||||
void Configure(IServiceCollection services)
|
|
||||||
{
|
|
||||||
// Skipped
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Kyoo.Abstractions.Models.Exceptions;
|
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Controllers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A manager to load plugins and retrieve information from them.
|
|
||||||
/// </summary>
|
|
||||||
public interface IPluginManager
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Get a single plugin that match the type and name given.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">The name of the plugin</param>
|
|
||||||
/// <typeparam name="T">The type of the plugin</typeparam>
|
|
||||||
/// <exception cref="ItemNotFoundException">If no plugins match the query</exception>
|
|
||||||
/// <returns>A plugin that match the queries</returns>
|
|
||||||
public T GetPlugin<T>(string name);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get all plugins of the given type.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of plugins to get</typeparam>
|
|
||||||
/// <returns>A list of plugins matching the given type or an empty list of none match.</returns>
|
|
||||||
public ICollection<T> GetPlugins<T>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get all plugins currently running on Kyoo. This also includes deleted plugins if the app as not been restarted.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>All plugins currently loaded.</returns>
|
|
||||||
public ICollection<IPlugin> GetAllPlugins();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Load plugins and their dependencies from the plugin directory.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="plugins">
|
|
||||||
/// An initial plugin list to use.
|
|
||||||
/// You should not try to put plugins from the plugins directory here as they will get automatically loaded.
|
|
||||||
/// </param>
|
|
||||||
public void LoadPlugins(ICollection<IPlugin> plugins);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Load plugins and their dependencies from the plugin directory.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="plugins">
|
|
||||||
/// An initial plugin list to use.
|
|
||||||
/// You should not try to put plugins from the plugins directory here as they will get automatically loaded.
|
|
||||||
/// </param>
|
|
||||||
public void LoadPlugins(params Type[] plugins);
|
|
||||||
}
|
|
@ -1,270 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Kyoo.Abstractions.Controllers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A list of constant priorities used for <see cref="IStartupAction"/>'s <see cref="IStartupAction.Priority"/>.
|
|
||||||
/// It also contains helper methods for creating new <see cref="StartupAction"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static class SA
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The highest predefined priority existing for <see cref="StartupAction"/>.
|
|
||||||
/// </summary>
|
|
||||||
public const int Before = 5000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Items defining routing (see IApplicationBuilder.UseRouting use this priority.
|
|
||||||
/// </summary>
|
|
||||||
public const int Routing = 4000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Actions defining new static files router use this priority.
|
|
||||||
/// </summary>
|
|
||||||
public const int StaticFiles = 3000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Actions calling IApplicationBuilder.UseAuthentication use this priority.
|
|
||||||
/// </summary>
|
|
||||||
public const int Authentication = 2000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Actions calling IApplicationBuilder.UseAuthorization use this priority.
|
|
||||||
/// </summary>
|
|
||||||
public const int Authorization = 1000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action adding endpoint should use this priority (with a negative modificator if there is a catchall).
|
|
||||||
/// </summary>
|
|
||||||
public const int Endpoint = 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The lowest predefined priority existing for <see cref="StartupAction"/>.
|
|
||||||
/// It should run after all other actions.
|
|
||||||
/// </summary>
|
|
||||||
public const int After = -1000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="StartupAction"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to run</param>
|
|
||||||
/// <param name="priority">The priority of the new action</param>
|
|
||||||
/// <returns>A new <see cref="StartupAction"/></returns>
|
|
||||||
public static StartupAction New(Action action, int priority) => new(action, priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="StartupAction"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to run</param>
|
|
||||||
/// <param name="priority">The priority of the new action</param>
|
|
||||||
/// <typeparam name="T">A dependency that this action will use.</typeparam>
|
|
||||||
/// <returns>A new <see cref="StartupAction"/></returns>
|
|
||||||
public static StartupAction<T> New<T>(Action<T> action, int priority)
|
|
||||||
where T : notnull => new(action, priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="StartupAction"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to run</param>
|
|
||||||
/// <param name="priority">The priority of the new action</param>
|
|
||||||
/// <typeparam name="T">A dependency that this action will use.</typeparam>
|
|
||||||
/// <typeparam name="T2">A second dependency that this action will use.</typeparam>
|
|
||||||
/// <returns>A new <see cref="StartupAction"/></returns>
|
|
||||||
public static StartupAction<T, T2> New<T, T2>(Action<T, T2> action, int priority)
|
|
||||||
where T : notnull
|
|
||||||
where T2 : notnull => new(action, priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="StartupAction"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to run</param>
|
|
||||||
/// <param name="priority">The priority of the new action</param>
|
|
||||||
/// <typeparam name="T">A dependency that this action will use.</typeparam>
|
|
||||||
/// <typeparam name="T2">A second dependency that this action will use.</typeparam>
|
|
||||||
/// <typeparam name="T3">A third dependency that this action will use.</typeparam>
|
|
||||||
/// <returns>A new <see cref="StartupAction"/></returns>
|
|
||||||
public static StartupAction<T, T2, T3> New<T, T2, T3>(Action<T, T2, T3> action, int priority)
|
|
||||||
where T : notnull
|
|
||||||
where T2 : notnull
|
|
||||||
where T3 : notnull => new(action, priority);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A <see cref="IStartupAction"/> with no dependencies.
|
|
||||||
/// </summary>
|
|
||||||
public class StartupAction : IStartupAction
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The action to execute at startup.
|
|
||||||
/// </summary>
|
|
||||||
private readonly Action _action;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public int Priority { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="StartupAction"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to execute on startup.</param>
|
|
||||||
/// <param name="priority">The priority of this action (see <see cref="Priority"/>).</param>
|
|
||||||
public StartupAction(Action action, int priority)
|
|
||||||
{
|
|
||||||
_action = action;
|
|
||||||
Priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Run(IServiceProvider provider)
|
|
||||||
{
|
|
||||||
_action.Invoke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A <see cref="IStartupAction"/> with one dependencies.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The dependency to use.</typeparam>
|
|
||||||
public class StartupAction<T> : IStartupAction
|
|
||||||
where T : notnull
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The action to execute at startup.
|
|
||||||
/// </summary>
|
|
||||||
private readonly Action<T> _action;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public int Priority { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="StartupAction{T}"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to execute on startup.</param>
|
|
||||||
/// <param name="priority">The priority of this action (see <see cref="Priority"/>).</param>
|
|
||||||
public StartupAction(Action<T> action, int priority)
|
|
||||||
{
|
|
||||||
_action = action;
|
|
||||||
Priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Run(IServiceProvider provider)
|
|
||||||
{
|
|
||||||
_action.Invoke(provider.GetRequiredService<T>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A <see cref="IStartupAction"/> with two dependencies.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The dependency to use.</typeparam>
|
|
||||||
/// <typeparam name="T2">The second dependency to use.</typeparam>
|
|
||||||
public class StartupAction<T, T2> : IStartupAction
|
|
||||||
where T : notnull
|
|
||||||
where T2 : notnull
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The action to execute at startup.
|
|
||||||
/// </summary>
|
|
||||||
private readonly Action<T, T2> _action;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public int Priority { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="StartupAction{T, T2}"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to execute on startup.</param>
|
|
||||||
/// <param name="priority">The priority of this action (see <see cref="Priority"/>).</param>
|
|
||||||
public StartupAction(Action<T, T2> action, int priority)
|
|
||||||
{
|
|
||||||
_action = action;
|
|
||||||
Priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Run(IServiceProvider provider)
|
|
||||||
{
|
|
||||||
_action.Invoke(provider.GetRequiredService<T>(), provider.GetRequiredService<T2>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A <see cref="IStartupAction"/> with three dependencies.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The dependency to use.</typeparam>
|
|
||||||
/// <typeparam name="T2">The second dependency to use.</typeparam>
|
|
||||||
/// <typeparam name="T3">The third dependency to use.</typeparam>
|
|
||||||
public class StartupAction<T, T2, T3> : IStartupAction
|
|
||||||
where T : notnull
|
|
||||||
where T2 : notnull
|
|
||||||
where T3 : notnull
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The action to execute at startup.
|
|
||||||
/// </summary>
|
|
||||||
private readonly Action<T, T2, T3> _action;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public int Priority { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="StartupAction{T, T2, T3}"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to execute on startup.</param>
|
|
||||||
/// <param name="priority">The priority of this action (see <see cref="Priority"/>).</param>
|
|
||||||
public StartupAction(Action<T, T2, T3> action, int priority)
|
|
||||||
{
|
|
||||||
_action = action;
|
|
||||||
Priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Run(IServiceProvider provider)
|
|
||||||
{
|
|
||||||
_action.Invoke(
|
|
||||||
provider.GetRequiredService<T>(),
|
|
||||||
provider.GetRequiredService<T2>(),
|
|
||||||
provider.GetRequiredService<T3>()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An action executed on kyoo's startup to initialize the asp-net container.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This is the base interface, see <see cref="SA.StartupAction"/> for a simpler use of this.
|
|
||||||
/// </remarks>
|
|
||||||
public interface IStartupAction
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The priority of this action. The actions will be executed on descending priority order.
|
|
||||||
/// If two actions have the same priority, their order is undefined.
|
|
||||||
/// </summary>
|
|
||||||
int Priority { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Run this action to configure the container, a service provider containing all services can be used.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="provider">The service provider containing all services can be used.</param>
|
|
||||||
void Run(IServiceProvider provider);
|
|
||||||
}
|
|
@ -3,7 +3,6 @@
|
|||||||
<Title>Kyoo.Abstractions</Title>
|
<Title>Kyoo.Abstractions</Title>
|
||||||
<Description>Base package to create plugins for Kyoo.</Description>
|
<Description>Base package to create plugins for Kyoo.</Description>
|
||||||
<RootNamespace>Kyoo.Abstractions</RootNamespace>
|
<RootNamespace>Kyoo.Abstractions</RootNamespace>
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -28,62 +27,41 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
namespace Kyoo.Authentication;
|
namespace Kyoo.Authentication;
|
||||||
|
|
||||||
/// <summary>
|
public static class AuthenticationModule
|
||||||
/// A module that enable OpenID authentication for Kyoo.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Create a new authentication module instance and use the given configuration.
|
|
||||||
/// </remarks>
|
|
||||||
public class AuthenticationModule(
|
|
||||||
IConfiguration configuration,
|
|
||||||
ILogger<AuthenticationModule> logger
|
|
||||||
) : IPlugin
|
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
public static void ConfigureAuthentication(this WebApplicationBuilder builder)
|
||||||
public string Name => "Authentication";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The configuration to use.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IConfiguration _configuration = configuration;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Configure(ContainerBuilder builder)
|
|
||||||
{
|
{
|
||||||
builder.RegisterType<PermissionValidator>().As<IPermissionValidator>().SingleInstance();
|
string secret = builder.Configuration.GetValue(
|
||||||
builder.RegisterType<TokenController>().As<ITokenController>().SingleInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Configure(IServiceCollection services)
|
|
||||||
{
|
|
||||||
string secret = _configuration.GetValue(
|
|
||||||
"AUTHENTICATION_SECRET",
|
"AUTHENTICATION_SECRET",
|
||||||
AuthenticationOption.DefaultSecret
|
AuthenticationOption.DefaultSecret
|
||||||
)!;
|
)!;
|
||||||
PermissionOption options =
|
PermissionOption options =
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
Default = _configuration
|
Default = builder
|
||||||
.GetValue("UNLOGGED_PERMISSIONS", "")!
|
.Configuration.GetValue("UNLOGGED_PERMISSIONS", "")!
|
||||||
.Split(',')
|
.Split(',')
|
||||||
.Where(x => x.Length > 0)
|
.Where(x => x.Length > 0)
|
||||||
.ToArray(),
|
.ToArray(),
|
||||||
NewUser = _configuration
|
NewUser = builder
|
||||||
.GetValue("DEFAULT_PERMISSIONS", "overall.read,overall.play")!
|
.Configuration.GetValue("DEFAULT_PERMISSIONS", "overall.read,overall.play")!
|
||||||
.Split(','),
|
.Split(','),
|
||||||
RequireVerification = _configuration.GetValue("REQUIRE_ACCOUNT_VERIFICATION", true),
|
RequireVerification = builder.Configuration.GetValue(
|
||||||
|
"REQUIRE_ACCOUNT_VERIFICATION",
|
||||||
|
true
|
||||||
|
),
|
||||||
PublicUrl =
|
PublicUrl =
|
||||||
_configuration.GetValue<string?>("PUBLIC_URL") ?? "http://localhost:8901",
|
builder.Configuration.GetValue<string?>("PUBLIC_URL")
|
||||||
ApiKeys = _configuration.GetValue("KYOO_APIKEYS", string.Empty)!.Split(','),
|
?? "http://localhost:8901",
|
||||||
OIDC = _configuration
|
ApiKeys = builder.Configuration.GetValue("KYOO_APIKEYS", string.Empty)!.Split(','),
|
||||||
.AsEnumerable()
|
OIDC = builder
|
||||||
|
.Configuration.AsEnumerable()
|
||||||
.Where((pair) => pair.Key.StartsWith("OIDC_"))
|
.Where((pair) => pair.Key.StartsWith("OIDC_"))
|
||||||
.Aggregate(
|
.Aggregate(
|
||||||
new Dictionary<string, OidcProvider>(),
|
new Dictionary<string, OidcProvider>(),
|
||||||
@ -93,7 +71,7 @@ public class AuthenticationModule(
|
|||||||
return acc;
|
return acc;
|
||||||
if (val.Key.Split("_") is not ["OIDC", string provider, string key])
|
if (val.Key.Split("_") is not ["OIDC", string provider, string key])
|
||||||
{
|
{
|
||||||
logger.LogError("Invalid oidc config value: {Key}", val.Key);
|
Log.Error("Invalid oidc config value: {Key}", val.Key);
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
provider = provider.ToLowerInvariant();
|
provider = provider.ToLowerInvariant();
|
||||||
@ -129,20 +107,20 @@ public class AuthenticationModule(
|
|||||||
acc[provider].LogoUrl = val.Value;
|
acc[provider].LogoUrl = val.Value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.LogError("Invalid oidc config value: {Key}", key);
|
Log.Error("Invalid oidc config value: {Key}", key);
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
services.AddSingleton(options);
|
builder.Services.AddSingleton(options);
|
||||||
services.AddSingleton(
|
builder.Services.AddSingleton(
|
||||||
new AuthenticationOption() { Secret = secret, Permissions = options, }
|
new AuthenticationOption() { Secret = secret, Permissions = options, }
|
||||||
);
|
);
|
||||||
|
|
||||||
services
|
builder
|
||||||
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||||
.AddJwtBearer(options =>
|
.AddJwtBearer(options =>
|
||||||
{
|
{
|
||||||
options.Events = new()
|
options.Events = new()
|
||||||
@ -171,12 +149,8 @@ public class AuthenticationModule(
|
|||||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret))
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret))
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
builder.Services.AddSingleton<IPermissionValidator, PermissionValidator>();
|
||||||
public IEnumerable<IStartupAction> ConfigureSteps =>
|
builder.Services.AddSingleton<ITokenController, TokenController>();
|
||||||
new IStartupAction[]
|
}
|
||||||
{
|
|
||||||
SA.New<IApplicationBuilder>(app => app.UseAuthentication(), SA.Authentication),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.3" />
|
||||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||||
|
<PackageReference Include="Serilog" Version="3.1.1" />
|
||||||
|
|
||||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -53,8 +53,8 @@ public class LibraryManager : ILibraryManager
|
|||||||
Studios = studioRepository;
|
Studios = studioRepository;
|
||||||
Users = userRepository;
|
Users = userRepository;
|
||||||
|
|
||||||
_repositories = new IBaseRepository[]
|
_repositories =
|
||||||
{
|
[
|
||||||
LibraryItems,
|
LibraryItems,
|
||||||
News,
|
News,
|
||||||
Collections,
|
Collections,
|
||||||
@ -64,7 +64,7 @@ public class LibraryManager : ILibraryManager
|
|||||||
Episodes,
|
Episodes,
|
||||||
Studios,
|
Studios,
|
||||||
Users
|
Users
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -42,7 +42,7 @@ public class ThumbnailsManager(
|
|||||||
Lazy<IRepository<User>> users
|
Lazy<IRepository<User>> users
|
||||||
) : IThumbnailsManager
|
) : IThumbnailsManager
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<string, TaskCompletionSource<object>> _downloading = new();
|
private static readonly Dictionary<string, TaskCompletionSource<object>> _downloading = [];
|
||||||
|
|
||||||
private static async Task _WriteTo(SKBitmap bitmap, string path, int quality)
|
private static async Task _WriteTo(SKBitmap bitmap, string path, int quality)
|
||||||
{
|
{
|
||||||
|
@ -17,29 +17,15 @@
|
|||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using AspNetCore.Proxy;
|
|
||||||
using Autofac;
|
|
||||||
using Kyoo.Abstractions;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models.Utils;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Core.Api;
|
|
||||||
using Kyoo.Core.Controllers;
|
using Kyoo.Core.Controllers;
|
||||||
using Kyoo.Utils;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Routing;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Kyoo.Core;
|
namespace Kyoo.Core;
|
||||||
|
|
||||||
/// <summary>
|
public static class CoreModule
|
||||||
/// The core module containing default implementations
|
|
||||||
/// </summary>
|
|
||||||
public class CoreModule : IPlugin
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A service provider to access services in static context (in events for example).
|
/// A service provider to access services in static context (in events for example).
|
||||||
@ -47,102 +33,31 @@ public class CoreModule : IPlugin
|
|||||||
/// <remarks>Don't forget to create a scope.</remarks>
|
/// <remarks>Don't forget to create a scope.</remarks>
|
||||||
public static IServiceProvider Services { get; set; }
|
public static IServiceProvider Services { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
public static void AddRepository<T, TRepo>(this IServiceCollection services)
|
||||||
public string Name => "Core";
|
where T:IResource
|
||||||
|
where TRepo : class, IRepository<T>
|
||||||
/// <inheritdoc />
|
|
||||||
public void Configure(ContainerBuilder builder)
|
|
||||||
{
|
{
|
||||||
builder
|
services.AddScoped<TRepo>();
|
||||||
.RegisterType<ThumbnailsManager>()
|
services.AddScoped<IRepository<T>>(x => x.GetRequiredService<TRepo>());
|
||||||
.As<IThumbnailsManager>()
|
|
||||||
.InstancePerLifetimeScope();
|
|
||||||
builder.RegisterType<LibraryManager>().As<ILibraryManager>().InstancePerLifetimeScope();
|
|
||||||
|
|
||||||
builder.RegisterRepository<LibraryItemRepository>();
|
|
||||||
builder.RegisterRepository<CollectionRepository>();
|
|
||||||
builder.RegisterRepository<MovieRepository>();
|
|
||||||
builder.RegisterRepository<ShowRepository>();
|
|
||||||
builder.RegisterRepository<SeasonRepository>();
|
|
||||||
builder.RegisterRepository<EpisodeRepository>();
|
|
||||||
builder.RegisterRepository<StudioRepository>();
|
|
||||||
builder.RegisterRepository<UserRepository>().As<IUserRepository>();
|
|
||||||
builder.RegisterRepository<NewsRepository>();
|
|
||||||
builder
|
|
||||||
.RegisterType<WatchStatusRepository>()
|
|
||||||
.As<IWatchStatusRepository>()
|
|
||||||
.AsSelf()
|
|
||||||
.InstancePerLifetimeScope();
|
|
||||||
builder
|
|
||||||
.RegisterType<IssueRepository>()
|
|
||||||
.As<IIssueRepository>()
|
|
||||||
.AsSelf()
|
|
||||||
.InstancePerLifetimeScope();
|
|
||||||
builder.RegisterType<SqlVariableContext>().InstancePerLifetimeScope();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
public static void ConfigureKyoo(this WebApplicationBuilder builder)
|
||||||
public void Configure(IServiceCollection services)
|
|
||||||
{
|
{
|
||||||
services.AddHttpContextAccessor();
|
builder.Services.AddScoped<IThumbnailsManager, ThumbnailsManager>();
|
||||||
|
builder.Services.AddScoped<ILibraryManager, LibraryManager>();
|
||||||
|
|
||||||
services
|
builder.Services.AddRepository<ILibraryItem, LibraryItemRepository>();
|
||||||
.AddMvcCore(options =>
|
builder.Services.AddRepository<Collection, CollectionRepository>();
|
||||||
{
|
builder.Services.AddRepository<Movie, MovieRepository>();
|
||||||
options.Filters.Add<ExceptionFilter>();
|
builder.Services.AddRepository<Show, ShowRepository>();
|
||||||
options.ModelBinderProviders.Insert(0, new SortBinder.Provider());
|
builder.Services.AddRepository<Season, SeasonRepository>();
|
||||||
options.ModelBinderProviders.Insert(0, new IncludeBinder.Provider());
|
builder.Services.AddRepository<Episode, EpisodeRepository>();
|
||||||
options.ModelBinderProviders.Insert(0, new FilterBinder.Provider());
|
builder.Services.AddRepository<Studio, StudioRepository>();
|
||||||
})
|
builder.Services.AddRepository<INews, NewsRepository>();
|
||||||
.AddJsonOptions(x =>
|
builder.Services.AddRepository<User, UserRepository>();
|
||||||
{
|
builder.Services.AddScoped<IUserRepository>(x => x.GetRequiredService<UserRepository>());
|
||||||
x.JsonSerializerOptions.TypeInfoResolver = new JsonKindResolver()
|
builder.Services.AddScoped<IWatchStatusRepository, WatchStatusRepository>();
|
||||||
{
|
builder.Services.AddScoped<IIssueRepository, IssueRepository>();
|
||||||
Modifiers = { IncludeBinder.HandleLoadableFields }
|
builder.Services.AddScoped<SqlVariableContext>();
|
||||||
};
|
|
||||||
x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
|
||||||
x.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
|
||||||
})
|
|
||||||
.AddDataAnnotations()
|
|
||||||
.AddControllersAsServices()
|
|
||||||
.AddApiExplorer()
|
|
||||||
.ConfigureApiBehaviorOptions(options =>
|
|
||||||
{
|
|
||||||
options.SuppressMapClientErrors = true;
|
|
||||||
options.InvalidModelStateResponseFactory = ctx =>
|
|
||||||
{
|
|
||||||
string[] errors = ctx
|
|
||||||
.ModelState.SelectMany(x => x.Value!.Errors)
|
|
||||||
.Select(x => x.ErrorMessage)
|
|
||||||
.ToArray();
|
|
||||||
return new BadRequestObjectResult(new RequestError(errors));
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
services.Configure<RouteOptions>(x =>
|
|
||||||
{
|
|
||||||
x.ConstraintMap.Add("id", typeof(IdentifierRouteConstraint));
|
|
||||||
});
|
|
||||||
|
|
||||||
services.AddResponseCompression(x =>
|
|
||||||
{
|
|
||||||
x.EnableForHttps = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
services.AddProxies();
|
|
||||||
services.AddHttpClient();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IEnumerable<IStartupAction> ConfigureSteps =>
|
|
||||||
new IStartupAction[]
|
|
||||||
{
|
|
||||||
SA.New<IApplicationBuilder>(app => app.UseHsts(), SA.Before),
|
|
||||||
SA.New<IApplicationBuilder>(app => app.UseResponseCompression(), SA.Routing + 1),
|
|
||||||
SA.New<IApplicationBuilder>(app => app.UseRouting(), SA.Routing),
|
|
||||||
SA.New<IApplicationBuilder>(
|
|
||||||
app => app.UseEndpoints(x => x.MapControllers()),
|
|
||||||
SA.Endpoint
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
86
back/src/Kyoo.Core/Extensions/ServiceExtensions.cs
Normal file
86
back/src/Kyoo.Core/Extensions/ServiceExtensions.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Kyoo - A portable and vast media library solution.
|
||||||
|
// Copyright (c) Kyoo.
|
||||||
|
//
|
||||||
|
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
// Kyoo is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// Kyoo is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using AspNetCore.Proxy;
|
||||||
|
using Kyoo.Abstractions.Models.Utils;
|
||||||
|
using Kyoo.Core.Api;
|
||||||
|
using Kyoo.Core.Controllers;
|
||||||
|
using Kyoo.Utils;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Kyoo.Core.Extensions;
|
||||||
|
|
||||||
|
public static class ServiceExtensions
|
||||||
|
{
|
||||||
|
public static void ConfigureMvc(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddHttpContextAccessor();
|
||||||
|
|
||||||
|
services
|
||||||
|
.AddMvcCore(options =>
|
||||||
|
{
|
||||||
|
options.Filters.Add<ExceptionFilter>();
|
||||||
|
options.ModelBinderProviders.Insert(0, new SortBinder.Provider());
|
||||||
|
options.ModelBinderProviders.Insert(0, new IncludeBinder.Provider());
|
||||||
|
options.ModelBinderProviders.Insert(0, new FilterBinder.Provider());
|
||||||
|
})
|
||||||
|
.AddJsonOptions(x =>
|
||||||
|
{
|
||||||
|
x.JsonSerializerOptions.TypeInfoResolver = new JsonKindResolver()
|
||||||
|
{
|
||||||
|
Modifiers = { IncludeBinder.HandleLoadableFields }
|
||||||
|
};
|
||||||
|
x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||||
|
x.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||||
|
})
|
||||||
|
.AddDataAnnotations()
|
||||||
|
.AddControllersAsServices()
|
||||||
|
.AddApiExplorer()
|
||||||
|
.ConfigureApiBehaviorOptions(options =>
|
||||||
|
{
|
||||||
|
options.SuppressMapClientErrors = true;
|
||||||
|
options.InvalidModelStateResponseFactory = ctx =>
|
||||||
|
{
|
||||||
|
string[] errors = ctx
|
||||||
|
.ModelState.SelectMany(x => x.Value!.Errors)
|
||||||
|
.Select(x => x.ErrorMessage)
|
||||||
|
.ToArray();
|
||||||
|
return new BadRequestObjectResult(new RequestError(errors));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
services.Configure<RouteOptions>(x =>
|
||||||
|
{
|
||||||
|
x.ConstraintMap.Add("id", typeof(IdentifierRouteConstraint));
|
||||||
|
});
|
||||||
|
|
||||||
|
services.AddResponseCompression(x =>
|
||||||
|
{
|
||||||
|
x.EnableForHttps = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
services.AddProxies();
|
||||||
|
services.AddHttpClient();
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,10 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyName>Kyoo.Core</AssemblyName>
|
<AssemblyName>Kyoo.Core</AssemblyName>
|
||||||
<RootNamespace>Kyoo.Core</RootNamespace>
|
<RootNamespace>Kyoo.Core</RootNamespace>
|
||||||
<Nullable>enable</Nullable>
|
<OutputType>Exe</OutputType>
|
||||||
|
<!-- Limit the number of threads, the default is to not limit so scanning the library
|
||||||
|
create way too many of them and slows the whole server. -->
|
||||||
|
<ThreadPoolMaxThreads>50</ThreadPoolMaxThreads>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -12,6 +15,11 @@
|
|||||||
<PackageReference Include="InterpolatedSql.Dapper" Version="2.3.0" />
|
<PackageReference Include="InterpolatedSql.Dapper" Version="2.3.0" />
|
||||||
<PackageReference Include="FlexLabs.EntityFrameworkCore.Upsert" Version="8.0.0" />
|
<PackageReference Include="FlexLabs.EntityFrameworkCore.Upsert" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
|
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Serilog" Version="3.1.1" />
|
||||||
|
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
|
||||||
|
<PackageReference Include="Serilog.Expressions" Version="4.0.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.SyslogMessages" Version="3.0.1" />
|
||||||
<PackageReference Include="SkiaSharp" Version="2.88.7" />
|
<PackageReference Include="SkiaSharp" Version="2.88.7" />
|
||||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
|
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -19,6 +27,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||||
<ProjectReference Include="../Kyoo.Postgresql/Kyoo.Postgresql.csproj" />
|
<ProjectReference Include="../Kyoo.Postgresql/Kyoo.Postgresql.csproj" />
|
||||||
|
<ProjectReference Include="../Kyoo.Meilisearch/Kyoo.Meilisearch.csproj" />
|
||||||
|
<ProjectReference Include="../Kyoo.RabbitMq/Kyoo.RabbitMq.csproj" />
|
||||||
<ProjectReference Include="../Kyoo.Authentication/Kyoo.Authentication.csproj" />
|
<ProjectReference Include="../Kyoo.Authentication/Kyoo.Authentication.csproj" />
|
||||||
|
<ProjectReference Include="../Kyoo.Swagger/Kyoo.Swagger.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
109
back/src/Kyoo.Core/Program.cs
Normal file
109
back/src/Kyoo.Core/Program.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// Kyoo - A portable and vast media library solution.
|
||||||
|
// Copyright (c) Kyoo.
|
||||||
|
//
|
||||||
|
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
// Kyoo is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// Kyoo is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Kyoo.Authentication;
|
||||||
|
using Kyoo.Core;
|
||||||
|
using Kyoo.Core.Extensions;
|
||||||
|
using Kyoo.Meiliseach;
|
||||||
|
using Kyoo.Postgresql;
|
||||||
|
using Kyoo.RabbitMq;
|
||||||
|
using Kyoo.Swagger;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Serilog;
|
||||||
|
using Serilog.Events;
|
||||||
|
using Serilog.Templates;
|
||||||
|
using Serilog.Templates.Themes;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
const string EnvironmentName = "Development";
|
||||||
|
#else
|
||||||
|
const string EnvironmentName = "Production";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WebApplicationBuilder builder = WebApplication.CreateBuilder(
|
||||||
|
new WebApplicationOptions()
|
||||||
|
{
|
||||||
|
Args = args,
|
||||||
|
EnvironmentName = EnvironmentName,
|
||||||
|
ApplicationName = "Kyoo",
|
||||||
|
ContentRootPath = AppDomain.CurrentDomain.BaseDirectory,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
builder.WebHost.UseKestrel(opt =>
|
||||||
|
{
|
||||||
|
opt.AddServerHeader = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
const string template =
|
||||||
|
"[{@t:HH:mm:ss} {@l:u3} {Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1), 25} "
|
||||||
|
+ "({@i:D10})] {@m}{#if not EndsWith(@m, '\n')}\n{#end}{@x}";
|
||||||
|
Log.Logger = new LoggerConfiguration()
|
||||||
|
.MinimumLevel.Warning()
|
||||||
|
.MinimumLevel.Override("Kyoo", LogEventLevel.Verbose)
|
||||||
|
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Verbose)
|
||||||
|
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Fatal)
|
||||||
|
.WriteTo.Console(new ExpressionTemplate(template, theme: TemplateTheme.Code))
|
||||||
|
.Enrich.WithThreadId()
|
||||||
|
.Enrich.FromLogContext()
|
||||||
|
.CreateLogger();
|
||||||
|
AppDomain.CurrentDomain.ProcessExit += (_, _) => Log.CloseAndFlush();
|
||||||
|
AppDomain.CurrentDomain.UnhandledException += (_, ex) =>
|
||||||
|
Log.Fatal(ex.ExceptionObject as Exception, "Unhandled exception");
|
||||||
|
builder.Host.UseSerilog();
|
||||||
|
|
||||||
|
|
||||||
|
// Set current directory, used by thumbnails for example.
|
||||||
|
string path = Path.GetFullPath(builder.Configuration.GetValue("DATADIR", "/kyoo")!);
|
||||||
|
if (!Directory.Exists(path))
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
Environment.CurrentDirectory = path;
|
||||||
|
Log.Information("Data directory: {DataDirectory}", Environment.CurrentDirectory);
|
||||||
|
|
||||||
|
builder.Services.ConfigureMvc();
|
||||||
|
builder.Services.ConfigureOpenApi();
|
||||||
|
builder.ConfigureKyoo();
|
||||||
|
builder.ConfigureAuthentication();
|
||||||
|
builder.ConfigurePostgres();
|
||||||
|
builder.ConfigureMeilisearch();
|
||||||
|
|
||||||
|
WebApplication app = builder.Build();
|
||||||
|
CoreModule.Services = app.Services;
|
||||||
|
|
||||||
|
app.UseHsts();
|
||||||
|
app.UseKyooOpenApi();
|
||||||
|
app.UseResponseCompression();
|
||||||
|
app.UseRouting();
|
||||||
|
app.UseAuthentication();
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
// Activate services that always run in the background
|
||||||
|
app.Services.GetRequiredService<MeiliSync>();
|
||||||
|
app.Services.GetRequiredService<RabbitProducer>();
|
||||||
|
|
||||||
|
await using (AsyncServiceScope scope = app.Services.CreateAsyncScope())
|
||||||
|
{
|
||||||
|
await MeilisearchModule.Initialize(scope.ServiceProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
app.Run(Environment.GetEnvironmentVariable("KYOO_BIND_URL") ?? "http://*:5000");
|
@ -1,195 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Autofac;
|
|
||||||
using Autofac.Extensions.DependencyInjection;
|
|
||||||
using Kyoo.Core;
|
|
||||||
using Kyoo.Meiliseach;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Serilog;
|
|
||||||
using Serilog.Events;
|
|
||||||
using Serilog.Templates;
|
|
||||||
using Serilog.Templates.Themes;
|
|
||||||
using ILogger = Serilog.ILogger;
|
|
||||||
|
|
||||||
namespace Kyoo.Host;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hosts of kyoo (main functions) generally only create a new <see cref="Application"/>
|
|
||||||
/// and return <see cref="Start(string[])"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class Application
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The environment in witch Kyoo will run (ether "Production" or "Development").
|
|
||||||
/// </summary>
|
|
||||||
private readonly string _environment;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The logger used for startup and error messages.
|
|
||||||
/// </summary>
|
|
||||||
private ILogger _logger;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="Application"/> that will use the specified environment.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="environment">The environment to run in.</param>
|
|
||||||
public Application(string environment)
|
|
||||||
{
|
|
||||||
_environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start the application with the given console args.
|
|
||||||
/// This is generally called from the Main entrypoint of Kyoo.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">The console arguments to use for kyoo.</param>
|
|
||||||
/// <returns>A task representing the whole process</returns>
|
|
||||||
public Task Start(string[] args)
|
|
||||||
{
|
|
||||||
return Start(args, _ => { });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start the application with the given console args.
|
|
||||||
/// This is generally called from the Main entrypoint of Kyoo.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">The console arguments to use for kyoo.</param>
|
|
||||||
/// <param name="configure">A custom action to configure the container before the start</param>
|
|
||||||
/// <returns>A task representing the whole process</returns>
|
|
||||||
public async Task Start(string[] args, Action<ContainerBuilder> configure)
|
|
||||||
{
|
|
||||||
IConfiguration parsed = _SetupConfig(new ConfigurationBuilder(), args).Build();
|
|
||||||
string path = Path.GetFullPath(parsed.GetValue("DATADIR", "/kyoo"));
|
|
||||||
if (!Directory.Exists(path))
|
|
||||||
Directory.CreateDirectory(path);
|
|
||||||
Environment.CurrentDirectory = path;
|
|
||||||
|
|
||||||
LoggerConfiguration config = new();
|
|
||||||
_ConfigureLogging(config);
|
|
||||||
Log.Logger = config.CreateBootstrapLogger();
|
|
||||||
_logger = Log.Logger.ForContext<Application>();
|
|
||||||
|
|
||||||
AppDomain.CurrentDomain.ProcessExit += (_, _) => Log.CloseAndFlush();
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += (_, ex) =>
|
|
||||||
Log.Fatal(ex.ExceptionObject as Exception, "Unhandled exception");
|
|
||||||
|
|
||||||
IHost host = _CreateWebHostBuilder(args).ConfigureContainer(configure).Build();
|
|
||||||
|
|
||||||
await using (AsyncServiceScope scope = host.Services.CreateAsyncScope())
|
|
||||||
{
|
|
||||||
await MeilisearchModule.Initialize(scope.ServiceProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
await _StartWithHost(host);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start the given host and log failing exceptions.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="host">The host to start.</param>
|
|
||||||
/// <param name="cancellationToken">A token to allow one to stop the host.</param>
|
|
||||||
private async Task _StartWithHost(IHost host, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CoreModule.Services = host.Services;
|
|
||||||
_logger.Information(
|
|
||||||
"Version: {Version}",
|
|
||||||
Assembly.GetExecutingAssembly().GetName().Version.ToString(3)
|
|
||||||
);
|
|
||||||
_logger.Information("Data directory: {DataDirectory}", Environment.CurrentDirectory);
|
|
||||||
await host.RunAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.Fatal(ex, "Unhandled exception");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a a web host
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">Command line parameters that can be handled by kestrel</param>
|
|
||||||
/// <returns>A new web host instance</returns>
|
|
||||||
private IHostBuilder _CreateWebHostBuilder(string[] args)
|
|
||||||
{
|
|
||||||
return new HostBuilder()
|
|
||||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
|
||||||
.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory)
|
|
||||||
.UseEnvironment(_environment)
|
|
||||||
.ConfigureAppConfiguration(x => _SetupConfig(x, args))
|
|
||||||
.UseSerilog((host, services, builder) => _ConfigureLogging(builder))
|
|
||||||
.ConfigureServices(x => x.AddRouting())
|
|
||||||
.ConfigureWebHost(x =>
|
|
||||||
x.UseKestrel(options =>
|
|
||||||
{
|
|
||||||
options.AddServerHeader = false;
|
|
||||||
})
|
|
||||||
.UseIIS()
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(Environment.GetEnvironmentVariable("KYOO_BIND_URL") ?? "http://*:5000")
|
|
||||||
.UseStartup(host =>
|
|
||||||
PluginsStartup.FromWebHost(host, new LoggerFactory().AddSerilog())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Register settings.json, environment variables and command lines arguments as configuration.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The configuration builder to use</param>
|
|
||||||
/// <param name="args">The command line arguments</param>
|
|
||||||
/// <returns>The modified configuration builder</returns>
|
|
||||||
private IConfigurationBuilder _SetupConfig(IConfigurationBuilder builder, string[] args)
|
|
||||||
{
|
|
||||||
return builder
|
|
||||||
.AddEnvironmentVariables()
|
|
||||||
.AddEnvironmentVariables("KYOO_")
|
|
||||||
.AddCommandLine(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configure the logging.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The logger builder to configure.</param>
|
|
||||||
private void _ConfigureLogging(LoggerConfiguration builder)
|
|
||||||
{
|
|
||||||
const string template =
|
|
||||||
"[{@t:HH:mm:ss} {@l:u3} {Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1), 25} "
|
|
||||||
+ "({@i:D10})] {@m}{#if not EndsWith(@m, '\n')}\n{#end}{@x}";
|
|
||||||
builder
|
|
||||||
.MinimumLevel.Warning()
|
|
||||||
.MinimumLevel.Override("Kyoo", LogEventLevel.Verbose)
|
|
||||||
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Verbose)
|
|
||||||
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Fatal)
|
|
||||||
.WriteTo.Console(new ExpressionTemplate(template, theme: TemplateTheme.Code))
|
|
||||||
.Enrich.WithThreadId()
|
|
||||||
.Enrich.FromLogContext();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Kyoo.Host.Controllers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An implementation of <see cref="IPluginManager"/>.
|
|
||||||
/// This is used to load plugins and retrieve information from them.
|
|
||||||
/// </summary>
|
|
||||||
public class PluginManager : IPluginManager
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The service provider. It allow plugin's activation.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IServiceProvider _provider;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The logger used by this class.
|
|
||||||
/// </summary>
|
|
||||||
private readonly ILogger<PluginManager> _logger;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of plugins that are currently loaded.
|
|
||||||
/// </summary>
|
|
||||||
private readonly List<IPlugin> _plugins = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="PluginManager"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="provider">A service container to allow initialization of plugins</param>
|
|
||||||
/// <param name="logger">The logger used by this class.</param>
|
|
||||||
public PluginManager(IServiceProvider provider, ILogger<PluginManager> logger)
|
|
||||||
{
|
|
||||||
_provider = provider;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public T GetPlugin<T>(string name)
|
|
||||||
{
|
|
||||||
return (T)_plugins?.FirstOrDefault(x => x.Name == name && x is T);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ICollection<T> GetPlugins<T>()
|
|
||||||
{
|
|
||||||
return _plugins?.OfType<T>().ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ICollection<IPlugin> GetAllPlugins()
|
|
||||||
{
|
|
||||||
return _plugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void LoadPlugins(ICollection<IPlugin> plugins)
|
|
||||||
{
|
|
||||||
_plugins.AddRange(plugins);
|
|
||||||
_logger.LogInformation("Modules enabled: {Plugins}", _plugins.Select(x => x.Name));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void LoadPlugins(params Type[] plugins)
|
|
||||||
{
|
|
||||||
LoadPlugins(
|
|
||||||
plugins.Select(x => (IPlugin)ActivatorUtilities.CreateInstance(_provider, x)).ToArray()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Autofac;
|
|
||||||
using Autofac.Extras.AttributeMetadata;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Kyoo.Host;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A module that registers host controllers and other needed things.
|
|
||||||
/// </summary>
|
|
||||||
public class HostModule : IPlugin
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Name => "Host";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The plugin manager that loaded all plugins.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IPluginManager _plugins;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="HostModule"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="plugins">The plugin manager that loaded all plugins.</param>
|
|
||||||
public HostModule(IPluginManager plugins)
|
|
||||||
{
|
|
||||||
_plugins = plugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Configure(ContainerBuilder builder)
|
|
||||||
{
|
|
||||||
builder.RegisterModule<AttributedMetadataModule>();
|
|
||||||
builder.RegisterInstance(_plugins).As<IPluginManager>().ExternallyOwned();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IEnumerable<IStartupAction> ConfigureSteps =>
|
|
||||||
new[] { SA.New<IApplicationBuilder>(app => app.UseSerilogRequestLogging(), SA.Before) };
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<AssemblyName>Kyoo.Host</AssemblyName>
|
|
||||||
<RootNamespace>Kyoo.Host</RootNamespace>
|
|
||||||
<StartupObject>Kyoo.Host.Program</StartupObject>
|
|
||||||
<!-- Limit the number of threads, the default is to not limit so scanning the library
|
|
||||||
create way too many of them and slows the whole server. -->
|
|
||||||
<ThreadPoolMaxThreads>50</ThreadPoolMaxThreads>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Serilog" Version="3.1.1" />
|
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
|
||||||
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
|
|
||||||
<PackageReference Include="Serilog.Expressions" Version="4.0.0" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.SyslogMessages" Version="3.0.1" />
|
|
||||||
<PackageReference Include="System.Collections.Immutable" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Autofac" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
|
|
||||||
<PackageReference Include="Autofac.Extras.AttributeMetadata" Version="6.0.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
|
||||||
<ProjectReference Include="../Kyoo.Core/Kyoo.Core.csproj" />
|
|
||||||
<ProjectReference Include="../Kyoo.Postgresql/Kyoo.Postgresql.csproj" />
|
|
||||||
<ProjectReference Include="../Kyoo.Meilisearch/Kyoo.Meilisearch.csproj" />
|
|
||||||
<ProjectReference Include="../Kyoo.RabbitMq/Kyoo.RabbitMq.csproj" />
|
|
||||||
<ProjectReference Include="../Kyoo.Authentication/Kyoo.Authentication.csproj" />
|
|
||||||
<ProjectReference Include="../Kyoo.Swagger/Kyoo.Swagger.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -1,195 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using Autofac;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Authentication;
|
|
||||||
using Kyoo.Core;
|
|
||||||
using Kyoo.Host.Controllers;
|
|
||||||
using Kyoo.Meiliseach;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Kyoo.RabbitMq;
|
|
||||||
using Kyoo.Swagger;
|
|
||||||
using Kyoo.Utils;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Kyoo.Host;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Startup class is used to configure the AspNet's webhost.
|
|
||||||
/// </summary>
|
|
||||||
public class PluginsStartup
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A plugin manager used to load plugins and allow them to configure services / asp net.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IPluginManager _plugins;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The plugin that adds controllers and tasks specific to this host.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IPlugin _hostModule;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Created from the DI container, those services are needed to load information and instantiate plugins.s
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="plugins">The plugin manager to use to load new plugins and configure the host.</param>
|
|
||||||
public PluginsStartup(IPluginManager plugins)
|
|
||||||
{
|
|
||||||
_plugins = plugins;
|
|
||||||
_hostModule = new HostModule(_plugins);
|
|
||||||
_plugins.LoadPlugins(
|
|
||||||
typeof(CoreModule),
|
|
||||||
typeof(AuthenticationModule),
|
|
||||||
typeof(PostgresModule),
|
|
||||||
typeof(MeilisearchModule),
|
|
||||||
typeof(RabbitMqModule),
|
|
||||||
typeof(SwaggerModule)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="PluginsStartup"/> from a webhost.
|
|
||||||
/// This is meant to be used from <see cref="WebHostBuilderExtensions.UseStartup"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="host">The context of the web host.</param>
|
|
||||||
/// <param name="logger">
|
|
||||||
/// The logger factory used to log while the application is setting itself up.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>A new <see cref="PluginsStartup"/>.</returns>
|
|
||||||
public static PluginsStartup FromWebHost(WebHostBuilderContext host, ILoggerFactory logger)
|
|
||||||
{
|
|
||||||
HostServiceProvider hostProvider = new(host.HostingEnvironment, host.Configuration, logger);
|
|
||||||
PluginManager plugins = new(hostProvider, logger.CreateLogger<PluginManager>());
|
|
||||||
return new PluginsStartup(plugins);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configure the services context via the <see cref="PluginManager"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="services">The service collection to fill.</param>
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
foreach (Assembly assembly in _plugins.GetAllPlugins().Select(x => x.GetType().Assembly))
|
|
||||||
services.AddMvcCore().AddApplicationPart(assembly);
|
|
||||||
|
|
||||||
_hostModule.Configure(services);
|
|
||||||
foreach (IPlugin plugin in _plugins.GetAllPlugins())
|
|
||||||
plugin.Configure(services);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configure the autofac container via the <see cref="PluginManager"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The builder to configure.</param>
|
|
||||||
public void ConfigureContainer(ContainerBuilder builder)
|
|
||||||
{
|
|
||||||
_hostModule.Configure(builder);
|
|
||||||
foreach (IPlugin plugin in _plugins.GetAllPlugins())
|
|
||||||
plugin.Configure(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configure the asp net host.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="app">The asp net host to configure</param>
|
|
||||||
/// <param name="container">An autofac container used to create a new scope to configure asp-net.</param>
|
|
||||||
public void Configure(IApplicationBuilder app, ILifetimeScope container)
|
|
||||||
{
|
|
||||||
IEnumerable<IStartupAction> steps = _plugins
|
|
||||||
.GetAllPlugins()
|
|
||||||
.Append(_hostModule)
|
|
||||||
.SelectMany(x => x.ConfigureSteps)
|
|
||||||
.OrderByDescending(x => x.Priority);
|
|
||||||
|
|
||||||
using ILifetimeScope scope = container.BeginLifetimeScope(x =>
|
|
||||||
x.RegisterInstance(app).SingleInstance().ExternallyOwned()
|
|
||||||
);
|
|
||||||
IServiceProvider provider = scope.Resolve<IServiceProvider>();
|
|
||||||
foreach (IStartupAction step in steps)
|
|
||||||
step.Run(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A simple host service provider used to activate plugins instance.
|
|
||||||
/// The same services as a generic host are available and an <see cref="ILoggerFactory"/> has been added.
|
|
||||||
/// </summary>
|
|
||||||
private class HostServiceProvider(
|
|
||||||
IWebHostEnvironment hostEnvironment,
|
|
||||||
IConfiguration configuration,
|
|
||||||
ILoggerFactory loggerFactory
|
|
||||||
) : IServiceProvider
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public object GetService(Type serviceType)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
serviceType == typeof(IWebHostEnvironment)
|
|
||||||
|| serviceType == typeof(IHostEnvironment)
|
|
||||||
)
|
|
||||||
return hostEnvironment;
|
|
||||||
if (serviceType == typeof(IConfiguration))
|
|
||||||
return configuration;
|
|
||||||
if (serviceType == typeof(IServiceProviderIsService))
|
|
||||||
return new ProviderIsService();
|
|
||||||
if (
|
|
||||||
serviceType.IsGenericType
|
|
||||||
&& serviceType.GetGenericTypeDefinition() == typeof(ILogger<>)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return Utility.RunGenericMethod<object>(
|
|
||||||
typeof(LoggerFactoryExtensions),
|
|
||||||
nameof(LoggerFactoryExtensions.CreateLogger),
|
|
||||||
serviceType.GetGenericArguments().First(),
|
|
||||||
loggerFactory
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ArgumentException(
|
|
||||||
$"{serviceType.Name} is not available in configuration stpe"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ProviderIsService : IServiceProviderIsService
|
|
||||||
{
|
|
||||||
public bool IsService(Type serviceType)
|
|
||||||
{
|
|
||||||
Type[] supported =
|
|
||||||
[
|
|
||||||
typeof(IWebHostEnvironment),
|
|
||||||
typeof(IHostEnvironment),
|
|
||||||
typeof(IConfiguration),
|
|
||||||
typeof(IServiceProviderIsService),
|
|
||||||
];
|
|
||||||
if (supported.Contains(serviceType))
|
|
||||||
return true;
|
|
||||||
return serviceType.IsGenericType
|
|
||||||
&& serviceType.GetGenericTypeDefinition() == typeof(ILogger<>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
|
|
||||||
namespace Kyoo.Host;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Program entrypoint.
|
|
||||||
/// </summary>
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The string representation of the environment used in <see cref="IWebHostEnvironment"/>.
|
|
||||||
/// </summary>
|
|
||||||
#if DEBUG
|
|
||||||
private const string Environment = "Development";
|
|
||||||
#else
|
|
||||||
private const string Environment = "Production";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Main function of the program
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">Command line arguments</param>
|
|
||||||
/// <returns>A <see cref="Task"/> representing the lifetime of the program.</returns>
|
|
||||||
public static Task Main(string[] args)
|
|
||||||
{
|
|
||||||
Application application = new(Environment);
|
|
||||||
return application.Start(args);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<RootNamespace>Kyoo.Meilisearch</RootNamespace>
|
<RootNamespace>Kyoo.Meilisearch</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -16,21 +16,18 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using Autofac;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Meilisearch;
|
using Meilisearch;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using static System.Text.Json.JsonNamingPolicy;
|
using static System.Text.Json.JsonNamingPolicy;
|
||||||
|
|
||||||
namespace Kyoo.Meiliseach;
|
namespace Kyoo.Meiliseach;
|
||||||
|
|
||||||
public class MeilisearchModule(IConfiguration configuration) : IPlugin
|
public static class MeilisearchModule
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
public string Name => "Meilisearch";
|
|
||||||
|
|
||||||
public static Dictionary<string, Settings> IndexSettings =>
|
public static Dictionary<string, Settings> IndexSettings =>
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
@ -145,17 +142,16 @@ public class MeilisearchModule(IConfiguration configuration) : IPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Configure(ContainerBuilder builder)
|
public static void ConfigureMeilisearch(this WebApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
builder
|
builder
|
||||||
.RegisterInstance(
|
.Services.AddSingleton(
|
||||||
new MeilisearchClient(
|
new MeilisearchClient(
|
||||||
configuration.GetValue("MEILI_HOST", "http://meilisearch:7700"),
|
builder.Configuration.GetValue("MEILI_HOST", "http://meilisearch:7700"),
|
||||||
configuration.GetValue<string?>("MEILI_MASTER_KEY")
|
builder.Configuration.GetValue<string?>("MEILI_MASTER_KEY")
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
.SingleInstance();
|
builder.Services.AddSingleton<ISearchManager, SearchManager>();
|
||||||
builder.RegisterType<MeiliSync>().AsSelf().SingleInstance().AutoActivate();
|
builder.Services.AddSingleton<MeiliSync>();
|
||||||
builder.RegisterType<SearchManager>().As<ISearchManager>().InstancePerLifetimeScope();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyName>Kyoo.Postgresql</AssemblyName>
|
<AssemblyName>Kyoo.Postgresql</AssemblyName>
|
||||||
<RootNamespace>Kyoo.Postgresql</RootNamespace>
|
<RootNamespace>Kyoo.Postgresql</RootNamespace>
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -3,8 +3,8 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
namespace Kyoo.Postgresql.Migrations
|
namespace Kyoo.Postgresql.Migrations;
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public partial class UseDateOnly : Migration
|
public partial class UseDateOnly : Migration
|
||||||
{
|
{
|
||||||
@ -178,4 +178,3 @@ namespace Kyoo.Postgresql.Migrations
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -33,39 +33,19 @@ using Npgsql;
|
|||||||
|
|
||||||
namespace Kyoo.Postgresql;
|
namespace Kyoo.Postgresql;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A postgresql implementation of <see cref="DatabaseContext"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class PostgresContext : DatabaseContext
|
public class PostgresContext : DatabaseContext
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Is this instance in debug mode?
|
|
||||||
/// </summary>
|
|
||||||
private readonly bool _debugMode;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Should the configure step be skipped? This is used when the database is created via DbContextOptions.
|
/// Should the configure step be skipped? This is used when the database is created via DbContextOptions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly bool _skipConfigure;
|
private readonly bool _skipConfigure;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Design time constructor (dotnet ef migrations add). Do not use
|
|
||||||
/// </summary>
|
|
||||||
public PostgresContext()
|
|
||||||
: base(null!) { }
|
|
||||||
|
|
||||||
public PostgresContext(DbContextOptions options, IHttpContextAccessor accessor)
|
public PostgresContext(DbContextOptions options, IHttpContextAccessor accessor)
|
||||||
: base(options, accessor)
|
: base(options, accessor)
|
||||||
{
|
{
|
||||||
_skipConfigure = true;
|
_skipConfigure = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PostgresContext(string connection, bool debugMode, IHttpContextAccessor accessor)
|
|
||||||
: base(accessor)
|
|
||||||
{
|
|
||||||
_debugMode = debugMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set connection information for this database context
|
/// Set connection information for this database context
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -75,8 +55,6 @@ public class PostgresContext : DatabaseContext
|
|||||||
if (!_skipConfigure)
|
if (!_skipConfigure)
|
||||||
{
|
{
|
||||||
optionsBuilder.UseNpgsql();
|
optionsBuilder.UseNpgsql();
|
||||||
if (_debugMode)
|
|
||||||
optionsBuilder.EnableDetailedErrors().EnableSensitiveDataLogging();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
optionsBuilder.UseSnakeCaseNamingConvention();
|
optionsBuilder.UseSnakeCaseNamingConvention();
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@ -28,49 +28,42 @@ using Npgsql;
|
|||||||
|
|
||||||
namespace Kyoo.Postgresql;
|
namespace Kyoo.Postgresql;
|
||||||
|
|
||||||
/// <summary>
|
public static class PostgresModule
|
||||||
/// A module to add postgresql capacity to the app.
|
|
||||||
/// </summary>
|
|
||||||
public class PostgresModule(IConfiguration configuration, IWebHostEnvironment environment) : IPlugin
|
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
public static void ConfigurePostgres(this WebApplicationBuilder builder)
|
||||||
public string Name => "Postgresql";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Configure(IServiceCollection services)
|
|
||||||
{
|
{
|
||||||
DbConnectionStringBuilder builder =
|
DbConnectionStringBuilder conBuilder =
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
["USER ID"] = configuration.GetValue("POSTGRES_USER", "KyooUser"),
|
["USER ID"] = builder.Configuration.GetValue("POSTGRES_USER", "KyooUser"),
|
||||||
["PASSWORD"] = configuration.GetValue("POSTGRES_PASSWORD", "KyooPassword"),
|
["PASSWORD"] = builder.Configuration.GetValue("POSTGRES_PASSWORD", "KyooPassword"),
|
||||||
["SERVER"] = configuration.GetValue("POSTGRES_SERVER", "db"),
|
["SERVER"] = builder.Configuration.GetValue("POSTGRES_SERVER", "db"),
|
||||||
["PORT"] = configuration.GetValue("POSTGRES_PORT", "5432"),
|
["PORT"] = builder.Configuration.GetValue("POSTGRES_PORT", "5432"),
|
||||||
["DATABASE"] = configuration.GetValue("POSTGRES_DB", "kyooDB"),
|
["DATABASE"] = builder.Configuration.GetValue("POSTGRES_DB", "kyooDB"),
|
||||||
["POOLING"] = "true",
|
["POOLING"] = "true",
|
||||||
["MAXPOOLSIZE"] = "95",
|
["MAXPOOLSIZE"] = "95",
|
||||||
["TIMEOUT"] = "30"
|
["TIMEOUT"] = "30"
|
||||||
};
|
};
|
||||||
|
|
||||||
NpgsqlDataSourceBuilder dsBuilder = new(builder.ConnectionString);
|
NpgsqlDataSourceBuilder dsBuilder = new(conBuilder.ConnectionString);
|
||||||
dsBuilder.MapEnum<Status>();
|
dsBuilder.MapEnum<Status>();
|
||||||
dsBuilder.MapEnum<Genre>();
|
dsBuilder.MapEnum<Genre>();
|
||||||
dsBuilder.MapEnum<WatchStatus>();
|
dsBuilder.MapEnum<WatchStatus>();
|
||||||
NpgsqlDataSource dataSource = dsBuilder.Build();
|
NpgsqlDataSource dataSource = dsBuilder.Build();
|
||||||
|
|
||||||
services.AddDbContext<DatabaseContext, PostgresContext>(
|
builder.Services.AddDbContext<DatabaseContext, PostgresContext>(
|
||||||
x =>
|
x =>
|
||||||
{
|
{
|
||||||
x.UseNpgsql(dataSource).UseProjectables();
|
x.UseNpgsql(dataSource).UseProjectables();
|
||||||
if (environment.IsDevelopment())
|
if (builder.Environment.IsDevelopment())
|
||||||
x.EnableDetailedErrors().EnableSensitiveDataLogging();
|
x.EnableDetailedErrors().EnableSensitiveDataLogging();
|
||||||
},
|
},
|
||||||
ServiceLifetime.Transient
|
ServiceLifetime.Transient
|
||||||
);
|
);
|
||||||
services.AddTransient(
|
builder.Services.AddTransient(
|
||||||
(services) => services.GetRequiredService<DatabaseContext>().Database.GetDbConnection()
|
(services) => services.GetRequiredService<DatabaseContext>().Database.GetDbConnection()
|
||||||
);
|
);
|
||||||
|
|
||||||
services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
|
builder.Services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<RootNamespace>Kyoo.RabbitMq</RootNamespace>
|
<RootNamespace>Kyoo.RabbitMq</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -16,39 +16,30 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using Autofac;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using RabbitMQ.Client;
|
using RabbitMQ.Client;
|
||||||
|
|
||||||
namespace Kyoo.RabbitMq;
|
namespace Kyoo.RabbitMq;
|
||||||
|
|
||||||
public class RabbitMqModule(IConfiguration configuration) : IPlugin
|
public static class RabbitMqModule
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
public static void ConfigureRabbitMq(this WebApplicationBuilder builder)
|
||||||
public string Name => "RabbitMq";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Configure(ContainerBuilder builder)
|
|
||||||
{
|
{
|
||||||
builder
|
builder.Services.AddSingleton(_ =>
|
||||||
.Register(
|
|
||||||
(_) =>
|
|
||||||
{
|
{
|
||||||
ConnectionFactory factory =
|
ConnectionFactory factory =
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
UserName = configuration.GetValue("RABBITMQ_DEFAULT_USER", "guest"),
|
UserName = builder.Configuration.GetValue("RABBITMQ_DEFAULT_USER", "guest"),
|
||||||
Password = configuration.GetValue("RABBITMQ_DEFAULT_PASS", "guest"),
|
Password = builder.Configuration.GetValue("RABBITMQ_DEFAULT_PASS", "guest"),
|
||||||
HostName = configuration.GetValue("RABBITMQ_HOST", "rabbitmq"),
|
HostName = builder.Configuration.GetValue("RABBITMQ_HOST", "rabbitmq"),
|
||||||
Port = 5672,
|
Port = 5672,
|
||||||
};
|
};
|
||||||
|
|
||||||
return factory.CreateConnection();
|
return factory.CreateConnection();
|
||||||
}
|
});
|
||||||
)
|
builder.Services.AddSingleton<RabbitProducer>();
|
||||||
.AsSelf()
|
|
||||||
.SingleInstance();
|
|
||||||
builder.RegisterType<RabbitProducer>().AsSelf().SingleInstance().AutoActivate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyName>Kyoo.Swagger</AssemblyName>
|
<AssemblyName>Kyoo.Swagger</AssemblyName>
|
||||||
<RootNamespace>Kyoo.Swagger</RootNamespace>
|
<RootNamespace>Kyoo.Swagger</RootNamespace>
|
||||||
|
<Nullable>disable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models.Utils;
|
using Kyoo.Abstractions.Models.Utils;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
@ -31,16 +30,9 @@ using static Kyoo.Abstractions.Models.Utils.Constants;
|
|||||||
|
|
||||||
namespace Kyoo.Swagger;
|
namespace Kyoo.Swagger;
|
||||||
|
|
||||||
/// <summary>
|
public static class SwaggerModule
|
||||||
/// A module to enable a swagger interface and an OpenAPI endpoint to document Kyoo.
|
|
||||||
/// </summary>
|
|
||||||
public class SwaggerModule : IPlugin
|
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
public static void ConfigureOpenApi(this IServiceCollection services)
|
||||||
public string Name => "Swagger";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Configure(IServiceCollection services)
|
|
||||||
{
|
{
|
||||||
services.AddTransient<IApplicationModelProvider, GenericResponseProvider>();
|
services.AddTransient<IApplicationModelProvider, GenericResponseProvider>();
|
||||||
services.AddOpenApiDocument(document =>
|
services.AddOpenApiDocument(document =>
|
||||||
@ -106,24 +98,17 @@ public class SwaggerModule : IPlugin
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
public static void UseKyooOpenApi(this IApplicationBuilder app)
|
||||||
public IEnumerable<IStartupAction> ConfigureSteps =>
|
|
||||||
new IStartupAction[]
|
|
||||||
{
|
{
|
||||||
SA.New<IApplicationBuilder>(app => app.UseOpenApi(), SA.Before + 1),
|
app.UseOpenApi();
|
||||||
SA.New<IApplicationBuilder>(
|
|
||||||
app =>
|
|
||||||
app.UseReDoc(x =>
|
app.UseReDoc(x =>
|
||||||
{
|
{
|
||||||
x.Path = "/doc";
|
x.Path = "/doc";
|
||||||
x.TransformToExternalPath = (internalUiRoute, _) =>
|
x.TransformToExternalPath = (internalUiRoute, _) => "/api" + internalUiRoute;
|
||||||
"/api" + internalUiRoute;
|
|
||||||
x.AdditionalSettings["theme"] = new
|
x.AdditionalSettings["theme"] = new
|
||||||
{
|
{
|
||||||
colors = new { primary = new { main = "#e13e13" } }
|
colors = new { primary = new { main = "#e13e13" } }
|
||||||
};
|
};
|
||||||
}),
|
});
|
||||||
SA.Before
|
}
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user