Files
TinfoilVibeServer/TinfoilVibeServer/Program.cs
T
ecenshu 0e2fec8c01
Build & Push Docker image / build-and-push (push) Successful in 14m38s
ci / build_linux (push) Successful in 4m43s
Skip hashed and same location files
Explicit usings
Multipart rar handling
2025-11-23 21:05:58 +10:30

108 lines
5.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.IO;
using System.Linq;
using System.Text.Json;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using TinfoilVibeServer.Authentication;
using TinfoilVibeServer.Middleware;
using TinfoilVibeServer.Services;
using TinfoilVibeServer.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();
builder.Services.AddMemoryCache();
var dataRoot = builder.Configuration["CONFIG_ROOT"] ?? "/app/config/";
// 1️⃣ Load the embedded default
var defaultResource = typeof(Program).Assembly
.GetManifestResourceStream("TinfoilVibeServer.appsettings.default.json")!; // adjust namespace
var defaultConfig = JsonDocument.Parse(defaultResource).RootElement;
// 2️⃣ Try to write the file if it doesn't exist
var configPath = Path.Combine(dataRoot, "appsettings.json");
if (!File.Exists(configPath))
{
// write the embedded JSON straight to disk
try
{
File.WriteAllText(configPath, defaultConfig.GetRawText());
}
catch (Exception e)
{
var tempFactory = LoggerFactory.Create(loggingBuilder =>
{
loggingBuilder.AddConsole();
loggingBuilder.AddDebug();
});
var logger = tempFactory.CreateLogger<Program>();
logger.LogError(e, "Failed to write default config file");
}
}
var config = new ConfigurationBuilder()
.AddJsonFile(Path.Combine(dataRoot,"appsettings.json"), optional: false, reloadOnChange: true)
.AddJsonFile(Path.Combine(dataRoot,$"appsettings.{builder.Environment.EnvironmentName}.json"), optional: true, reloadOnChange: true)
.AddJsonFile(Path.Combine(dataRoot,$"appsettings.{builder.Environment.EnvironmentName}.local.json"), optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.AddCommandLine(args).Build();
builder.Configuration.AddConfiguration(config);
builder.Services.AddOptions();
builder.Services.Configure<TitleDbOptions>(builder.Configuration.GetSection("TitleDb"));
builder.Services.Configure<NSPExtractorOptions>(builder.Configuration.GetSection("NSPExtractor"));
builder.Services.Configure<AuthSettings>(builder.Configuration.GetSection("AuthSettings"));
builder.Services.Configure<IndexBuilderSettings>(builder.Configuration.GetSection("IndexBuilder"));
builder.Services.AddOptions<SnapshotOptions>().Bind(builder.Configuration.GetSection("Snapshot")).ValidateOnStart();
builder.Services.AddSingleton<ConfigManager>();
builder.Services.AddSingleton<INSPExtractor, NSPExtractor>();
builder.Services.AddSingleton<SnapshotService>();
builder.Services.AddSingleton<ISnapshotService, SnapshotService>(sp => sp.GetRequiredService<SnapshotService>());
builder.Services.AddSingleton<IAuthStore, AuthStore>();
builder.Services.AddSingleton<TitleDatabaseService>();
builder.Services.AddSingleton<IArchiveHandler, ArchiveHandler>();
builder.Services.AddSingleton<IndexBuilderService>();
builder.Services.AddHostedService<IndexBuilderService>(provider => provider.GetRequiredService<IndexBuilderService>());
builder.Services.AddHostedService<SnapshotService>(provider => provider.GetRequiredService<SnapshotService>());
builder.Services.AddHostedService<TitleDatabaseService>(provider => provider.GetRequiredService<TitleDatabaseService>()).AddHttpClient();
builder.Services.AddControllers(); // add MVC
// -------------------------------------------------------------------
// 2) Middleware BasicAuth (verifies username, password, UID, blacklist)
// -------------------------------------------------------------------
var app = builder.Build();
app.UseMiddleware<BasicAuthMiddleware>();
app.MapControllers(); // routes the /index.json & /download endpoints
// -------------------------------------------------------------------
// 3) Endpoints
// -------------------------------------------------------------------
app.MapGet("/debug", () => new SnapshotService(
app.Services.GetRequiredService<IMemoryCache>(),
app.Services.GetRequiredService<IOptionsMonitor<SnapshotOptions>>(),
app.Services.GetRequiredService<INSPExtractor>(),
app.Services.GetRequiredService<IArchiveHandler>(),
app.Services.GetRequiredService<ILogger<SnapshotService>>(), app.Services.GetRequiredService<IHostEnvironment>())
.GetSnapshot());
app.Lifetime.ApplicationStarted.Register(() =>
app.Services.GetRequiredService<ILogger<Program>>().LogInformation("Application started. Listening on {Urls}", string.Join(", ", app.Urls)));
app.Use(async (ctx, next) =>
{
var logger = app.Services.GetRequiredService<ILogger<Program>>();
var correlationId = ctx.Request.Headers["X-Correlation-ID"].FirstOrDefault()
?? Guid.NewGuid().ToString();
using (logger.BeginScope("CorrelationId:{CorrelationId}", correlationId))
{
await next();
}
});
app.Run();