feat: add reliable OpenList segment uploads

This commit is contained in:
2026-08-01 19:27:56 +08:00
parent 12ba62e2a0
commit 9091c1abc7
30 changed files with 3910 additions and 35 deletions
@@ -150,6 +150,14 @@ public sealed class RecordArtifactUploadItemResultDto
public string? RemoteDanmakuPath { get; init; }
public bool DeletedLocalFilesAfterUpload { get; init; }
public RecordArtifactUploadStatus? UploadStatus { get; init; }
public double? ProgressPercent { get; init; }
public int AttemptCount { get; init; }
public DateTimeOffset? NextAttemptAt { get; init; }
}
public sealed class RecordArtifactUploadBatchResultDto
@@ -211,6 +219,16 @@ public sealed class UploadTaskItemDto
public bool DeletedLocalFilesAfterUpload { get; init; }
public DateTimeOffset CreatedAt { get; init; }
public double? UploadProgressPercent { get; init; }
public int UploadAttemptCount { get; init; }
public DateTimeOffset? NextUploadAttemptAt { get; init; }
public string? CurrentUploadArtifact { get; init; }
public string? ExternalUploadTaskId { get; init; }
}
public sealed class UploadTaskListResponse
@@ -224,4 +242,10 @@ public sealed class UploadTaskListResponse
public int SucceededCount { get; init; }
public int FailedCount { get; init; }
public int QueuedCount { get; init; }
public int UploadingCount { get; init; }
public int WaitingRetryCount { get; init; }
}
@@ -91,6 +91,49 @@ public sealed class OpenListUploadSettingsDto
public string Password { get; set; } = string.Empty;
public string BasePath { get; set; } = string.Empty;
public string SourcePath { get; set; } = string.Empty;
public string DestinationPath { get; set; } = string.Empty;
}
public class OpenListConnectionRequest
{
public string BaseUrl { get; set; } = string.Empty;
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
public sealed class OpenListDirectoryRequest : OpenListConnectionRequest
{
public string Path { get; set; } = "/";
}
public sealed class OpenListDirectoryItemDto
{
public required string Name { get; init; }
public required string Path { get; init; }
}
public sealed class OpenListDirectoryListDto
{
public required string Path { get; init; }
public bool CanWrite { get; init; }
public required IReadOnlyList<OpenListDirectoryItemDto> Directories { get; init; }
}
public sealed class OpenListConnectionTestDto
{
public bool Success { get; init; }
public string? Version { get; init; }
public required string Message { get; init; }
}
public sealed class SystemSettingsDto
@@ -58,6 +58,8 @@ public sealed class SystemSettingsService : ISystemSettingsService
private const string OpenListUsernameKey = "upload.openlist.username";
private const string OpenListPasswordKey = "upload.openlist.password";
private const string OpenListBasePathKey = "upload.openlist.base_path";
private const string OpenListSourcePathKey = "upload.openlist.source_path";
private const string OpenListDestinationPathKey = "upload.openlist.destination_path";
private const string DouyinProxyEnabledKey = "platform_proxy.douyin.enabled";
private const string DouyinProxyUrlKey = "platform_proxy.douyin.url";
private const string BilibiliProxyEnabledKey = "platform_proxy.bilibili.enabled";
@@ -189,7 +191,12 @@ public sealed class SystemSettingsService : ISystemSettingsService
BaseUrl = GetValue(lookup, OpenListBaseUrlKey, string.Empty),
Username = GetValue(lookup, OpenListUsernameKey, string.Empty),
Password = GetValue(lookup, OpenListPasswordKey, string.Empty),
BasePath = GetValue(lookup, OpenListBasePathKey, string.Empty)
BasePath = GetValue(lookup, OpenListBasePathKey, string.Empty),
SourcePath = GetValue(lookup, OpenListSourcePathKey, string.Empty),
DestinationPath = GetValue(
lookup,
OpenListDestinationPathKey,
GetValue(lookup, OpenListBasePathKey, string.Empty))
},
EnableEventScripts = bool.TryParse(GetValue(lookup, EnableEventScriptsKey, "false"), out var enableEventScripts) && enableEventScripts,
EnableLiveStartedScript = GetEventScriptEnabled(
@@ -363,7 +370,12 @@ public sealed class SystemSettingsService : ISystemSettingsService
await UpsertAsync(OpenListBaseUrlKey, openListUpload.BaseUrl.Trim(), now, cancellationToken);
await UpsertAsync(OpenListUsernameKey, openListUpload.Username.Trim(), now, cancellationToken);
await UpsertAsync(OpenListPasswordKey, openListUpload.Password, now, cancellationToken);
await UpsertAsync(OpenListBasePathKey, openListUpload.BasePath.Trim(), now, cancellationToken);
var openListDestinationPath = string.IsNullOrWhiteSpace(openListUpload.DestinationPath)
? openListUpload.BasePath.Trim()
: openListUpload.DestinationPath.Trim();
await UpsertAsync(OpenListBasePathKey, openListDestinationPath, now, cancellationToken);
await UpsertAsync(OpenListSourcePathKey, openListUpload.SourcePath.Trim(), now, cancellationToken);
await UpsertAsync(OpenListDestinationPathKey, openListDestinationPath, now, cancellationToken);
foreach (var platformDefinition in LivePlatformCatalog.All)
{
var platformRequestSettings = request.GetPlatformRequestSettings(platformDefinition.Type);