- Interleave Trakt movies/shows by rank so the mixed row shows both types instead of burying all series past the display limit. - Treat any Trakt sub-fetch failure as fatal (errors.Join) so a partial result never overwrites the last-good snapshot with a media type missing. - Skip non-title entries (TMDB trending/all returns media_type "person") in both ID batching and ordering so they can't match an unrelated library title. - Guard the refresh task against a nil refresher. - Tests: person skip, Trakt interleave, Trakt partial-failure preserves last-good, snapshot read error propagation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
66 lines
2.1 KiB
Go
66 lines
2.1 KiB
Go
package tasks
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/Silo-Server/silo-server/internal/taskmanager"
|
|
)
|
|
|
|
// TrendingDiscoverRefresher runs a single pass of the trending refresh.
|
|
// Satisfied by *sections.TrendingRefresher.
|
|
type TrendingDiscoverRefresher interface {
|
|
RunOnce(ctx context.Context) (json.RawMessage, error)
|
|
}
|
|
|
|
// RefreshTrendingDiscoverTask refreshes the persisted external-trending
|
|
// snapshots used by trending_discover home sections.
|
|
type RefreshTrendingDiscoverTask struct {
|
|
refresher TrendingDiscoverRefresher
|
|
}
|
|
|
|
// NewRefreshTrendingDiscoverTask creates a new RefreshTrendingDiscoverTask.
|
|
func NewRefreshTrendingDiscoverTask(refresher TrendingDiscoverRefresher) *RefreshTrendingDiscoverTask {
|
|
return &RefreshTrendingDiscoverTask{refresher: refresher}
|
|
}
|
|
|
|
func (t *RefreshTrendingDiscoverTask) Key() string { return "refresh_trending_discover" }
|
|
func (t *RefreshTrendingDiscoverTask) Name() string { return "Refresh Trending Discover" }
|
|
func (t *RefreshTrendingDiscoverTask) Description() string {
|
|
return "Refreshes the persisted external trending list (TMDB/Trakt) for the Trending Discover home section"
|
|
}
|
|
|
|
func (t *RefreshTrendingDiscoverTask) Category() taskmanager.TaskCategory {
|
|
return taskmanager.TaskCategoryLibrary
|
|
}
|
|
|
|
func (t *RefreshTrendingDiscoverTask) IsHidden() bool { return false }
|
|
|
|
func (t *RefreshTrendingDiscoverTask) DefaultTriggers() []taskmanager.TriggerConfig {
|
|
return []taskmanager.TriggerConfig{
|
|
{Type: taskmanager.TriggerTypeStartup},
|
|
{Type: taskmanager.TriggerTypeInterval, IntervalMs: 60 * 60 * 1000}, // hourly
|
|
}
|
|
}
|
|
|
|
func (t *RefreshTrendingDiscoverTask) Execute(ctx context.Context, progress taskmanager.ProgressReporter) error {
|
|
progress.Report(0, "Refreshing trending discover")
|
|
|
|
if t.refresher == nil {
|
|
return errors.New("trending discover refresh: refresher not configured")
|
|
}
|
|
|
|
resultData, err := t.refresher.RunOnce(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("trending discover refresh: %w", err)
|
|
}
|
|
if resultData != nil {
|
|
progress.SetResultData(resultData)
|
|
}
|
|
|
|
progress.Report(100, "Trending discover refresh complete")
|
|
return nil
|
|
}
|