Files
RenewCMS/internal/infrastructure/useCases/GenerateAllImageVariants.go
T

101 lines
2.9 KiB
Go

package useCases
import (
"RenewCMS/internal/domain/audit"
"RenewCMS/internal/domain/image"
"context"
"slices"
)
type GenerateAllResult struct {
Generated int
Failed int
Failures []VariantFailure
Items []ImageVariantView
}
type GenerateAllImageVariantsUseCase struct {
images image.Repository
variants image.VariantRepository
files image.VariantFileRepository
renderer image.VariantRenderer
generator *ServeVariantUseCase
recorder audit.Recorder
}
func NewGenerateAllImageVariantsUseCase(images image.Repository, variants image.VariantRepository, files image.VariantFileRepository, renderer image.VariantRenderer, generator *ServeVariantUseCase, recorder audit.Recorder) *GenerateAllImageVariantsUseCase {
return &GenerateAllImageVariantsUseCase{images, variants, files, renderer, generator, recorder}
}
func (u *GenerateAllImageVariantsUseCase) Generate(ctx context.Context, id uint32) (GenerateAllResult, error) {
img, err := u.images.Get(id)
if err != nil {
return GenerateAllResult{}, err
}
if isVectorSource(img) {
return GenerateAllResult{}, image.ErrVariantSourceUnsupported
}
enabled, err := enabledVariants(u.variants)
if err != nil {
return GenerateAllResult{}, err
}
storedName := image.StoredName(img.Path)
rows, err := currentFiles(u.files, storedName)
if err != nil {
return GenerateAllResult{}, err
}
result := GenerateAllResult{Failures: []VariantFailure{}}
var firstFailure error
for _, variant := range enabled {
if isCurrent(variant, rows) {
continue
}
if _, err := u.generator.Generate(ctx, variant, storedName); err != nil {
result.Failed++
result.Failures = append(result.Failures, VariantFailure{Name: variant.Name, Cause: generationCause(err)})
if firstFailure == nil {
firstFailure = err
}
continue
}
result.Generated++
}
refreshed, err := currentFiles(u.files, storedName)
if err != nil {
return GenerateAllResult{}, err
}
result.Items = viewsOf(enabled, img, refreshed, u.renderer.EncodableFormats())
u.record(ctx, img, result, firstFailure)
return result, nil
}
func (u *GenerateAllImageVariantsUseCase) record(ctx context.Context, img image.Image, result GenerateAllResult, firstFailure error) {
if result.Generated == 0 && result.Failed == 0 {
return
}
event := audit.NewEvent(audit.ActionVariantGenerateAll, audit.CategoryMedia)
event.Target = imageTarget(img)
event.Params = map[string]any{
audit.ParamGenerated: result.Generated,
audit.ParamFailed: result.Failed,
audit.ParamCauses: distinctCauses(result.Failures),
}
if result.Generated == 0 {
failFrom(ctx, u.recorder, event, reasonFor(firstFailure))
return
}
u.recorder.Record(ctx, event)
}
func distinctCauses(failures []VariantFailure) []string {
causes := []string{}
for _, failure := range failures {
if !slices.Contains(causes, failure.Cause) {
causes = append(causes, failure.Cause)
}
}
return causes
}