mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
commit
43d2153bd3
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@ -31,12 +31,12 @@ jobs:
|
||||
workflow: build.yml
|
||||
path: ./artifacts
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
- name: Public the common to nuget
|
||||
- name: Public the abstractions to nuget
|
||||
id: publish_nuget
|
||||
uses: rohith/publish-nuget@v2
|
||||
with:
|
||||
PROJECT_FILE_PATH: Kyoo.Common/Kyoo.Common.csproj
|
||||
PACKAGE_NAME: Kyoo.Common
|
||||
PROJECT_FILE_PATH: Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
||||
PACKAGE_NAME: Kyoo.Abstractions
|
||||
VERSION_REGEX: ^\s*<PackageVersion>(.*)<\/PackageVersion>\s*$
|
||||
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
|
||||
INCLUDE_SYMBOLS: true
|
||||
|
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
- name: Build
|
||||
run: |
|
||||
dotnet build --no-restore '-p:SkipWebApp=true;SkipTranscoder=true' -p:CopyLocalLockFileAssemblies=true
|
||||
cp ./Kyoo.Common/bin/Debug/net5.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll ./tests/Kyoo.Tests/bin/Debug/net5.0/
|
||||
cp ./Kyoo.Abstractions/bin/Debug/net5.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll ./tests/Kyoo.Tests/bin/Debug/net5.0/
|
||||
- name: Test
|
||||
run: dotnet test --no-build '-p:CollectCoverage=true;CoverletOutputFormat=opencover'
|
||||
env:
|
||||
|
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -3,6 +3,6 @@
|
||||
url = ../Kyoo.Transcoder.git
|
||||
branch = master
|
||||
[submodule "WebApp"]
|
||||
path = Kyoo.WebApp
|
||||
path = Kyoo.WebApp/Front
|
||||
url = ../Kyoo.WebApp.git
|
||||
branch = master
|
||||
|
@ -7,6 +7,7 @@ RUN cmake . && make -j
|
||||
FROM node:alpine as webapp
|
||||
WORKDIR /webapp
|
||||
COPY Kyoo.WebApp .
|
||||
WORKDIR /webapp/Front
|
||||
RUN npm install
|
||||
RUN npm run build -- --prod
|
||||
|
||||
@ -19,6 +20,6 @@ RUN apt-get update && apt-get install -y libavutil-dev libavcodec-dev libavforma
|
||||
EXPOSE 5000
|
||||
COPY --from=builder /opt/kyoo /usr/lib/kyoo
|
||||
COPY --from=transcoder /transcoder/libtranscoder.so /usr/lib/kyoo
|
||||
COPY --from=webapp /webapp/dist/* /usr/lib/kyoo/wwwroot/
|
||||
COPY --from=webapp /webapp/Front/dist/* /usr/lib/kyoo/wwwroot/
|
||||
CMD ["/usr/lib/kyoo/Kyoo", "/var/lib/kyoo"]
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// A class to ease configuration management. This work WITH Microsoft's package, you can still use IOptions patterns
|
||||
@ -26,6 +27,15 @@ namespace Kyoo.Controllers
|
||||
/// </summary>
|
||||
/// <param name="path">The root path of the editable configuration. It should not be a nested type.</param>
|
||||
void AddUntyped(string path);
|
||||
|
||||
/// <summary>
|
||||
/// An helper method of <see cref="AddTyped{T}"/> and <see cref="AddUntyped"/>.
|
||||
/// This register a typed value if <paramref name="type"/> is not <c>null</c> and registers an untyped type
|
||||
/// if <paramref name="type"/> is <c>null</c>.
|
||||
/// </summary>
|
||||
/// <param name="path">The root path of the editable configuration. It should not be a nested type.</param>
|
||||
/// <param name="type">The type of the configuration or null.</param>
|
||||
void Register(string path, [CanBeNull] Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Get the value of a setting using it's path.
|
@ -2,25 +2,11 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// A class wrapping a value that will be set after the completion of the task it is related to.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class replace the use of an out parameter on a task since tasks and out can't be combined.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The type of the value</typeparam>
|
||||
public class AsyncRef<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// The value that will be set before the completion of the task.
|
||||
/// </summary>
|
||||
public T Value { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A service to abstract the file system to allow custom file systems (like distant file systems or external providers)
|
||||
/// </summary>
|
@ -1,8 +1,8 @@
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface to identify episodes, shows and metadata based on the episode file.
|
@ -4,10 +4,10 @@ using System.Linq.Expressions;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface to interract with the database. Every repository is mapped through here.
|
@ -1,9 +1,9 @@
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface to automatically retrieve metadata from external providers.
|
106
Kyoo.Abstractions/Controllers/IPlugin.cs
Normal file
106
Kyoo.Abstractions/Controllers/IPlugin.cs
Normal file
@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using JetBrains.Annotations;
|
||||
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>
|
||||
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
|
||||
public interface IPlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// A slug to identify this plugin in queries.
|
||||
/// </summary>
|
||||
string Slug { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the plugin
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The description of this plugin. This will be displayed on the "installed plugins" page.
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <c>true</c> if the plugin should be enabled, <c>false</c> otherwise.
|
||||
/// If a plugin is not enabled, no configure method will be called.
|
||||
/// This allow one to enable a plugin if a specific configuration value is set or if the environment contains
|
||||
/// the right settings.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default, a plugin is always enabled. This method can be overriden to change this behavior.
|
||||
/// </remarks>
|
||||
virtual bool Enabled => true;
|
||||
|
||||
/// <summary>
|
||||
/// A list of types that will be available via the IOptions interfaces and will be listed inside
|
||||
/// an IConfiguration.
|
||||
///
|
||||
/// If a field should be loosely typed, <see cref="Dictionary{TKey,TValue}"/> or <c>null</c>
|
||||
/// can be specified.
|
||||
/// WARNING: null means an unmanaged type that won't be editable. This can be used
|
||||
/// for external libraries or variable arguments.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// All use of the configuration must be specified here and not registered elsewhere, if a type is registered
|
||||
/// elsewhere the configuration won't be editable via the <see cref="IConfigurationManager"/> and all values
|
||||
/// will be discarded on edit.
|
||||
/// </remarks>
|
||||
Dictionary<string, Type> Configuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// An optional configuration step to allow a plugin to change asp net configurations.
|
||||
/// </summary>
|
||||
/// <seealso cref="SA"/>
|
||||
virtual 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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional function to execute and initialize your plugin.
|
||||
/// It can be used to initialize a database connection, fill initial data or anything.
|
||||
/// </summary>
|
||||
/// <param name="provider">A service provider to request services</param>
|
||||
void Initialize(IServiceProvider provider)
|
||||
{
|
||||
// Skipped
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional callback function called when the startups ends and this plugin has been flagged has disabled.
|
||||
/// It allow a plugin to log an error or warning message to inform why it has been disabled.
|
||||
/// </summary>
|
||||
void Disabled()
|
||||
{
|
||||
// Skipped
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// A manager to load plugins and retrieve information from them.
|
||||
@ -41,23 +39,14 @@ namespace Kyoo.Controllers
|
||||
/// You should not try to put plugins from the plugins directory here as they will get automatically loaded.
|
||||
/// </param>
|
||||
public void LoadPlugins(ICollection<IPlugin> plugins);
|
||||
|
||||
/// <summary>
|
||||
/// Configure container adding or removing services as the plugins wants.
|
||||
/// </summary>
|
||||
/// <param name="builder">The container to populate</param>
|
||||
void ConfigureContainer(ContainerBuilder builder);
|
||||
|
||||
/// <summary>
|
||||
/// Configure services via the microsoft way. This allow libraries to add their services.
|
||||
/// Load plugins and their dependencies from the plugin directory.
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection to populate</param>
|
||||
public void ConfigureServices(IServiceCollection services);
|
||||
|
||||
/// <summary>
|
||||
/// Configure an asp net application applying plugins policies.
|
||||
/// </summary>
|
||||
/// <param name="app">The asp net application to configure</param>
|
||||
public void ConfigureAspnet(IApplicationBuilder app);
|
||||
/// <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);
|
||||
}
|
||||
}
|
@ -4,10 +4,10 @@ using System.Linq.Expressions;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Information about the pagination. How many items should be displayed and where to start.
|
||||
@ -106,7 +106,7 @@ namespace Kyoo.Controllers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A base class for repositories. Every service implementing this will be handled by the <see cref="LibraryManager"/>.
|
||||
/// A base class for repositories. Every service implementing this will be handled by the <see cref="ILibraryManager"/>.
|
||||
/// </summary>
|
||||
public interface IBaseRepository
|
||||
{
|
||||
@ -309,20 +309,20 @@ namespace Kyoo.Controllers
|
||||
Task<Season> Get(string showSlug, int seasonNumber);
|
||||
|
||||
/// <summary>
|
||||
/// Get a season from it's showID and it's seasonNumber or null if it is not found.
|
||||
/// </summary>
|
||||
/// <param name="showID">The id of the show</param>
|
||||
/// <param name="seasonNumber">The season's number</param>
|
||||
/// <returns>The season found</returns>
|
||||
Task<Season> GetOrDefault(int showID, int seasonNumber);
|
||||
|
||||
/// <summary>
|
||||
/// Get a season from it's show slug and it's seasonNumber or null if it is not found.
|
||||
/// </summary>
|
||||
/// <param name="showSlug">The slug of the show</param>
|
||||
/// <param name="seasonNumber">The season's number</param>
|
||||
/// <returns>The season found</returns>
|
||||
Task<Season> GetOrDefault(string showSlug, int seasonNumber);
|
||||
/// Get a season from it's showID and it's seasonNumber or null if it is not found.
|
||||
/// </summary>
|
||||
/// <param name="showID">The id of the show</param>
|
||||
/// <param name="seasonNumber">The season's number</param>
|
||||
/// <returns>The season found</returns>
|
||||
Task<Season> GetOrDefault(int showID, int seasonNumber);
|
||||
|
||||
/// <summary>
|
||||
/// Get a season from it's show slug and it's seasonNumber or null if it is not found.
|
||||
/// </summary>
|
||||
/// <param name="showSlug">The slug of the show</param>
|
||||
/// <param name="seasonNumber">The season's number</param>
|
||||
/// <returns>The season found</returns>
|
||||
Task<Season> GetOrDefault(string showSlug, int seasonNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
@ -4,11 +4,10 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// A single task parameter. This struct contains metadata to display and utility functions to get them in the task.
|
||||
@ -55,7 +54,7 @@ namespace Kyoo.Controllers
|
||||
/// <returns>A new task parameter.</returns>
|
||||
public static TaskParameter Create<T>(string name, string description)
|
||||
{
|
||||
return new()
|
||||
return new TaskParameter
|
||||
{
|
||||
Name = name,
|
||||
Description = description,
|
||||
@ -72,7 +71,7 @@ namespace Kyoo.Controllers
|
||||
/// <returns>A new task parameter.</returns>
|
||||
public static TaskParameter CreateRequired<T>(string name, string description)
|
||||
{
|
||||
return new()
|
||||
return new TaskParameter
|
||||
{
|
||||
Name = name,
|
||||
Description = description,
|
||||
@ -182,11 +181,6 @@ namespace Kyoo.Controllers
|
||||
/// <param name="cancellationToken">A token to request the task's cancellation.
|
||||
/// If this task is not cancelled quickly, it might be killed by the runner.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// Your task can have any service as a public field and use the <see cref="InjectedAttribute"/>,
|
||||
/// they will be set to an available service from the service container before calling this method.
|
||||
/// They also will be removed after this method return (or throw) to prevent dangling services.
|
||||
/// </remarks>
|
||||
/// <exception cref="TaskFailedException">
|
||||
/// An exception meaning that the task has failed for handled reasons like invalid arguments,
|
||||
/// invalid environment, missing plugins or failures not related to a default in the code.
|
@ -2,10 +2,10 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading;
|
||||
using Kyoo.Common.Models.Attributes;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// A service to handle long running tasks.
|
@ -1,8 +1,8 @@
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Download images and retrieve the path of those images for a resource.
|
@ -1,7 +1,7 @@
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
public interface ITranscoder
|
||||
{
|
221
Kyoo.Abstractions/Controllers/StartupAction.cs
Normal file
221
Kyoo.Abstractions/Controllers/StartupAction.cs
Normal file
@ -0,0 +1,221 @@
|
||||
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
|
||||
{
|
||||
public const int Before = 5000;
|
||||
public const int Routing = 4000;
|
||||
public const int StaticFiles = 3000;
|
||||
public const int Authentication = 2000;
|
||||
public const int Authorization = 1000;
|
||||
public const int Endpoint = 0;
|
||||
public const int After = -1000;
|
||||
|
||||
/// <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)
|
||||
=> 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)
|
||||
=> 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)
|
||||
=> new(action, priority);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// An action executed on kyoo's startup to initialize the asp-net container.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the base interface, see <see cref="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);
|
||||
}
|
||||
|
||||
/// <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
|
||||
{
|
||||
/// <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
|
||||
{
|
||||
/// <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
|
||||
{
|
||||
/// <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>()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Title>Kyoo.Common</Title>
|
||||
<Title>Kyoo.Abstractions</Title>
|
||||
<Authors>Zoe Roux</Authors>
|
||||
<Description>Base package to create plugins for Kyoo.</Description>
|
||||
<PackageProjectUrl>https://github.com/AnonymusRaccoon/Kyoo</PackageProjectUrl>
|
||||
@ -12,10 +12,11 @@
|
||||
<Company>SDG</Company>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||
<PackageVersion>1.0.25</PackageVersion>
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<LangVersion>default</LangVersion>
|
||||
<RootNamespace>Kyoo.Abstractions</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
17
Kyoo.Abstractions/Models/AsyncRef.cs
Normal file
17
Kyoo.Abstractions/Models/AsyncRef.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A class wrapping a value that will be set after the completion of the task it is related to.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class replace the use of an out parameter on a task since tasks and out can't be combined.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The type of the value</typeparam>
|
||||
public class AsyncRef<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// The value that will be set before the completion of the task.
|
||||
/// </summary>
|
||||
public T Value { get; set; }
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// An attribute to inform that the property is computed automatically and can't be assigned manually.
|
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Common.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// An attribute to inform how a <see cref="IFileSystem"/> works.
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Specify that a property can't be merged.
|
@ -2,7 +2,7 @@ using System;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Models.Permissions
|
||||
namespace Kyoo.Abstractions.Models.Permissions
|
||||
{
|
||||
/// <summary>
|
||||
/// The kind of permission needed.
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// The targeted relation can be edited via calls to the repository's <see cref="IRepository{T}.Edit"/> method.
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Remove an property from the serialization pipeline. It will simply be skipped.
|
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Common.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// An attribute to inform how a <see cref="IFileSystem"/> works.
|
@ -1,4 +1,4 @@
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A chapter to split an episode in multiple parts.
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A class given information about a strongly typed configuration.
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Kyoo.Models.Exceptions
|
||||
namespace Kyoo.Abstractions.Models.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// An exception raised when an item already exists in the database.
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Models.Exceptions
|
||||
namespace Kyoo.Abstractions.Models.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// An exception raised when an <see cref="IIdentifier"/> failed.
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Kyoo.Models.Exceptions
|
||||
namespace Kyoo.Abstractions.Models.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// An exception raised when an item could not be found.
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Models.Exceptions
|
||||
namespace Kyoo.Abstractions.Models.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// An exception raised when an <see cref="ITask"/> failed.
|
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of item, ether a show, a movie or a collection.
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// ID and link of an item on an external provider.
|
@ -2,7 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A page of resource that contains information about the pagination of resources.
|
@ -1,4 +1,4 @@
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A role a person played for a show. It can be an actor, musician, voice actor, director, writer...
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A class representing collections of <see cref="Show"/>.
|
@ -2,10 +2,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A class to represent a single show's episode.
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A genre that allow one to specify categories for shows.
|
@ -2,9 +2,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface applied to resources containing external metadata.
|
@ -1,6 +1,6 @@
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface to represent a resource that can be retrieved from the database.
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface representing items that contains images (like posters, thumbnails, logo, banners...)
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A library containing <see cref="Show"/> and <see cref="Collection"/>.
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// An actor, voice actor, writer, animator, somebody who worked on a <see cref="Show"/>.
|
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains metadata about <see cref="IMetadataProvider"/>.
|
@ -2,10 +2,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A season of a <see cref="Show"/>.
|
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A series or a movie.
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A studio that make shows.
|
@ -3,9 +3,9 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The list of available stream types.
|
||||
@ -60,9 +60,9 @@ namespace Kyoo.Models
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The slug of the episode that contain this track. If this is not set, this track is ill-formed.
|
||||
/// </summary>
|
||||
[SerializeIgnore] public string EpisodeSlug { private get; set; }
|
||||
/// The slug of the episode that contain this track. If this is not set, this track is ill-formed.
|
||||
/// </summary>
|
||||
[SerializeIgnore] public string EpisodeSlug { private get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The title of the stream.
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A single user of the app.
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Results of a search request.
|
@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
using PathIO = System.IO.Path;
|
||||
|
||||
namespace Kyoo.Models
|
||||
namespace Kyoo.Abstractions.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A watch item give information useful for playback.
|
@ -1,9 +1,9 @@
|
||||
using Autofac;
|
||||
using Autofac.Builder;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Kyoo
|
||||
namespace Kyoo.Abstractions
|
||||
{
|
||||
/// <summary>
|
||||
/// A static class with helper functions to setup external modules
|
@ -5,8 +5,8 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo
|
||||
{
|
@ -21,17 +21,17 @@ namespace Kyoo
|
||||
/// <exception cref="TaskCanceledException"></exception>
|
||||
/// <exception cref="TaskCanceledException">The source task has been canceled.</exception>
|
||||
public static Task<T> Then<T>(this Task<T> task, Action<T> then)
|
||||
{
|
||||
return task.ContinueWith(x =>
|
||||
{
|
||||
if (x.IsFaulted)
|
||||
x.Exception!.InnerException!.ReThrow();
|
||||
if (x.IsCanceled)
|
||||
throw new TaskCanceledException();
|
||||
then(x.Result);
|
||||
return x.Result;
|
||||
}, TaskContinuationOptions.ExecuteSynchronously);
|
||||
}
|
||||
{
|
||||
return task.ContinueWith(x =>
|
||||
{
|
||||
if (x.IsFaulted)
|
||||
x.Exception!.InnerException!.ReThrow();
|
||||
if (x.IsCanceled)
|
||||
throw new TaskCanceledException();
|
||||
then(x.Result);
|
||||
return x.Result;
|
||||
}, TaskContinuationOptions.ExecuteSynchronously);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Map the result of a task to another result.
|
||||
@ -42,28 +42,28 @@ namespace Kyoo
|
||||
/// <typeparam name="TResult">The resulting task after the mapping method</typeparam>
|
||||
/// <returns>A task wrapping the initial task and mapping the initial result.</returns>
|
||||
/// <exception cref="TaskCanceledException">The source task has been canceled.</exception>
|
||||
public static Task<TResult> Map<T, TResult>(this Task<T> task, Func<T, TResult> map)
|
||||
{
|
||||
return task.ContinueWith(x =>
|
||||
{
|
||||
if (x.IsFaulted)
|
||||
x.Exception!.InnerException!.ReThrow();
|
||||
if (x.IsCanceled)
|
||||
throw new TaskCanceledException();
|
||||
return map(x.Result);
|
||||
}, TaskContinuationOptions.ExecuteSynchronously);
|
||||
}
|
||||
public static Task<TResult> Map<T, TResult>(this Task<T> task, Func<T, TResult> map)
|
||||
{
|
||||
return task.ContinueWith(x =>
|
||||
{
|
||||
if (x.IsFaulted)
|
||||
x.Exception!.InnerException!.ReThrow();
|
||||
if (x.IsCanceled)
|
||||
throw new TaskCanceledException();
|
||||
return map(x.Result);
|
||||
}, TaskContinuationOptions.ExecuteSynchronously);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method to return the a default value from a task if the initial task is null.
|
||||
/// </summary>
|
||||
/// <param name="value">The initial task</param>
|
||||
/// <typeparam name="T">The type that the task will return</typeparam>
|
||||
/// <returns>A non-null task.</returns>
|
||||
[NotNull]
|
||||
public static Task<T> DefaultIfNull<T>([CanBeNull] Task<T> value)
|
||||
{
|
||||
return value ?? Task.FromResult<T>(default);
|
||||
}
|
||||
/// <summary>
|
||||
/// A method to return the a default value from a task if the initial task is null.
|
||||
/// </summary>
|
||||
/// <param name="value">The initial task</param>
|
||||
/// <typeparam name="T">The type that the task will return</typeparam>
|
||||
/// <returns>A non-null task.</returns>
|
||||
[NotNull]
|
||||
public static Task<T> DefaultIfNull<T>([CanBeNull] Task<T> value)
|
||||
{
|
||||
return value ?? Task.FromResult<T>(default);
|
||||
}
|
||||
}
|
||||
}
|
@ -155,7 +155,8 @@ namespace Kyoo
|
||||
IEnumerable<Type> types = genericType.IsInterface
|
||||
? type.GetInterfaces()
|
||||
: type.GetInheritanceTree();
|
||||
return types.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType);
|
||||
return types.Prepend(type)
|
||||
.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -179,7 +180,8 @@ namespace Kyoo
|
||||
IEnumerable<Type> types = genericType.IsInterface
|
||||
? type.GetInterfaces()
|
||||
: type.GetInheritanceTree();
|
||||
return types.FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType);
|
||||
return types.Prepend(type)
|
||||
.FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType);
|
||||
}
|
||||
|
||||
/// <summary>
|
@ -3,14 +3,15 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Autofac;
|
||||
using IdentityServer4.Extensions;
|
||||
using IdentityServer4.Models;
|
||||
using IdentityServer4.Services;
|
||||
using Kyoo.Abstractions;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Permissions;
|
||||
using Kyoo.Authentication.Models;
|
||||
using Kyoo.Authentication.Views;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Models.Permissions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@ -37,58 +38,61 @@ namespace Kyoo.Authentication
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "Enable OpenID authentication for Kyoo.";
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Provides => ArraySegment<Type>.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<ConditionalProvide> ConditionalProvides => ArraySegment<ConditionalProvide>.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Requires => new []
|
||||
public Dictionary<string, Type> Configuration => new()
|
||||
{
|
||||
typeof(IUserRepository)
|
||||
{ AuthenticationOption.Path, typeof(AuthenticationOption) },
|
||||
{ PermissionOption.Path, typeof(PermissionOption) },
|
||||
{ CertificateOption.Path, typeof(CertificateOption) }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use.
|
||||
/// </summary>
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// A logger factory to allow IdentityServer to log things.
|
||||
/// The logger used to allow IdentityServer to log things.
|
||||
/// </summary>
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly ILogger<DefaultCorsPolicyService> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// The environment information to check if the app runs in debug mode
|
||||
/// </summary>
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
|
||||
/// <summary>
|
||||
/// The configuration manager used to register typed/untyped implementations.
|
||||
/// </summary>
|
||||
[Injected] public IConfigurationManager ConfigurationManager { private get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new authentication module instance and use the given configuration and environment.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to use</param>
|
||||
/// <param name="loggerFactory">The logger factory to allow IdentityServer to log things</param>
|
||||
/// <param name="logger">The logger used to allow IdentityServer to log things</param>
|
||||
/// <param name="environment">The environment information to check if the app runs in debug mode</param>
|
||||
public AuthenticationModule(IConfiguration configuration,
|
||||
ILoggerFactory loggerFactory,
|
||||
ILogger<DefaultCorsPolicyService> logger,
|
||||
IWebHostEnvironment environment)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_loggerFactory = loggerFactory;
|
||||
_logger = logger;
|
||||
_environment = environment;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
public void Configure(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterType<PermissionValidatorFactory>().As<IPermissionValidator>().SingleInstance();
|
||||
|
||||
DefaultCorsPolicyService cors = new(_logger)
|
||||
{
|
||||
AllowedOrigins = { new Uri(_configuration.GetPublicUrl()).GetLeftPart(UriPartial.Authority) }
|
||||
};
|
||||
builder.RegisterInstance(cors).As<ICorsPolicyService>().SingleInstance();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services)
|
||||
{
|
||||
string publicUrl = _configuration.GetPublicUrl();
|
||||
|
||||
@ -100,10 +104,6 @@ namespace Kyoo.Authentication
|
||||
// TODO handle direct-videos with bearers (probably add a cookie and a app.Use to translate that for videos)
|
||||
|
||||
// TODO Check if tokens should be stored.
|
||||
|
||||
services.Configure<PermissionOption>(_configuration.GetSection(PermissionOption.Path));
|
||||
services.Configure<CertificateOption>(_configuration.GetSection(CertificateOption.Path));
|
||||
services.Configure<AuthenticationOption>(_configuration.GetSection(AuthenticationOption.Path));
|
||||
|
||||
List<Client> clients = new();
|
||||
_configuration.GetSection("authentication:clients").Bind(clients);
|
||||
@ -131,47 +131,46 @@ namespace Kyoo.Authentication
|
||||
options.Audience = "kyoo";
|
||||
options.RequireHttpsMetadata = false;
|
||||
});
|
||||
services.AddSingleton<IPermissionValidator, PermissionValidatorFactory>();
|
||||
|
||||
DefaultCorsPolicyService cors = new(_loggerFactory.CreateLogger<DefaultCorsPolicyService>())
|
||||
{
|
||||
AllowedOrigins = {new Uri(publicUrl).GetLeftPart(UriPartial.Authority)}
|
||||
};
|
||||
services.AddSingleton<ICorsPolicyService>(cors);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureAspNet(IApplicationBuilder app)
|
||||
public IEnumerable<IStartupAction> ConfigureSteps => new IStartupAction[]
|
||||
{
|
||||
ConfigurationManager.AddTyped<AuthenticationOption>(AuthenticationOption.Path);
|
||||
|
||||
app.UseCookiePolicy(new CookiePolicyOptions
|
||||
SA.New<IApplicationBuilder>(app =>
|
||||
{
|
||||
MinimumSameSitePolicy = SameSiteMode.Strict
|
||||
});
|
||||
app.UseAuthentication();
|
||||
app.Use((ctx, next) =>
|
||||
PhysicalFileProvider provider = new(Path.Combine(
|
||||
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!,
|
||||
"login"));
|
||||
app.UseDefaultFiles(new DefaultFilesOptions
|
||||
{
|
||||
RequestPath = new PathString("/login"),
|
||||
FileProvider = provider,
|
||||
RedirectToAppendTrailingSlash = true
|
||||
});
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
RequestPath = new PathString("/login"),
|
||||
FileProvider = provider
|
||||
});
|
||||
}, SA.StaticFiles),
|
||||
SA.New<IApplicationBuilder>(app =>
|
||||
{
|
||||
ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl());
|
||||
return next();
|
||||
});
|
||||
app.UseIdentityServer();
|
||||
app.UseAuthorization();
|
||||
|
||||
PhysicalFileProvider provider = new(Path.Combine(
|
||||
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!,
|
||||
"login"));
|
||||
app.UseDefaultFiles(new DefaultFilesOptions
|
||||
app.UseCookiePolicy(new CookiePolicyOptions
|
||||
{
|
||||
MinimumSameSitePolicy = SameSiteMode.Strict
|
||||
});
|
||||
app.UseAuthentication();
|
||||
}, SA.Authentication),
|
||||
SA.New<IApplicationBuilder>(app =>
|
||||
{
|
||||
RequestPath = new PathString("/login"),
|
||||
FileProvider = provider,
|
||||
RedirectToAppendTrailingSlash = true
|
||||
});
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
RequestPath = new PathString("/login"),
|
||||
FileProvider = provider
|
||||
});
|
||||
}
|
||||
app.Use((ctx, next) =>
|
||||
{
|
||||
ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl());
|
||||
return next();
|
||||
});
|
||||
app.UseIdentityServer();
|
||||
}, SA.Endpoint),
|
||||
SA.New<IApplicationBuilder>(app => app.UseAuthorization(), SA.Authorization)
|
||||
};
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ namespace Kyoo.Authentication
|
||||
X509Certificate2 certificate = GetCertificate(options);
|
||||
builder.AddSigningCredential(certificate);
|
||||
|
||||
if (certificate.NotAfter.AddDays(7) <= DateTime.UtcNow)
|
||||
if (certificate.NotAfter.AddDays(-7) <= DateTime.UtcNow)
|
||||
{
|
||||
Console.WriteLine("Signin certificate will expire soon, renewing it.");
|
||||
if (File.Exists(options.OldFile))
|
||||
@ -67,7 +67,7 @@ namespace Kyoo.Authentication
|
||||
/// <returns>The loaded certificate</returns>
|
||||
private static X509Certificate2 GetExistingCredential(string file, string password)
|
||||
{
|
||||
return new(file, password,
|
||||
return new X509Certificate2(file, password,
|
||||
X509KeyStorageFlags.MachineKeySet |
|
||||
X509KeyStorageFlags.PersistKeySet |
|
||||
X509KeyStorageFlags.Exportable
|
||||
|
@ -2,8 +2,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Models.Permissions;
|
||||
using Kyoo.Authentication.Models;
|
||||
using Kyoo.Models.Permissions;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
@ -3,7 +3,7 @@ using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using IdentityModel;
|
||||
using IdentityServer4;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
|
||||
namespace Kyoo.Authentication
|
||||
{
|
||||
|
@ -2,18 +2,12 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<OutputPath>../Kyoo/bin/$(Configuration)/$(TargetFramework)/plugins/authentication</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
|
||||
<GenerateDependencyFile>false</GenerateDependencyFile>
|
||||
<GenerateRuntimeConfigurationFiles>false</GenerateRuntimeConfigurationFiles>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
||||
<LoginRoot>../Kyoo.WebLogin/</LoginRoot>
|
||||
|
||||
<Company>SDG</Company>
|
||||
<Authors>Zoe Roux</Authors>
|
||||
<RepositoryUrl>https://github.com/AnonymusRaccoon/Kyoo</RepositoryUrl>
|
||||
<LangVersion>default</LangVersion>
|
||||
<LoginRoot>../Kyoo.WebLogin/</LoginRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -23,28 +17,14 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" />
|
||||
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<Private>false</Private>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<LoginFiles Include="$(LoginRoot)**" Visible="false" />
|
||||
<None Remove="$(LoginRoot)**;" />
|
||||
<Content Include="$(LoginRoot)**">
|
||||
<Link>login/%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="Publish login files" AfterTargets="ComputeFilesToPublish">
|
||||
<ItemGroup>
|
||||
<ResolvedFileToPublish Include="@(LoginFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
|
||||
<RelativePath>login/%(LoginFiles.RecursiveDir)%(LoginFiles.Filename)%(LoginFiles.Extension)</RelativePath>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</ResolvedFileToPublish>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="Prepare static files" AfterTargets="Build" Condition="$(Configuration) == 'Debug'">
|
||||
<Copy SourceFiles="@(LoginFiles)" DestinationFolder="$(OutputPath)/login/%(RecursiveDir)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
|
||||
namespace Kyoo.Authentication.Models.DTO
|
||||
{
|
||||
@ -34,7 +34,7 @@ namespace Kyoo.Authentication.Models.DTO
|
||||
/// <returns></returns>
|
||||
public User ToUser()
|
||||
{
|
||||
return new()
|
||||
return new User
|
||||
{
|
||||
Slug = Utility.ToSlug(Username),
|
||||
Username = Username,
|
||||
|
@ -8,11 +8,11 @@ using System.Threading.Tasks;
|
||||
using IdentityServer4.Extensions;
|
||||
using IdentityServer4.Models;
|
||||
using IdentityServer4.Services;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
using Kyoo.Authentication.Models;
|
||||
using Kyoo.Authentication.Models.DTO;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
@ -1,247 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
{
|
||||
/// <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>
|
||||
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
|
||||
public interface IPlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// A slug to identify this plugin in queries.
|
||||
/// </summary>
|
||||
string Slug { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the plugin
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The description of this plugin. This will be displayed on the "installed plugins" page.
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of services that are provided by this service. This allow other plugins to declare dependencies
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You should put the type's interface that will be register in configure.
|
||||
/// </remarks>
|
||||
ICollection<Type> Provides { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of types that will be provided only if a condition is met. The condition can be an arbitrary method or
|
||||
/// a condition based on other type availability. For more information, see <see cref="ConditionalProvides"/>.
|
||||
/// </summary>
|
||||
ICollection<ConditionalProvide> ConditionalProvides { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of services that are required by this plugin.
|
||||
/// You can put services that you provide conditionally here if you want.
|
||||
/// Kyoo will warn the user that this plugin can't be loaded if a required service is not found.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Put here the most complete type that are needed for your plugin to work. If you need a LibraryManager,
|
||||
/// put typeof(ILibraryManager).
|
||||
/// </remarks>
|
||||
ICollection<Type> Requires { get; }
|
||||
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <param name="services">A service container to register new services.</param>
|
||||
/// <param name="availableTypes">The list of types that are available for this instance. This can be used
|
||||
/// for conditional type. See <see cref="ProviderCondition.Has(System.Type,System.Collections.Generic.ICollection{System.Type})"/>
|
||||
/// or <see cref="ProviderCondition.Has(System.Collections.Generic.ICollection{System.Type},System.Collections.Generic.ICollection{System.Type})"/>>
|
||||
/// You can't simply check on the service collection because some dependencies might be registered after your plugin.
|
||||
/// </param>
|
||||
void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
{
|
||||
// Skipped
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// An optional configuration step to allow a plugin to change asp net configurations.
|
||||
/// WARNING: This is only called on Kyoo's startup so you must restart the app to apply this changes.
|
||||
/// </summary>
|
||||
/// <param name="app">
|
||||
/// The Asp.Net application builder. On most case it is not needed but you can use it to
|
||||
/// add asp net functionalities.
|
||||
/// </param>
|
||||
void ConfigureAspNet(IApplicationBuilder app)
|
||||
{
|
||||
// Skipped
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional function to execute and initialize your plugin.
|
||||
/// It can be used to initialize a database connection, fill initial data or anything.
|
||||
/// </summary>
|
||||
/// <param name="provider">A service provider to request services</param>
|
||||
void Initialize(IServiceProvider provider)
|
||||
{
|
||||
// Skipped
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A type that will only be provided if a special condition is met. To check that your condition is met,
|
||||
/// you can check the <see cref="ProviderCondition"/> class.
|
||||
/// </summary>
|
||||
public class ConditionalProvide : Tuple<Type, ProviderCondition>
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the type that may be provided
|
||||
/// </summary>
|
||||
public Type Type => Item1;
|
||||
|
||||
/// <summary>
|
||||
/// Get the condition.
|
||||
/// </summary>
|
||||
public ProviderCondition Condition => Item2;
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="ConditionalProvide"/> from a type and a condition.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to provide</param>
|
||||
/// <param name="condition">The condition</param>
|
||||
public ConditionalProvide(Type type, ProviderCondition condition)
|
||||
: base(type, condition)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="ConditionalProvide"/> from a tuple of (Type, ProviderCondition).
|
||||
/// </summary>
|
||||
/// <param name="tuple">The tuple to convert</param>
|
||||
public ConditionalProvide((Type type, ProviderCondition condition) tuple)
|
||||
: base(tuple.type, tuple.condition)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly convert a tuple to a <see cref="ConditionalProvide"/>.
|
||||
/// </summary>
|
||||
/// <param name="tuple">The tuple to convert</param>
|
||||
/// <returns>A new <see cref="ConditionalProvide"/> based on the given tuple.</returns>
|
||||
public static implicit operator ConditionalProvide((Type, Type) tuple) => new (tuple);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A condition for a conditional type.
|
||||
/// </summary>
|
||||
public class ProviderCondition
|
||||
{
|
||||
/// <summary>
|
||||
/// The condition as a method. If true is returned, the type will be provided.
|
||||
/// </summary>
|
||||
public Func<bool> Condition { get; } = () => true;
|
||||
/// <summary>
|
||||
/// The list of types that this method needs.
|
||||
/// </summary>
|
||||
public ICollection<Type> Needed { get; } = ArraySegment<Type>.Empty;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ProviderCondition"/> from a raw function.
|
||||
/// </summary>
|
||||
/// <param name="condition">The predicate that will be used as condition</param>
|
||||
public ProviderCondition(Func<bool> condition)
|
||||
{
|
||||
Condition = condition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ProviderCondition"/> from a type. This allow you to inform that a type will
|
||||
/// only be available if a dependency is met.
|
||||
/// </summary>
|
||||
/// <param name="needed">The type that you need</param>
|
||||
public ProviderCondition(Type needed)
|
||||
{
|
||||
Needed = new[] {needed};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ProviderCondition"/> from a list of type. This allow you to inform that a type will
|
||||
/// only be available if a list of dependencies are met.
|
||||
/// </summary>
|
||||
/// <param name="needed">The types that you need</param>
|
||||
public ProviderCondition(ICollection<Type> needed)
|
||||
{
|
||||
Needed = needed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ProviderCondition"/> with a list of types as dependencies and a predicate
|
||||
/// for arbitrary conditions.
|
||||
/// </summary>
|
||||
/// <param name="needed">The list of dependencies</param>
|
||||
/// <param name="condition">An arbitrary condition</param>
|
||||
public ProviderCondition(ICollection<Type> needed, Func<bool> condition)
|
||||
{
|
||||
Needed = needed;
|
||||
Condition = condition;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly convert a type to a <see cref="ProviderCondition"/>.
|
||||
/// </summary>
|
||||
/// <param name="type">The type dependency</param>
|
||||
/// <returns>A <see cref="ProviderCondition"/> that will return true if the given type is available.</returns>
|
||||
public static implicit operator ProviderCondition(Type type) => new(type);
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly convert a list of type to a <see cref="ProviderCondition"/>.
|
||||
/// </summary>
|
||||
/// <param name="types">The list of type dependencies</param>
|
||||
/// <returns>A <see cref="ProviderCondition"/> that will return true if the given types are available.</returns>
|
||||
public static implicit operator ProviderCondition(Type[] types) => new(types);
|
||||
|
||||
/// <inheritdoc cref="op_Implicit(System.Type[])"/>
|
||||
public static implicit operator ProviderCondition(List<Type> types) => new(types);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if a type is available.
|
||||
/// </summary>
|
||||
/// <param name="needed">The type to check</param>
|
||||
/// <param name="available">The list of types</param>
|
||||
/// <returns>True if the dependency is met, false otherwise</returns>
|
||||
public static bool Has(Type needed, ICollection<Type> available)
|
||||
{
|
||||
return available.Contains(needed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if a list of type are available.
|
||||
/// </summary>
|
||||
/// <param name="needed">The list of types to check</param>
|
||||
/// <param name="available">The list of types</param>
|
||||
/// <returns>True if the dependencies are met, false otherwise</returns>
|
||||
public static bool Has(ICollection<Type> needed, ICollection<Type> available)
|
||||
{
|
||||
return needed.All(x => Has(x, available));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Controllers;
|
||||
|
||||
namespace Kyoo.Models.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// An attribute to inform that the service will be injected automatically by a service provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It should only be used on <see cref="IPlugin"/> and it will be injected before
|
||||
/// calling <see cref="IPlugin.ConfigureAspNet"/>.
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
[MeansImplicitUse(ImplicitUseKindFlags.Assign)]
|
||||
public class InjectedAttribute : Attribute { }
|
||||
}
|
@ -5,13 +5,13 @@ using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
|
||||
namespace Kyoo
|
||||
namespace Kyoo.Database
|
||||
{
|
||||
/// <summary>
|
||||
/// The database handle used for all local repositories.
|
@ -11,16 +11,26 @@ namespace Kyoo
|
||||
/// <summary>
|
||||
/// Get a connection string from the Configuration's section "Database"
|
||||
/// </summary>
|
||||
/// <param name="config">The IConfiguration instance to load.</param>
|
||||
/// <param name="config">The IConfiguration instance to use.</param>
|
||||
/// <param name="database">The database's name.</param>
|
||||
/// <returns>A parsed connection string</returns>
|
||||
public static string GetDatabaseConnection(this IConfiguration config, string database)
|
||||
{
|
||||
DbConnectionStringBuilder builder = new();
|
||||
IConfigurationSection section = config.GetSection("Database").GetSection(database);
|
||||
IConfigurationSection section = config.GetSection("database:configurations").GetSection(database);
|
||||
foreach (IConfigurationSection child in section.GetChildren())
|
||||
builder[child.Key] = child.Value;
|
||||
return builder.ConnectionString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the name of the selected database.
|
||||
/// </summary>
|
||||
/// <param name="config">The IConfiguration instance to use.</param>
|
||||
/// <returns>The name of the selected database.</returns>
|
||||
public static string GetSelectedDatabase(this IConfiguration config)
|
||||
{
|
||||
return config.GetValue<string>("database:enabled");
|
||||
}
|
||||
}
|
||||
}
|
@ -2,9 +2,8 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<AssemblyName>Kyoo.CommonApi</AssemblyName>
|
||||
<RootNamespace>Kyoo.CommonApi</RootNamespace>
|
||||
<PackageId>Kyoo.CommonApi</PackageId>
|
||||
<AssemblyName>Kyoo.Database</AssemblyName>
|
||||
<RootNamespace>Kyoo.Database</RootNamespace>
|
||||
<Authors>Zoe Roux</Authors>
|
||||
<RepositoryUrl>https://github.com/AnonymusRaccoon/Kyoo</RepositoryUrl>
|
||||
<OutputType>Library</OutputType>
|
||||
@ -19,7 +18,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Kyoo.Common\Kyoo.Common.csproj" />
|
||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -18,9 +18,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Kyoo.CommonAPI/Kyoo.CommonAPI.csproj">
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj">
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Kyoo.Database\Kyoo.Database.csproj" />
|
||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,7 +1,7 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Postgresql;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Postgresql;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Postgresql;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
@ -3,7 +3,8 @@ using System.Globalization;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using EFCore.NamingConventions.Internal;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Database;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -23,19 +24,12 @@ namespace Kyoo.Postgresql
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "A database context for postgresql.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Provides => new[]
|
||||
{
|
||||
typeof(DatabaseContext)
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<ConditionalProvide> ConditionalProvides => ArraySegment<ConditionalProvide>.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Requires => ArraySegment<Type>.Empty;
|
||||
|
||||
public bool Enabled => _configuration.GetSelectedDatabase() == "postgres";
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use. The database connection string is pulled from it.
|
||||
@ -59,7 +53,7 @@ namespace Kyoo.Postgresql
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
public void Configure(IServiceCollection services)
|
||||
{
|
||||
services.AddDbContext<DatabaseContext, PostgresContext>(x =>
|
||||
{
|
||||
|
@ -18,9 +18,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Kyoo.CommonAPI/Kyoo.CommonAPI.csproj">
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj">
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Kyoo.Database\Kyoo.Database.csproj" />
|
||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -2,7 +2,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Database;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Database;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -22,20 +23,14 @@ namespace Kyoo.SqLite
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "A database context for sqlite.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Enabled => _configuration.GetSelectedDatabase() == "sqlite";
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Provides => new[]
|
||||
{
|
||||
typeof(DatabaseContext)
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<ConditionalProvide> ConditionalProvides => ArraySegment<ConditionalProvide>.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Requires => ArraySegment<Type>.Empty;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use. The database connection string is pulled from it.
|
||||
/// </summary>
|
||||
@ -59,7 +54,7 @@ namespace Kyoo.SqLite
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
public void Configure(IServiceCollection services)
|
||||
{
|
||||
services.AddDbContext<DatabaseContext, SqLiteContext>(x =>
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using TMDbLib.Objects.Search;
|
||||
|
||||
namespace Kyoo.TheMovieDb
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using TMDbLib.Objects.TvShows;
|
||||
|
||||
namespace Kyoo.TheMovieDb
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using TMDbLib.Objects.Movies;
|
||||
using TMDbLib.Objects.Search;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using TMDbLib.Objects.General;
|
||||
using TMDbLib.Objects.People;
|
||||
using TMDbLib.Objects.Search;
|
||||
using Images = Kyoo.Models.Images;
|
||||
using Images = Kyoo.Abstractions.Models.Images;
|
||||
using TvCast = TMDbLib.Objects.TvShows.Cast;
|
||||
using MovieCast = TMDbLib.Objects.Movies.Cast;
|
||||
|
||||
@ -15,11 +15,11 @@ namespace Kyoo.TheMovieDb
|
||||
public static partial class Convertors
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert a <see cref="MovieCast"/> to a <see cref="PeopleRole"/>.
|
||||
/// Convert a <see cref="MovieCast"/> to a <see cref="Abstractions.Models.PeopleRole"/>.
|
||||
/// </summary>
|
||||
/// <param name="cast">An internal TheMovieDB cast.</param>
|
||||
/// <param name="provider">The provider that represent TheMovieDB inside Kyoo.</param>
|
||||
/// <returns>A <see cref="PeopleRole"/> representing the movie cast.</returns>
|
||||
/// <returns>A <see cref="Abstractions.Models.PeopleRole"/> representing the movie cast.</returns>
|
||||
public static PeopleRole ToPeople(this MovieCast cast, Provider provider)
|
||||
{
|
||||
return new PeopleRole
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using TMDbLib.Objects.TvShows;
|
||||
|
||||
namespace Kyoo.TheMovieDb
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using TMDbLib.Objects.Search;
|
||||
using TMDbLib.Objects.TvShows;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using TMDbLib.Objects.Companies;
|
||||
using TMDbLib.Objects.Search;
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj">
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,12 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.TheMovieDb.Models;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.TheMovieDb
|
||||
{
|
||||
@ -25,55 +22,15 @@ namespace Kyoo.TheMovieDb
|
||||
public string Description => "A metadata provider for TheMovieDB.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Provides => new []
|
||||
public Dictionary<string, Type> Configuration => new()
|
||||
{
|
||||
typeof(IMetadataProvider)
|
||||
{ TheMovieDbOptions.Path, typeof(TheMovieDbOptions) }
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<ConditionalProvide> ConditionalProvides => ArraySegment<ConditionalProvide>.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Requires => ArraySegment<Type>.Empty;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use.
|
||||
/// </summary>
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The configuration manager used to register typed/untyped implementations.
|
||||
/// </summary>
|
||||
[Injected] public IConfigurationManager ConfigurationManager { private get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new tmdb module instance and use the given configuration.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to use</param>
|
||||
public PluginTmdb(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterProvider<TheMovieDbProvider>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
{
|
||||
services.Configure<TheMovieDbOptions>(_configuration.GetSection(TheMovieDbOptions.Path));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureAspNet(IApplicationBuilder app)
|
||||
{
|
||||
ConfigurationManager.AddTyped<TheMovieDbOptions>(TheMovieDbOptions.Path);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.TheMovieDb.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
@ -2,7 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using TvDbSharper.Dto;
|
||||
|
||||
namespace Kyoo.TheTvdb
|
||||
|
@ -16,7 +16,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj">
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,12 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Abstractions;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.TheTvdb.Models;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using TvDbSharper;
|
||||
|
||||
namespace Kyoo.TheTvdb
|
||||
@ -24,58 +21,18 @@ namespace Kyoo.TheTvdb
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "A metadata provider for The TVDB.";
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Provides => new []
|
||||
public Dictionary<string, Type> Configuration => new()
|
||||
{
|
||||
typeof(IMetadataProvider)
|
||||
{ TvdbOption.Path, typeof(TvdbOption) }
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<ConditionalProvide> ConditionalProvides => ArraySegment<ConditionalProvide>.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<Type> Requires => ArraySegment<Type>.Empty;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use.
|
||||
/// </summary>
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The configuration manager used to register typed/untyped implementations.
|
||||
/// </summary>
|
||||
[Injected] public IConfigurationManager ConfigurationManager { private get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new tvdb module instance and use the given configuration.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to use</param>
|
||||
public PluginTvdb(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterType<TvDbClient>().As<ITvDbClient>();
|
||||
builder.RegisterProvider<ProviderTvdb>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
{
|
||||
services.Configure<TvdbOption>(_configuration.GetSection(TvdbOption.Path));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureAspNet(IApplicationBuilder app)
|
||||
{
|
||||
ConfigurationManager.AddTyped<TvdbOption>(TvdbOption.Path);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.TheTvdb.Models;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TvDbSharper;
|
||||
|
62
Kyoo.WebApp/Kyoo.WebApp.csproj
Normal file
62
Kyoo.WebApp/Kyoo.WebApp.csproj
Normal file
@ -0,0 +1,62 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules/**</DefaultItemExcludes>
|
||||
<SpaRoot>Front/</SpaRoot>
|
||||
|
||||
<!-- Set this to true if you enable server-side prerendering -->
|
||||
<BuildServerSideRenderer>false</BuildServerSideRenderer>
|
||||
|
||||
<Company>SDG</Company>
|
||||
<Authors>Zoe Roux</Authors>
|
||||
<RepositoryUrl>https://github.com/AnonymusRaccoon/Kyoo</RepositoryUrl>
|
||||
<LangVersion>default</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="5.0.0-preview.8.20414.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="5.0.8" />
|
||||
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="$(SpaRoot)**" />
|
||||
<Compile Remove="$(SpaRoot)**" />
|
||||
|
||||
<Content Include="$(SpaRoot)static/**" Visible="false">
|
||||
<Link>wwwroot/%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
<None Remove="$(SpaRoot)dist/**; $(SpaRoot)dist-server/**" />
|
||||
<Content Include="$(SpaRoot)dist/**; $(SpaRoot)dist-server/**" Visible="false" Condition="'$(Configuration)' != 'Debug'">
|
||||
<Link>wwwroot/%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build"
|
||||
Condition="'$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') And '$(SkipWebApp)' != 'true'">
|
||||
<Exec Command="node --version" ContinueOnError="true">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
|
||||
</Exec>
|
||||
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
|
||||
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
|
||||
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishRunWebpack" BeforeTargets="Build" Condition="'$(SkipWebApp)' != 'true' And '$(Configuration)' != 'Debug'">
|
||||
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
|
||||
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
|
||||
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build -- --prod" />
|
||||
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --prod" Condition="'$(BuildServerSideRenderer)' == 'true'" />
|
||||
</Target>
|
||||
|
||||
<Target Name="SymlinkViews" AfterTargets="Build" Condition="'$(SkipWebApp)' != 'true' And $(Configuration) == 'Debug'">
|
||||
<Exec WorkingDirectory="$(ProjectDir)../Kyoo" Command="ln -fs '$(ProjectDir)' $(OutDir)" Condition="$(OS) == 'Unix'" />
|
||||
<Exec WorkingDirectory="$(ProjectDir)../Kyoo" Command="mklink /D '$(OutDir)$(ProjectName)' '$(ProjectDir)'" Condition="$(OS) != 'Unix'" />
|
||||
</Target>
|
||||
</Project>
|
110
Kyoo.WebApp/WebAppModule.cs
Normal file
110
Kyoo.WebApp/WebAppModule.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.SpaServices.AngularCli;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Kyoo.WebApp
|
||||
{
|
||||
/// <summary>
|
||||
/// A module to enable the web-app (the front-end of kyoo).
|
||||
/// </summary>
|
||||
public class WebAppModule : IPlugin
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Slug => "webapp";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "WebApp";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "A module to enable the web-app (the front-end of kyoo).";
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Enabled => Directory.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A logger only used to inform the user if the webapp could not be enabled.
|
||||
/// </summary>
|
||||
private readonly ILogger<WebAppModule> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="WebAppModule"/>.
|
||||
/// </summary>
|
||||
/// <param name="logger">A logger only used to inform the user if the webapp could not be enabled.</param>
|
||||
public WebAppModule(ILogger<WebAppModule> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Disabled()
|
||||
{
|
||||
_logger.LogError("The web app files could not be found, it will be disabled. " +
|
||||
"If you cloned the project, you probably forgot to use the --recurse flag");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services)
|
||||
{
|
||||
services.AddSpaStaticFiles(x =>
|
||||
{
|
||||
x.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot");
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IStartupAction> ConfigureSteps => new IStartupAction[]
|
||||
{
|
||||
SA.New<IApplicationBuilder, IWebHostEnvironment>((app, env) =>
|
||||
{
|
||||
if (!env.IsDevelopment())
|
||||
app.UseSpaStaticFiles();
|
||||
}, SA.StaticFiles),
|
||||
SA.New<IApplicationBuilder, IContentTypeProvider>((app, contentTypeProvider) =>
|
||||
{
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
ContentTypeProvider = contentTypeProvider,
|
||||
FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"))
|
||||
});
|
||||
}, SA.StaticFiles),
|
||||
SA.New<IApplicationBuilder>(app =>
|
||||
{
|
||||
app.Use((ctx, next) =>
|
||||
{
|
||||
ctx.Response.Headers.Remove("X-Powered-By");
|
||||
ctx.Response.Headers.Remove("Server");
|
||||
ctx.Response.Headers.Add("Feature-Policy", "autoplay 'self'; fullscreen");
|
||||
ctx.Response.Headers.Add("Content-Security-Policy", "default-src 'self' blob:; script-src 'self' blob: 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self'");
|
||||
ctx.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
|
||||
ctx.Response.Headers.Add("Referrer-Policy", "no-referrer");
|
||||
ctx.Response.Headers.Add("Access-Control-Allow-Origin", "null");
|
||||
ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff");
|
||||
return next();
|
||||
});
|
||||
}, SA.Endpoint - 499),
|
||||
SA.New<IApplicationBuilder, IWebHostEnvironment>((app, env) =>
|
||||
{
|
||||
app.UseSpa(spa =>
|
||||
{
|
||||
spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp", "Front");
|
||||
|
||||
if (env.IsDevelopment())
|
||||
spa.UseAngularCliServer("start");
|
||||
});
|
||||
}, SA.Endpoint - 500)
|
||||
};
|
||||
}
|
||||
}
|
10
Kyoo.sln
10
Kyoo.sln
@ -1,9 +1,9 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kyoo", "Kyoo\Kyoo.csproj", "{0F8275B6-C7DD-42DF-A168-755C81B1C329}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Common", "Kyoo.Common\Kyoo.Common.csproj", "{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Abstractions", "Kyoo.Abstractions\Kyoo.Abstractions.csproj", "{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.CommonAPI", "Kyoo.CommonAPI\Kyoo.CommonAPI.csproj", "{6F91B645-F785-46BB-9C4F-1EFC83E489B6}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Database", "Kyoo.Database\Kyoo.Database.csproj", "{6F91B645-F785-46BB-9C4F-1EFC83E489B6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Postgresql", "Kyoo.Postgresql\Kyoo.Postgresql.csproj", "{3213C96D-0BF3-460B-A8B5-B9977229408A}"
|
||||
EndProject
|
||||
@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.TheMovieDb", "Kyoo.The
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Tests", "tests\Kyoo.Tests\Kyoo.Tests.csproj", "{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.WebApp", "Kyoo.WebApp\Kyoo.WebApp.csproj", "{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -59,5 +61,9 @@ Global
|
||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -5,9 +5,10 @@ using System.Dynamic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
using Kyoo.Api;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
@ -50,6 +51,21 @@ namespace Kyoo.Controllers
|
||||
ConfigurationReference config = ConfigurationReference.CreateUntyped(path);
|
||||
_references.Add(config.Path, config.Type);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Register(string path, Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
ConfigurationReference config = ConfigurationReference.CreateUntyped(path);
|
||||
_references.Add(config.Path, config.Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (ConfigurationReference confRef in ConfigurationReference.CreateReference(path, type))
|
||||
_references.Add(confRef.Path, confRef.Type);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the type of the resource at the given path
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user