From 76e5f37eca4413d347ce62bca5195dc51fca2623 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sat, 28 Oct 2017 03:53:12 +0200 Subject: [PATCH] Nano integration improvements --- jobs/active-users/active-users.go | 114 -------------- jobs/airing-anime/airing-anime.go | 78 ---------- jobs/jobs.go | 3 - jobs/statistics/statistics.go | 251 ------------------------------ main.go | 3 +- pages/best/best.go | 35 +---- pages/explore/explore.go | 51 +++++- pages/explore/explore.pixy | 2 +- pages/statistics/anime.go | 125 ++++++++++++++- pages/statistics/statistics.go | 103 +++++++++++- pages/statistics/statistics.pixy | 2 +- pages/users/users.go | 41 +++-- sw/service-worker.ts | 6 +- tests.go | 1 - 14 files changed, 298 insertions(+), 517 deletions(-) delete mode 100644 jobs/active-users/active-users.go delete mode 100644 jobs/airing-anime/airing-anime.go delete mode 100644 jobs/statistics/statistics.go diff --git a/jobs/active-users/active-users.go b/jobs/active-users/active-users.go deleted file mode 100644 index 4719f262..00000000 --- a/jobs/active-users/active-users.go +++ /dev/null @@ -1,114 +0,0 @@ -package main - -import ( - "fmt" - "sort" - - "github.com/animenotifier/arn" - "github.com/fatih/color" -) - -func main() { - color.Yellow("Caching list of active users") - - // Filter out active users with an avatar - users, err := arn.FilterUsers(func(user *arn.User) bool { - return user.IsActive() && user.Avatar.Extension != "" - }) - fmt.Println(len(users)) - - arn.PanicOnError(err) - - // Sort - sort.Slice(users, func(i, j int) bool { - if users[i].LastSeen < users[j].LastSeen { - return false - } - - if users[i].LastSeen > users[j].LastSeen { - return true - } - - return users[i].Registered > users[j].Registered - }) - - // Add users to list - SaveInCache("active users", users) - - // Sort by osu rank - osuUsers := users[:] - - sort.Slice(osuUsers, func(i, j int) bool { - return osuUsers[i].Accounts.Osu.PP > osuUsers[j].Accounts.Osu.PP - }) - - // Cut off users with 0 pp - for index, user := range osuUsers { - if user.Accounts.Osu.PP == 0 { - osuUsers = osuUsers[:index] - break - } - } - - // Save osu users - SaveInCache("active osu users", osuUsers) - - // Sort by role - staff := users[:] - - sort.Slice(staff, func(i, j int) bool { - if staff[i].Role == "" { - return false - } - - if staff[j].Role == "" { - return true - } - - return staff[i].Role == "admin" - }) - - // Cut off non-staff - for index, user := range staff { - if user.Role == "" { - staff = staff[:index] - break - } - } - - // Save staff users - SaveInCache("active staff users", staff) - - // Sort by anime watching list length - watching := users[:] - - sort.Slice(watching, func(i, j int) bool { - return len(watching[i].AnimeList().FilterStatus(arn.AnimeListStatusWatching).Items) > len(watching[j].AnimeList().FilterStatus(arn.AnimeListStatusWatching).Items) - }) - - // Save watching users - SaveInCache("active anime watching users", watching) - - color.Green("Finished.") -} - -// SaveInCache ... -func SaveInCache(key string, users []*arn.User) { - cache := arn.ListOfIDs{ - IDList: GenerateIDList(users), - } - - fmt.Println(len(cache.IDList), key) - arn.PanicOnError(arn.DB.Set("Cache", key, cache)) -} - -// GenerateIDList generates an ID list from a slice of users. -func GenerateIDList(users []*arn.User) []string { - list := []string{} - - for _, user := range users { - list = append(list, user.ID) - } - - return list -} diff --git a/jobs/airing-anime/airing-anime.go b/jobs/airing-anime/airing-anime.go deleted file mode 100644 index 96d41214..00000000 --- a/jobs/airing-anime/airing-anime.go +++ /dev/null @@ -1,78 +0,0 @@ -package main - -import ( - "sort" - - "github.com/animenotifier/arn" - "github.com/fatih/color" -) - -const ( - currentlyAiringBonus = 5.0 - popularityThreshold = 5 - popularityPenalty = 8.0 - watchingPopularityWeight = 0.3 - plannedPopularityWeight = 0.2 -) - -func main() { - color.Yellow("Caching airing anime") - - animeList, err := arn.GetAiringAnime() - - if err != nil { - color.Red("Failed fetching airing anime") - color.Red(err.Error()) - return - } - - 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 - } - - scoreA += float64(a.Popularity.Watching) * watchingPopularityWeight - scoreB += float64(b.Popularity.Watching) * watchingPopularityWeight - - scoreA += float64(a.Popularity.Planned) * plannedPopularityWeight - scoreB += float64(b.Popularity.Planned) * plannedPopularityWeight - - return scoreA > scoreB - }) - - // Convert to small anime list - cache := &arn.ListOfIDs{} - - for _, anime := range animeList { - cache.IDList = append(cache.IDList, anime.ID) - } - - println(len(cache.IDList)) - - saveErr := arn.DB.Set("Cache", "airing anime", cache) - - if saveErr != nil { - color.Red("Error saving airing anime") - color.Red(saveErr.Error()) - return - } - - color.Green("Finished.") -} diff --git a/jobs/jobs.go b/jobs/jobs.go index d05f663e..280cb7b5 100644 --- a/jobs/jobs.go +++ b/jobs/jobs.go @@ -24,10 +24,7 @@ var colorPool = []*color.Color{ var jobs = map[string]time.Duration{ "forum-activity": 1 * time.Minute, - "active-users": 5 * time.Minute, "anime-ratings": 10 * time.Minute, - "airing-anime": 10 * time.Minute, - "statistics": 15 * time.Minute, "popular-anime": 20 * time.Minute, "avatars": 1 * time.Hour, "test": 1 * time.Hour, diff --git a/jobs/statistics/statistics.go b/jobs/statistics/statistics.go deleted file mode 100644 index deb9d5e1..00000000 --- a/jobs/statistics/statistics.go +++ /dev/null @@ -1,251 +0,0 @@ -package main - -import ( - "fmt" - "strings" - - "github.com/animenotifier/arn" - "github.com/fatih/color" -) - -type stats map[string]float64 - -func main() { - color.Yellow("Generating statistics") - - userStats := getUserStats() - animeStats := getAnimeStats() - - arn.PanicOnError(arn.DB.Set("Cache", "user statistics", &arn.StatisticsCategory{ - Name: "Users", - PieCharts: userStats, - })) - - arn.PanicOnError(arn.DB.Set("Cache", "anime statistics", &arn.StatisticsCategory{ - Name: "Anime", - PieCharts: animeStats, - })) - - color.Green("Finished.") -} - -func getUserStats() []*arn.PieChart { - println("Generating user statistics") - - analytics, err := arn.AllAnalytics() - arn.PanicOnError(err) - - screenSize := stats{} - pixelRatio := stats{} - browser := stats{} - country := stats{} - gender := stats{} - os := stats{} - notifications := stats{} - avatar := stats{} - ip := stats{} - pro := stats{} - - for _, info := range analytics { - user, err := arn.GetUser(info.UserID) - arn.PanicOnError(err) - - if !user.IsActive() { - continue - } - - pixelRatio[fmt.Sprintf("%.0f", info.Screen.PixelRatio)]++ - - size := arn.ToString(info.Screen.Width) + " x " + arn.ToString(info.Screen.Height) - screenSize[size]++ - } - - for user := range arn.MustStreamUsers() { - if !user.IsActive() { - continue - } - - if user.Gender != "" && user.Gender != "other" { - gender[user.Gender]++ - } - - if user.Browser.Name != "" { - browser[user.Browser.Name]++ - } - - if user.Location.CountryName != "" { - country[user.Location.CountryName]++ - } - - if user.OS.Name != "" { - if strings.HasPrefix(user.OS.Name, "CrOS") { - user.OS.Name = "Chrome OS" - } - - os[user.OS.Name]++ - } - - if len(user.PushSubscriptions().Items) > 0 { - notifications["Enabled"]++ - } else { - notifications["Disabled"]++ - } - - if user.Avatar.Source == "" { - avatar["none"]++ - } else { - avatar[user.Avatar.Source]++ - } - - if arn.IsIPv6(user.IP) { - ip["IPv6"]++ - } else { - ip["IPv4"]++ - } - - if user.IsPro() { - pro["PRO accounts"]++ - } else { - pro["Free accounts"]++ - } - } - - println("Finished user statistics") - - return []*arn.PieChart{ - arn.NewPieChart("OS", os), - arn.NewPieChart("Screen size", screenSize), - arn.NewPieChart("Browser", browser), - arn.NewPieChart("Country", country), - arn.NewPieChart("Avatar", avatar), - arn.NewPieChart("Notifications", notifications), - arn.NewPieChart("Gender", gender), - arn.NewPieChart("Pixel ratio", pixelRatio), - arn.NewPieChart("IP version", ip), - arn.NewPieChart("PRO accounts", pro), - } -} - -func getAnimeStats() []*arn.PieChart { - println("Generating anime statistics") - - allAnime, err := arn.AllAnime() - arn.PanicOnError(err) - - shoboi := stats{} - anilist := stats{} - mal := stats{} - anidb := stats{} - status := stats{} - types := stats{} - shoboiEdits := stats{} - anilistEdits := stats{} - malEdits := stats{} - anidbEdits := stats{} - rating := stats{} - twist := stats{} - - for _, anime := range allAnime { - for _, external := range anime.Mappings { - if external.Service == "shoboi/anime" { - if external.CreatedBy == "" { - shoboiEdits["(auto-generated)"]++ - } else { - user, err := arn.GetUser(external.CreatedBy) - arn.PanicOnError(err) - shoboiEdits[user.Nick]++ - } - } - - if external.Service == "anilist/anime" { - if external.CreatedBy == "" { - anilistEdits["(auto-generated)"]++ - } else { - user, err := arn.GetUser(external.CreatedBy) - arn.PanicOnError(err) - anilistEdits[user.Nick]++ - } - } - - if external.Service == "myanimelist/anime" { - if external.CreatedBy == "" { - malEdits["(auto-generated)"]++ - } else { - user, err := arn.GetUser(external.CreatedBy) - arn.PanicOnError(err) - malEdits[user.Nick]++ - } - } - - if external.Service == "anidb/anime" { - if external.CreatedBy == "" { - anidbEdits["(auto-generated)"]++ - } else { - user, err := arn.GetUser(external.CreatedBy) - arn.PanicOnError(err) - anidbEdits[user.Nick]++ - } - } - } - - if anime.GetMapping("shoboi/anime") != "" { - shoboi["Connected with Shoboi"]++ - } else { - shoboi["Not connected with Shoboi"]++ - } - - if anime.GetMapping("anilist/anime") != "" { - anilist["Connected with AniList"]++ - } else { - anilist["Not connected with AniList"]++ - } - - if anime.GetMapping("myanimelist/anime") != "" { - mal["Connected with MyAnimeList"]++ - } else { - mal["Not connected with MyAnimeList"]++ - } - - if anime.GetMapping("anidb/anime") != "" { - anidb["Connected with AniDB"]++ - } else { - anidb["Not connected with AniDB"]++ - } - - rating[arn.ToString(int(anime.Rating.Overall+0.5))]++ - - found := false - for _, episode := range anime.Episodes().Items { - if episode.Links != nil && episode.Links["twist.moe"] != "" { - found = true - break - } - } - - if found { - twist["Connected with AnimeTwist"]++ - } else { - twist["Not connected with AnimeTwist"]++ - } - - status[anime.Status]++ - types[anime.Type]++ - } - - println("Finished anime statistics") - - return []*arn.PieChart{ - arn.NewPieChart("Type", types), - arn.NewPieChart("Status", status), - arn.NewPieChart("Rating", rating), - arn.NewPieChart("MyAnimeList", mal), - arn.NewPieChart("AniList", anilist), - arn.NewPieChart("AniDB", anidb), - arn.NewPieChart("Shoboi", shoboi), - arn.NewPieChart("AnimeTwist", twist), - // arn.NewPieChart("MyAnimeList Editors", malEdits), - arn.NewPieChart("AniList Editors", anilistEdits), - // arn.NewPieChart("AniDB Editors", anidbEdits), - arn.NewPieChart("Shoboi Editors", shoboiEdits), - } -} diff --git a/main.go b/main.go index 4c7277e2..8debce18 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "github.com/aerogo/aero" + "github.com/aerogo/session-store-nano" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/auth" "github.com/animenotifier/notify.moe/components/css" @@ -70,8 +71,8 @@ func configure(app *aero.Application) *aero.Application { app.Sessions.Duration = 3600 * 24 * 30 * 6 // TODO: ... - println("Using memory session store") // app.Sessions.Store = aerospikestore.New(arn.DB, "Session", app.Sessions.Duration) + app.Sessions.Store = nanostore.New(arn.DB, "Session") // Layout app.Layout = layout.Render diff --git a/pages/best/best.go b/pages/best/best.go index e5ce245d..5257a910 100644 --- a/pages/best/best.go +++ b/pages/best/best.go @@ -1,10 +1,7 @@ package best import ( - "net/http" - "github.com/aerogo/aero" - "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" ) @@ -12,35 +9,5 @@ const maxEntries = 7 // Get search page. func Get(ctx *aero.Context) string { - overall, err := arn.GetListOfAnimeCached("best anime overall") - - if err != nil { - return ctx.Error(http.StatusInternalServerError, "Error fetching popular anime", err) - } - - story, err := arn.GetListOfAnimeCached("best anime story") - - if err != nil { - return ctx.Error(http.StatusInternalServerError, "Error fetching popular anime", err) - } - - visuals, err := arn.GetListOfAnimeCached("best anime visuals") - - if err != nil { - return ctx.Error(http.StatusInternalServerError, "Error fetching popular anime", err) - } - - soundtrack, err := arn.GetListOfAnimeCached("best anime soundtrack") - - if err != nil { - return ctx.Error(http.StatusInternalServerError, "Error fetching popular anime", err) - } - - airing, err := arn.GetAiringAnimeCached() - - if err != nil { - return ctx.Error(500, "Couldn't fetch airing anime", err) - } - - return ctx.HTML(components.BestAnime(overall[:maxEntries], story[:maxEntries], visuals[:maxEntries], soundtrack[:maxEntries], airing[:maxEntries])) + return ctx.HTML(components.BestAnime(nil, nil, nil, nil, nil)) } diff --git a/pages/explore/explore.go b/pages/explore/explore.go index fe1225f5..be55016b 100644 --- a/pages/explore/explore.go +++ b/pages/explore/explore.go @@ -1,20 +1,55 @@ package explore import ( + "sort" + "github.com/aerogo/aero" + "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/components" +) + +const ( + currentlyAiringBonus = 5.0 + popularityThreshold = 5 + popularityPenalty = 8.0 + watchingPopularityWeight = 0.3 + plannedPopularityWeight = 0.2 ) // Get ... func Get(ctx *aero.Context) string { - // var cache arn.ListOfIDs - // err := arn.DB.GetObject("Cache", "airing anime", &cache) + animeList := arn.GetAiringAnime() - // airing, err := arn.GetAiringAnimeCached() + sort.Slice(animeList, func(i, j int) bool { + a := animeList[i] + b := animeList[j] + scoreA := a.Rating.Overall + scoreB := b.Rating.Overall - // if err != nil { - // return ctx.Error(500, "Couldn't fetch airing anime", err) - // } + if a.Status == "current" { + scoreA += currentlyAiringBonus + } - // return ctx.HTML(components.Airing(airing)) - return ctx.HTML("Not implemented") + if b.Status == "current" { + scoreB += currentlyAiringBonus + } + + if a.Popularity.Total() < popularityThreshold { + scoreA -= popularityPenalty + } + + if b.Popularity.Total() < popularityThreshold { + scoreB -= popularityPenalty + } + + scoreA += float64(a.Popularity.Watching) * watchingPopularityWeight + scoreB += float64(b.Popularity.Watching) * watchingPopularityWeight + + scoreA += float64(a.Popularity.Planned) * plannedPopularityWeight + scoreB += float64(b.Popularity.Planned) * plannedPopularityWeight + + return scoreA > scoreB + }) + + return ctx.HTML(components.Explore(animeList)) } diff --git a/pages/explore/explore.pixy b/pages/explore/explore.pixy index 8a0149a5..7c7c2cc0 100644 --- a/pages/explore/explore.pixy +++ b/pages/explore/explore.pixy @@ -1,3 +1,3 @@ -component Airing(animeList []*arn.Anime) +component Explore(animeList []*arn.Anime) h1.page-title(title=toString(len(animeList)) + " anime") Explore AnimeGrid(animeList) \ No newline at end of file diff --git a/pages/statistics/anime.go b/pages/statistics/anime.go index 19e4ed4e..06b04db6 100644 --- a/pages/statistics/anime.go +++ b/pages/statistics/anime.go @@ -2,12 +2,129 @@ package statistics import ( "github.com/aerogo/aero" + "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/components" ) // Anime ... func Anime(ctx *aero.Context) string { - // statistics := arn.StatisticsCategory{} - // arn.DB.GetObject("Cache", "anime statistics", &statistics) - // return ctx.HTML(components.Statistics(statistics.PieCharts...)) - return ctx.HTML("Not implemented") + pieCharts := getAnimeStats() + return ctx.HTML(components.Statistics(pieCharts)) +} + +func getAnimeStats() []*arn.PieChart { + shoboi := stats{} + anilist := stats{} + mal := stats{} + anidb := stats{} + status := stats{} + types := stats{} + shoboiEdits := stats{} + anilistEdits := stats{} + malEdits := stats{} + anidbEdits := stats{} + rating := stats{} + twist := stats{} + + for anime := range arn.StreamAnime() { + for _, external := range anime.Mappings { + if external.Service == "shoboi/anime" { + if external.CreatedBy == "" { + shoboiEdits["(auto-generated)"]++ + } else { + user, err := arn.GetUser(external.CreatedBy) + arn.PanicOnError(err) + shoboiEdits[user.Nick]++ + } + } + + if external.Service == "anilist/anime" { + if external.CreatedBy == "" { + anilistEdits["(auto-generated)"]++ + } else { + user, err := arn.GetUser(external.CreatedBy) + arn.PanicOnError(err) + anilistEdits[user.Nick]++ + } + } + + if external.Service == "myanimelist/anime" { + if external.CreatedBy == "" { + malEdits["(auto-generated)"]++ + } else { + user, err := arn.GetUser(external.CreatedBy) + arn.PanicOnError(err) + malEdits[user.Nick]++ + } + } + + if external.Service == "anidb/anime" { + if external.CreatedBy == "" { + anidbEdits["(auto-generated)"]++ + } else { + user, err := arn.GetUser(external.CreatedBy) + arn.PanicOnError(err) + anidbEdits[user.Nick]++ + } + } + } + + if anime.GetMapping("shoboi/anime") != "" { + shoboi["Connected with Shoboi"]++ + } else { + shoboi["Not connected with Shoboi"]++ + } + + if anime.GetMapping("anilist/anime") != "" { + anilist["Connected with AniList"]++ + } else { + anilist["Not connected with AniList"]++ + } + + if anime.GetMapping("myanimelist/anime") != "" { + mal["Connected with MyAnimeList"]++ + } else { + mal["Not connected with MyAnimeList"]++ + } + + if anime.GetMapping("anidb/anime") != "" { + anidb["Connected with AniDB"]++ + } else { + anidb["Not connected with AniDB"]++ + } + + rating[arn.ToString(int(anime.Rating.Overall+0.5))]++ + + found := false + for _, episode := range anime.Episodes().Items { + if episode.Links != nil && episode.Links["twist.moe"] != "" { + found = true + break + } + } + + if found { + twist["Connected with AnimeTwist"]++ + } else { + twist["Not connected with AnimeTwist"]++ + } + + status[anime.Status]++ + types[anime.Type]++ + } + + return []*arn.PieChart{ + arn.NewPieChart("Type", types), + arn.NewPieChart("Status", status), + arn.NewPieChart("Rating", rating), + arn.NewPieChart("MyAnimeList", mal), + arn.NewPieChart("AniList", anilist), + arn.NewPieChart("AniDB", anidb), + arn.NewPieChart("Shoboi", shoboi), + arn.NewPieChart("AnimeTwist", twist), + // arn.NewPieChart("MyAnimeList Editors", malEdits), + arn.NewPieChart("AniList Editors", anilistEdits), + // arn.NewPieChart("AniDB Editors", anidbEdits), + arn.NewPieChart("Shoboi Editors", shoboiEdits), + } } diff --git a/pages/statistics/statistics.go b/pages/statistics/statistics.go index a9219f76..649deb63 100644 --- a/pages/statistics/statistics.go +++ b/pages/statistics/statistics.go @@ -1,13 +1,108 @@ package statistics import ( + "fmt" + "strings" + "github.com/aerogo/aero" + "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/components" ) +type stats map[string]float64 + // Get ... func Get(ctx *aero.Context) string { - // statistics := arn.StatisticsCategory{} - // arn.DB.GetObject("Cache", "user statistics", &statistics) - // return ctx.HTML(components.Statistics(statistics.PieCharts...)) - return ctx.HTML("Not implemented") + pieCharts := getUserStats() + return ctx.HTML(components.Statistics(pieCharts)) +} + +func getUserStats() []*arn.PieChart { + screenSize := stats{} + pixelRatio := stats{} + browser := stats{} + country := stats{} + gender := stats{} + os := stats{} + notifications := stats{} + avatar := stats{} + ip := stats{} + pro := stats{} + + for info := range arn.StreamAnalytics() { + user, err := arn.GetUser(info.UserID) + arn.PanicOnError(err) + + if !user.IsActive() { + continue + } + + pixelRatio[fmt.Sprintf("%.0f", info.Screen.PixelRatio)]++ + + size := arn.ToString(info.Screen.Width) + " x " + arn.ToString(info.Screen.Height) + screenSize[size]++ + } + + for user := range arn.StreamUsers() { + if !user.IsActive() { + continue + } + + if user.Gender != "" && user.Gender != "other" { + gender[user.Gender]++ + } + + if user.Browser.Name != "" { + browser[user.Browser.Name]++ + } + + if user.Location.CountryName != "" { + country[user.Location.CountryName]++ + } + + if user.OS.Name != "" { + if strings.HasPrefix(user.OS.Name, "CrOS") { + user.OS.Name = "Chrome OS" + } + + os[user.OS.Name]++ + } + + if len(user.PushSubscriptions().Items) > 0 { + notifications["Enabled"]++ + } else { + notifications["Disabled"]++ + } + + if user.Avatar.Source == "" { + avatar["none"]++ + } else { + avatar[user.Avatar.Source]++ + } + + if arn.IsIPv6(user.IP) { + ip["IPv6"]++ + } else { + ip["IPv4"]++ + } + + if user.IsPro() { + pro["PRO accounts"]++ + } else { + pro["Free accounts"]++ + } + } + + return []*arn.PieChart{ + arn.NewPieChart("OS", os), + arn.NewPieChart("Screen size", screenSize), + arn.NewPieChart("Browser", browser), + arn.NewPieChart("Country", country), + arn.NewPieChart("Avatar", avatar), + arn.NewPieChart("Notifications", notifications), + arn.NewPieChart("Gender", gender), + arn.NewPieChart("Pixel ratio", pixelRatio), + arn.NewPieChart("IP version", ip), + arn.NewPieChart("PRO accounts", pro), + } } diff --git a/pages/statistics/statistics.pixy b/pages/statistics/statistics.pixy index c9fad809..7abdc72f 100644 --- a/pages/statistics/statistics.pixy +++ b/pages/statistics/statistics.pixy @@ -1,4 +1,4 @@ -component Statistics(pieCharts ...*arn.PieChart) +component Statistics(pieCharts []*arn.PieChart) h1.page-title Statistics StatisticsHeader diff --git a/pages/users/users.go b/pages/users/users.go index b12b5fe2..7004e18e 100644 --- a/pages/users/users.go +++ b/pages/users/users.go @@ -1,7 +1,7 @@ package users import ( - "net/http" + "sort" "github.com/aerogo/aero" "github.com/animenotifier/arn" @@ -21,11 +21,14 @@ func Active(ctx *aero.Context) string { // Osu ... func Osu(ctx *aero.Context) string { - users, err := arn.GetListOfUsersCached("active osu users") + users := arn.FilterUsers(func(user *arn.User) bool { + return user.IsActive() && user.HasAvatar() && user.Accounts.Osu.PP > 0 + }) - if err != nil { - return ctx.Error(http.StatusInternalServerError, "Could not fetch user data", err) - } + // Sort by pp + sort.Slice(users, func(i, j int) bool { + return users[i].Accounts.Osu.PP > users[j].Accounts.Osu.PP + }) if len(users) > 50 { users = users[:50] @@ -36,22 +39,34 @@ func Osu(ctx *aero.Context) string { // Staff ... func Staff(ctx *aero.Context) string { - users, err := arn.GetListOfUsersCached("active staff users") + users := arn.FilterUsers(func(user *arn.User) bool { + return user.IsActive() && user.HasAvatar() && user.Role != "" + }) - if err != nil { - return ctx.Error(http.StatusInternalServerError, "Could not fetch user data", err) - } + sort.Slice(users, func(i, j int) bool { + if users[i].Role == "" { + return false + } + + if users[j].Role == "" { + return true + } + + return users[i].Role == "admin" + }) return ctx.HTML(components.Users(users)) } // AnimeWatching ... func AnimeWatching(ctx *aero.Context) string { - users, err := arn.GetListOfUsersCached("active anime watching users") + users := arn.FilterUsers(func(user *arn.User) bool { + return user.IsActive() && user.HasAvatar() + }) - if err != nil { - return ctx.Error(http.StatusInternalServerError, "Could not fetch user data", err) - } + sort.Slice(users, func(i, j int) bool { + return len(users[i].AnimeList().Watching().Items) > len(users[j].AnimeList().Watching().Items) + }) return ctx.HTML(components.Users(users)) } diff --git a/sw/service-worker.ts b/sw/service-worker.ts index 901a49ca..e87756cc 100644 --- a/sw/service-worker.ts +++ b/sw/service-worker.ts @@ -87,8 +87,6 @@ class MyServiceWorker { onRequest(evt: FetchEvent) { let request = evt.request as Request - // console.log("fetch:", request.url) - // If it's not a GET request, fetch it normally if(request.method !== "GET") { return evt.respondWith(fetch(request)) @@ -96,7 +94,7 @@ class MyServiceWorker { // Clear cache on authentication and fetch it normally if(request.url.includes("/auth/") || request.url.includes("/logout")) { - return caches.delete(this.cache.version).then(() => evt.respondWith(fetch(request))) + return evt.respondWith(caches.delete(this.cache.version).then(() => fetch(request))) } // Exclude certain URLs from being cached @@ -109,7 +107,7 @@ class MyServiceWorker { // If the request included the header "X-CacheOnly", return a cache-only response. // This is used in reloads to avoid generating a 2nd request after a cache refresh. if(request.headers.get("X-CacheOnly") === "true") { - return this.fromCache(request) + return evt.respondWith(this.fromCache(request)) } // Start fetching the request diff --git a/tests.go b/tests.go index 0e8fe3e7..00c691be 100644 --- a/tests.go +++ b/tests.go @@ -245,7 +245,6 @@ var routeTests = map[string][]string{ "/paypal/cancel": nil, "/anime/:id/edit": nil, "/new/thread": nil, - "/new/soundtrack": nil, "/admin/purchases": nil, "/editor/anilist": nil, "/editor/shoboi": nil,