[Blazor] Use settings from appsettings.json to configure folders and log levels.

This commit is contained in:
2025-07-27 18:19:01 +01:00
parent b62f495824
commit ab804239bb
9 changed files with 130 additions and 102 deletions

View File

@@ -34,6 +34,7 @@
<PackageVersion Include="Serilog.AspNetCore" Version="9.0.0"/> <PackageVersion Include="Serilog.AspNetCore" Version="9.0.0"/>
<PackageVersion Include="Serilog.Extensions.Logging" Version="9.0.2"/> <PackageVersion Include="Serilog.Extensions.Logging" Version="9.0.2"/>
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0"/> <PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0"/>
<PackageVersion Include="Serilog.Sinks.File" Version="7.0.0"/>
<PackageVersion Include="SharpCompress" Version="0.39.0"/> <PackageVersion Include="SharpCompress" Version="0.39.0"/>
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31"/> <PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31"/>
<PackageVersion Include="System.Security.Principal.Windows" Version="5.0.0"/> <PackageVersion Include="System.Security.Principal.Windows" Version="5.0.0"/>

View File

@@ -1,8 +1,8 @@
@using Microsoft.Extensions.Localization
@using RomRepoMgr.Blazor.Resources @using RomRepoMgr.Blazor.Resources
@implements IDialogContentComponent @implements IDialogContentComponent
@inject ILogger<ImportDats> Logger @inject ILogger<ImportDats> Logger
@inject IStringLocalizer<Localization> Localizer @inject IStringLocalizer<Localization> Localizer
@inject IConfiguration Configuration
<FluentDialog Width="800px" Height="400px" Title="Import DATs" Modal="true" TrapFocus="true"> <FluentDialog Width="800px" Height="400px" Title="Import DATs" Modal="true" TrapFocus="true">
<FluentDialogBody> <FluentDialogBody>

View File

