mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
WebApp: Moving SPA logics to a new module
This commit is contained in:
parent
16eca6da8e
commit
e35b4f5527
@ -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,11 +17,7 @@
|
||||
<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.Common/Kyoo.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -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.
|
||||
/// </param>
|
||||
public void LoadPlugins(params Type[] 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.
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection to populate</param>
|
||||
public void ConfigureServices(IServiceCollection services);
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Kyoo.Common\Kyoo.Common.csproj" />
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.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.CommonAPI/Kyoo.CommonAPI.csproj" />
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.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.CommonAPI/Kyoo.CommonAPI.csproj" />
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -17,7 +17,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj">
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -16,7 +16,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj">
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit dca10903ff54a8999732695b5c2a0a5c94f85200
|
||||
Subproject commit dc37ce398d6c9cacc7703e21552a116c42b548ed
|
6
Kyoo.sln
6
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
|
||||
|
@ -20,7 +20,7 @@ namespace Kyoo.Controllers
|
||||
/// <summary>
|
||||
/// An extension provider to get content types from files extensions.
|
||||
/// </summary>
|
||||
private FileExtensionContentTypeProvider _provider;
|
||||
private readonly IContentTypeProvider _provider;
|
||||
|
||||
/// <summary>
|
||||
/// 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 <see cref="LocalFileSystem"/> with the specified options.
|
||||
/// </summary>
|
||||
/// <param name="options">The options to use.</param>
|
||||
public LocalFileSystem(IOptionsMonitor<BasicOptions> options)
|
||||
/// <param name="provider">An extension provider to get content types from files extensions.</param>
|
||||
public LocalFileSystem(IOptionsMonitor<BasicOptions> options, IContentTypeProvider provider)
|
||||
{
|
||||
_options = options;
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -44,15 +46,6 @@ namespace Kyoo.Controllers
|
||||
/// <returns>The content type of the file</returns>
|
||||
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}");
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureContainer(ContainerBuilder builder)
|
||||
{
|
||||
foreach (IPlugin plugin in _plugins)
|
||||
plugin.Configure(builder);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
foreach (IPlugin plugin in _plugins)
|
||||
plugin.Configure(services);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A custom <see cref="AssemblyLoadContext"/> to load plugin's dependency if they are on the same folder.
|
||||
/// </summary>
|
||||
|
@ -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
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterModule<AttributedMetadataModule>();
|
||||
|
||||
builder.RegisterComposite<FileSystemComposite, IFileSystem>().InstancePerLifetimeScope();
|
||||
builder.RegisterType<LocalFileSystem>().As<IFileSystem>().SingleInstance();
|
||||
builder.RegisterType<HttpFileSystem>().As<IFileSystem>().SingleInstance();
|
||||
@ -98,13 +100,24 @@ namespace Kyoo
|
||||
|
||||
builder.RegisterType<PassthroughPermissionValidator>().As<IPermissionValidator>()
|
||||
.IfNotRegistered(typeof(IPermissionValidator));
|
||||
|
||||
builder.RegisterType<FileExtensionContentTypeProvider>().As<IContentTypeProvider>().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";
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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<ITaskManager>() as TaskManager);
|
||||
}
|
||||
|
||||
@ -128,17 +148,8 @@ namespace Kyoo
|
||||
app.UseHsts();
|
||||
}
|
||||
}, SA.Before),
|
||||
SA.New<IApplicationBuilder>(app => app.UseResponseCompression(), SA.Routing + 1),
|
||||
SA.New<IApplicationBuilder>(app => app.UseRouting(), SA.Routing),
|
||||
SA.New<IApplicationBuilder>(app =>
|
||||
{
|
||||
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<IApplicationBuilder>(app => app.UseEndpoints(x => x.MapControllers()), SA.Endpoint)
|
||||
};
|
||||
}
|
||||
|
104
Kyoo/Kyoo.csproj
104
Kyoo/Kyoo.csproj
@ -2,15 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
<SpaRoot>../Kyoo.WebApp/</SpaRoot>
|
||||
<TranscoderRoot>../Kyoo.Transcoder/</TranscoderRoot>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules/**</DefaultItemExcludes>
|
||||
|
||||
<!-- Set this to true if you enable server-side prerendering -->
|
||||
<BuildServerSideRenderer>false</BuildServerSideRenderer>
|
||||
|
||||
<Company>SDG</Company>
|
||||
<Authors>Zoe Roux</Authors>
|
||||
@ -33,79 +25,30 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Collections.Immutable" Version="5.0.0" />
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj" />
|
||||
<ProjectReference Include="../Kyoo.CommonAPI/Kyoo.CommonAPI.csproj" />
|
||||
<PackageReference Include="Autofac" Version="6.2.0" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
|
||||
<PackageReference Include="Autofac.Extras.AttributeMetadata" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="5.0.0-preview.8.20414.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="5.0.8" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<ProjectReference Include="..\Kyoo.TheMovieDb\Kyoo.TheMovieDb.csproj" />
|
||||
<ProjectReference Include="..\Kyoo.TheTvdb\Kyoo.TheTvdb.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Kyoo.Postgresql/Kyoo.Postgresql.csproj">
|
||||
<!-- <ExcludeAssets>all</ExcludeAssets>-->
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.Authentication/Kyoo.Authentication.csproj">
|
||||
<!-- <ExcludeAssets>all</ExcludeAssets>-->
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.SqLite/Kyoo.SqLite.csproj">
|
||||
<!-- <ExcludeAssets>all</ExcludeAssets>-->
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj" />
|
||||
<ProjectReference Include="../Kyoo.CommonAPI/Kyoo.CommonAPI.csproj" />
|
||||
<ProjectReference Include="../Kyoo.TheMovieDb/Kyoo.TheMovieDb.csproj" />
|
||||
<ProjectReference Include="../Kyoo.TheTvdb/Kyoo.TheTvdb.csproj" />
|
||||
<ProjectReference Include="../Kyoo.Postgresql/Kyoo.Postgresql.csproj" />
|
||||
<ProjectReference Include="../Kyoo.SqLite/Kyoo.SqLite.csproj" />
|
||||
<ProjectReference Include="../Kyoo.Authentication/Kyoo.Authentication.csproj" />
|
||||
<ProjectReference Include="../Kyoo.WebApp/Kyoo.WebApp.csproj" Condition="'$(SkipWebApp)' != 'true'"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules/**" Visible="false" />
|
||||
<StaticFiles Include="$(SpaRoot)static/**" Visible="false" />
|
||||
<Content Remove="$(SpaRoot)**" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish" Condition="'$(SkipWebApp)' != 'true'">
|
||||
<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'" />
|
||||
|
||||
<ItemGroup>
|
||||
<DistFiles Include="$(SpaRoot)dist/**; $(SpaRoot)dist-server/**" />
|
||||
<DistFiles Include="$(SpaRoot)node_modules/**" Condition="'$(BuildServerSideRenderer)' == 'true'" />
|
||||
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
|
||||
<RelativePath>wwwroot/%(DistFiles.Filename)%(DistFiles.Extension)</RelativePath>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</ResolvedFileToPublish>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="Publish static files" AfterTargets="ComputeFilesToPublish">
|
||||
<ItemGroup>
|
||||
<ResolvedFileToPublish Include="@(StaticFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
|
||||
<RelativePath>wwwroot/%(StaticFiles.RecursiveDir)%(StaticFiles.Filename)%(StaticFiles.Extension)</RelativePath>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</ResolvedFileToPublish>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="Prepare the web app" AfterTargets="Build" Condition="$(Configuration) == 'Debug' and '$(SkipWebApp)' != 'true'">
|
||||
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
|
||||
</Target>
|
||||
|
||||
<Target Name="Prepare static files" AfterTargets="Build" Condition="$(Configuration) == 'Debug'">
|
||||
<Copy SourceFiles="@(StaticFiles)" DestinationFolder="$(OutputPath)/wwwroot/%(RecursiveDir)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="Symlink views to output - Linux" AfterTargets="Build" Condition="$(Configuration) == 'Debug' And $(OS) == 'Unix'">
|
||||
<Exec WorkingDirectory="$(OutputPath)" Command="ln -fs $(ProjectDir)/$(SpaRoot)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="BuildTranscoder" BeforeTargets="BeforeBuild" Condition="'$(SkipTranscoder)' != 'true'">
|
||||
<Exec WorkingDirectory="$(TranscoderRoot)" Condition="'$(IsWindows)' != 'true'" Command="mkdir -p build %26%26 cd build %26%26 cmake .. %26%26 make -j" />
|
||||
<Exec WorkingDirectory="$(TranscoderRoot)" Condition="'$(IsWindows)' == 'true'" Command="(if not exist build mkdir build) %26%26 cd build %26%26 cmake .. -G "NMake Makefiles" %26%26 nmake" />
|
||||
<Exec WorkingDirectory="$(TranscoderRoot)" Condition="'$(IsWindows)' != 'true'"
|
||||
Command="mkdir -p build %26%26 cd build %26%26 cmake .. %26%26 make -j" />
|
||||
<Exec WorkingDirectory="$(TranscoderRoot)" Condition="'$(IsWindows)' == 'true'"
|
||||
Command="(if not exist build mkdir build) %26%26 cd build %26%26 cmake .. -G "NMake Makefiles" %26%26 nmake" />
|
||||
<Copy SourceFiles="$(TranscoderRoot)/build/$(TranscoderBinary)" DestinationFolder="." />
|
||||
</Target>
|
||||
|
||||
@ -115,25 +58,4 @@
|
||||
<Visible>false</Visible>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<!--TODO remove this once plugins are reworked. This is useful because the authentication plugin is loaded manually and not by the plugin manager-->
|
||||
<PropertyGroup>
|
||||
<LoginRoot>../Kyoo.WebLogin/</LoginRoot>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<LoginFiles Include="$(LoginRoot)**" Visible="false" />
|
||||
</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,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
|
||||
/// <param name="services">The service collection to fill.</param>
|
||||
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<KeyValuePair<string, Type>> configTypes = _plugins.GetAllPlugins()
|
||||
.SelectMany(x => x.Configuration)
|
||||
.Where(x => x.Value != null);
|
||||
@ -99,41 +85,26 @@ namespace Kyoo
|
||||
/// <param name="builder">The builder to configure.</param>
|
||||
public void ConfigureContainer(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterModule<AttributedMetadataModule>();
|
||||
builder.RegisterInstance(_plugins).As<IPluginManager>().ExternallyOwned();
|
||||
builder.RegisterTask<PluginInitializer>();
|
||||
_plugins.ConfigureContainer(builder);
|
||||
|
||||
foreach (IPlugin plugin in _plugins.GetAllPlugins())
|
||||
plugin.Configure(builder);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Configure the asp net host.
|
||||
/// </summary>
|
||||
/// <param name="app">The asp net host to configure</param>
|
||||
/// <param name="env">The host environment (is the app in development mode?)</param>
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IConfigurationManager config, ILifetimeScope container)
|
||||
/// <param name="container">An autofac container used to create a new scope to configure asp-net.</param>
|
||||
/// <param name="config">The configuration manager used to register strongly typed config.</param>
|
||||
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<IStartupAction> 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<IServiceProvider>();
|
||||
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");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,7 +64,7 @@ namespace Kyoo.Tests
|
||||
[Fact]
|
||||
public async Task GetByFakeSlugTest()
|
||||
{
|
||||
await Assert.ThrowsAsync<ItemNotFoundException>(() => _repository.Get("non-existent"));
|
||||
await Assert.ThrowsAsync<ItemNotFoundException>(() => _repository.Get("non-existent"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
Loading…
x
Reference in New Issue
Block a user