cpolis/cmd/backend/images.go

114 lines
2.6 KiB
Go
Raw 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 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 {
if err := filepath.Walk(c.PicsDir, func(path string, info fs.FileInfo, err error) error {
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
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)
}
2025-01-17 05:04:03 +01:00
2025-01-19 10:04:16 +01:00
if !info.IsDir() {
mdFile, err := os.Open(path)
2025-01-17 05:04:03 +01:00
if err != nil {
2025-01-19 10:04:16 +01:00
return fmt.Errorf("error opening article %v: %v", info.Name(), err)
2025-01-17 05:04:03 +01:00
}
2025-01-19 10:04:16 +01:00
defer mdFile.Close()
2025-01-17 05:04:03 +01:00
2025-01-19 10:04:16 +01:00
scanner := bufio.NewScanner(mdFile)
2025-01-17 05:04:03 +01:00
2025-01-19 10:04:16 +01:00
for scanner.Scan() {
if strings.Contains(scanner.Text(), imageName) {
imageWasFound = true
2025-01-17 05:04:03 +01:00
}
2025-01-19 10:04:16 +01:00
}
2025-01-17 05:04:03 +01:00
2025-01-19 10:04:16 +01:00
return scanner.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 walking articles filepath: %v", err)
}
2025-01-17 05:04:03 +01:00
2025-01-19 10:04:16 +01:00
users, err := db.GetAllUsers(c)
if err != nil {
return fmt.Errorf("error getting all users: %v", err)
}
for _, user := range users {
if imageName == user.ProfilePicLink {
imageWasFound = true
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
}