Sync from /srv/compose/unified-media-manager
This commit is contained in:
112
internal/worker/subtitle_search.go
Normal file
112
internal/worker/subtitle_search.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package worker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/TopherMayor/unified-media-manager/internal/config"
|
||||
"github.com/TopherMayor/unified-media-manager/internal/db"
|
||||
"github.com/TopherMayor/unified-media-manager/internal/service"
|
||||
)
|
||||
|
||||
type SubtitleSearchWorker struct {
|
||||
database *db.DB
|
||||
subtitleSvc *service.SubtitleService
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
func NewSubtitleSearchWorker(database *db.DB, subtitleSvc *service.SubtitleService, cfg *config.Config) *SubtitleSearchWorker {
|
||||
return &SubtitleSearchWorker{
|
||||
database: database,
|
||||
subtitleSvc: subtitleSvc,
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *SubtitleSearchWorker) Name() string {
|
||||
return "subtitle_search"
|
||||
}
|
||||
|
||||
func (w *SubtitleSearchWorker) CronExpr() string {
|
||||
return w.cfg.WorkerSubtitleInterval
|
||||
}
|
||||
|
||||
func (w *SubtitleSearchWorker) Run(ctx context.Context) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
searched := 0
|
||||
downloaded := 0
|
||||
errors := 0
|
||||
|
||||
rows, err := w.database.Pool.Query(ctx,
|
||||
`SELECT m.id, m.media_type, m.title, mf.path
|
||||
FROM media m
|
||||
JOIN media_files mf ON m.id = mf.media_id AND mf.deleted_at IS NULL
|
||||
WHERE m.deleted_at IS NULL AND m.status = 'available'
|
||||
ORDER BY m.id`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
type mediaFile struct {
|
||||
mediaID int64
|
||||
mediaType string
|
||||
title string
|
||||
path string
|
||||
}
|
||||
|
||||
var files []mediaFile
|
||||
for rows.Next() {
|
||||
var f mediaFile
|
||||
if err := rows.Scan(&f.mediaID, &f.mediaType, &f.title, &f.path); err != nil {
|
||||
slog.Error("failed to scan media file", "error", err)
|
||||
continue
|
||||
}
|
||||
files = append(files, f)
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
ext := filepath.Ext(f.path)
|
||||
basePath := f.path[:len(f.path)-len(ext)]
|
||||
srtPath := basePath + ".eng.srt"
|
||||
sdhPath := basePath + ".eng.sdh.srt"
|
||||
|
||||
if _, err := os.Stat(srtPath); err == nil {
|
||||
continue
|
||||
}
|
||||
if _, err := os.Stat(sdhPath); err == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
results, err := w.subtitleSvc.Search(ctx, f.title, service.SubtitleSearchOptions{
|
||||
LanguageCodes: []string{"eng"},
|
||||
})
|
||||
if err != nil {
|
||||
slog.Error("failed to search subtitles", "media_id", f.mediaID, "error", err)
|
||||
errors++
|
||||
continue
|
||||
}
|
||||
searched++
|
||||
|
||||
if len(results) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
baseName := filepath.Base(basePath)
|
||||
_, err = w.subtitleSvc.Download(ctx, results[0].ID, filepath.Dir(f.path), baseName, results[0].LanguageCode, results[0].HI, results[0].Forced)
|
||||
if err != nil {
|
||||
slog.Error("failed to download subtitle", "media_id", f.mediaID, "error", err)
|
||||
errors++
|
||||
continue
|
||||
}
|
||||
downloaded++
|
||||
}
|
||||
|
||||
slog.Info("subtitle search completed", "searched", searched, "downloaded", downloaded, "errors", errors)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user