91 lines
2.0 KiB
Go
91 lines
2.0 KiB
Go
package useCases
|
|
|
|
import (
|
|
"RenewCMS/internal/domain/image"
|
|
"bytes"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
stdimage "image"
|
|
"io"
|
|
"path"
|
|
|
|
_ "golang.org/x/image/webp"
|
|
_ "image/jpeg"
|
|
_ "image/png"
|
|
)
|
|
|
|
var extensionContentTypes = map[string]string{
|
|
".png": "image/png",
|
|
".jpg": "image/jpeg",
|
|
".jpeg": "image/jpeg",
|
|
".webp": "image/webp",
|
|
".svg": "image/svg+xml",
|
|
}
|
|
|
|
type BackfillImageMetadataUseCase struct {
|
|
imageRepository image.Repository
|
|
storage image.Storage
|
|
}
|
|
|
|
func NewBackfillImageMetadataUseCase(imageRepository image.Repository, storage image.Storage) *BackfillImageMetadataUseCase {
|
|
return &BackfillImageMetadataUseCase{imageRepository, storage}
|
|
}
|
|
|
|
func (u *BackfillImageMetadataUseCase) Run() error {
|
|
pending, err := u.imageRepository.ListMissingMetadata()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, row := range pending {
|
|
metadata, ok := u.readStoredImage(row.Path)
|
|
if !ok {
|
|
continue
|
|
}
|
|
if err := u.imageRepository.UpdateMetadata(row.ID, metadata); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (u *BackfillImageMetadataUseCase) readStoredImage(storedPath string) (image.Metadata, bool) {
|
|
fileName := image.StoredName(storedPath)
|
|
contentType, known := extensionContentTypes[path.Ext(fileName)]
|
|
if !known {
|
|
return image.Metadata{}, false
|
|
}
|
|
|
|
data, err := u.read(fileName)
|
|
if err != nil {
|
|
return image.Metadata{}, false
|
|
}
|
|
|
|
width, height := 0, 0
|
|
if contentType != "image/svg+xml" {
|
|
config, _, err := stdimage.DecodeConfig(bytes.NewReader(data))
|
|
if err != nil {
|
|
return image.Metadata{}, false
|
|
}
|
|
width, height = config.Width, config.Height
|
|
}
|
|
|
|
checksum := sha256.Sum256(data)
|
|
return image.Metadata{
|
|
Filename: fileName,
|
|
Size: int64(len(data)),
|
|
ContentType: contentType,
|
|
Width: width,
|
|
Height: height,
|
|
SHA256: hex.EncodeToString(checksum[:]),
|
|
}, true
|
|
}
|
|
|
|
func (u *BackfillImageMetadataUseCase) read(storedName string) ([]byte, error) {
|
|
blob, err := u.storage.Open(storedName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer blob.Content.Close()
|
|
return io.ReadAll(blob.Content)
|
|
}
|