cpolis/cmd/backend/images.go

126 lines
2.8 KiB
Go
Raw Permalink Normal View History

package backend
import (
2025-01-17 05:04:03 +01:00
"bufio"
"fmt"
"image"
"io"
2025-01-17 05:04:03 +01:00
"io/fs"
"os"
2025-01-17 05:04:03 +01:00
"path/filepath"
"strings"
"github.com/chai2010/webp"
"github.com/disintegration/imaging"
"github.com/google/uuid"
)
var ErrUnsupportedFormat error = image.ErrFormat // used internally by imaging
func checkImageUsage(c *Config, db *DB, name string) (bool, error) {
imageWasFound := false
if err := filepath.Walk(c.ArticleDir, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("error walking articles filepath: %v", err)
}
if !info.IsDir() {
mdFile, err := os.Open(path)
if err != nil {
return fmt.Errorf("error opening article %v: %v", info.Name(), err)
}
defer mdFile.Close()
scanner := bufio.NewScanner(mdFile)
for scanner.Scan() {
if strings.Contains(scanner.Text(), name) {
imageWasFound = true
return nil
}
}
return scanner.Err()
}
return nil
}); err != nil {
return false, fmt.Errorf("error walking articles filepath: %v", err)
}
if !imageWasFound {
users, err := db.GetAllUsers(c)
if err != nil {
return false, fmt.Errorf("error getting all users: %v", err)
}
for _, user := range users {
if name == user.ProfilePicLink {
return true, nil
}
}
}
return imageWasFound, nil
}
func SaveImage(src io.Reader, maxHeight, maxWidth int, path string) (string, error) {
img, err := imaging.Decode(src, imaging.AutoOrientation(true))
if err != nil {
if err == ErrUnsupportedFormat {
return "", ErrUnsupportedFormat
}
return "", fmt.Errorf("error decoding image: %v", err)
}
if img.Bounds().Dy() > maxHeight {
img = imaging.Resize(img, 0, maxHeight, imaging.Lanczos)
}
if img.Bounds().Dx() > maxWidth {
img = imaging.Resize(img, maxWidth, 0, imaging.Lanczos)
}
filename := fmt.Sprint(uuid.New(), ".webp")
2025-01-17 05:04:03 +01:00
file, err := os.Create(filepath.Join(path, filename))
if err != nil {
return "", fmt.Errorf("error creating new image file: %v", err)
}
defer file.Close()
2024-10-27 07:21:36 +01:00
if err = webp.Encode(file, img, &webp.Options{Quality: 80}); err != nil {
return "", fmt.Errorf("error encoding image as webp: %v", err)
}
return filename, nil
}
2025-01-17 05:04:03 +01:00
2025-01-19 10:04:16 +01:00
func CleanUpImages(c *Config, db *DB) error {
2025-01-19 20:10:06 +01:00
if err := filepath.Walk(c.ImgDir, func(path string, info fs.FileInfo, err error) error {
2025-01-19 10:04:16 +01:00
if err != nil {
return fmt.Errorf("error walking images filepath: %v", err)
}
2025-01-17 05:04:03 +01:00
2025-01-19 10:04:16 +01:00
if !info.IsDir() {
imageName := info.Name()
imagePath := path
2025-01-17 05:04:03 +01:00
imageWasFound, err := checkImageUsage(c, db, imageName)
2025-01-19 10:04:16 +01:00
if err != nil {
return fmt.Errorf("error checking image usage: %v", err)
2025-01-17 05:04:03 +01:00
}
2025-01-19 10:04:16 +01:00
if !imageWasFound {
if err = os.Remove(imagePath); err != nil {
return fmt.Errorf("error removing unused image: %v", err)
}
}
2025-01-17 05:04:03 +01:00
}
2025-01-19 10:04:16 +01:00
return nil
}); err != nil {
return fmt.Errorf("error cleaning up: %v", err)
2025-01-17 05:04:03 +01:00
}
2025-01-19 10:04:16 +01:00
return nil
2025-01-17 05:04:03 +01:00
}