feat: add fnOS packaging, storage workflows and release pipeline

This commit is contained in:
2026-08-11 18:05:49 +08:00
parent c5922f9b08
commit 95932f0199
181 changed files with 24024 additions and 1164 deletions
+31 -2
View File
@@ -4,13 +4,15 @@ using dy.net.utils;
using Serilog;
using System.Reflection;
using System.Text;
using Microsoft.AspNetCore.DataProtection;
using dy.net.storage;
namespace dy.net
{
public class Program
{
// 常量定义
private static readonly string DefaultListenUrl = "http://*:10101";
private static readonly string DefaultListenUrl = Environment.GetEnvironmentVariable("DYSYNC_LISTEN_URL") ?? "http://*:10101";
private const string SpaRootPath = "app/dist";
private const string SpaSourcePath = "app/";
private const string SwaggerDocTitle = "dysync.net WebApi Docs";
@@ -29,6 +31,9 @@ namespace dy.net
ConfigureHost(builder, isDevelopment);
// 配置服务--数据库保存路径从命令行参数传入的第一个参数
string dbPath = args.Length > 0 ? args[0] : "";
// The backup is deliberately completed before DI can construct SqlSugar and run CodeFirst.
// A failed schema update therefore leaves the previous database, WAL/SHM and key ring recoverable.
var upgradeBackup = DatabaseUpgradeBackup.Prepare(dbPath);
ConfigureServices(builder.Services, builder.Configuration, builder.Environment, dbPath);
// 构建应用
var app = builder.Build();
@@ -37,6 +42,7 @@ namespace dy.net
Log.Debug($"dy.sync app is started successfully on {DefaultListenUrl}");
// 初始化应用服务
await InitApplicationServices(app, isDevelopment, dbPath);
upgradeBackup.MarkSchemaReady();
Console.WriteLine();
await app.RunAsync();
@@ -124,6 +130,16 @@ namespace dy.net
//PrintApp();
services.AddSingleton(new Appsettings(config));
// WebDAV 密码使用 Data Protection 加密;密钥与 SQLite 一同持久化,容器重启后仍可解密。
var databaseRoot = string.IsNullOrWhiteSpace(dbPath)
? Path.Combine(Environment.CurrentDirectory, "db")
: Path.Combine(dbPath, "db");
var keyRingPath = Path.Combine(databaseRoot, "keys");
Directory.CreateDirectory(keyRingPath);
services.AddDataProtection()
.SetApplicationName("dysync.net")
.PersistKeysToFileSystem(new DirectoryInfo(keyRingPath));
// 雪花ID生成器
services.AddSnowFlakeId(options => options.WorkId = new Random().Next(1, 100));
@@ -143,6 +159,17 @@ namespace dy.net
services.AddServicesFromNamespace("dy.net.repository")
.AddServicesFromNamespace("dy.net.service");
services.AddScoped<LocalMediaStorage>();
services.AddScoped<WebDavMediaStorage>();
services.AddScoped<OpenListMediaStorage>();
services.AddSingleton<OpenListClient>();
services.AddScoped<MediaStorageRouter>();
services.AddHostedService<OpenListTransferWorker>();
services.AddHostedService<OpenListDirectoryRepairWorker>();
services.AddHostedService<StorageMigrationWorker>();
services.AddHostedService<VideoRedownloadWorker>();
services.AddHostedService<VideoTaskWorker>();
services.AddScoped<FFmpegHelper>();
// SPA静态文件支持
@@ -263,8 +290,10 @@ namespace dy.net
catch (Exception ex)
{
Serilog.Log.Error(ex, "Failed to initialize services on startup");
// Never listen with a partially migrated schema. fnOS can retain/restore the pre-upgrade backup.
throw;
}
}
}
}
}