WeddingPlatform.Web 1.0.0.0
지도, 갤러리, 방명록, 계좌 안내와 배경음악을 링크 하나에 담는 무료 모바일 청첩장 서비스입니다.
로딩중...
검색중...
일치하는것 없음
FileSystemMediaUsageQueryService.cs
이 파일의 문서화 페이지로 가기
1using System.IO;
3
5
15{
24 private static readonly HashSet<string> ImageExtensions = new(StringComparer.OrdinalIgnoreCase)
25 {
26 ".jpg", ".jpeg", ".png", ".webp", ".gif"
27 };
28
37 private static readonly HashSet<string> VideoExtensions = new(StringComparer.OrdinalIgnoreCase)
38 {
39 ".mp4", ".webm", ".mov", ".m4v"
40 };
41
50 private static readonly HashSet<string> RootMediaExtensions = new(StringComparer.OrdinalIgnoreCase)
51 {
52 ".jpg", ".jpeg", ".png", ".webp", ".gif", ".mp3", ".ogg", ".wav", ".aac", ".m4a"
53 };
54
63 private readonly ITenantStore _tenants;
73
99 {
100 _tenants = tenants;
101 _migrations = migrations;
102 }
103
136 public async Task<TenantMediaUsageSummary> GetTenantUsageAsync(TenantConfig tenant, CancellationToken ct = default)
137 {
138 var root = _tenants.GetTenantDataPath(tenant.Slug);
139 var galleryDir = Path.Combine(root, "gallery");
140 var thumbDir = Path.Combine(root, "thumb");
141 var originalDir = Path.Combine(root, "original");
142 var status = await _migrations.GetTenantStatusAsync(tenant.Slug, ct).ConfigureAwait(false);
143
144 var summary = new TenantMediaUsageSummary
145 {
146 Slug = tenant.Slug,
147 ImageCount = tenant.GalleryFileNames.Count,
148 VideoCount = tenant.VideoFileNames.Count,
149 MigrationState = status?.State ?? InferMigrationState(tenant),
150 LastModified = tenant.CreatedAt,
151 };
152
153 summary.OptimizedImageBytes = SumFiles(galleryDir, ImageExtensions, out var galleryModified);
154 var thumbBytes = SumFiles(thumbDir, ImageExtensions, out var thumbModified);
155 summary.OriginalImageBytes = SumFiles(originalDir, ImageExtensions, out var originalModified);
156 summary.VideoBytes = SumTenantVideos(root, tenant.VideoFileNames, out var videoModified);
157 var rootMediaBytes = SumFiles(root, RootMediaExtensions, out var rootModified);
158 summary.TotalBytes = summary.OptimizedImageBytes + thumbBytes + summary.OriginalImageBytes + summary.VideoBytes + rootMediaBytes;
159 summary.LastModified = MaxDate(galleryModified, thumbModified, originalModified, videoModified, rootModified) ?? tenant.CreatedAt;
160
161 return summary;
162 }
163
196 public async Task<IReadOnlyDictionary<string, TenantMediaUsageSummary>> GetTenantUsageAsync(IEnumerable<TenantConfig> tenants, CancellationToken ct = default)
197 {
198 var result = new Dictionary<string, TenantMediaUsageSummary>(StringComparer.OrdinalIgnoreCase);
199 foreach (var tenant in tenants)
200 {
201 result[tenant.Slug] = await GetTenantUsageAsync(tenant, ct).ConfigureAwait(false);
202 }
203
204 return result;
205 }
206
232 {
233 if (tenant.GalleryFileNames.Count == 0) return MediaMigrationState.Skipped;
234 return tenant.GalleryFileNames.All(x => Path.GetExtension(x).Equals(".webp", StringComparison.OrdinalIgnoreCase))
236 : MediaMigrationState.Pending;
237 }
238
279 private static long SumTenantVideos(string root, IEnumerable<string> fileNames, out DateTime? lastModified)
280 {
281 long total = 0;
282 lastModified = null;
283
284 foreach (var fileName in fileNames)
285 {
286 var path = Path.Combine(root, fileName);
287 if (!File.Exists(path) || !VideoExtensions.Contains(Path.GetExtension(path))) continue;
288 AddFile(path, ref total, ref lastModified);
289 }
290
291 return total;
292 }
293
334 private static long SumFiles(string path, ISet<string> allowedExtensions, out DateTime? lastModified)
335 {
336 long total = 0;
337 lastModified = null;
338 if (!Directory.Exists(path)) return 0;
339
340 foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly))
341 {
342 if (!allowedExtensions.Contains(Path.GetExtension(file))) continue;
343 AddFile(file, ref total, ref lastModified);
344 }
345
346 return total;
347 }
348
381 private static void AddFile(string path, ref long total, ref DateTime? lastModified)
382 {
383 try
384 {
385 var info = new FileInfo(path);
386 total += info.Length;
387 lastModified = MaxDate(lastModified, info.LastWriteTime);
388 }
389 catch
390 {
391 // 파일이 동시에 삭제되는 경우 사용량 계산에서만 제외합니다.
392 }
393 }
394
419 private static DateTime? MaxDate(params DateTime?[] values)
420 {
421 var concrete = values.Where(x => x.HasValue).Select(x => x!.Value).ToArray();
422 return concrete.Length == 0 ? null : concrete.Max();
423 }
424}
static void AddFile(string path, ref long total, ref DateTime? lastModified)
static long SumTenantVideos(string root, IEnumerable< string > fileNames, out DateTime? lastModified)
static long SumFiles(string path, ISet< string > allowedExtensions, out DateTime? lastModified)
async Task< IReadOnlyDictionary< string, TenantMediaUsageSummary > > GetTenantUsageAsync(IEnumerable< TenantConfig > tenants, CancellationToken ct=default)
async Task< TenantMediaUsageSummary > GetTenantUsageAsync(TenantConfig tenant, CancellationToken ct=default)
static MediaMigrationState InferMigrationState(TenantConfig tenant)
FileSystemMediaUsageQueryService(ITenantStore tenants, IMediaMigrationService migrations)