func Search(show *store.Show) ([]Torrent, error) { // torrents holds the torrents to complete a serie var torrents []Torrent // TODO perhaps mashing season and episode jobs together is a bad idea queryJobs := createQueryJobs(show) for _, queryJob := range queryJobs { torrent, err := executeJob(queryJob) if err != nil { continue } torrent.AssociatedMedia = queryJob.media queryJob.snippet.Score = torrent.seeds // *ouch* this type switch is ugly switch queryJob.media.(type) { case *store.Season: show.StoreSeasonSnippet(queryJob.snippet) case *store.Episode: show.StoreEpisodeSnippet(queryJob.snippet) default: panic("unknown media type") } torrents = append(torrents, *torrent) } return torrents, nil }
func selectEpisodeSnippet(show *store.Show) store.Snippet { if len(show.QuerySnippets.ForEpisode) == 0 || isExplore() { // select random snippet var snippets []store.Snippet for k, _ := range episodeQueryAlternatives { for _, morpher := range titleMorphers { snippets = append( snippets, store.Snippet{ Score: 0, TitleSnippet: morpher(show.Title), FormatSnippet: k, }, ) } } snippet := snippets[rand.Intn(len(snippets))] log.WithFields( log.Fields{ "title_snippet": snippet.TitleSnippet, "format_snippet": snippet.FormatSnippet, }).Debug("Random snippet") return snippet } // select the current best return show.BestEpisodeSnippet() }
func TestStoreEpisodeSnippet(t *testing.T) { show := store.Show{} snippet := store.Snippet{Score: 123, TitleSnippet: "abc", FormatSnippet: "sxs"} show.StoreEpisodeSnippet(snippet) assert.Equal(t, snippet, show.QuerySnippets.ForEpisode[0]) }
// SearchTorrents provides some feedback to the user and searches for torrents // for the pending items. func SearchTorrents(show *store.Show) ([]torrents.Torrent, error) { fmt.Printf( "Searching for %d torrents", len(show.PendingSeasons())+len(show.PendingEpisodes()), ) c := startProgressBar() defer stopProgressBar(c) return torrents.Search(show) }
func TestEpisodes(t *testing.T) { season1 := &store.Season{Episodes: []*store.Episode{ {Episode: 1}, {Episode: 2}}} season2 := &store.Season{Episodes: []*store.Episode{ {Episode: 1}, {Episode: 2}}} s := store.Show{Seasons: []*store.Season{season1, season2}} if len(s.Episodes()) != 4 { t.Error("Expected to have 4 episodes, got: ", len(s.Episodes())) } }
// DisplayPendingEpisodes shows, on stdout, the episodes pending for a // particular show. func DisplayPendingEpisodes(show *store.Show) { xs := show.PendingSeasons() for _, x := range xs { fmt.Printf("Pending: %s season %d\n", show.Title, x.Season) } ys := show.PendingEpisodes() if len(ys) > 10 { fmt.Println("<snip>") ys = ys[len(ys)-10:] } for _, y := range ys { fmt.Printf("Pending: %s season %d episode %d\n", show.Title, y.Season(), y.Episode) } }
func queriesForEpisodes(show *store.Show) []queryJob { episodes := show.PendingEpisodes() sort.Sort(store.ByAirDate(episodes)) min := math.Min(float64(len(episodes)), float64(batchSize)) queries := []queryJob{} for _, episode := range episodes[0:int(min)] { snippet := selectEpisodeSnippet(show) query := episodeQueryAlternatives[snippet.FormatSnippet](snippet.TitleSnippet, episode) queries = append(queries, queryJob{ snippet: snippet, query: query, media: episode, }) } return queries }
func queriesForSeasons(show *store.Show) []queryJob { queries := []queryJob{} for _, season := range show.PendingSeasons() { // ignore Season 0, which are specials and are rarely found and/or // interesting. if season.Season == 0 { continue } snippet := selectSeasonSnippet(show) query := seasonQueryAlternatives[snippet.FormatSnippet](snippet.TitleSnippet, season) queries = append(queries, queryJob{ snippet: snippet, query: query, media: season, season: season.Season, }) } return queries }
func selectSeasonSnippet(show *store.Show) store.Snippet { if len(show.QuerySnippets.ForSeason) == 0 || isExplore() { // select random snippet var snippets []store.Snippet for k, _ := range seasonQueryAlternatives { for _, morpher := range titleMorphers { snippets = append( snippets, store.Snippet{ Score: 0, TitleSnippet: morpher(show.Title), FormatSnippet: k, }, ) } } return snippets[rand.Intn(len(snippets))] } // select the current best return show.BestSeasonSnippet() }
func addSeason(show *store.Show, season Season) { newSeason := store.Season{ Season: season.Season, } for _, episode := range season.Episodes { newEpisode := store.Episode{ Episode: episode.Episode, AirDate: episode.AirDate, Title: episode.Title, Pending: true, } newSeason.Episodes = append(newSeason.Episodes, &newEpisode) } show.Seasons = append(show.Seasons, &newSeason) }
func TestDisplayTitle(t *testing.T) { s := store.Show{Title: "bar"} if s.DisplayTitle() != s.Title { t.Error("Expected DisplayTitle to return the Title, got: ", s.DisplayTitle()) } }
func TestPendingItems(t *testing.T) { show := store.Show{} episodes := []*store.Episode{ {Pending: true}, {Pending: true}, {Pending: true}, } season1 := store.Season{Season: 1, Episodes: episodes} show.Seasons = append(show.Seasons, &season1) if len(show.PendingSeasons()) != 0 { t.Error("All episodes are pending but it's from the last seasons thus no seasons should be returned, got:", len(show.PendingSeasons())) } if len(show.PendingEpisodes()) != 3 { t.Error("All episodes are pending, got:", len(show.PendingEpisodes())) } episodes = []*store.Episode{ {Pending: true}, {Pending: true}, } season2 := store.Season{Season: 2, Episodes: episodes} show.Seasons = append(show.Seasons, &season2) if len(show.PendingSeasons()) != 1 { t.Error("Expected 2 items representing the episodes of the last season and 1 item representing the first season.") } if len(show.PendingEpisodes()) != 2 { t.Error("Expected 2 items representing the episodes of the last season and 1 item representing the first season.") } }