Files
MeBox/internal/service/strm_generate_cleanup.go
T

117 lines
3.1 KiB
Go

package service
import (
"context"
"errors"
"io/fs"
"net/url"
"os"
"path/filepath"
"strings"
"github.com/ShukeBta/MediaStationGo/internal/model"
)
func (s *STRMService) upsertGeneratedRecord(ctx context.Context, media model.Media, filePath, playURL, mediaType string) error {
protocol := ""
if u, err := url.Parse(playURL); err == nil {
protocol = strings.ToLower(u.Scheme)
}
if protocol == "" {
protocol = "http"
}
record := model.STRMRecord{
Title: media.Title,
URL: playURL,
FilePath: filePath,
Protocol: protocol,
MediaID: media.ID,
MediaType: mediaType,
SeasonNum: media.SeasonNum,
EpisodeNum: media.EpisodeNum,
}
var existing model.STRMRecord
err := s.repo.DB.WithContext(ctx).Where("media_id = ? AND file_path = ?", media.ID, filePath).First(&existing).Error
if err == nil {
existing.Title = record.Title
existing.URL = record.URL
existing.Protocol = record.Protocol
existing.MediaType = record.MediaType
existing.SeasonNum = record.SeasonNum
existing.EpisodeNum = record.EpisodeNum
return s.repo.DB.WithContext(ctx).Save(&existing).Error
}
return s.repo.DB.WithContext(ctx).Create(&record).Error
}
func (s *STRMService) cleanupStaleGeneratedSTRM(ctx context.Context, outputDir string, expected map[string]struct{}) (int, error) {
outputDir = filepath.Clean(strings.TrimSpace(outputDir))
if outputDir == "" || outputDir == "." {
return 0, nil
}
cleaned, err := removeStaleSTRMFiles(outputDir, expected)
if err != nil {
return cleaned, err
}
recordsCleaned, err := s.removeStaleSTRMRecords(ctx, outputDir, expected)
return cleaned + recordsCleaned, err
}
func removeStaleSTRMFiles(outputDir string, expected map[string]struct{}) (int, error) {
cleaned := 0
err := filepath.WalkDir(outputDir, func(path string, entry fs.DirEntry, walkErr error) error {
if walkErr != nil {
return nil
}
if entry.IsDir() || strings.ToLower(filepath.Ext(path)) != ".strm" {
return nil
}
cleanPath := filepath.Clean(path)
if _, ok := expected[cleanPath]; ok {
return nil
}
if err := os.Remove(cleanPath); err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
cleaned++
return nil
})
if err != nil && !errors.Is(err, os.ErrNotExist) {
return cleaned, err
}
return cleaned, nil
}
func (s *STRMService) removeStaleSTRMRecords(ctx context.Context, outputDir string, expected map[string]struct{}) (int, error) {
if s == nil || s.repo == nil || s.repo.DB == nil {
return 0, nil
}
var records []model.STRMRecord
if err := s.repo.DB.WithContext(ctx).Find(&records).Error; err != nil {
return 0, err
}
rootAbs, err := filepath.Abs(outputDir)
if err != nil {
return 0, nil
}
cleaned := 0
for i := range records {
filePath := filepath.Clean(strings.TrimSpace(records[i].FilePath))
if filePath == "" {
continue
}
fileAbs, err := filepath.Abs(filePath)
if err != nil || !pathWithin(fileAbs, rootAbs) {
continue
}
if _, ok := expected[filePath]; ok {
continue
}
if err := s.repo.DB.WithContext(ctx).Delete(&records[i]).Error; err != nil {
return cleaned, err
}
cleaned++
}
return cleaned, nil
}