Добавил обновление библиотеки jellyfin после добавления медиа
This commit is contained in:
@@ -73,6 +73,30 @@ func TestNotifier_FiresOnDone(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// recordingScanner ловит вызовы пересканирования Jellyfin (RefreshLibraries
|
||||
// асинхронен — через канал).
|
||||
type recordingScanner struct{ ch chan struct{} }
|
||||
|
||||
func (s *recordingScanner) RefreshLibraries(_ context.Context) error {
|
||||
s.ch <- struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestScanner_FiresOnDone(t *testing.T) {
|
||||
f := newApplyFixture(t, seriesResult().Plan)
|
||||
s := &recordingScanner{ch: make(chan struct{}, 4)}
|
||||
f.w.SetScanner(s)
|
||||
|
||||
if err := f.w.Apply(context.Background(), 1); err != nil {
|
||||
t.Fatalf("Apply: %v", err)
|
||||
}
|
||||
select {
|
||||
case <-s.ch:
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("пересканирование Jellyfin не запустилось")
|
||||
}
|
||||
}
|
||||
|
||||
// memStore — полноценный in-memory store для тестов Ф3.
|
||||
type memStore struct {
|
||||
downloads map[int64]*store.Download
|
||||
|
||||
@@ -86,6 +86,13 @@ type Notifier interface {
|
||||
Notify(ctx context.Context, downloadID int64, event NotifyEvent)
|
||||
}
|
||||
|
||||
// Scanner — триггер пересканирования медиатеки Jellyfin. Вызывается
|
||||
// неблокирующе после успешной раскладки, чтобы новые файлы быстрее появились
|
||||
// в проигрывателе.
|
||||
type Scanner interface {
|
||||
RefreshLibraries(ctx context.Context) error
|
||||
}
|
||||
|
||||
// Config — параметры воркера.
|
||||
type Config struct {
|
||||
Category string
|
||||
@@ -110,11 +117,15 @@ type Worker struct {
|
||||
now func() time.Time // подменяется в тестах
|
||||
newID func() string // генератор apply_batch_id (подменяется в тестах)
|
||||
notifier Notifier // опц. исходящие пинги
|
||||
scanner Scanner // опц. пересканирование Jellyfin
|
||||
}
|
||||
|
||||
// SetNotifier подключает исходящие пинги (до запуска Run).
|
||||
func (w *Worker) SetNotifier(n Notifier) { w.notifier = n }
|
||||
|
||||
// SetScanner подключает пересканирование Jellyfin (до запуска Run).
|
||||
func (w *Worker) SetScanner(s Scanner) { w.scanner = s }
|
||||
|
||||
// New собирает воркер. recognizer/layouter могут быть nil (Ф1 без Ф3-ступеней
|
||||
// распознавания и раскладки) — тогда completed-задачи не двигаются дальше.
|
||||
func New(st Store, qb QBittorrent, rec Recognizer, lay Layouter, cfg Config, log *slog.Logger) *Worker {
|
||||
@@ -260,6 +271,18 @@ func (w *Worker) transition(ctx context.Context, d store.Download, state store.S
|
||||
go w.notifier.Notify(context.Background(), d.ID, EventDone)
|
||||
}
|
||||
}
|
||||
|
||||
// Раскладка завершена — просим Jellyfin пересканировать библиотеку, чтобы
|
||||
// новые файлы быстрее появились в проигрывателе. Тоже неблокирующе и вне
|
||||
// w.mu; недоступность Jellyfin не влияет на состояние задачи.
|
||||
if w.scanner != nil && state == store.StateDone {
|
||||
id := d.ID
|
||||
go func() {
|
||||
if err := w.scanner.RefreshLibraries(context.Background()); err != nil {
|
||||
w.log.Warn("jellyfin: library refresh failed", "download_id", id, "err", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel отклоняет задачу. Торрент в qBittorrent не трогаем — он продолжает
|
||||
|
||||
Reference in New Issue
Block a user