Files
orbits/internal/server/service/fileservice.go
T
2026-04-29 23:38:43 +02:00

119 lines
2.6 KiB
Go

package service
import (
"io"
"log/slog"
"orbits-server/internal/server/api/assets"
"orbits-server/internal/server/bootstrap"
"orbits-server/internal/server/database"
"os"
"path/filepath"
"gorm.io/gorm"
)
type FileService struct {
db *gorm.DB
env bootstrap.Environment
}
func NewFileService(db *gorm.DB, env bootstrap.Environment) *FileService {
return &FileService{db: db, env: env}
}
func (s *FileService) SyncFile(fp string) {
f, err := os.Open(fp)
if err != nil {
slog.Error("failed to open the file", "file", fp, "error", err)
return
}
defer f.Close()
fileData, err := database.BuildFileRecord(f, filepath.Base(fp), s.env.ContentDirectory)
if err != nil {
slog.Error("failed to build file record", "error", err)
return
}
if err := database.CreateFile(s.db, &fileData); err != nil {
slog.Error("failed to create file record", "error", err)
return
}
if err := os.Rename(fp, fileData.FilePath); err != nil {
// if this fails across mounts then try copy + delete
slog.Error("failed to move file", "error", err)
database.DeleteFileByID(s.db, fileData.ID)
return
}
}
func (s *FileService) ListFiles() ([]assets.FileResponse, error) {
fileRecords, err := database.ListFiles(s.db)
if err != nil {
return nil, err
}
resp := make([]assets.FileResponse, 0, len(fileRecords))
for _, f := range fileRecords {
resp = append(resp, assets.FileResponse{
ID: f.ID,
MetaName: f.MetaName,
MediaType: string(f.MediaType),
FileID: f.FileID,
FilePath: f.FilePath,
Checksum: f.Checksum,
CreatedAt: f.CreatedAt,
UpdatedAt: f.ExpiresAt,
})
}
return resp, nil
}
func (s *FileService) Create(r io.Reader, filename string) (assets.FileResponse, error) {
f, err := database.BuildFileRecord(r, filename, s.env.ContentDirectory)
if err != nil {
return assets.FileResponse{}, err
}
if err := database.CreateFile(s.db, &f); err != nil {
return assets.FileResponse{}, err
}
resp := assets.FileResponse{
ID: f.ID,
MetaName: f.MetaName,
MediaType: string(f.MediaType),
FileID: f.FileID,
FilePath: f.FilePath,
Checksum: f.Checksum,
CreatedAt: f.CreatedAt,
UpdatedAt: f.UpdatedAt,
}
return resp, nil
}
func (s *FileService) DeleteByName(filename string) error {
fileRecord, err := database.FindFileByFileID(s.db, filename)
if err != nil {
return err
}
_ = os.Remove(fileRecord.FilePath)
if err := database.DeleteFileByID(s.db, fileRecord.ID); err != nil {
return err
}
return nil
}
func (s *FileService) DeleteRecordByID(id int) error {
return database.DeleteFileByID(s.db, id)
}