Files
backend/cloudprint-backend/internal/service/file_service.go

106 lines
3.0 KiB
Go
Raw Normal View History

package service
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"github.com/cloudprint/cloudprint-backend/internal/model"
"github.com/cloudprint/cloudprint-backend/internal/repository"
"github.com/cloudprint/cloudprint-backend/pkg/upload"
)
type FileService struct {
fileRepo *repository.FileRepository
uploader *upload.FileUploader
uploadDir string
}
func NewFileService(fileRepo *repository.FileRepository, uploader *upload.FileUploader, uploadDir string) *FileService {
return &FileService{
fileRepo: fileRepo,
uploader: uploader,
uploadDir: uploadDir,
}
}
func (s *FileService) Upload(ctx context.Context, fileName string, fileType string, uploaderType string, uploaderID int32, data []byte) (*model.File, error) {
if !s.uploader.ValidateFileType(fileName) {
return nil, fmt.Errorf("file type not allowed")
}
// Save file
filePath := s.uploader.GenerateFilePath(fileName)
fullPath := s.uploader.GetFilePath(filePath)
if err := os.WriteFile(fullPath, data, 0644); err != nil {
return nil, fmt.Errorf("failed to write file: %w", err)
}
// Create file record
file := &model.File{
FileName: fileName,
FilePath: filePath,
FileType: strings.ToLower(fileType),
FileSize: int64(len(data)),
UploaderType: uploaderType,
UploaderID: uploaderID,
}
if err := s.fileRepo.Create(ctx, file); err != nil {
// Clean up file on error
os.Remove(fullPath)
return nil, fmt.Errorf("failed to create file record: %w", err)
}
return file, nil
}
func (s *FileService) GetFile(ctx context.Context, fileID int32) (*model.File, error) {
return s.fileRepo.GetByID(ctx, fileID)
}
func (s *FileService) GetFileReader(ctx context.Context, file *model.File) (io.ReadCloser, error) {
fullPath := filepath.Join(s.uploadDir, file.FilePath)
return os.Open(fullPath)
}
func (s *FileService) DeleteFile(ctx context.Context, fileID int32, uploaderType string, uploaderID int32) error {
file, err := s.fileRepo.GetByID(ctx, fileID)
if err != nil || file == nil {
return fmt.Errorf("file not found")
}
// Verify ownership
if file.UploaderType != uploaderType || file.UploaderID != uploaderID {
return fmt.Errorf("unauthorized")
}
// Delete physical file
fullPath := s.uploader.GetFilePath(file.FilePath)
os.Remove(fullPath)
// Delete record
return s.fileRepo.Delete(ctx, fileID)
}
func (s *FileService) GetFileList(ctx context.Context, uploaderType string, uploaderID int32, page, pageSize int) ([]*model.File, int64, error) {
return s.fileRepo.GetListByUploader(ctx, uploaderType, uploaderID, page, pageSize)
}
func (s *FileService) AddWatermark(ctx context.Context, fileID int32, text string, opacity float32, position int, fontSize int) (*model.File, error) {
file, err := s.fileRepo.GetByID(ctx, fileID)
if err != nil || file == nil {
return nil, fmt.Errorf("file not found")
}
// In production, use a PDF library to add watermark
// For now, just return the original file
// TODO: Implement actual watermark using pdf-lib or similar
return file, nil
}