package explore import ( "sort" "time" "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" "github.com/animenotifier/notify.moe/utils" ) const ( currentlyAiringBonus = 5.0 popularityThreshold = 5 popularityPenalty = 8.0 watchingPopularityWeight = 0.3 completedPopularityWeight = 0.3 plannedPopularityWeight = 0.2 agePenalty = 11.0 ageThreshold = 6 * 30 * 24 * time.Hour ) // Get ... func Get(ctx *aero.Context) string { year := "2017" status := "current" typ := "tv" results := filterAnime(year, status, typ) user := utils.GetUser(ctx) return ctx.HTML(components.ExploreAnime(results, year, status, typ, user)) } // Filter ... func Filter(ctx *aero.Context) string { year := ctx.Get("year") status := ctx.Get("status") typ := ctx.Get("type") user := utils.GetUser(ctx) results := filterAnime(year, status, typ) return ctx.HTML(components.ExploreAnime(results, year, status, typ, user)) } func filterAnime(year, status, typ string) []*arn.Anime { var results []*arn.Anime for anime := range arn.StreamAnime() { if len(anime.StartDate) < 4 { continue } if anime.StartDate[:4] != year { continue } if anime.Status != status { continue } if anime.Type != typ { continue } results = append(results, anime) } sortAnime(results, status) return results } func sortAnime(animeList []*arn.Anime, filterStatus string) { sort.Slice(animeList, func(i, j int) bool { a := animeList[i] b := animeList[j] scoreA := a.Rating.Overall scoreB := b.Rating.Overall if a.Status == "current" { scoreA += currentlyAiringBonus } if b.Status == "current" { scoreB += currentlyAiringBonus } if a.Popularity.Total() < popularityThreshold { scoreA -= popularityPenalty } if b.Popularity.Total() < popularityThreshold { scoreB -= popularityPenalty } // If we show current shows, rank old shows a bit lower if filterStatus == "current" { if a.StartDate != "" && time.Since(a.StartDateTime()) > ageThreshold { scoreA -= agePenalty } if b.StartDate != "" && time.Since(b.StartDateTime()) > ageThreshold { scoreB -= agePenalty } } scoreA += float64(a.Popularity.Watching) * watchingPopularityWeight scoreB += float64(b.Popularity.Watching) * watchingPopularityWeight scoreA += float64(a.Popularity.Planned) * plannedPopularityWeight scoreB += float64(b.Popularity.Planned) * plannedPopularityWeight scoreA += float64(a.Popularity.Completed) * completedPopularityWeight scoreB += float64(b.Popularity.Completed) * completedPopularityWeight return scoreA > scoreB }) }