mirror of
https://github.com/pocket-id/pocket-id.git
synced 2025-12-10 23:32:56 +03:00
124 lines
2.9 KiB
Go
124 lines
2.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"mime/multipart"
|
|
"path"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/pocket-id/pocket-id/backend/internal/common"
|
|
"github.com/pocket-id/pocket-id/backend/internal/storage"
|
|
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
|
)
|
|
|
|
type AppImagesService struct {
|
|
mu sync.RWMutex
|
|
extensions map[string]string
|
|
storage storage.FileStorage
|
|
}
|
|
|
|
func NewAppImagesService(extensions map[string]string, storage storage.FileStorage) *AppImagesService {
|
|
return &AppImagesService{extensions: extensions, storage: storage}
|
|
}
|
|
|
|
func (s *AppImagesService) GetImage(ctx context.Context, name string) (io.ReadCloser, int64, string, error) {
|
|
ext, err := s.getExtension(name)
|
|
if err != nil {
|
|
return nil, 0, "", err
|
|
}
|
|
|
|
mimeType := utils.GetImageMimeType(ext)
|
|
if mimeType == "" {
|
|
return nil, 0, "", fmt.Errorf("unsupported image type '%s'", ext)
|
|
}
|
|
|
|
imagePath := path.Join("application-images", name+"."+ext)
|
|
reader, size, err := s.storage.Open(ctx, imagePath)
|
|
if err != nil {
|
|
if storage.IsNotExist(err) {
|
|
return nil, 0, "", &common.ImageNotFoundError{}
|
|
}
|
|
return nil, 0, "", err
|
|
}
|
|
return reader, size, mimeType, nil
|
|
}
|
|
|
|
func (s *AppImagesService) UpdateImage(ctx context.Context, file *multipart.FileHeader, imageName string) error {
|
|
fileType := strings.ToLower(utils.GetFileExtension(file.Filename))
|
|
mimeType := utils.GetImageMimeType(fileType)
|
|
if mimeType == "" {
|
|
return &common.FileTypeNotSupportedError{}
|
|
}
|
|
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
currentExt, ok := s.extensions[imageName]
|
|
if !ok {
|
|
s.extensions[imageName] = fileType
|
|
}
|
|
|
|
imagePath := path.Join("application-images", imageName+"."+fileType)
|
|
fileReader, err := file.Open()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fileReader.Close()
|
|
|
|
if err := s.storage.Save(ctx, imagePath, fileReader); err != nil {
|
|
return err
|
|
}
|
|
|
|
if currentExt != "" && currentExt != fileType {
|
|
oldImagePath := path.Join("application-images", imageName+"."+currentExt)
|
|
if err := s.storage.Delete(ctx, oldImagePath); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
s.extensions[imageName] = fileType
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *AppImagesService) DeleteImage(ctx context.Context, imageName string) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
ext, ok := s.extensions[imageName]
|
|
if !ok || ext == "" {
|
|
return &common.ImageNotFoundError{}
|
|
}
|
|
|
|
imagePath := path.Join("application-images", imageName+"."+ext)
|
|
if err := s.storage.Delete(ctx, imagePath); err != nil {
|
|
return err
|
|
}
|
|
|
|
delete(s.extensions, imageName)
|
|
return nil
|
|
}
|
|
|
|
func (s *AppImagesService) IsDefaultProfilePictureSet() bool {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
_, ok := s.extensions["default-profile-picture"]
|
|
return ok
|
|
}
|
|
|
|
func (s *AppImagesService) getExtension(name string) (string, error) {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
ext, ok := s.extensions[name]
|
|
if !ok || ext == "" {
|
|
return "", &common.ImageNotFoundError{}
|
|
}
|
|
|
|
return strings.ToLower(ext), nil
|
|
}
|