package service import ( "fmt" "os" "path/filepath" "strings" "vidarchive/internal/models" "vidarchive/internal/repository" ) type MediaService struct { repo *repository.MediaRepository downloadDir string } func NewMediaService(repo *repository.MediaRepository, downloadDir string) *MediaService { return &MediaService{repo: repo, downloadDir: downloadDir} } func (s *MediaService) GetByID(id int64) (*models.Media, error) { return s.repo.GetByID(id) } func (s *MediaService) GetByRelativePath(relPath string) (*models.Media, error) { return s.repo.GetByRelativePath(relPath) } func (s *MediaService) GetAll(path, sortBy, filter string) ([]*models.Media, []string, error) { if path != "" && !strings.HasSuffix(path, "/") { path += "/" } media, err := s.repo.GetAll(path, sortBy, filter) if err != nil { return nil, nil, err } folders, err := s.repo.GetFolders(path) if err != nil { return nil, nil, err } return media, folders, nil } func (s *MediaService) ScanLibrary() error { return filepath.Walk(s.downloadDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { return nil } // Check if this file is already in DB relPath, _ := filepath.Rel(s.downloadDir, path) relPath = filepath.ToSlash(relPath) _, err = s.repo.GetByRelativePath(relPath) if err == nil { return nil // already exists } // Determine file type ext := strings.ToLower(filepath.Ext(path)) isAudio := ext == ".mp3" || ext == ".m4a" || ext == ".ogg" || ext == ".wav" || ext == ".flac" || ext == ".aac" || ext == ".opus" isVideo := ext == ".mp4" || ext == ".webm" || ext == ".mkv" || ext == ".avi" || ext == ".mov" if !isAudio && !isVideo { return nil } // Try to find info.json basePath := strings.TrimSuffix(path, ext) infoJSONPath := basePath + ".info.json" if _, err := os.Stat(infoJSONPath); err != nil { infoJSONPath = "" } media := &models.Media{ Filepath: path, RelativePath: relPath, IsAudio: isAudio, InfoJSONPath: infoJSONPath, } // Try to extract title from filename media.Title = strings.TrimSuffix(filepath.Base(path), ext) return s.repo.Create(media) }) } func (s *MediaService) Delete(id int64) error { media, err := s.repo.GetByID(id) if err != nil { return err } // Delete file if err := os.Remove(media.Filepath); err != nil && !os.IsNotExist(err) { return fmt.Errorf("remove file: %w", err) } // Delete info json if exists if media.InfoJSONPath != "" { os.Remove(media.InfoJSONPath) } return s.repo.Delete(id) }