feat: add fnOS packaging, storage workflows and release pipeline
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
using System.Net;
|
||||
|
||||
namespace dy.net.model.dto
|
||||
{
|
||||
public enum MediaDownloadFailureKind
|
||||
{
|
||||
None = 0,
|
||||
SourceUnavailable = 1,
|
||||
SourceForbidden = 2,
|
||||
SourceUnauthorized = 3,
|
||||
SourceNotFound = 4,
|
||||
SourceRateLimited = 5,
|
||||
SourceInvalidContent = 6,
|
||||
StorageUnavailable = 7,
|
||||
IntegrityCheckFailed = 8,
|
||||
Cancelled = 9
|
||||
}
|
||||
|
||||
public sealed class MediaDownloadResult
|
||||
{
|
||||
public bool Success { get; init; }
|
||||
public string ActualSavePath { get; init; }
|
||||
public MediaDownloadFailureKind FailureKind { get; init; }
|
||||
public int? HttpStatusCode { get; init; }
|
||||
public string SourceHost { get; init; }
|
||||
public int AttemptedUrlCount { get; init; }
|
||||
public DateTime? RetryAfter { get; init; }
|
||||
public string Message { get; init; }
|
||||
|
||||
public void Deconstruct(out bool success, out string actualSavePath)
|
||||
{
|
||||
success = Success;
|
||||
actualSavePath = ActualSavePath;
|
||||
}
|
||||
|
||||
public Exception ToException() => FailureKind switch
|
||||
{
|
||||
MediaDownloadFailureKind.StorageUnavailable => new MediaStorageException(Message ?? "媒体存储写入失败。"),
|
||||
MediaDownloadFailureKind.IntegrityCheckFailed => new MediaIntegrityException(Message ?? "媒体完整性校验失败。"),
|
||||
MediaDownloadFailureKind.Cancelled => new OperationCanceledException(Message ?? "媒体下载已取消。"),
|
||||
_ => new MediaSourceException(FailureKind, Message ?? "媒体来源不可用。", HttpStatusCode, SourceHost, RetryAfter)
|
||||
};
|
||||
|
||||
public static MediaDownloadResult Succeeded(string path, string host, int attempted) => new()
|
||||
{
|
||||
Success = true,
|
||||
ActualSavePath = path,
|
||||
SourceHost = host,
|
||||
AttemptedUrlCount = attempted
|
||||
};
|
||||
}
|
||||
|
||||
public sealed class MediaSourceException : Exception
|
||||
{
|
||||
public MediaSourceException(
|
||||
MediaDownloadFailureKind kind,
|
||||
string message,
|
||||
int? statusCode = null,
|
||||
string sourceHost = null,
|
||||
DateTime? retryAfter = null,
|
||||
Exception innerException = null) : base(message, innerException)
|
||||
{
|
||||
FailureKind = kind;
|
||||
StatusCode = statusCode;
|
||||
SourceHost = sourceHost;
|
||||
RetryAfter = retryAfter;
|
||||
}
|
||||
|
||||
public MediaDownloadFailureKind FailureKind { get; }
|
||||
public int? StatusCode { get; }
|
||||
public string SourceHost { get; }
|
||||
public DateTime? RetryAfter { get; }
|
||||
}
|
||||
|
||||
public sealed class MediaStorageException : IOException
|
||||
{
|
||||
public MediaStorageException(string message, Exception innerException = null) : base(message, innerException) { }
|
||||
}
|
||||
|
||||
public sealed class MediaIntegrityException : IOException
|
||||
{
|
||||
public MediaIntegrityException(string message, Exception innerException = null) : base(message, innerException) { }
|
||||
}
|
||||
|
||||
public enum SourceFailureDisposition
|
||||
{
|
||||
Continue = 0,
|
||||
WaitForSource = 1,
|
||||
RequiresAuthorization = 2
|
||||
}
|
||||
|
||||
public sealed class SourceAccessDecision
|
||||
{
|
||||
public bool Allowed { get; init; }
|
||||
public bool IsProbe { get; init; }
|
||||
public string Message { get; init; }
|
||||
public DateTime? RetryAt { get; init; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user