diff --git a/Kyoo.Authentication/Kyoo.Authentication.csproj b/Kyoo.Authentication/Kyoo.Authentication.csproj
index 2cde6c7e..47113130 100644
--- a/Kyoo.Authentication/Kyoo.Authentication.csproj
+++ b/Kyoo.Authentication/Kyoo.Authentication.csproj
@@ -2,18 +2,12 @@
net5.0
- ../Kyoo/bin/$(Configuration)/$(TargetFramework)/plugins/authentication
- false
- false
- false
- false
- true
-
+ ../Kyoo.WebLogin/
+
SDG
Zoe Roux
https://github.com/AnonymusRaccoon/Kyoo
default
- ../Kyoo.WebLogin/
@@ -23,11 +17,7 @@
-
- all
- false
- runtime
-
+
diff --git a/Kyoo.Common/Controllers/IPluginManager.cs b/Kyoo.Common/Controllers/IPluginManager.cs
index 294aabb2..7bf64baf 100644
--- a/Kyoo.Common/Controllers/IPluginManager.cs
+++ b/Kyoo.Common/Controllers/IPluginManager.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
-using Autofac;
using Kyoo.Models.Exceptions;
-using Microsoft.Extensions.DependencyInjection;
namespace Kyoo.Controllers
{
@@ -50,17 +48,5 @@ namespace Kyoo.Controllers
/// You should not try to put plugins from the plugins directory here as they will get automatically loaded.
///
public void LoadPlugins(params Type[] plugins);
-
- ///
- /// Configure container adding or removing services as the plugins wants.
- ///
- /// The container to populate
- void ConfigureContainer(ContainerBuilder builder);
-
- ///
- /// Configure services via the microsoft way. This allow libraries to add their services.
- ///
- /// The service collection to populate
- public void ConfigureServices(IServiceCollection services);
}
}
\ No newline at end of file
diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs
index c5fe7a7c..f221bbcf 100644
--- a/Kyoo.Common/Controllers/IRepository.cs
+++ b/Kyoo.Common/Controllers/IRepository.cs
@@ -309,20 +309,20 @@ namespace Kyoo.Controllers
Task Get(string showSlug, int seasonNumber);
///
- /// Get a season from it's showID and it's seasonNumber or null if it is not found.
- ///
- /// The id of the show
- /// The season's number
- /// The season found
- Task GetOrDefault(int showID, int seasonNumber);
-
- ///
- /// Get a season from it's show slug and it's seasonNumber or null if it is not found.
- ///
- /// The slug of the show
- /// The season's number
- /// The season found
- Task GetOrDefault(string showSlug, int seasonNumber);
+ /// Get a season from it's showID and it's seasonNumber or null if it is not found.
+ ///
+ /// The id of the show
+ /// The season's number
+ /// The season found
+ Task GetOrDefault(int showID, int seasonNumber);
+
+ ///
+ /// Get a season from it's show slug and it's seasonNumber or null if it is not found.
+ ///
+ /// The slug of the show
+ /// The season's number
+ /// The season found
+ Task GetOrDefault(string showSlug, int seasonNumber);
}
///
diff --git a/Kyoo.Common/Models/Resources/Track.cs b/Kyoo.Common/Models/Resources/Track.cs
index d82cdbe1..d4454f5f 100644
--- a/Kyoo.Common/Models/Resources/Track.cs
+++ b/Kyoo.Common/Models/Resources/Track.cs
@@ -60,9 +60,9 @@ namespace Kyoo.Models
}
///
- /// The slug of the episode that contain this track. If this is not set, this track is ill-formed.
- ///
- [SerializeIgnore] public string EpisodeSlug { private get; set; }
+ /// The slug of the episode that contain this track. If this is not set, this track is ill-formed.
+ ///
+ [SerializeIgnore] public string EpisodeSlug { private get; set; }
///
/// The title of the stream.
diff --git a/Kyoo.Common/Utility/TaskUtils.cs b/Kyoo.Common/Utility/TaskUtils.cs
index 78332cc9..a0d04b03 100644
--- a/Kyoo.Common/Utility/TaskUtils.cs
+++ b/Kyoo.Common/Utility/TaskUtils.cs
@@ -21,17 +21,17 @@ namespace Kyoo
///
/// The source task has been canceled.
public static Task Then(this Task task, Action then)
- {
- return task.ContinueWith(x =>
- {
- if (x.IsFaulted)
- x.Exception!.InnerException!.ReThrow();
- if (x.IsCanceled)
- throw new TaskCanceledException();
- then(x.Result);
- return x.Result;
- }, TaskContinuationOptions.ExecuteSynchronously);
- }
+ {
+ return task.ContinueWith(x =>
+ {
+ if (x.IsFaulted)
+ x.Exception!.InnerException!.ReThrow();
+ if (x.IsCanceled)
+ throw new TaskCanceledException();
+ then(x.Result);
+ return x.Result;
+ }, TaskContinuationOptions.ExecuteSynchronously);
+ }
///
/// Map the result of a task to another result.
@@ -42,28 +42,28 @@ namespace Kyoo
/// The resulting task after the mapping method
/// A task wrapping the initial task and mapping the initial result.
/// The source task has been canceled.
- public static Task Map(this Task task, Func map)
- {
- return task.ContinueWith(x =>
- {
- if (x.IsFaulted)
- x.Exception!.InnerException!.ReThrow();
- if (x.IsCanceled)
- throw new TaskCanceledException();
- return map(x.Result);
- }, TaskContinuationOptions.ExecuteSynchronously);
- }
+ public static Task Map(this Task task, Func map)
+ {
+ return task.ContinueWith(x =>
+ {
+ if (x.IsFaulted)
+ x.Exception!.InnerException!.ReThrow();
+ if (x.IsCanceled)
+ throw new TaskCanceledException();
+ return map(x.Result);
+ }, TaskContinuationOptions.ExecuteSynchronously);
+ }
- ///
- /// A method to return the a default value from a task if the initial task is null.
- ///
- /// The initial task
- /// The type that the task will return
- /// A non-null task.
- [NotNull]
- public static Task DefaultIfNull([CanBeNull] Task value)
- {
- return value ?? Task.FromResult(default);
- }
+ ///
+ /// A method to return the a default value from a task if the initial task is null.
+ ///
+ /// The initial task
+ /// The type that the task will return
+ /// A non-null task.
+ [NotNull]
+ public static Task DefaultIfNull([CanBeNull] Task value)
+ {
+ return value ?? Task.FromResult(default);
+ }
}
}
\ No newline at end of file
diff --git a/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj b/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj
index 451c387d..0eca28f1 100644
--- a/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj
+++ b/Kyoo.CommonAPI/Kyoo.CommonAPI.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/Kyoo.Postgresql/Kyoo.Postgresql.csproj b/Kyoo.Postgresql/Kyoo.Postgresql.csproj
index a53ba3b7..a1bcaa3f 100644
--- a/Kyoo.Postgresql/Kyoo.Postgresql.csproj
+++ b/Kyoo.Postgresql/Kyoo.Postgresql.csproj
@@ -18,9 +18,7 @@
-
-
-
-
+
+
diff --git a/Kyoo.SqLite/Kyoo.SqLite.csproj b/Kyoo.SqLite/Kyoo.SqLite.csproj
index cdedc4ca..e61fd702 100644
--- a/Kyoo.SqLite/Kyoo.SqLite.csproj
+++ b/Kyoo.SqLite/Kyoo.SqLite.csproj
@@ -18,9 +18,7 @@
-
-
-
-
+
+
diff --git a/Kyoo.TheMovieDb/Kyoo.TheMovieDb.csproj b/Kyoo.TheMovieDb/Kyoo.TheMovieDb.csproj
index 72b8bdec..b423b046 100644
--- a/Kyoo.TheMovieDb/Kyoo.TheMovieDb.csproj
+++ b/Kyoo.TheMovieDb/Kyoo.TheMovieDb.csproj
@@ -17,7 +17,6 @@
-
-
+
diff --git a/Kyoo.TheTvdb/Kyoo.TheTvdb.csproj b/Kyoo.TheTvdb/Kyoo.TheTvdb.csproj
index 9553bef5..11392cf7 100644
--- a/Kyoo.TheTvdb/Kyoo.TheTvdb.csproj
+++ b/Kyoo.TheTvdb/Kyoo.TheTvdb.csproj
@@ -16,7 +16,6 @@
-
-
+
diff --git a/Kyoo.WebApp b/Kyoo.WebApp
index dca10903..dc37ce39 160000
--- a/Kyoo.WebApp
+++ b/Kyoo.WebApp
@@ -1 +1 @@
-Subproject commit dca10903ff54a8999732695b5c2a0a5c94f85200
+Subproject commit dc37ce398d6c9cacc7703e21552a116c42b548ed
diff --git a/Kyoo.sln b/Kyoo.sln
index fdb1f643..599922a3 100644
--- a/Kyoo.sln
+++ b/Kyoo.sln
@@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.TheMovieDb", "Kyoo.The
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Tests", "tests\Kyoo.Tests\Kyoo.Tests.csproj", "{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.WebApp", "Kyoo.WebApp\Kyoo.WebApp.csproj", "{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -59,5 +61,9 @@ Global
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/Kyoo/Controllers/FileSystems/LocalFileSystem.cs b/Kyoo/Controllers/FileSystems/LocalFileSystem.cs
index 87575e0a..d5a19a68 100644
--- a/Kyoo/Controllers/FileSystems/LocalFileSystem.cs
+++ b/Kyoo/Controllers/FileSystems/LocalFileSystem.cs
@@ -20,7 +20,7 @@ namespace Kyoo.Controllers
///
/// An extension provider to get content types from files extensions.
///
- private FileExtensionContentTypeProvider _provider;
+ private readonly IContentTypeProvider _provider;
///
/// Options to check if the metadata should be kept in the show directory or in a kyoo's directory.
@@ -31,9 +31,11 @@ namespace Kyoo.Controllers
/// Create a new with the specified options.
///
/// The options to use.
- public LocalFileSystem(IOptionsMonitor options)
+ /// An extension provider to get content types from files extensions.
+ public LocalFileSystem(IOptionsMonitor options, IContentTypeProvider provider)
{
_options = options;
+ _provider = provider;
}
///
@@ -44,15 +46,6 @@ namespace Kyoo.Controllers
/// The content type of the file
private string _GetContentType(string path)
{
- if (_provider == null)
- {
- _provider = new FileExtensionContentTypeProvider();
- _provider.Mappings[".mkv"] = "video/x-matroska";
- _provider.Mappings[".ass"] = "text/x-ssa";
- _provider.Mappings[".srt"] = "application/x-subrip";
- _provider.Mappings[".m3u8"] = "application/x-mpegurl";
- }
-
if (_provider.TryGetContentType(path, out string contentType))
return contentType;
throw new NotImplementedException($"Can't get the content type of the file at: {path}");
diff --git a/Kyoo/Controllers/PluginManager.cs b/Kyoo/Controllers/PluginManager.cs
index 04dacccc..2727124c 100644
--- a/Kyoo/Controllers/PluginManager.cs
+++ b/Kyoo/Controllers/PluginManager.cs
@@ -4,7 +4,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
-using Autofac;
using Kyoo.Models.Options;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -133,20 +132,6 @@ namespace Kyoo.Controllers
);
}
- ///
- public void ConfigureContainer(ContainerBuilder builder)
- {
- foreach (IPlugin plugin in _plugins)
- plugin.Configure(builder);
- }
-
- ///
- public void ConfigureServices(IServiceCollection services)
- {
- foreach (IPlugin plugin in _plugins)
- plugin.Configure(services);
- }
-
///
/// A custom to load plugin's dependency if they are on the same folder.
///
diff --git a/Kyoo/CoreModule.cs b/Kyoo/CoreModule.cs
index 6c049aee..0ac9485a 100644
--- a/Kyoo/CoreModule.cs
+++ b/Kyoo/CoreModule.cs
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
-using System.IO;
using Autofac;
using Autofac.Core;
using Autofac.Core.Registration;
+using Autofac.Extras.AttributeMetadata;
using Kyoo.Controllers;
using Kyoo.Models.Options;
using Kyoo.Models.Permissions;
@@ -12,8 +12,8 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
+using IMetadataProvider = Kyoo.Controllers.IMetadataProvider;
namespace Kyoo
{
@@ -60,6 +60,8 @@ namespace Kyoo
///
public void Configure(ContainerBuilder builder)
{
+ builder.RegisterModule();
+
builder.RegisterComposite().InstancePerLifetimeScope();
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
@@ -98,13 +100,24 @@ namespace Kyoo
builder.RegisterType().As()
.IfNotRegistered(typeof(IPermissionValidator));
+
+ builder.RegisterType().As().SingleInstance()
+ .OnActivating(x =>
+ {
+ x.Instance.Mappings[".data"] = "application/octet-stream";
+ x.Instance.Mappings[".mkv"] = "video/x-matroska";
+ x.Instance.Mappings[".ass"] = "text/x-ssa";
+ x.Instance.Mappings[".srt"] = "application/x-subrip";
+ x.Instance.Mappings[".m3u8"] = "application/x-mpegurl";
+ });
}
///
- public void Configure(IServiceCollection services)
+ public void Configure(IServiceCollection services)
{
string publicUrl = _configuration.GetPublicUrl();
+ services.AddMvc().AddControllersAsServices();
services.AddControllers()
.AddNewtonsoftJson(x =>
{
@@ -112,6 +125,13 @@ namespace Kyoo
x.SerializerSettings.Converters.Add(new PeopleRoleConverter());
});
+ services.AddResponseCompression(x =>
+ {
+ x.EnableForHttps = true;
+ });
+
+ services.AddHttpClient();
+
services.AddHostedService(x => x.GetService() as TaskManager);
}
@@ -128,17 +148,8 @@ namespace Kyoo
app.UseHsts();
}
}, SA.Before),
+ SA.New(app => app.UseResponseCompression(), SA.Routing + 1),
SA.New(app => app.UseRouting(), SA.Routing),
- SA.New(app =>
- {
- FileExtensionContentTypeProvider contentTypeProvider = new();
- contentTypeProvider.Mappings[".data"] = "application/octet-stream";
- app.UseStaticFiles(new StaticFileOptions
- {
- ContentTypeProvider = contentTypeProvider,
- FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"))
- });
- }, SA.StaticFiles),
SA.New(app => app.UseEndpoints(x => x.MapControllers()), SA.Endpoint)
};
}
diff --git a/Kyoo/Kyoo.csproj b/Kyoo/Kyoo.csproj
index 0185da01..37200c34 100644
--- a/Kyoo/Kyoo.csproj
+++ b/Kyoo/Kyoo.csproj
@@ -2,15 +2,7 @@
net5.0
- true
- Latest
- false
- ../Kyoo.WebApp/
../Kyoo.Transcoder/
- $(DefaultItemExcludes);$(SpaRoot)node_modules/**
-
-
- false
SDG
Zoe Roux
@@ -33,79 +25,30 @@
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- wwwroot/%(DistFiles.Filename)%(DistFiles.Extension)
- PreserveNewest
- true
-
-
-
-
-
-
-
- wwwroot/%(StaticFiles.RecursiveDir)%(StaticFiles.Filename)%(StaticFiles.Extension)
- PreserveNewest
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -115,25 +58,4 @@
false
-
-
-
-
- ../Kyoo.WebLogin/
-
-
-
-
-
-
-
- login/%(LoginFiles.RecursiveDir)%(LoginFiles.Filename)%(LoginFiles.Extension)
- PreserveNewest
- true
-
-
-
-
-
-
diff --git a/Kyoo/PluginsStartup.cs b/Kyoo/PluginsStartup.cs
index 189ebb92..22ba3e18 100644
--- a/Kyoo/PluginsStartup.cs
+++ b/Kyoo/PluginsStartup.cs
@@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using Autofac;
-using Autofac.Extras.AttributeMetadata;
using Kyoo.Authentication;
using Kyoo.Controllers;
using Kyoo.Models.Options;
@@ -14,7 +12,6 @@ using Kyoo.TheMovieDb;
using Kyoo.TheTvdb;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -65,20 +62,9 @@ namespace Kyoo
/// The service collection to fill.
public void ConfigureServices(IServiceCollection services)
{
- services.AddMvc().AddControllersAsServices();
+ foreach (IPlugin plugin in _plugins.GetAllPlugins())
+ plugin.Configure(services);
- services.AddSpaStaticFiles(x =>
- {
- x.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot");
- });
- services.AddResponseCompression(x =>
- {
- x.EnableForHttps = true;
- });
-
- services.AddHttpClient();
-
- _plugins.ConfigureServices(services);
IEnumerable> configTypes = _plugins.GetAllPlugins()
.SelectMany(x => x.Configuration)
.Where(x => x.Value != null);
@@ -99,41 +85,26 @@ namespace Kyoo
/// The builder to configure.
public void ConfigureContainer(ContainerBuilder builder)
{
- builder.RegisterModule();
builder.RegisterInstance(_plugins).As().ExternallyOwned();
builder.RegisterTask();
- _plugins.ConfigureContainer(builder);
+
+ foreach (IPlugin plugin in _plugins.GetAllPlugins())
+ plugin.Configure(builder);
}
-
+
///
/// Configure the asp net host.
///
/// The asp net host to configure
- /// The host environment (is the app in development mode?)
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IConfigurationManager config, ILifetimeScope container)
+ /// An autofac container used to create a new scope to configure asp-net.
+ /// The configuration manager used to register strongly typed config.
+ public void Configure(IApplicationBuilder app, ILifetimeScope container, IConfigurationManager config)
{
- if (!env.IsDevelopment())
- app.UseSpaStaticFiles();
-
- app.Use((ctx, next) =>
- {
- ctx.Response.Headers.Remove("X-Powered-By");
- ctx.Response.Headers.Remove("Server");
- ctx.Response.Headers.Add("Feature-Policy", "autoplay 'self'; fullscreen");
- ctx.Response.Headers.Add("Content-Security-Policy", "default-src 'self' blob:; script-src 'self' blob: 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self' https://www.youtube.com");
- ctx.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
- ctx.Response.Headers.Add("Referrer-Policy", "no-referrer");
- ctx.Response.Headers.Add("Access-Control-Allow-Origin", "null");
- ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff");
- return next();
- });
- app.UseResponseCompression();
-
IEnumerable steps = _plugins.GetAllPlugins()
.SelectMany(x => x.ConfigureSteps)
.OrderByDescending(x => x.Priority);
- using ILifetimeScope scope = container.BeginLifetimeScope(x =>
+ using ILifetimeScope scope = container.BeginLifetimeScope(x =>
x.RegisterInstance(app).SingleInstance().ExternallyOwned());
IServiceProvider provider = scope.Resolve();
foreach (IStartupAction step in steps)
@@ -148,14 +119,6 @@ namespace Kyoo
);
foreach ((string path, Type type) in pluginConfig)
config.Register(path, type);
-
- app.UseSpa(spa =>
- {
- spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp");
-
- if (env.IsDevelopment())
- spa.UseAngularCliServer("start");
- });
}
diff --git a/tests/Kyoo.Tests/Database/RepositoryTests.cs b/tests/Kyoo.Tests/Database/RepositoryTests.cs
index 4cc72b4c..2c984568 100644
--- a/tests/Kyoo.Tests/Database/RepositoryTests.cs
+++ b/tests/Kyoo.Tests/Database/RepositoryTests.cs
@@ -64,7 +64,7 @@ namespace Kyoo.Tests
[Fact]
public async Task GetByFakeSlugTest()
{
- await Assert.ThrowsAsync(() => _repository.Get("non-existent"));
+ await Assert.ThrowsAsync(() => _repository.Get("non-existent"));
}
[Fact]