Build: Removing the need of symlink, cleaning up plugin enable state and fixing main logger

This commit is contained in:
Zoe Roux 2021-09-01 17:29:52 +02:00
parent 87244df497
commit 186a2d15ca
9 changed files with 100 additions and 63 deletions

View File

@ -93,14 +93,5 @@ namespace Kyoo.Abstractions.Controllers
{
// 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
}
}
}

View File

@ -42,6 +42,11 @@ namespace Kyoo.Core
/// </summary>
private readonly string _environment;
/// <summary>
/// The logger used for startup and error messages.
/// </summary>
private ILogger _logger;
/// <summary>
/// Create a new <see cref="Application"/> that will use the specified environment.
@ -76,9 +81,9 @@ namespace Kyoo.Core
_dataDir = _SetupDataDir(args);
LoggerConfiguration config = new();
_ConfigureLogging(config, null);
Log.Logger = config.CreateBootstrapLogger()
.ForContext<Application>();
_ConfigureLogging(config, null, null);
Log.Logger = config.CreateBootstrapLogger();
_logger = Log.Logger.ForContext<Application>();
AppDomain.CurrentDomain.ProcessExit += (_, _) => Log.CloseAndFlush();
AppDomain.CurrentDomain.UnhandledException += (_, ex)
@ -89,7 +94,6 @@ namespace Kyoo.Core
IHost host = _CreateWebHostBuilder(args)
.ConfigureContainer(configure)
.Build();
Log.Logger = host.Services.GetRequiredService<ILogger>().ForContext<Application>();
_tokenSource = new CancellationTokenSource();
await _StartWithHost(host, _tokenSource.Token);
@ -173,13 +177,13 @@ namespace Kyoo.Core
{
try
{
Log.Information("Running as {Name}", Environment.UserName);
Log.Information("Data directory: {DataDirectory}", GetDataDirectory());
_logger.Information("Running as {Name}", Environment.UserName);
_logger.Information("Data directory: {DataDirectory}", GetDataDirectory());
await host.RunAsync(cancellationToken);
}
catch (Exception ex)
{
Log.Fatal(ex, "Unhandled exception");
_logger.Fatal(ex, "Unhandled exception");
}
}
@ -197,7 +201,7 @@ namespace Kyoo.Core
.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory)
.UseEnvironment(_environment)
.ConfigureAppConfiguration(x => _SetupConfig(x, args))
.UseSerilog((host, builder) => _ConfigureLogging(builder, host.Configuration))
.UseSerilog((host, services, builder) => _ConfigureLogging(builder, host.Configuration, services))
.ConfigureServices(x => x.AddRouting())
.ConfigureContainer<ContainerBuilder>(x =>
{
@ -227,13 +231,16 @@ namespace Kyoo.Core
.AddEnvironmentVariables("KYOO_")
.AddCommandLine(args);
}
/// <summary>
/// Configure the logging.
/// </summary>
/// <param name="builder">The logger builder to configure.</param>
/// <param name="configuration">The configuration to read settings from.</param>
private void _ConfigureLogging(LoggerConfiguration builder, [CanBeNull] IConfiguration configuration)
/// <param name="services">The services to read configuration from.</param>
private void _ConfigureLogging(LoggerConfiguration builder,
[CanBeNull] IConfiguration configuration,
[CanBeNull] IServiceProvider services)
{
if (configuration != null)
{
@ -243,10 +250,13 @@ namespace Kyoo.Core
}
catch (Exception ex)
{
Log.Fatal(ex, "Could not read serilog configuration");
_logger.Fatal(ex, "Could not read serilog configuration");
}
}
if (services != null)
builder.ReadFrom.Services(services);
const string template =
"[{@t:HH:mm:ss} {@l:u3} {Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1), 15} "
+ "({@i:0000000000})] {@m}{#if not EndsWith(@m, '\n')}\n{#end}{@x}";

View File

@ -51,14 +51,6 @@ namespace Kyoo.Core.Controllers
_logger = logger;
}
public void SetProvider(IServiceProvider provider)
{
// TODO temporary bullshit to inject services before the configure asp net.
// TODO should rework this when the host will be reworked, as well as the asp net configure.
_provider = provider;
}
/// <inheritdoc />
public T GetPlugin<T>(string name)
{
@ -111,16 +103,13 @@ namespace Kyoo.Core.Controllers
_logger.LogTrace("Loading new plugins...");
string[] pluginsPaths = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories);
IPlugin[] newPlugins = plugins
_plugins.AddRange(plugins
.Concat(pluginsPaths.SelectMany(LoadPlugin))
.Where(x => x.Enabled)
.GroupBy(x => x.Name)
.Select(x => x.First())
.ToArray();
_plugins.AddRange(newPlugins.Where(x => x.Enabled));
foreach (IPlugin plugin in newPlugins.Where(x => !x.Enabled))
plugin.Disabled();
);
if (!_plugins.Any())
_logger.LogInformation("No plugin enabled");
else