@@ -1,6 +1,5 @@
using System.Diagnostics; using System.Diagnostics;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.FluentUI.AspNetCore.Components;
using RomRepoMgr.Core.EventArgs; using RomRepoMgr.Core.EventArgs;
using RomRepoMgr.Core.Workers; using RomRepoMgr.Core.Workers;
using Serilog; using Serilog;
@@ -37,7 +36,7 @@ public partial class ImportDats : ComponentBase
{ {
base.OnInitialized(); base.OnInitialized();
path = Path.Combine(Environment.CurrentDirectory, Consts.IncomingDatFolder); path = Configuration["DataFolders:ImportDats"] ?? "incoming-dats";
StatusMessage = ""; StatusMessage = "";
StatusMessage2 = ""; StatusMessage2 = "";
IsBusy = false; IsBusy = false;

View File

@@ -1,10 +1,10 @@
@using Microsoft.Extensions.Localization
@using RomRepoMgr.Blazor.Resources @using RomRepoMgr.Blazor.Resources
@using RomRepoMgr.Database @using RomRepoMgr.Database
@implements IDialogContentComponent @implements IDialogContentComponent
@inject ILogger<ImportRoms> Logger @inject ILogger<ImportRoms> Logger
@inject Context _ctx @inject Context _ctx
@inject IStringLocalizer<Localization> Localizer @inject IStringLocalizer<Localization> Localizer
@inject IConfiguration Configuration
<FluentDialog Width="1600px" Height="800px" Title="Import DATs" Modal="true" TrapFocus="true"> <FluentDialog Width="1600px" Height="800px" Title="Import DATs" Modal="true" TrapFocus="true">
<FluentDialogBody> <FluentDialogBody>

View File

@@ -1,7 +1,6 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics; using System.Diagnostics;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.FluentUI.AspNetCore.Components;
using RomRepoMgr.Core.EventArgs; using RomRepoMgr.Core.EventArgs;
using RomRepoMgr.Core.Workers; using RomRepoMgr.Core.Workers;
using RomRepoMgr.Database.Models; using RomRepoMgr.Database.Models;
@@ -45,7 +44,7 @@ public partial class ImportRoms : ComponentBase
protected override void OnInitialized() protected override void OnInitialized()
{ {
base.OnInitialized(); base.OnInitialized();
FolderPath = Path.Combine(Environment.CurrentDirectory, Consts.IncomingRomsFolder); FolderPath = Configuration["DataFolders:ImportRoms"] ?? "incoming";
IsBusy = false; IsBusy = false;
NotYetStarted = true; NotYetStarted = true;
RemoveFilesChecked = false; RemoveFilesChecked = false;

View File

@@ -1,11 +0,0 @@
namespace RomRepoMgr.Blazor;
public class Consts
{
public const string DbFolder = "db";
public const string DatFolder = "dats";
public const string IncomingDatFolder = "incoming-dats";
public const string RepositoryFolder = "repo";
public const string IncomingRomsFolder = "incoming";
public const string TemporaryFolder = "tmp";
}

View File

@@ -1,12 +1,40 @@
using System.Diagnostics; using System.Diagnostics;
using Microsoft.EntityFrameworkCore;
using Microsoft.FluentUI.AspNetCore.Components;
using RomRepoMgr.Blazor;
using RomRepoMgr.Blazor.Components; using RomRepoMgr.Blazor.Components;
using RomRepoMgr.Database; using RomRepoMgr.Database;
using RomRepoMgr.Settings; using RomRepoMgr.Settings;
using Serilog; using Serilog;
using Serilog.Events;
// Start the application
Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().Enrich.FromLogContext().CreateLogger();
Log.Information("Welcome to ROM Repository Manager!");
Log.Information("Copyright © 2020-2025 Natalia Portillo");
// Configuration and settings
// We need the builder now
Log.Debug("Creating the builder...");
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
// Access the full configuration
Log.Debug("Creating the configuration reader...");
ConfigurationManager config = builder.Configuration;
string logFile = config["LogFile"] ?? "logs/rom-repo-mgr.log";
string defaultLogLevel = config["Logging:LogLevel:Default"] ?? "Information";
// Parse to LogEventLevel
if(!Enum.TryParse(defaultLogLevel, true, out LogEventLevel level))
{
// Fallback if parsing fails
#if DEBUG
level = LogEventLevel.Debug;
#else
level = LogEventLevel.Information;
#endif
}
// Now create a logger with the specified log level and log file
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
#if DEBUG #if DEBUG
.MinimumLevel.Debug() .MinimumLevel.Debug()
@@ -14,23 +42,37 @@ Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information() .MinimumLevel.Information()
#endif #endif
.WriteTo.Console() .WriteTo.Console()
.WriteTo.File(logFile, rollingInterval: RollingInterval.Day, fileSizeLimitBytes: 10 * 1048576)
.Enrich.FromLogContext() .Enrich.FromLogContext()
.CreateLogger(); .CreateLogger();
Log.Information("Welcome to ROM Repository Manager!"); // Read the rest of the configuration and settings
Log.Information("Copyright © 2020-2025 Natalia Portillo"); Log.Debug("Reading configuration settings...");
string repoFolder = config["DataFolders:Repository"] ?? "repo";
string importRoms = config["DataFolders:ImportRoms"] ?? "incoming";
string importDats = config["DataFolders:ImportDats"] ?? "incoming-dats";
string exportRoms = config["DataFolders:ExportRoms"] ?? "export";
string exportDats = config["DataFolders:ExportDats"] ?? "export-dats";
string databaseFolder = config["DataFolders:Database"] ?? "db";
string temporaryFolder = config["DataFolders:Temporary"] ?? "tmp";
string compressionTypeString = config["CompressionType"] ?? "Zstd";
// Parse the compression type
if(!Enum.TryParse(compressionTypeString, true, out CompressionType compressionType))
{
// Fallback if parsing fails
compressionType = CompressionType.Zstd;
}
// Ensure the folders exist // Ensure the folders exist
Log.Information("Ensuring folders exist..."); Log.Information("Ensuring folders exist...");
string[] folders = string[] folders = [repoFolder, importRoms, importDats, databaseFolder, exportRoms, exportDats, temporaryFolder];
[
Consts.DbFolder, Consts.DatFolder, Consts.IncomingDatFolder, Consts.RepositoryFolder, Consts.IncomingRomsFolder
];
foreach(string folder in folders) foreach(string folder in folders)
{ {
if(!Directory.Exists(folder)) // Check File.Exists for symlinks or junctions
if(!Directory.Exists(folder) && !File.Exists(folder))
{ {
Log.Debug("Creating folder: {Folder}", folder); Log.Debug("Creating folder: {Folder}", folder);
Directory.CreateDirectory(folder); Directory.CreateDirectory(folder);
@@ -39,19 +81,8 @@ foreach(string folder in folders)
Log.Debug("Folder already exists: {Folder}", folder); Log.Debug("Folder already exists: {Folder}", folder);
} }
// Ensure the temporary folder exists but it can also be a symlink // ✅ Plug Serilog into the host
if(!Directory.Exists(Consts.TemporaryFolder) && !File.Exists(Consts.TemporaryFolder)) builder.Host.UseSerilog();
{
Log.Debug("Creating folder: {TemporaryFolder}", Consts.TemporaryFolder);
Directory.CreateDirectory(Consts.TemporaryFolder);
}
else
Log.Debug("Folder already exists: {TemporaryFolder}", Consts.TemporaryFolder);
Log.Debug("Creating the builder...");
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog(); // ✅ Plug Serilog into the host
// Add services to the container. // Add services to the container.
builder.Services.AddRazorComponents().AddInteractiveServerComponents(); builder.Services.AddRazorComponents().AddInteractiveServerComponents();
@@ -64,7 +95,7 @@ Log.Debug("Creating database context...");
builder.Services.AddDbContextFactory<Context>(options => builder.Services.AddDbContextFactory<Context>(options =>
{ {
options.UseSqlite($"Data Source={Consts.DbFolder}/database.db"); options.UseSqlite($"Data Source={databaseFolder}/database.db");
#if DEBUG #if DEBUG
options.EnableSensitiveDataLogging(); options.EnableSensitiveDataLogging();
options.LogTo(Log.Debug); options.LogTo(Log.Debug);
@@ -79,11 +110,11 @@ Log.Debug("Setting the settings...");
Settings.Current = new SetSettings Settings.Current = new SetSettings
{ {
DatabasePath = Path.Combine(Environment.CurrentDirectory, Consts.DbFolder, "database.db"), DatabasePath = Path.Combine(Environment.CurrentDirectory, databaseFolder, "database.db"),
TemporaryFolder = Path.Combine(Environment.CurrentDirectory, Consts.TemporaryFolder), TemporaryFolder = Path.Combine(Environment.CurrentDirectory, temporaryFolder),
RepositoryPath = Path.Combine(Environment.CurrentDirectory, Consts.RepositoryFolder), RepositoryPath = Path.Combine(Environment.CurrentDirectory, repoFolder),
UseInternalDecompressor = true, UseInternalDecompressor = true,
Compression = CompressionType.Zstd // Todo: Read from configuration Compression = compressionType
}; };
Log.Debug("Building the application..."); Log.Debug("Building the application...");
@@ -104,10 +135,7 @@ app.MapStaticAssets();
app.MapRazorComponents<App>().AddInteractiveServerRenderMode(); app.MapRazorComponents<App>().AddInteractiveServerRenderMode();
// Localization // Localization
string[] supportedCultures = string[] supportedCultures = ["en", "es"];
[
"en", "es"
];
RequestLocalizationOptions localizationOptions = new RequestLocalizationOptions().SetDefaultCulture("en") RequestLocalizationOptions localizationOptions = new RequestLocalizationOptions().SetDefaultCulture("en")
.AddSupportedCultures(supportedCultures) .AddSupportedCultures(supportedCultures)

View File

@@ -20,6 +20,7 @@
<PackageReference Include="Serilog"/> <PackageReference Include="Serilog"/>
<PackageReference Include="Serilog.AspNetCore"/> <PackageReference Include="Serilog.AspNetCore"/>
<PackageReference Include="Serilog.Sinks.Console"/> <PackageReference Include="Serilog.Sinks.Console"/>
<PackageReference Include="Serilog.Sinks.File"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -5,5 +5,16 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "LogFile": "logs/romrepomgr.log",
"AllowedHosts": "*",
"DataFolders": {
"Repository": "repo",
"ImportRoms": "incoming",
"ImportDats": "incoming-dats",
"ExportRoms": "export",
"ExportDats": "export-dats",
"Database": "db",
"Temporary": "tmp"
},
"CompressionType": "Zstd"
} }