feat: add native fnOS package
This commit is contained in:
@@ -130,7 +130,7 @@ public sealed class SystemSettingsService : ISystemSettingsService
|
||||
return new SystemSettingsDto
|
||||
{
|
||||
FfmpegPath = GetValue(lookup, FfmpegPathKey, "ffmpeg"),
|
||||
OutputRoot = GetValue(lookup, OutputRootKey, "records"),
|
||||
OutputRoot = GetValue(lookup, OutputRootKey, GetDefaultOutputRoot()),
|
||||
OutputDirectoryTemplate = GetValue(lookup, OutputDirectoryTemplateKey, "{platform}/{yyyy}/{MM}/{dd}/{anchor}"),
|
||||
OutputFileNameTemplate = GetValue(lookup, OutputFileNameTemplateKey, "{HHmmss}_{quality}_{anchor}_{title}_{roomId}{segmentSuffix}"),
|
||||
DefaultQuality = GetValue(lookup, DefaultQualityKey, "origin"),
|
||||
@@ -292,6 +292,12 @@ public sealed class SystemSettingsService : ISystemSettingsService
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetDefaultOutputRoot()
|
||||
{
|
||||
var configured = Environment.GetEnvironmentVariable("LIVE_RECORDER_DEFAULT_OUTPUT_ROOT");
|
||||
return string.IsNullOrWhiteSpace(configured) ? "records" : configured.Trim();
|
||||
}
|
||||
|
||||
public async Task<SystemSettingsDto> UpdateAsync(UpdateSystemSettingsRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace LiveRecorder.Infrastructure.Persistence;
|
||||
|
||||
public sealed class DatabaseInitializer
|
||||
{
|
||||
private const string DefaultAdminPasswordEnvironmentVariable = "LIVE_RECORDER_DEFAULT_ADMIN_PASSWORD";
|
||||
|
||||
private readonly LiveRecorderDbContext _dbContext;
|
||||
|
||||
public DatabaseInitializer(LiveRecorderDbContext dbContext)
|
||||
@@ -28,14 +30,16 @@ public sealed class DatabaseInitializer
|
||||
if (!await _dbContext.UserAccounts.AnyAsync(cancellationToken))
|
||||
{
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var admin = new UserAccount("admin", "Administrator", PasswordHasher.Hash("Admin@123"), now);
|
||||
var passwordHash = PasswordHasher.Hash(GetDefaultAdminPassword());
|
||||
Environment.SetEnvironmentVariable(DefaultAdminPasswordEnvironmentVariable, null);
|
||||
var admin = new UserAccount("admin", "Administrator", passwordHash, now);
|
||||
await _dbContext.UserAccounts.AddAsync(admin, cancellationToken);
|
||||
}
|
||||
|
||||
var defaults = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
["ffmpeg.path"] = "ffmpeg",
|
||||
["recording.output_root"] = "records",
|
||||
["recording.output_root"] = GetDefaultOutputRoot(),
|
||||
["recording.output_directory_template"] = "{platform}/{yyyy}/{MM}/{dd}/{anchor}",
|
||||
["recording.output_file_name_template"] = "{HHmmss}_{anchor}_{title}_{roomId}{segmentSuffix}",
|
||||
["recording.default_quality"] = "origin",
|
||||
@@ -167,4 +171,16 @@ public sealed class DatabaseInitializer
|
||||
|
||||
await _dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private static string GetDefaultOutputRoot()
|
||||
{
|
||||
var configured = Environment.GetEnvironmentVariable("LIVE_RECORDER_DEFAULT_OUTPUT_ROOT");
|
||||
return string.IsNullOrWhiteSpace(configured) ? "records" : configured.Trim();
|
||||
}
|
||||
|
||||
private static string GetDefaultAdminPassword()
|
||||
{
|
||||
var configured = Environment.GetEnvironmentVariable(DefaultAdminPasswordEnvironmentVariable);
|
||||
return string.IsNullOrEmpty(configured) ? "Admin@123" : configured;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,14 +247,26 @@ builder.Services.AddHostedService<RetentionCleanupBackgroundService>();
|
||||
builder.Services.AddHostedService<OpenListUploadBackgroundService>();
|
||||
|
||||
var app = builder.Build();
|
||||
var webRootPath = app.Environment.WebRootPath ?? Path.Combine(app.Environment.ContentRootPath, "wwwroot");
|
||||
var hasBundledFrontend = File.Exists(Path.Combine(webRootPath, "index.html"));
|
||||
|
||||
app.UseMiddleware<ExceptionHandlingMiddleware>();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
app.UseCors("frontend");
|
||||
if (hasBundledFrontend)
|
||||
{
|
||||
app.UseDefaultFiles();
|
||||
app.UseStaticFiles();
|
||||
}
|
||||
|
||||
app.UseMiddleware<ApiTokenAuthenticationMiddleware>();
|
||||
|
||||
app.MapGet("/", () => Results.Redirect("/swagger"));
|
||||
if (!hasBundledFrontend)
|
||||
{
|
||||
app.MapGet("/", () => Results.Redirect("/swagger"));
|
||||
}
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
// ── Health check endpoints ────────────────────────────────────────────
|
||||
@@ -359,6 +371,11 @@ if (resetRecordingData)
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasBundledFrontend)
|
||||
{
|
||||
app.MapFallbackToFile("index.html");
|
||||
}
|
||||
|
||||
app.Run();
|
||||
|
||||
static async Task<Dictionary<string, long>> ReadRecordingDataCountsAsync(LiveRecorderDbContext dbContext)
|
||||
|
||||
Reference in New Issue
Block a user