109 lines
2.8 KiB
Go
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
|
|
}
|
|
}
|