View File

@ -74,9 +74,9 @@
},
"tvdb": {
"apiKey": "REDACTED"
"apiKey": ""
},
"the-moviedb": {
"apiKey": "REDACTED"
"apiKey": ""
}
}

View File

@ -4,6 +4,8 @@ using Autofac;
using Kyoo.Abstractions;
using Kyoo.Abstractions.Controllers;
using Kyoo.TheMovieDb.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Kyoo.TheMovieDb
{
@ -16,17 +18,38 @@ namespace Kyoo.TheMovieDb
public string Slug => "the-moviedb";
/// <inheritdoc />
public string Name => "TheMovieDb Provider";
public string Name => "TheMovieDb";
/// <inheritdoc />
public string Description => "A metadata provider for TheMovieDB.";
/// <inheritdoc />
public bool Enabled => !string.IsNullOrEmpty(_configuration.GetValue<string>("the-moviedb:apikey"));
/// <inheritdoc />
public Dictionary<string, Type> Configuration => new()
{
{ TheMovieDbOptions.Path, typeof(TheMovieDbOptions) }
};
/// <summary>
/// The configuration used to check if the api key is present or not.
/// </summary>
private readonly IConfiguration _configuration;
/// <summary>
/// Create a new <see cref="PluginTmdb"/>.
/// </summary>
/// <param name="configuration">The configuration used to check if the api key is present or not.</param>
/// <param name="logger">The logger used to warn when the api key is not present.</param>
public PluginTmdb(IConfiguration configuration, ILogger<PluginTmdb> logger)
{
_configuration = configuration;
if (!Enabled)
logger.LogWarning("No API key configured for TheMovieDB provider. " +
"To enable TheMovieDB, specify one in the setting the-moviedb:APIKEY ");
}
/// <inheritdoc />
public void Configure(ContainerBuilder builder)
{

View File

@ -10,6 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
<PackageReference Include="TvDbSharper" Version="3.2.2" />

View File

@ -4,6 +4,8 @@ using Autofac;
using Kyoo.Abstractions;
using Kyoo.Abstractions.Controllers;
using Kyoo.TheTvdb.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using TvDbSharper;
namespace Kyoo.TheTvdb
@ -15,19 +17,40 @@ namespace Kyoo.TheTvdb
{
/// <inheritdoc />
public string Slug => "the-tvdb";
/// <inheritdoc />
public string Name => "The TVDB Provider";
public string Name => "TVDB";
/// <inheritdoc />
public string Description => "A metadata provider for The TVDB.";
/// <inheritdoc />
public bool Enabled => !string.IsNullOrEmpty(_configuration.GetValue<string>("tvdb:apikey"));
/// <inheritdoc />
public Dictionary<string, Type> Configuration => new()
{
{ TvdbOption.Path, typeof(TvdbOption) }
};
/// <summary>
/// The configuration used to check if the api key is present or not.
/// </summary>
private readonly IConfiguration _configuration;
/// <summary>
/// Create a new <see cref="PluginTvdb"/>.
/// </summary>
/// <param name="configuration">The configuration used to check if the api key is present or not.</param>
/// <param name="logger">The logger used to warn when the api key is not present.</param>
public PluginTvdb(IConfiguration configuration, ILogger<PluginTvdb> logger)
{
_configuration = configuration;
if (!Enabled)
logger.LogWarning("No API key configured for TVDB provider. " +
"To enable TVDB, specify one in the setting TVDB:APIKEY ");
}
/// <inheritdoc />
public void Configure(ContainerBuilder builder)
{

View File

@ -63,11 +63,6 @@
</ItemGroup>
</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="if not exist %22$(OutDir)$(ProjectName)%22 mklink /D %22$(OutDir)$(ProjectName)%22 %22$(ProjectDir)%22" Condition="$(OS) != 'Unix'" />
</Target>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using Kyoo.Abstractions.Controllers;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@ -33,28 +34,17 @@ namespace Kyoo.WebApp
/// <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;
if (!Enabled)
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 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)
{
@ -99,12 +89,27 @@ namespace Kyoo.WebApp
{
app.UseSpa(spa =>
{
spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp", "Front");
spa.Options.SourcePath = _GetSpaSourcePath();
if (env.IsDevelopment())
spa.UseAngularCliServer("start");
});
}, SA.Endpoint - 500)
};
/// <summary>
/// Get the root directory of the web app
/// </summary>
/// <returns>The path of the source code of the web app or null if the directory has been deleted.</returns>
private static string _GetSpaSourcePath()
{
string GetSelfPath([CallerFilePath] string path = null)
{
return path;
}
string path = Path.Join(Path.GetDirectoryName(GetSelfPath()), "Front");
return Directory.Exists(path) ? path : null;
}
}
}