412 var config = await
_tenants.GetAsync(slug, ct).ConfigureAwait(
false);
413 if (config is
null)
return;
415 var policy = await
_policyResolver.ResolveAsync(config, ct).ConfigureAwait(
false);
416 var all = await
LoadAsync(ct).ConfigureAwait(
false);
419 status.Message =
"처리 중";
420 status.UpdatedAt = DateTime.Now;
421 await
SaveAsync(all, ct).ConfigureAwait(
false);
423 var root =
_tenants.GetTenantDataPath(slug);
424 var galleryDir = Path.Combine(root,
"gallery");
425 var thumbDir = Path.Combine(root,
"thumb");
426 var originalDir = Path.Combine(root,
"original");
427 Directory.CreateDirectory(galleryDir);
428 Directory.CreateDirectory(thumbDir);
429 Directory.CreateDirectory(originalDir);
431 if (config.GalleryFileNames.Count == 0)
434 status.Message =
"변환할 이미지가 없습니다.";
435 status.UpdatedAt = DateTime.Now;
436 await
SaveAsync(all, ct).ConfigureAwait(
false);
440 var anyFailed =
false;
441 var anyProcessed =
false;
442 var allSkipped =
true;
443 var total = config.GalleryFileNames.Count;
446 foreach (var fileName
in config.GalleryFileNames.ToArray())
448 ct.ThrowIfCancellationRequested();
449 var fileStatus = status.Files.FirstOrDefault(x =>
string.Equals(x.SourceFileName, fileName, StringComparison.OrdinalIgnoreCase));
457 if (!status.Files.Contains(fileStatus)) status.Files.Add(fileStatus);
459 var sourcePath = Path.Combine(galleryDir, fileName);
460 if (!File.Exists(sourcePath))
467 if (
string.IsNullOrWhiteSpace(outputFormat))
477 fileStatus.Message = $
"처리 중 ({processed + 1}/{total})";
478 fileStatus.UpdatedAt = DateTime.Now;
479 status.Message = fileStatus.Message;
480 await
SaveAsync(all, ct).ConfigureAwait(
false);
482 var targetName = $
"{Path.GetFileNameWithoutExtension(fileName)}.{outputFormat}";
483 var tempPath = Path.Combine(galleryDir, $
"{Path.GetFileNameWithoutExtension(fileName)}.migration.tmp.{outputFormat}");
484 var finalPath = Path.Combine(galleryDir, targetName);
485 var result = await
_imageOptimization.OptimizeAsync(sourcePath, tempPath, policy, ct).ConfigureAwait(
false);
486 if (!result.Succeeded || !File.Exists(tempPath) ||
new FileInfo(tempPath).Length == 0)
488 if (File.Exists(tempPath)) File.Delete(tempPath);
489 throw new InvalidOperationException(result.Message);
492 if (policy.KeepOriginalImages)
494 File.Copy(sourcePath, Path.Combine(originalDir, fileName), overwrite:
true);
497 File.Move(tempPath, finalPath, overwrite:
true);
498 File.Copy(finalPath, Path.Combine(thumbDir, targetName), overwrite:
true);
500 var index = config.GalleryFileNames.FindIndex(x =>
string.Equals(x, fileName, StringComparison.OrdinalIgnoreCase));
503 config.GalleryFileNames[index] = targetName;
504 await
_tenants.SaveAsync(config, ct).ConfigureAwait(
false);
507 if (!policy.KeepOriginalImages && !
string.Equals(sourcePath, finalPath, StringComparison.OrdinalIgnoreCase))
509 File.Delete(sourcePath);
510 var oldThumb = Path.Combine(thumbDir, fileName);
511 if (File.Exists(oldThumb)) File.Delete(oldThumb);
514 fileStatus.TargetFileName = targetName;
516 var formatMessage =
string.Equals(requestedFormat, outputFormat, StringComparison.OrdinalIgnoreCase)
518 : $
"완료 ({policy.ImageOutputFormat} 미지원, {outputFormat.ToUpperInvariant()}로 최적화)";
531 await
SaveAsync(all, ct).ConfigureAwait(
false);
534 status.State = anyFailed
541 status.Message = status.State
switch
548 status.UpdatedAt = DateTime.Now;
549 await
SaveAsync(all, ct).ConfigureAwait(
false);