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.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.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.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.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.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.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.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.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.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.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.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.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
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Swagger", "src\Kyoo.Swagger\Kyoo.Swagger.csproj", "{7D1A7596-73F6-4D35-842E-A5AD9C620596}"
|
||||
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}"
|
||||
EndProject
|
||||
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}.Release|Any CPU.ActiveCfg = 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.Build.0 = Debug|Any CPU
|
||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -1,4 +1,2 @@
|
||||
--project
|
||||
src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||
--msbuildprojectextensionspath
|
||||
out/obj/Kyoo.Postgresql
|
||||
|
@ -2,6 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<LangVersion>default</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<Company>Kyoo</Company>
|
||||
<Authors>Kyoo</Authors>
|
||||
<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>
|
||||
<Description>Base package to create plugins for Kyoo.</Description>
|
||||
<RootNamespace>Kyoo.Abstractions</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -16,7 +16,6 @@
|
||||
// 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.Text;
|
||||
@ -28,62 +27,41 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Serilog;
|
||||
|
||||
namespace Kyoo.Authentication;
|
||||
|
||||
/// <summary>
|
||||
/// A module that enable OpenID authentication for Kyoo.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Create a new authentication module instance and use the given configuration.
|
||||
/// </remarks>
|
||||
public class AuthenticationModule(
|
||||
IConfiguration configuration,
|
||||
ILogger<AuthenticationModule> logger
|
||||
) : IPlugin
|
||||
public static class AuthenticationModule
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Name => "Authentication";
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use.
|
||||
/// </summary>
|
||||
private readonly IConfiguration _configuration = configuration;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
public static void ConfigureAuthentication(this WebApplicationBuilder builder)
|
||||
{
|
||||
builder.RegisterType<PermissionValidator>().As<IPermissionValidator>().SingleInstance();
|
||||
builder.RegisterType<TokenController>().As<ITokenController>().SingleInstance();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services)
|
||||
{
|
||||
string secret = _configuration.GetValue(
|
||||
string secret = builder.Configuration.GetValue(
|
||||
"AUTHENTICATION_SECRET",
|
||||
AuthenticationOption.DefaultSecret
|
||||
)!;
|
||||
PermissionOption options =
|
||||
new()
|
||||
{
|
||||
Default = _configuration
|
||||
.GetValue("UNLOGGED_PERMISSIONS", "")!
|
||||
Default = builder
|
||||
.Configuration.GetValue("UNLOGGED_PERMISSIONS", "")!
|
||||
.Split(',')
|
||||
.Where(x => x.Length > 0)
|
||||
.ToArray(),
|
||||
NewUser = _configuration
|
||||
.GetValue("DEFAULT_PERMISSIONS", "overall.read,overall.play")!
|
||||
NewUser = builder
|
||||
.Configuration.GetValue("DEFAULT_PERMISSIONS", "overall.read,overall.play")!
|
||||
.Split(','),
|
||||
RequireVerification = _configuration.GetValue("REQUIRE_ACCOUNT_VERIFICATION", true),
|
||||
RequireVerification = builder.Configuration.GetValue(
|
||||
"REQUIRE_ACCOUNT_VERIFICATION",
|
||||
true
|
||||
),
|
||||
PublicUrl =
|
||||
_configuration.GetValue<string?>("PUBLIC_URL") ?? "http://localhost:8901",
|
||||
ApiKeys = _configuration.GetValue("KYOO_APIKEYS", string.Empty)!.Split(','),
|
||||
OIDC = _configuration
|
||||
.AsEnumerable()
|
||||
builder.Configuration.GetValue<string?>("PUBLIC_URL")
|
||||
?? "http://localhost:8901",
|
||||
ApiKeys = builder.Configuration.GetValue("KYOO_APIKEYS", string.Empty)!.Split(','),
|
||||
OIDC = builder
|
||||
.Configuration.AsEnumerable()
|
||||
.Where((pair) => pair.Key.StartsWith("OIDC_"))
|
||||
.Aggregate(
|
||||
new Dictionary<string, OidcProvider>(),
|
||||
@ -93,7 +71,7 @@ public class AuthenticationModule(
|
||||
return acc;
|
||||
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;
|
||||
}
|
||||
provider = provider.ToLowerInvariant();
|
||||
@ -129,20 +107,20 @@ public class AuthenticationModule(
|
||||
acc[provider].LogoUrl = val.Value;
|
||||
break;
|
||||
default:
|
||||
logger.LogError("Invalid oidc config value: {Key}", key);
|
||||
Log.Error("Invalid oidc config value: {Key}", key);
|
||||
return acc;
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
),
|
||||
};
|
||||
services.AddSingleton(options);
|
||||
services.AddSingleton(
|
||||
builder.Services.AddSingleton(options);
|
||||
builder.Services.AddSingleton(
|
||||
new AuthenticationOption() { Secret = secret, Permissions = options, }
|
||||
);
|
||||
|
||||
services
|
||||
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
builder
|
||||
.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.Events = new()
|
||||
@ -171,12 +149,8 @@ public class AuthenticationModule(
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret))
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IStartupAction> ConfigureSteps =>
|
||||
new IStartupAction[]
|
||||
{
|
||||
SA.New<IApplicationBuilder>(app => app.UseAuthentication(), SA.Authentication),
|
||||
};
|
||||
builder.Services.AddSingleton<IPermissionValidator, PermissionValidator>();
|
||||
builder.Services.AddSingleton<ITokenController, TokenController>();
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.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" />
|
||||
</ItemGroup>
|
||||
|
@ -53,8 +53,8 @@ public class LibraryManager : ILibraryManager
|
||||
Studios = studioRepository;
|
||||
Users = userRepository;
|
||||
|
||||
_repositories = new IBaseRepository[]
|
||||
{
|
||||
_repositories =
|
||||
[
|
||||
LibraryItems,
|
||||
News,
|
||||
Collections,
|
||||
@ -64,7 +64,7 @@ public class LibraryManager : ILibraryManager
|
||||
Episodes,
|
||||
Studios,
|
||||
Users
|
||||
};
|
||||
];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -42,7 +42,7 @@ public class ThumbnailsManager(
|
||||
Lazy<IRepository<User>> users
|
||||
) : 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)
|
||||
{
|
||||
|
@ -17,29 +17,15 @@
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
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.Models.Utils;
|
||||
using Kyoo.Core.Api;
|
||||
using Kyoo.Abstractions.Models;
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// The core module containing default implementations
|
||||
/// </summary>
|
||||
public class CoreModule : IPlugin
|
||||
public static class CoreModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 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>
|
||||
public static IServiceProvider Services { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Core";
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
public static void AddRepository<T, TRepo>(this IServiceCollection services)
|
||||
where T:IResource
|
||||
where TRepo : class, IRepository<T>
|
||||
{
|
||||
builder
|
||||
.RegisterType<ThumbnailsManager>()
|
||||
.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();
|
||||
services.AddScoped<TRepo>();
|
||||
services.AddScoped<IRepository<T>>(x => x.GetRequiredService<TRepo>());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services)
|
||||
public static void ConfigureKyoo(this WebApplicationBuilder builder)
|
||||
{
|
||||
services.AddHttpContextAccessor();
|
||||
builder.Services.AddScoped<IThumbnailsManager, ThumbnailsManager>();
|
||||
builder.Services.AddScoped<ILibraryManager, LibraryManager>();
|
||||
|
||||
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();
|
||||
builder.Services.AddRepository<ILibraryItem, LibraryItemRepository>();
|
||||
builder.Services.AddRepository<Collection, CollectionRepository>();
|
||||
builder.Services.AddRepository<Movie, MovieRepository>();
|
||||
builder.Services.AddRepository<Show, ShowRepository>();
|
||||
builder.Services.AddRepository<Season, SeasonRepository>();
|
||||
builder.Services.AddRepository<Episode, EpisodeRepository>();
|
||||
builder.Services.AddRepository<Studio, StudioRepository>();
|
||||
builder.Services.AddRepository<INews, NewsRepository>();
|
||||
builder.Services.AddRepository<User, UserRepository>();
|
||||
builder.Services.AddScoped<IUserRepository>(x => x.GetRequiredService<UserRepository>());
|
||||
builder.Services.AddScoped<IWatchStatusRepository, WatchStatusRepository>();
|
||||
builder.Services.AddScoped<IIssueRepository, IssueRepository>();
|
||||
builder.Services.AddScoped<SqlVariableContext>();
|
||||
}
|
||||
|
||||
/// <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>
|
||||
<AssemblyName>Kyoo.Core</AssemblyName>
|
||||
<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>
|
||||
|
||||
<ItemGroup>
|
||||
@ -12,6 +15,11 @@
|
||||
<PackageReference Include="InterpolatedSql.Dapper" Version="2.3.0" />
|
||||
<PackageReference Include="FlexLabs.EntityFrameworkCore.Upsert" Version="8.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.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
|
||||
</ItemGroup>
|
||||
@ -19,6 +27,9 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.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>
|
||||
|
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">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Kyoo.Meilisearch</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -16,21 +16,18 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Autofac;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Meilisearch;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using static System.Text.Json.JsonNamingPolicy;
|
||||
|
||||
namespace Kyoo.Meiliseach;
|
||||
|
||||
public class MeilisearchModule(IConfiguration configuration) : IPlugin
|
||||
public static class MeilisearchModule
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Name => "Meilisearch";
|
||||
|
||||
public static Dictionary<string, Settings> IndexSettings =>
|
||||
new()
|
||||
{
|
||||
@ -145,17 +142,16 @@ public class MeilisearchModule(IConfiguration configuration) : IPlugin
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
public static void ConfigureMeilisearch(this WebApplicationBuilder builder)
|
||||
{
|
||||
builder
|
||||
.RegisterInstance(
|
||||
.Services.AddSingleton(
|
||||
new MeilisearchClient(
|
||||
configuration.GetValue("MEILI_HOST", "http://meilisearch:7700"),
|
||||
configuration.GetValue<string?>("MEILI_MASTER_KEY")
|
||||
builder.Configuration.GetValue("MEILI_HOST", "http://meilisearch:7700"),
|
||||
builder.Configuration.GetValue<string?>("MEILI_MASTER_KEY")
|
||||
)
|
||||
)
|
||||
.SingleInstance();
|
||||
builder.RegisterType<MeiliSync>().AsSelf().SingleInstance().AutoActivate();
|
||||
builder.RegisterType<SearchManager>().As<ISearchManager>().InstancePerLifetimeScope();
|
||||
);
|
||||
builder.Services.AddSingleton<ISearchManager, SearchManager>();
|
||||
builder.Services.AddSingleton<MeiliSync>();
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
<PropertyGroup>
|
||||
<AssemblyName>Kyoo.Postgresql</AssemblyName>
|
||||
<RootNamespace>Kyoo.Postgresql</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -3,11 +3,11 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Kyoo.Postgresql.Migrations
|
||||
namespace Kyoo.Postgresql.Migrations;
|
||||
|
||||
/// <inheritdoc />
|
||||
public partial class UseDateOnly : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class UseDateOnly : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
@ -177,5 +177,4 @@ namespace Kyoo.Postgresql.Migrations
|
||||
oldNullable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,39 +33,19 @@ using Npgsql;
|
||||
|
||||
namespace Kyoo.Postgresql;
|
||||
|
||||
/// <summary>
|
||||
/// A postgresql implementation of <see cref="DatabaseContext"/>.
|
||||
/// </summary>
|
||||
public class PostgresContext : DatabaseContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Is this instance in debug mode?
|
||||
/// </summary>
|
||||
private readonly bool _debugMode;
|
||||
|
||||
/// <summary>
|
||||
/// Should the configure step be skipped? This is used when the database is created via DbContextOptions.
|
||||
/// </summary>
|
||||
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)
|
||||
: base(options, accessor)
|
||||
{
|
||||
_skipConfigure = true;
|
||||
}
|
||||
|
||||
public PostgresContext(string connection, bool debugMode, IHttpContextAccessor accessor)
|
||||
: base(accessor)
|
||||
{
|
||||
_debugMode = debugMode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set connection information for this database context
|
||||
/// </summary>
|
||||
@ -75,8 +55,6 @@ public class PostgresContext : DatabaseContext
|
||||
if (!_skipConfigure)
|
||||
{
|
||||
optionsBuilder.UseNpgsql();
|
||||
if (_debugMode)
|
||||
optionsBuilder.EnableDetailedErrors().EnableSensitiveDataLogging();
|
||||
}
|
||||
|
||||
optionsBuilder.UseSnakeCaseNamingConvention();
|
||||
|
@ -17,8 +17,8 @@
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Data.Common;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -28,49 +28,42 @@ using Npgsql;
|
||||
|
||||
namespace Kyoo.Postgresql;
|
||||
|
||||
/// <summary>
|
||||
/// A module to add postgresql capacity to the app.
|
||||
/// </summary>
|
||||
public class PostgresModule(IConfiguration configuration, IWebHostEnvironment environment) : IPlugin
|
||||
public static class PostgresModule
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Name => "Postgresql";
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services)
|
||||
public static void ConfigurePostgres(this WebApplicationBuilder builder)
|
||||
{
|
||||
DbConnectionStringBuilder builder =
|
||||
DbConnectionStringBuilder conBuilder =
|
||||
new()
|
||||
{
|
||||
["USER ID"] = configuration.GetValue("POSTGRES_USER", "KyooUser"),
|
||||
["PASSWORD"] = configuration.GetValue("POSTGRES_PASSWORD", "KyooPassword"),
|
||||
["SERVER"] = configuration.GetValue("POSTGRES_SERVER", "db"),
|
||||
["PORT"] = configuration.GetValue("POSTGRES_PORT", "5432"),
|
||||
["DATABASE"] = configuration.GetValue("POSTGRES_DB", "kyooDB"),
|
||||
["USER ID"] = builder.Configuration.GetValue("POSTGRES_USER", "KyooUser"),
|
||||
["PASSWORD"] = builder.Configuration.GetValue("POSTGRES_PASSWORD", "KyooPassword"),
|
||||
["SERVER"] = builder.Configuration.GetValue("POSTGRES_SERVER", "db"),
|
||||
["PORT"] = builder.Configuration.GetValue("POSTGRES_PORT", "5432"),
|
||||
["DATABASE"] = builder.Configuration.GetValue("POSTGRES_DB", "kyooDB"),
|
||||
["POOLING"] = "true",
|
||||
["MAXPOOLSIZE"] = "95",
|
||||
["TIMEOUT"] = "30"
|
||||
};
|
||||
|
||||
NpgsqlDataSourceBuilder dsBuilder = new(builder.ConnectionString);
|
||||
NpgsqlDataSourceBuilder dsBuilder = new(conBuilder.ConnectionString);
|
||||
dsBuilder.MapEnum<Status>();
|
||||
dsBuilder.MapEnum<Genre>();
|
||||
dsBuilder.MapEnum<WatchStatus>();
|
||||
NpgsqlDataSource dataSource = dsBuilder.Build();
|
||||
|
||||
services.AddDbContext<DatabaseContext, PostgresContext>(
|
||||
builder.Services.AddDbContext<DatabaseContext, PostgresContext>(
|
||||
x =>
|
||||
{
|
||||
x.UseNpgsql(dataSource).UseProjectables();
|
||||
if (environment.IsDevelopment())
|
||||
if (builder.Environment.IsDevelopment())
|
||||
x.EnableDetailedErrors().EnableSensitiveDataLogging();
|
||||
},
|
||||
ServiceLifetime.Transient
|
||||
);
|
||||
services.AddTransient(
|
||||
builder.Services.AddTransient(
|
||||
(services) => services.GetRequiredService<DatabaseContext>().Database.GetDbConnection()
|
||||
);
|
||||
|
||||
services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
|
||||
builder.Services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Kyoo.RabbitMq</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -16,39 +16,30 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Autofac;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using RabbitMQ.Client;
|
||||
|
||||
namespace Kyoo.RabbitMq;
|
||||
|
||||
public class RabbitMqModule(IConfiguration configuration) : IPlugin
|
||||
public static class RabbitMqModule
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Name => "RabbitMq";
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
public static void ConfigureRabbitMq(this WebApplicationBuilder builder)
|
||||
{
|
||||
builder
|
||||
.Register(
|
||||
(_) =>
|
||||
builder.Services.AddSingleton(_ =>
|
||||
{
|
||||
ConnectionFactory factory =
|
||||
new()
|
||||
{
|
||||
UserName = configuration.GetValue("RABBITMQ_DEFAULT_USER", "guest"),
|
||||
Password = configuration.GetValue("RABBITMQ_DEFAULT_PASS", "guest"),
|
||||
HostName = configuration.GetValue("RABBITMQ_HOST", "rabbitmq"),
|
||||
UserName = builder.Configuration.GetValue("RABBITMQ_DEFAULT_USER", "guest"),
|
||||
Password = builder.Configuration.GetValue("RABBITMQ_DEFAULT_PASS", "guest"),
|
||||
HostName = builder.Configuration.GetValue("RABBITMQ_HOST", "rabbitmq"),
|
||||
Port = 5672,
|
||||
};
|
||||
|
||||
return factory.CreateConnection();
|
||||
}
|
||||
)
|
||||
.AsSelf()
|
||||
.SingleInstance();
|
||||
builder.RegisterType<RabbitProducer>().AsSelf().SingleInstance().AutoActivate();
|
||||
});
|
||||
builder.Services.AddSingleton<RabbitProducer>();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<AssemblyName>Kyoo.Swagger</AssemblyName>
|
||||
<RootNamespace>Kyoo.Swagger</RootNamespace>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Utils;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
@ -31,16 +30,9 @@ using static Kyoo.Abstractions.Models.Utils.Constants;
|
||||
|
||||
namespace Kyoo.Swagger;
|
||||
|
||||
/// <summary>
|
||||
/// A module to enable a swagger interface and an OpenAPI endpoint to document Kyoo.
|
||||
/// </summary>
|
||||
public class SwaggerModule : IPlugin
|
||||
public static class SwaggerModule
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Name => "Swagger";
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services)
|
||||
public static void ConfigureOpenApi(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<IApplicationModelProvider, GenericResponseProvider>();
|
||||
services.AddOpenApiDocument(document =>
|
||||
@ -106,24 +98,17 @@ public class SwaggerModule : IPlugin
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IStartupAction> ConfigureSteps =>
|
||||
new IStartupAction[]
|
||||
public static void UseKyooOpenApi(this IApplicationBuilder app)
|
||||
{
|
||||
SA.New<IApplicationBuilder>(app => app.UseOpenApi(), SA.Before + 1),
|
||||
SA.New<IApplicationBuilder>(
|
||||
app =>
|
||||
app.UseOpenApi();
|
||||
app.UseReDoc(x =>
|
||||
{
|
||||
x.Path = "/doc";
|
||||
x.TransformToExternalPath = (internalUiRoute, _) =>
|
||||
"/api" + internalUiRoute;
|
||||
x.TransformToExternalPath = (internalUiRoute, _) => "/api" + internalUiRoute;
|
||||
x.AdditionalSettings["theme"] = new
|
||||
{
|
||||
colors = new { primary = new { main = "#e13e13" } }
|
||||
};
|
||||
}),
|
||||
SA.Before
|
||||
)
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user