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

109 lines
2.8 KiB
Go

package useCases
import (
"RenewCMS/internal/domain/image"
"errors"
"slices"
"strings"
)
const (
svgContentType = "image/svg+xml"
unsupportedSVG = "svg"
causeTooLarge = "too_large"
causeUnsupported = "unsupported_format"
causeFailed = "failed"
variantURLQuery = "?" + image.VariantQueryParameter + "="
)
type ImageVariantView struct {
Variant image.Variant
OutputWidth int
OutputHeight int
OutputFormat image.VariantFormat
Generated bool
Size int64
URL string
}
type ImageVariantList struct {
Unsupported string
Items []ImageVariantView
}
type VariantFailure struct {
Name string
Cause string
}
func isVectorSource(img image.Image) bool {
return img.ContentType == svgContentType
}
func enabledVariants(variants image.VariantRepository) ([]image.Variant, error) {
listed, err := variants.List()
if err != nil {
return nil, err
}
enabled := make([]image.Variant, 0, len(listed))
for _, variant := range listed {
if variant.Enabled {
enabled = append(enabled, variant)
}
}
slices.SortFunc(enabled, func(a, b image.Variant) int { return strings.Compare(a.Name, b.Name) })
return enabled, nil
}
func currentFiles(files image.VariantFileRepository, storedName string) (map[string]image.VariantFile, error) {
rows, err := files.ListBySource(storedName)
if err != nil {
return nil, err
}
byVariant := make(map[string]image.VariantFile, len(rows))
for _, row := range rows {
byVariant[row.VariantName] = row
}
return byVariant, nil
}
func isCurrent(variant image.Variant, rows map[string]image.VariantFile) bool {
row, found := rows[variant.Name]
return found && row.Fingerprint == variant.Settings().Fingerprint()
}
func viewOf(variant image.Variant, img image.Image, rows map[string]image.VariantFile, encodable []image.VariantFormat) ImageVariantView {
width, height := image.OutputSize(img.Width, img.Height, variant.Settings())
view := ImageVariantView{
Variant: variant,
OutputWidth: width,
OutputHeight: height,
OutputFormat: image.OutputFormat(variant.Format, img.ContentType, encodable),
URL: image.PublicPath(image.StoredName(img.Path)) + variantURLQuery + variant.Name,
}
if isCurrent(variant, rows) {
view.Generated = true
view.Size = rows[variant.Name].Size
}
return view
}
func viewsOf(variants []image.Variant, img image.Image, rows map[string]image.VariantFile, encodable []image.VariantFormat) []ImageVariantView {
views := make([]ImageVariantView, 0, len(variants))
for _, variant := range variants {
views = append(views, viewOf(variant, img, rows, encodable))
}
return views
}
func generationCause(err error) string {
switch {
case errors.Is(err, image.ErrSourceTooLarge):
return causeTooLarge
case errors.Is(err, image.ErrVariantSourceUnreadable):
return causeUnsupported
default:
return causeFailed
}
}