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) }