Вынести виды файлов Storage в каталог

This commit is contained in:
2026-09-13 20:51:42 +03:00
parent 04d7a0f6fb
commit b7c5e13fc3
3 changed files with 63 additions and 24 deletions
@@ -37,6 +37,8 @@ public sealed class StorageOptions
/// </summary> /// </summary>
public const string SecureEnvKey = "DEAL_STORAGE_SECURE"; public const string SecureEnvKey = "DEAL_STORAGE_SECURE";
private const string TrueLiteral = "true";
public string Endpoint { get; init; } = string.Empty; public string Endpoint { get; init; } = string.Empty;
public string AccessKey { get; init; } = string.Empty; public string AccessKey { get; init; } = string.Empty;
@@ -69,5 +71,5 @@ public sealed class StorageOptions
/// </summary> /// </summary>
public static bool IsEnabled(string? rawValue) public static bool IsEnabled(string? rawValue)
=> string.Equals(rawValue, "1", StringComparison.Ordinal) => string.Equals(rawValue, "1", StringComparison.Ordinal)
|| string.Equals(rawValue, "true", StringComparison.OrdinalIgnoreCase); || string.Equals(rawValue, TrueLiteral, StringComparison.OrdinalIgnoreCase);
} }
@@ -8,7 +8,7 @@ public static class FileKindSniffer
/// <summary> /// <summary>
/// Тип «прочее». /// Тип «прочее».
/// </summary> /// </summary>
public const string KindOther = "other"; public const string KindOther = FileKinds.Other;
private const string DefaultMime = "application/octet-stream"; private const string DefaultMime = "application/octet-stream";
@@ -22,95 +22,95 @@ public static class FileKindSniffer
{ {
if (StartsWith(head, 0x89, 0x50, 0x4E, 0x47)) if (StartsWith(head, 0x89, 0x50, 0x4E, 0x47))
{ {
return ("image", "image/png"); return (FileKinds.Image, "image/png");
} }
if (StartsWith(head, 0xFF, 0xD8, 0xFF)) if (StartsWith(head, 0xFF, 0xD8, 0xFF))
{ {
return ("image", "image/jpeg"); return (FileKinds.Image, "image/jpeg");
} }
if (StartsWith(head, 0x47, 0x49, 0x46, 0x38)) if (StartsWith(head, 0x47, 0x49, 0x46, 0x38))
{ {
return ("image", "image/gif"); return (FileKinds.Image, "image/gif");
} }
if (StartsWith(head, 0x42, 0x4D)) if (StartsWith(head, 0x42, 0x4D))
{ {
return ("image", "image/bmp"); return (FileKinds.Image, "image/bmp");
} }
if (StartsWith(head, 0x49, 0x49, 0x2A, 0x00) || StartsWith(head, 0x4D, 0x4D, 0x00, 0x2A)) if (StartsWith(head, 0x49, 0x49, 0x2A, 0x00) || StartsWith(head, 0x4D, 0x4D, 0x00, 0x2A))
{ {
return ("image", "image/tiff"); return (FileKinds.Image, "image/tiff");
} }
if (StartsWith(head, 0x25, 0x50, 0x44, 0x46)) if (StartsWith(head, 0x25, 0x50, 0x44, 0x46))
{ {
return ("document", "application/pdf"); return (FileKinds.Document, "application/pdf");
} }
if (StartsWith(head, 0x50, 0x4B, 0x03, 0x04) || StartsWith(head, 0x50, 0x4B, 0x05, 0x06)) if (StartsWith(head, 0x50, 0x4B, 0x03, 0x04) || StartsWith(head, 0x50, 0x4B, 0x05, 0x06))
{ {
return ("archive", "application/zip"); return (FileKinds.Archive, "application/zip");
} }
if (StartsWith(head, 0x52, 0x61, 0x72, 0x21)) if (StartsWith(head, 0x52, 0x61, 0x72, 0x21))
{ {
return ("archive", "application/vnd.rar"); return (FileKinds.Archive, "application/vnd.rar");
} }
if (StartsWith(head, 0x37, 0x7A, 0xBC, 0xAF)) if (StartsWith(head, 0x37, 0x7A, 0xBC, 0xAF))
{ {
return ("archive", "application/x-7z-compressed"); return (FileKinds.Archive, "application/x-7z-compressed");
} }
if (StartsWith(head, 0x1F, 0x8B)) if (StartsWith(head, 0x1F, 0x8B))
{ {
return ("archive", "application/gzip"); return (FileKinds.Archive, "application/gzip");
} }
if (StartsWith(head, 0x1A, 0x45, 0xDF, 0xA3)) if (StartsWith(head, 0x1A, 0x45, 0xDF, 0xA3))
{ {
return ("video", "video/webm"); return (FileKinds.Video, "video/webm");
} }
if (head.Length >= 12 && StartsWith(head, 0x52, 0x49, 0x46, 0x46)) if (head.Length >= 12 && StartsWith(head, 0x52, 0x49, 0x46, 0x46))
{ {
if (StartsWith(head[8..], 0x57, 0x45, 0x42, 0x50)) if (StartsWith(head[8..], 0x57, 0x45, 0x42, 0x50))
{ {
return ("image", "image/webp"); return (FileKinds.Image, "image/webp");
} }
if (StartsWith(head[8..], 0x57, 0x41, 0x56, 0x45)) if (StartsWith(head[8..], 0x57, 0x41, 0x56, 0x45))
{ {
return ("audio", "audio/wav"); return (FileKinds.Audio, "audio/wav");
} }
if (StartsWith(head[8..], 0x41, 0x56, 0x49, 0x20)) if (StartsWith(head[8..], 0x41, 0x56, 0x49, 0x20))
{ {
return ("video", "video/x-msvideo"); return (FileKinds.Video, "video/x-msvideo");
} }
} }
if (head.Length >= 8 && StartsWith(head[4..], 0x66, 0x74, 0x79, 0x70)) if (head.Length >= 8 && StartsWith(head[4..], 0x66, 0x74, 0x79, 0x70))
{ {
return ("video", "video/mp4"); return (FileKinds.Video, "video/mp4");
} }
if (StartsWith(head, 0x49, 0x44, 0x33) || StartsWith(head, 0xFF, 0xFB)) if (StartsWith(head, 0x49, 0x44, 0x33) || StartsWith(head, 0xFF, 0xFB))
{ {
return ("audio", "audio/mpeg"); return (FileKinds.Audio, "audio/mpeg");
} }
if (StartsWith(head, 0x4F, 0x67, 0x67, 0x53)) if (StartsWith(head, 0x4F, 0x67, 0x67, 0x53))
{ {
return ("audio", "audio/ogg"); return (FileKinds.Audio, "audio/ogg");
} }
if (StartsWith(head, 0x66, 0x4C, 0x61, 0x43)) if (StartsWith(head, 0x66, 0x4C, 0x61, 0x43))
{ {
return ("audio", "audio/flac"); return (FileKinds.Audio, "audio/flac");
} }
string declared = (contentType ?? string.Empty).Trim(); string declared = (contentType ?? string.Empty).Trim();
@@ -125,10 +125,10 @@ public static class FileKindSniffer
// Определяет общий тип по префиксу MIME-типа. // Определяет общий тип по префиксу MIME-типа.
private static string KindFromMime(string mime) private static string KindFromMime(string mime)
{ {
if (mime.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) return "image"; if (mime.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) return FileKinds.Image;
if (mime.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) return "video"; if (mime.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) return FileKinds.Video;
if (mime.StartsWith("audio/", StringComparison.OrdinalIgnoreCase)) return "audio"; if (mime.StartsWith("audio/", StringComparison.OrdinalIgnoreCase)) return FileKinds.Audio;
if (mime.StartsWith("text/", StringComparison.OrdinalIgnoreCase)) return "document"; if (mime.StartsWith("text/", StringComparison.OrdinalIgnoreCase)) return FileKinds.Document;
return KindOther; return KindOther;
} }
@@ -0,0 +1,37 @@
namespace Deal.Storage.Services;
/// <summary>
/// Коды категорий файлов, возвращаемые определителем типа.
/// </summary>
public static class FileKinds
{
/// <summary>
/// Категория «изображение».
/// </summary>
public const string Image = "image";
/// <summary>
/// Категория «видео».
/// </summary>
public const string Video = "video";
/// <summary>
/// Категория «аудио».
/// </summary>
public const string Audio = "audio";
/// <summary>
/// Категория «документ».
/// </summary>
public const string Document = "document";
/// <summary>
/// Категория «архив».
/// </summary>
public const string Archive = "archive";
/// <summary>
/// Категория «прочее».
/// </summary>
public const string Other = "other";
}