diff --git a/assets/assets.go b/assets/assets.go index d84dc91e..308a474d 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -19,6 +19,7 @@ var ( CSS string ServiceWorker string Organization string + Domain = "notify.moe" ) // load loads all the necessary assets into memory. @@ -57,55 +58,55 @@ func load() { CSS = css.Bundle() } -// Configure adds all the routes used for media assets. +// Configure adds all the routes used for media func Configure(app *aero.Application) { load() - app.Get("/scripts", func(ctx *aero.Context) string { + app.Get("/scripts", func(ctx aero.Context) error { return ctx.JavaScript(JS) }) - app.Get("/styles", func(ctx *aero.Context) string { + app.Get("/styles", func(ctx aero.Context) error { return ctx.CSS(CSS) }) - app.Get("/service-worker", func(ctx *aero.Context) string { + app.Get("/service-worker", func(ctx aero.Context) error { return ctx.JavaScript(ServiceWorker) }) // Web manifest - app.Get("/manifest.json", func(ctx *aero.Context) string { + app.Get("/manifest.json", func(ctx aero.Context) error { return ctx.JSON(Manifest) }) // Favicon - app.Get("/favicon.ico", func(ctx *aero.Context) string { - ctx.Response().Header().Set("Access-Control-Allow-Origin", "*") + app.Get("/favicon.ico", func(ctx aero.Context) error { + ctx.Response().SetHeader("Access-Control-Allow-Origin", "*") return ctx.File("images/brand/64.png") }) // Images - app.Get("/images/*file", func(ctx *aero.Context) string { - ctx.Response().Header().Set("Access-Control-Allow-Origin", "*") + app.Get("/images/*file", func(ctx aero.Context) error { + ctx.Response().SetHeader("Access-Control-Allow-Origin", "*") return ctx.File("images/" + ctx.Get("file")) }) // Videos - app.Get("/videos/*file", func(ctx *aero.Context) string { - ctx.Response().Header().Set("Access-Control-Allow-Origin", "*") + app.Get("/videos/*file", func(ctx aero.Context) error { + ctx.Response().SetHeader("Access-Control-Allow-Origin", "*") return ctx.File("videos/" + ctx.Get("file")) }) // Audio - app.Get("/audio/*file", func(ctx *aero.Context) string { - ctx.Response().Header().Set("Access-Control-Allow-Origin", "*") + app.Get("/audio/*file", func(ctx aero.Context) error { + ctx.Response().SetHeader("Access-Control-Allow-Origin", "*") return ctx.File("audio/" + ctx.Get("file")) }) // Anime sitemap - app.Get("/sitemap/anime.txt", func(ctx *aero.Context) string { + app.Get("/sitemap/anime.txt", func(ctx aero.Context) error { sitemap := sitemap.New() - prefix := "https://" + app.Config.Domain + prefix := "https://" + Domain for anime := range arn.StreamAnime() { sitemap.Add(prefix + anime.Link()) @@ -115,9 +116,9 @@ func Configure(app *aero.Application) { }) // Character sitemap - app.Get("/sitemap/character.txt", func(ctx *aero.Context) string { + app.Get("/sitemap/character.txt", func(ctx aero.Context) error { sitemap := sitemap.New() - prefix := "https://" + app.Config.Domain + prefix := "https://" + Domain for character := range arn.StreamCharacters() { sitemap.Add(prefix + character.Link()) @@ -127,9 +128,9 @@ func Configure(app *aero.Application) { }) // User sitemap - app.Get("/sitemap/user.txt", func(ctx *aero.Context) string { + app.Get("/sitemap/user.txt", func(ctx aero.Context) error { sitemap := sitemap.New() - prefix := "https://" + app.Config.Domain + prefix := "https://" + Domain for user := range arn.StreamUsers() { if !user.HasNick() { @@ -143,9 +144,9 @@ func Configure(app *aero.Application) { }) // SoundTrack sitemap - app.Get("/sitemap/soundtrack.txt", func(ctx *aero.Context) string { + app.Get("/sitemap/soundtrack.txt", func(ctx aero.Context) error { sitemap := sitemap.New() - prefix := "https://" + app.Config.Domain + prefix := "https://" + Domain for soundTrack := range arn.StreamSoundTracks() { sitemap.Add(prefix + soundTrack.Link()) @@ -155,9 +156,9 @@ func Configure(app *aero.Application) { }) // Thread sitemap - app.Get("/sitemap/thread.txt", func(ctx *aero.Context) string { + app.Get("/sitemap/thread.txt", func(ctx aero.Context) error { sitemap := sitemap.New() - prefix := "https://" + app.Config.Domain + prefix := "https://" + Domain for thread := range arn.StreamThreads() { sitemap.Add(prefix + thread.Link()) @@ -167,9 +168,9 @@ func Configure(app *aero.Application) { }) // Post sitemap - app.Get("/sitemap/post.txt", func(ctx *aero.Context) string { + app.Get("/sitemap/post.txt", func(ctx aero.Context) error { sitemap := sitemap.New() - prefix := "https://" + app.Config.Domain + prefix := "https://" + Domain for post := range arn.StreamPosts() { sitemap.Add(prefix + post.Link()) @@ -179,7 +180,7 @@ func Configure(app *aero.Application) { }) // For benchmarks - app.Get("/hello", func(ctx *aero.Context) string { + app.Get("/hello", func(ctx aero.Context) error { return ctx.Text("Hello World") }) } diff --git a/auth/auth.go b/auth/auth.go index 140d3704..78470c98 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -1,6 +1,8 @@ package auth import ( + "net/http" + "github.com/aerogo/aero" "github.com/animenotifier/notify.moe/utils" ) @@ -19,17 +21,17 @@ func Install(app *aero.Application) { InstallTwitterAuth(app) // Logout - app.Get("/logout", func(ctx *aero.Context) string { + app.Get("/logout", func(ctx aero.Context) error { if ctx.HasSession() { user := utils.GetUser(ctx) if user != nil { - authLog.Info("%s logged out | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("%s logged out | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) } ctx.Session().Delete("userId") } - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") }) } diff --git a/auth/facebook.go b/auth/facebook.go index 5e2d0447..93ac1662 100644 --- a/auth/facebook.go +++ b/auth/facebook.go @@ -9,6 +9,7 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/utils" jsoniter "github.com/json-iterator/go" "golang.org/x/oauth2" @@ -33,7 +34,7 @@ func InstallFacebookAuth(app *aero.Application) { config := &oauth2.Config{ ClientID: arn.APIKeys.Facebook.ID, ClientSecret: arn.APIKeys.Facebook.Secret, - RedirectURL: "https://" + app.Config.Domain + "/auth/facebook/callback", + RedirectURL: "https://" + assets.Domain + "/auth/facebook/callback", Scopes: []string{ "public_profile", "email", @@ -44,10 +45,10 @@ func InstallFacebookAuth(app *aero.Application) { // When a user visits /auth/facebook, we ask OAuth2 config for a URL // to redirect the user to. Once the user has logged in on that page, // he'll be redirected back to our servers to the callback page. - app.Get("/auth/facebook", func(ctx *aero.Context) string { + app.Get("/auth/facebook", func(ctx aero.Context) error { state := ctx.Session().ID() url := config.AuthCodeURL(state) - return ctx.Redirect(url) + return ctx.Redirect(http.StatusFound, url) }) // This is the redirect URL that we specified in the OAuth2 config. @@ -55,7 +56,7 @@ func InstallFacebookAuth(app *aero.Application) { // Now we have to check for fraud requests and request user information. // If both Facebook ID and email can't be found in our DB, register a new user. // Otherwise, log in the user with the given Facebook ID or email. - app.Get("/auth/facebook/callback", func(ctx *aero.Context) string { + app.Get("/auth/facebook/callback", func(ctx aero.Context) error { if !ctx.HasSession() { return ctx.Error(http.StatusUnauthorized, "Facebook login failed", errors.New("Session does not exist")) } @@ -108,9 +109,9 @@ func InstallFacebookAuth(app *aero.Application) { user.Save() // Log - authLog.Info("Added Facebook ID to existing account | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("Added Facebook ID to existing account | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } var getErr error @@ -119,7 +120,7 @@ func InstallFacebookAuth(app *aero.Application) { user, getErr = arn.GetUserByFacebookID(fbUser.ID) if getErr == nil && user != nil { - authLog.Info("User logged in via Facebook ID | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("User logged in via Facebook ID | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) // Add FacebookToUser reference user.ConnectFacebook(fbUser.ID) @@ -128,20 +129,20 @@ func InstallFacebookAuth(app *aero.Application) { user.Save() session.Set("userId", user.ID) - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } // Try to find an existing user via the associated e-mail address user, getErr = arn.GetUserByEmail(fbUser.Email) if getErr == nil && user != nil { - authLog.Info("User logged in via Email | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("User logged in via Email | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) user.LastLogin = arn.DateTimeUTC() user.Save() session.Set("userId", user.ID) - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } // Register new user @@ -169,9 +170,9 @@ func InstallFacebookAuth(app *aero.Application) { session.Set("userId", user.ID) // Log - authLog.Info("Registered new user via Facebook | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("Registered new user via Facebook | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) // Redirect to starting page for new users - return ctx.Redirect(newUserStartRoute) + return ctx.Redirect(http.StatusFound, newUserStartRoute) }) } diff --git a/auth/google.go b/auth/google.go index 5db50d25..d96f67fb 100644 --- a/auth/google.go +++ b/auth/google.go @@ -9,6 +9,7 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/utils" jsoniter "github.com/json-iterator/go" "golang.org/x/oauth2" @@ -38,7 +39,7 @@ func InstallGoogleAuth(app *aero.Application) { config := &oauth2.Config{ ClientID: arn.APIKeys.Google.ID, ClientSecret: arn.APIKeys.Google.Secret, - RedirectURL: "https://" + app.Config.Domain + "/auth/google/callback", + RedirectURL: "https://" + assets.Domain + "/auth/google/callback", Scopes: []string{ "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", @@ -51,10 +52,10 @@ func InstallGoogleAuth(app *aero.Application) { // When a user visits /auth/google, we ask OAuth2 config for a URL // to redirect the user to. Once the user has logged in on that page, // he'll be redirected back to our servers to the callback page. - app.Get("/auth/google", func(ctx *aero.Context) string { + app.Get("/auth/google", func(ctx aero.Context) error { state := ctx.Session().ID() url := config.AuthCodeURL(state) - return ctx.Redirect(url) + return ctx.Redirect(http.StatusFound, url) }) // This is the redirect URL that we specified in the OAuth2 config. @@ -62,7 +63,7 @@ func InstallGoogleAuth(app *aero.Application) { // Now we have to check for fraud requests and request user information. // If both Google ID and email can't be found in our DB, register a new user. // Otherwise, log in the user with the given Google ID or email. - app.Get("/auth/google/callback", func(ctx *aero.Context) string { + app.Get("/auth/google/callback", func(ctx aero.Context) error { if !ctx.HasSession() { return ctx.Error(http.StatusUnauthorized, "Google login failed", errors.New("Session does not exist")) } @@ -119,9 +120,9 @@ func InstallGoogleAuth(app *aero.Application) { user.Save() // Log - authLog.Info("Added Google ID to existing account | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("Added Google ID to existing account | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } var getErr error @@ -130,20 +131,20 @@ func InstallGoogleAuth(app *aero.Application) { user, getErr = arn.GetUserByGoogleID(googleUser.Sub) if getErr == nil && user != nil { - authLog.Info("User logged in via Google ID | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("User logged in via Google ID | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) user.LastLogin = arn.DateTimeUTC() user.Save() session.Set("userId", user.ID) - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } // Try to find an existing user via the associated e-mail address user, getErr = arn.GetUserByEmail(googleUser.Email) if getErr == nil && user != nil { - authLog.Info("User logged in via Email | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("User logged in via Email | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) // Add GoogleToUser reference user.ConnectGoogle(googleUser.Sub) @@ -152,7 +153,7 @@ func InstallGoogleAuth(app *aero.Application) { user.Save() session.Set("userId", user.ID) - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } // Register new user @@ -180,9 +181,9 @@ func InstallGoogleAuth(app *aero.Application) { session.Set("userId", user.ID) // Log - authLog.Info("Registered new user via Google | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("Registered new user via Google | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) // Redirect to starting page for new users - return ctx.Redirect(newUserStartRoute) + return ctx.Redirect(http.StatusFound, newUserStartRoute) }) } diff --git a/auth/twitter.go b/auth/twitter.go index 4fa4dd16..da5371cc 100644 --- a/auth/twitter.go +++ b/auth/twitter.go @@ -10,6 +10,7 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/utils" "github.com/gomodule/oauth1/oauth" jsoniter "github.com/json-iterator/go" @@ -42,8 +43,8 @@ func InstallTwitterAuth(app *aero.Application) { // a request token and give us a URL to redirect the user to. // Once the user has approved the application on that page, // he'll be redirected back to our servers to the callback page. - app.Get("/auth/twitter", func(ctx *aero.Context) string { - callback := "https://" + ctx.App.Config.Domain + "/auth/twitter/callback" + app.Get("/auth/twitter", func(ctx aero.Context) error { + callback := "https://" + assets.Domain + "/auth/twitter/callback" tempCred, err := config.RequestTemporaryCredentials(nil, callback, nil) if err != nil { @@ -52,7 +53,7 @@ func InstallTwitterAuth(app *aero.Application) { ctx.Session().Set("tempCred", tempCred) url := config.AuthorizationURL(tempCred, nil) - return ctx.Redirect(url) + return ctx.Redirect(http.StatusFound, url) }) // This is the redirect URL that we specified in /auth/twitter. @@ -60,7 +61,7 @@ func InstallTwitterAuth(app *aero.Application) { // Now we have to check for fraud requests and request user information. // If both Twitter ID and email can't be found in our DB, register a new user. // Otherwise, log in the user with the given Twitter ID or email. - app.Get("/auth/twitter/callback", func(ctx *aero.Context) string { + app.Get("/auth/twitter/callback", func(ctx aero.Context) error { if !ctx.HasSession() { return ctx.Error(http.StatusUnauthorized, "Twitter login failed", errors.New("Session does not exist")) } @@ -121,9 +122,9 @@ func InstallTwitterAuth(app *aero.Application) { user.Save() // Log - authLog.Info("Added Twitter ID to existing account | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("Added Twitter ID to existing account | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } var getErr error @@ -132,20 +133,20 @@ func InstallTwitterAuth(app *aero.Application) { user, getErr = arn.GetUserByTwitterID(twUser.ID) if getErr == nil && user != nil { - authLog.Info("User logged in via Twitter ID | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("User logged in via Twitter ID | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) user.LastLogin = arn.DateTimeUTC() user.Save() session.Set("userId", user.ID) - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } // Try to find an existing user via the associated e-mail address user, getErr = arn.GetUserByEmail(twUser.Email) if getErr == nil && user != nil { - authLog.Info("User logged in via Email | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("User logged in via Email | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) // Add TwitterToUser reference user.ConnectTwitter(twUser.ID) @@ -155,7 +156,7 @@ func InstallTwitterAuth(app *aero.Application) { user.Save() session.Set("userId", user.ID) - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } // Register new user @@ -187,9 +188,9 @@ func InstallTwitterAuth(app *aero.Application) { session.Set("userId", user.ID) // Log - authLog.Info("Registered new user via Twitter | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.RealIP(), user.Email, user.RealName()) + authLog.Info("Registered new user via Twitter | %s | %s | %s | %s | %s", user.Nick, user.ID, ctx.IP(), user.Email, user.RealName()) // Redirect to starting page for new users - return ctx.Redirect(newUserStartRoute) + return ctx.Redirect(http.StatusFound, newUserStartRoute) }) } diff --git a/config.json b/config.json index 18095d8c..272e8577 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,4 @@ { - "domain": "notify.moe", - "title": "Anime Notifier", "fonts": [ "Ubuntu" ], diff --git a/docs/new-contributor-task.md b/docs/new-contributor-task.md index 2b302e98..9424af52 100644 --- a/docs/new-contributor-task.md +++ b/docs/new-contributor-task.md @@ -16,7 +16,7 @@ import ( ) // Get returns the contents of our amazing page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { return ctx.HTML("Hey it's me, foobar!") } ``` @@ -73,7 +73,7 @@ import ( ) // Get returns the contents of our amazing page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { return ctx.HTML(components.FooBar()) } ``` diff --git a/go.mod b/go.mod index 6514a35a..814b3743 100644 --- a/go.mod +++ b/go.mod @@ -4,27 +4,25 @@ go 1.12 require ( cloud.google.com/go v0.39.0 // indirect - github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705 // indirect - github.com/aerogo/aero v1.2.5 - github.com/aerogo/api v0.1.7 + github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect + github.com/aerogo/aero v1.3.2 + github.com/aerogo/api v0.2.0 github.com/aerogo/crawler v0.2.5 - github.com/aerogo/graphql v0.3.6 + github.com/aerogo/graphql v0.4.0 github.com/aerogo/http v1.0.6 - github.com/aerogo/layout v0.1.9 + github.com/aerogo/layout v0.3.0 github.com/aerogo/log v0.2.5 github.com/aerogo/manifest v0.1.4 github.com/aerogo/markdown v0.1.8 github.com/aerogo/nano v0.3.2 - github.com/aerogo/pack v0.5.0 - github.com/aerogo/run v1.0.1 github.com/aerogo/session-store-nano v0.1.5 - github.com/aerogo/sitemap v0.1.2 + github.com/aerogo/sitemap v0.1.3 github.com/akyoto/cache v1.0.2 github.com/akyoto/color v1.8.5 - github.com/akyoto/hash v0.3.3 + github.com/akyoto/hash v0.3.5 github.com/akyoto/stringutils v0.2.1 github.com/animenotifier/anilist v0.2.3 - github.com/animenotifier/arn v1.1.25 + github.com/animenotifier/arn v1.2.0 github.com/animenotifier/kitsu v0.2.3 github.com/animenotifier/mal v0.2.3 github.com/animenotifier/shoboi v0.2.3 @@ -44,11 +42,10 @@ require ( github.com/pariz/gountries v0.0.0-20171019111738-adb00f6513a3 github.com/shirou/gopsutil v2.18.12+incompatible github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect - github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3 // indirect + github.com/smartystreets/assertions v1.0.0 // indirect github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect github.com/stretchr/testify v1.3.0 golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0 - golang.org/x/sync v0.0.0-20190423024810-112230192c58 // indirect golang.org/x/text v0.3.2 // indirect google.golang.org/appengine v1.6.0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect @@ -56,4 +53,6 @@ require ( gopkg.in/yaml.v2 v2.2.2 // indirect ) +replace github.com/aerogo/layout => /home/eduard/projects/aerogo/layout + exclude github.com/logpacker/PayPal-Go-SDK v2.0.0+incompatible diff --git a/go.sum b/go.sum index 8e5326f6..bf49c31e 100644 --- a/go.sum +++ b/go.sum @@ -5,54 +5,34 @@ cloud.google.com/go v0.39.0 h1:UgQP9na6OTfp4dsAiz/eFpFA1C6tPdH5wiRdi19tuMw= cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI= -github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk= github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= -github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705 h1:UUppSQnhf4Yc6xGxSkoQpPhb7RVzuv5Nb1mwJ5VId9s= -github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/aerogo/aero v1.1.8 h1:bV87Q15IGJY4XZdZM6jBVBp/rnGjQGIMqUh+WTC4PAY= -github.com/aerogo/aero v1.1.8/go.mod h1:Xpl5AFecG/cpx9As733/zM36UiPrpd4s12stfyx6i5w= -github.com/aerogo/aero v1.1.9 h1:EB+oTljSIfQENZTVyvnZ24Pb2UsV+Ows04/HfzOJ/3c= -github.com/aerogo/aero v1.1.9/go.mod h1:MvHPJcXZmZUu5mh4q6j5n3DijKmAMY6puhzCH1w22Vw= -github.com/aerogo/aero v1.1.13 h1:e+FXHaSRZ2a/xrLwF1Yeujh5yHBovdLfHxJYtZvPpWw= -github.com/aerogo/aero v1.1.13/go.mod h1:jcHCf+a3vExpo1SKRPrmkspO9VWiDZHC5/ITss/Sz6Y= -github.com/aerogo/aero v1.2.5 h1:xn1POlFP8gWUDv99QqetijOsghgHt5WXAEXiqhmRQbQ= -github.com/aerogo/aero v1.2.5/go.mod h1:jRXI34hJL3iwH+llwLLnMPPHr9tFgLfl0JQhaH+8eJQ= -github.com/aerogo/api v0.1.7 h1:2cEOUlPvlRnLo6A0xn8+UpmluWqRoYEGn0Ik4kxmUEI= -github.com/aerogo/api v0.1.7/go.mod h1:6uPqLd2/VzFiuC7L7hPMtUNjfRjczJQUP6Uks7EiXpw= -github.com/aerogo/cluster v0.1.5 h1:mOYQmaYRsvIi1inaGLICmeJgCYycBxiHnjcTFLtC6kc= -github.com/aerogo/cluster v0.1.5/go.mod h1:uFZAv2XWV+/clNy0iciCIP2Ygndv8rC8QCX/RCO2R2g= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/aerogo/aero v1.3.1 h1:P4XS4ePrJWSJwHLXKkX5YjFsoywhWuXf3dPIX5XVAW0= +github.com/aerogo/aero v1.3.1/go.mod h1:5rPhXo2DNMFQ7XhDsuZ3L7Zr6TH/349+WczUbrOUZvM= +github.com/aerogo/aero v1.3.2 h1:Sj/2U860HLJG5iq5het6QFgo/ERQ7cS4Zdz38xPWSwQ= +github.com/aerogo/aero v1.3.2/go.mod h1:5rPhXo2DNMFQ7XhDsuZ3L7Zr6TH/349+WczUbrOUZvM= +github.com/aerogo/api v0.2.0 h1:mIc/y381e+Qc85eSc2cKPdpDDOmT0hlnEeCw2Dcf7no= +github.com/aerogo/api v0.2.0/go.mod h1:6objJn5XiKpYpywQUPrFjxZIXD4NVI2LwcBNYCEcS3Y= github.com/aerogo/cluster v0.1.6 h1:9HYjJwo19uuh9thIc80T3caap9t9b4BXZ1iN8aztjlU= github.com/aerogo/cluster v0.1.6/go.mod h1:XzYmY5MqNxASmYQWFMh5iCl4tcm1ekReaCQQXVCpJtY= github.com/aerogo/cluster v0.1.7 h1:hMG7oPzYmo4TPtzn4zJc291YzNRrnoSPWSKVaDS4ODA= github.com/aerogo/cluster v0.1.7/go.mod h1:XzYmY5MqNxASmYQWFMh5iCl4tcm1ekReaCQQXVCpJtY= -github.com/aerogo/codetree v1.2.4 h1:Gf6JHjzUBEGn0Z+h4EK1pikexqFZc8+b/3LiLkRXhms= -github.com/aerogo/codetree v1.2.4/go.mod h1:MhElfskRtfAKGy5ukRIFcLTtHcSCwLRBjDAlsbuFts0= github.com/aerogo/crawler v0.2.5 h1:tsaRViwBKNJAotzjEmGOln7quzka4f0goiEZVg4Fdxc= github.com/aerogo/crawler v0.2.5/go.mod h1:nyFPwxOFm3gy5cvif8rG1ogXO0fTDVrxsQHwicJz1F8= -github.com/aerogo/csp v0.1.5 h1:4l8AaMWndSb0t/03onf4lc0th2zoaapmtKgysDIznW4= -github.com/aerogo/csp v0.1.5/go.mod h1:KNqnTFffuDwIPJxBEFTl3baBx+x3Vw+9kcMfu5APFJA= github.com/aerogo/csp v0.1.6 h1:C2OpzPZHY1S5H+Dz0Or+YgVSfXT36avJw9e1smrIWUY= github.com/aerogo/csp v0.1.6/go.mod h1:KNqnTFffuDwIPJxBEFTl3baBx+x3Vw+9kcMfu5APFJA= github.com/aerogo/flow v0.1.2 h1:fZ3V7Bo7jwBjqnM1mWxYbg5O/FlQX2XovzMZU2D+o5M= github.com/aerogo/flow v0.1.2/go.mod h1:xXIb7GY0AKouhbp4/ViCsiOmvvgRGonqPG30d6FnACI= github.com/aerogo/flow v0.1.4 h1:BCb+nF58tj41xx3aJcxCLsNcGzZH6CGrodRMOIXYfOE= github.com/aerogo/flow v0.1.4/go.mod h1:xXIb7GY0AKouhbp4/ViCsiOmvvgRGonqPG30d6FnACI= -github.com/aerogo/graphql v0.3.6 h1:6rAM4yFXa0qLaNz7bnLja3JAyV5fu2kq833Nsyzjizo= -github.com/aerogo/graphql v0.3.6/go.mod h1:bcAaQk3IGODFLF2gFwVszP3hyumWOhwKKuOh1xClSeI= -github.com/aerogo/http v1.0.1 h1:KTzYarhp5yougurxuAhJKFh3YvZ7R7CfaDVwJv5+xIs= -github.com/aerogo/http v1.0.1/go.mod h1:B1igUmMLpE6KabMpc9reHCJJNUOJ2U/PR9s1fF3TpPQ= +github.com/aerogo/graphql v0.4.0 h1:b5OyqzMNdskH6cKxRCLG6hKEpNYKCpxuad3tLjodox8= +github.com/aerogo/graphql v0.4.0/go.mod h1:yAY/KPoBejdN41JUGyK50pPZexFcGp//UMk/GjxqjZc= github.com/aerogo/http v1.0.3 h1:vf6A+Igme5OHQPaP3a00uPDS0oxsx3puMA23d1NsWDM= github.com/aerogo/http v1.0.3/go.mod h1:B1igUmMLpE6KabMpc9reHCJJNUOJ2U/PR9s1fF3TpPQ= github.com/aerogo/http v1.0.6 h1:+aswlcWlUxjVcokF8hUjNJmGIEZuhbFbHi8uSadEvtc= github.com/aerogo/http v1.0.6/go.mod h1:LwJ7b+LjrHj60FhYQ586K3/O7aNGxkE2dy/exEkQ6rA= -github.com/aerogo/layout v0.1.9 h1:pLGj1RaQgduDdhnRKoc40D5Mq4wINohQe08m7+TxTXA= -github.com/aerogo/layout v0.1.9/go.mod h1:cJ9Gyh0H9xHI2uVyPqSDIlpMDdgAosdYlRArEEh9oME= -github.com/aerogo/linter-performance v1.0.1 h1:/1Hak+7sxpO2AkjdMVcpkyurmA4YD77EDi7FRnLqnwM= -github.com/aerogo/linter-performance v1.0.1/go.mod h1:3ZXxPgQ0cEo0x6DCGZwXHrwKNYK86XvB5QRJR9s7Z6I= github.com/aerogo/linter-performance v1.0.3 h1:pYsmUd8jp6CVrFx+YNo9Gfdf222CKG2gCVjp8cljZNY= github.com/aerogo/linter-performance v1.0.3/go.mod h1:po6XSSbSgR30lazzqSRGV++a2omxYr2qjqFvcvUCH40= github.com/aerogo/log v0.2.5 h1:LGeElbLqyaD8r8Ls9HuG7tYF6YV4kP56IxJWl/b4cZQ= @@ -61,54 +41,28 @@ github.com/aerogo/manifest v0.1.4 h1:JGRMJAANtgzhygMCMov6WgIRkiVuMgP3a+ossf//TJU github.com/aerogo/manifest v0.1.4/go.mod h1:3SvBzx0rCDNQ+C779aEj5ZyP0YWwdGPeEzsPM3VIOzg= github.com/aerogo/markdown v0.1.8 h1:X/FlyuBqdVaFflggxDbXcqGCQNInLKwU/tvyNhg+mQw= github.com/aerogo/markdown v0.1.8/go.mod h1:8+ZWJnLT2rxY75TEd/Y5+rV89Sw9NOh5WiGSjptGNYk= -github.com/aerogo/mirror v0.2.2 h1:kASC9ZsTDBPwzZehb2o5qLbNv+bj8t9V167ExjEMRS0= -github.com/aerogo/mirror v0.2.2/go.mod h1:Un87Jq8RIRrb2bU1CxVToJjVZgSMLUQXxVLCXln4rUU= github.com/aerogo/mirror v0.2.3 h1:mV4Bse2o2HiRN7rNntE6mOtWQLiLgTLkIrlt9vUoPD8= github.com/aerogo/mirror v0.2.3/go.mod h1:Un87Jq8RIRrb2bU1CxVToJjVZgSMLUQXxVLCXln4rUU= -github.com/aerogo/nano v0.2.0 h1:qcCdCsAtN1Qpw8DhZQXiLVJYsjmpQMmZ7TPFD2GkwVw= -github.com/aerogo/nano v0.2.0/go.mod h1:tbR/fVGJb2rRFdPp9+D0INJgkhzQ+9XKefLTI11xNFU= github.com/aerogo/nano v0.2.1 h1:YDGytzYoswid2x8cR5yAc9TmjgR+wEMF8+HowR1UCKI= github.com/aerogo/nano v0.2.1/go.mod h1:1xgPREJH6aW5sE91AwYkvxMDg5YCbAaIYpAL7T1+JgA= github.com/aerogo/nano v0.3.2 h1:1JWaZX8e+dtKZuPWC7Ls1AuzN33auCw7hPjZ8JCjjjE= github.com/aerogo/nano v0.3.2/go.mod h1:o86DA68cpXx5inh8tygTJBF+8sXQ0eoOm36NHIN86YI= -github.com/aerogo/pack v0.5.0 h1:0BQVGNaPTIV4fQ5YG17eqOoe30aqpZp1NXCZxxRXxrA= -github.com/aerogo/pack v0.5.0/go.mod h1:TBMV1rF4ZO7qafslhLKCGbKsAGTbKPuCB5KpOUYW7ks= -github.com/aerogo/packet v0.1.4 h1:435YxvxMiH1KaBPELU+jCLqj0T9noLBSY4zk53t1gpQ= -github.com/aerogo/packet v0.1.4/go.mod h1:/t25yF9WG8B5/QB7wTiHLqwCEQ+nAze7uNm/JJNDQbQ= github.com/aerogo/packet v0.1.5 h1:+J9VyVGlXnmaynukktwc7d+/nGxX7hBSNSj/7X8tg90= github.com/aerogo/packet v0.1.5/go.mod h1:/t25yF9WG8B5/QB7wTiHLqwCEQ+nAze7uNm/JJNDQbQ= github.com/aerogo/packet v0.1.6 h1:P9TwEV9xcyWxsjQQAXDfM3jItX4xEqRFNGXWMqH9j3Q= github.com/aerogo/packet v0.1.6/go.mod h1:/t25yF9WG8B5/QB7wTiHLqwCEQ+nAze7uNm/JJNDQbQ= github.com/aerogo/packet v0.1.7 h1:k/gBdAX/yecGW2xWJXt6dpg4Jb84xZScRPExt2rW+hY= github.com/aerogo/packet v0.1.7/go.mod h1:/t25yF9WG8B5/QB7wTiHLqwCEQ+nAze7uNm/JJNDQbQ= -github.com/aerogo/pixy v1.2.4 h1:4VC9GmxSZALbaDKk5sd7hz2du/VhI2Tk2946PIE0k2I= -github.com/aerogo/pixy v1.2.4/go.mod h1:+8WIzngckOb4UDSRAgGY/CZX0lpZPFTbfLqOdJDIBC8= -github.com/aerogo/run v1.0.1 h1:IjvFUWo/97srJUIzAkETpj6e/bd9KcweRSQJF8vPJTs= -github.com/aerogo/run v1.0.1/go.mod h1:z4kZn3pRRiOd38DaFcMnLc5kR0coyGUFiIjH4vLCVNI= -github.com/aerogo/scarlet v0.2.4 h1:QSIHMuUKg2oW5V9bVvOsSC6QxND6B8AxxCEjFqiHPuU= -github.com/aerogo/scarlet v0.2.4/go.mod h1:0bIQypPu/IcSOAV7YtMXt6fhvxCaChDb6YI40/HqThI= -github.com/aerogo/session v0.1.2 h1:f0X3YJQJcFhtmw47U60jdSsH18/T51SkhkhAuXwnYI8= -github.com/aerogo/session v0.1.2/go.mod h1:A4S5dvAhpm+DRdQbno5Rn4Jvj0UVGJmOUKQXataNIDg= -github.com/aerogo/session v0.1.3 h1:ABE2DP0Cp92sqZDe/GkcbqjuZbYq+OV9Y9kpmZtchTw= -github.com/aerogo/session v0.1.3/go.mod h1:A4S5dvAhpm+DRdQbno5Rn4Jvj0UVGJmOUKQXataNIDg= github.com/aerogo/session v0.1.4 h1:4OgQyUm3wxSsjNRReZhYdHX8X5lXnFp1W+M3EXr4a3E= github.com/aerogo/session v0.1.4/go.mod h1:aM3FUclBU+wt8kwSs3leTByuaBu0sXrw4P+HwKVkSSw= -github.com/aerogo/session-store-memory v0.1.3 h1:6tPSh4HrJald0akOQIdUc8S1MxmBaOs1eXgC9Yiz2co= -github.com/aerogo/session-store-memory v0.1.3/go.mod h1:GYiLJNk8h3pcBB/UwfCJrtTZl1CLxBg8xnzt45wPmIM= -github.com/aerogo/session-store-memory v0.1.4 h1:nqeTEUtNZtwExVqo8HWOEUgIJKt5tQlWg1kG/gjtmQE= -github.com/aerogo/session-store-memory v0.1.4/go.mod h1:GYiLJNk8h3pcBB/UwfCJrtTZl1CLxBg8xnzt45wPmIM= github.com/aerogo/session-store-memory v0.1.5 h1:l4uBDs4cVkByTE1N/IVSpU6oIrgx+4abtjztxk13zcI= github.com/aerogo/session-store-memory v0.1.5/go.mod h1:Agy7YibR8yxUePqcl2rFyIGIwvXJiNsV1yaLtJHnnrI= github.com/aerogo/session-store-nano v0.1.5 h1:klabo+Hyh1GKhpYJExdGvXDxNCxW7sSJevFGGzIqVCo= github.com/aerogo/session-store-nano v0.1.5/go.mod h1:HEm80cLszsfh7yUsX1zbddznPhz2sPWhsHRXNLo9tJs= -github.com/aerogo/sitemap v0.1.2 h1:0+o/B0IrikZxGdi0yjgwa/jm36OMdOHxe6zChj8zGZA= -github.com/aerogo/sitemap v0.1.2/go.mod h1:/1NT13qIsTm/ydlZHEMd8m014E2yyQkI5coimmIfqc0= -github.com/akyoto/autoimport v0.6.3 h1:YpO9UqPr0GqHiD4c5qFKicTOA2a+yzudk2gs5yqpzBw= -github.com/akyoto/autoimport v0.6.3/go.mod h1:BKSPRNRNHYGGpoBsE/CfhV/ZljNDDFLvTRrmngMAZ30= +github.com/aerogo/sitemap v0.1.3 h1:HjiyvMCFvoB8a8Lm1+3LaA6B5EeP/f5CChrsAYjAFSQ= +github.com/aerogo/sitemap v0.1.3/go.mod h1:/1NT13qIsTm/ydlZHEMd8m014E2yyQkI5coimmIfqc0= github.com/akyoto/cache v1.0.2 h1:YNaLbfbfBRr21dReBErQxfnVPBsVR/aeFpIKxsF88n8= github.com/akyoto/cache v1.0.2/go.mod h1:MgYroBUaHREY9mmTcavctH4NDzQohCr4WMWPUKv7pq4= -github.com/akyoto/color v1.8.2 h1:FOTpvfQkCk00yCl8oU/wjO3+jBi3FWpwUogLkeyzWfU= -github.com/akyoto/color v1.8.2/go.mod h1:wiwOfYJb0XdHYznfIes7wjr79A/EjGPZ64FfbwJv4RY= github.com/akyoto/color v1.8.3 h1:d+xQM5ra9aCxUzchbxSX2Szkd7cQwuJARSQMzNb3aLM= github.com/akyoto/color v1.8.3/go.mod h1:wiwOfYJb0XdHYznfIes7wjr79A/EjGPZ64FfbwJv4RY= github.com/akyoto/color v1.8.4 h1:XS1AL8/JmDHNgN9JRMd1epsQADQF7UXMzUz0nx0kTvY= @@ -117,16 +71,10 @@ github.com/akyoto/color v1.8.5 h1:xvHRmBJdsT5HJxnfyIT8l3zNbexA/2YIIeAlaHuhYGY= github.com/akyoto/color v1.8.5/go.mod h1:mI8lhoKcgnvH8fnaupVUE3BmKUp2bpDn5wFS1xEQ4hw= github.com/akyoto/go-matroska v0.1.1 h1:HgoCAkeWrGjYr0FZr3yCzAIkXuOGRiVil7Ul329lm+A= github.com/akyoto/go-matroska v0.1.1/go.mod h1:x+GUVwyby6HN/MKKNP4BvGqP9VrHuEznfBf288gehek= -github.com/akyoto/hash v0.3.2 h1:T6nwsswtzXUjk5pBOLSDdj/8m9hcZzVzj35qnfG24aA= -github.com/akyoto/hash v0.3.2/go.mod h1:t6CqUCKqLvd1QfbNSt9yfv9BiOY+qPsZABimD86fNPY= -github.com/akyoto/hash v0.3.3 h1:zOQ71sRCRU56beF148dWUaCmWWpuLmi3dBd1Jiy8vHE= -github.com/akyoto/hash v0.3.3/go.mod h1:uPmnZyhBJIyLON8V9LNi0CcqtwYaH2RiKLFQg67fwq0= -github.com/akyoto/ignore v1.0.2 h1:A9hy/aUjaiKfjci0OPvwvme5F0e3PHrN9bjNn9oASkM= -github.com/akyoto/ignore v1.0.2/go.mod h1:GhkaVB2bVMq7KuV9AkB1U6FGWZ7mTpuXeKVQNEWVUc0= +github.com/akyoto/hash v0.3.5 h1:5EJGHx6RfE9aHrEzWU3pfLGFUWMvPVqtsxt7mSON+mY= +github.com/akyoto/hash v0.3.5/go.mod h1:uPmnZyhBJIyLON8V9LNi0CcqtwYaH2RiKLFQg67fwq0= github.com/akyoto/imageserver v0.3.6 h1:Sxcbgo45Lh7afcSmcU8OS49VYbqh4kE3DK0Lxuuxf74= github.com/akyoto/imageserver v0.3.6/go.mod h1:9AuMUxIt5CPlTmJre4ETwWxRnThOkkE1EhavC8HX4U8= -github.com/akyoto/stringutils v0.1.0 h1:MuRXgxETSPgkrT+j3L9/oEqHs2/yW/gr2ioq3j/5LtI= -github.com/akyoto/stringutils v0.1.0/go.mod h1:a83vMdYtgvZD3nuWJIW5kzbrjv5dHH3Qg6ucbF1Z/k4= github.com/akyoto/stringutils v0.2.0 h1:86gMW/31LO7zc8mGGWB4gLqyFzrNHMZYyj6ebSQbpH4= github.com/akyoto/stringutils v0.2.0/go.mod h1:EigXf5ZaULP6f5CNjqIIo0fjDHbRe8P4BQwlqCsvi9k= github.com/akyoto/stringutils v0.2.1 h1:4St8vcRnNFuCNSMEJ34TeLb7/FfsvZaSU8/Scr6Zymg= @@ -137,8 +85,8 @@ github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRy github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/animenotifier/anilist v0.2.3 h1:409h1m4m59EBTQHc/F2U5PGY3lIWlvD/kRXxY1oTl5Q= github.com/animenotifier/anilist v0.2.3/go.mod h1:WmivLHBTIs+zmqENjiVXH66laTYB8vT5d+8q1yzLX9I= -github.com/animenotifier/arn v1.1.25 h1:RyAMLdOVQrGto5A+RSLgs/OrnTy5WSyql559YkyPvUI= -github.com/animenotifier/arn v1.1.25/go.mod h1:qf9Uq5lsw3uIgFFrfOSu1L9hjtHer9VcmgIWWcuN/Jo= +github.com/animenotifier/arn v1.2.0 h1:BsWB6CXUFRgPKeh8MtNtgi8TPwDoqpAkgV8ah+bDTR8= +github.com/animenotifier/arn v1.2.0/go.mod h1:1wyusZbu0AbbjPn60TR20xwL8alLPo41oysxsttEP2A= github.com/animenotifier/ffxiv v0.2.1 h1:gV5h47skizAWLJQb+M3CmExy1hlqDuKmNxkOpn3JwF0= github.com/animenotifier/ffxiv v0.2.1/go.mod h1:9p0z9iQIT8nIlwH4xHUvdo0qFvJ4pVnFbBQ0G/JiY0k= github.com/animenotifier/japanese v0.2.3 h1:fGX3CcX5lGzRC+JkokDCwJqRniPOmM44FLm7aqdnOEo= @@ -205,8 +153,6 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -214,8 +160,6 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/logpacker/PayPal-Go-SDK v1.1.4 h1:YXfHvkDLMKkdmHmeusBum45MMG4n3iJeeQ9mZPWPAUQ= github.com/logpacker/PayPal-Go-SDK v1.1.4/go.mod h1:DUf5ncyG0n3jFnU9VsuQqe/Vo6KHtWQ6HYf80JwP4rY= -github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= -github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= @@ -241,11 +185,8 @@ github.com/mssola/user_agent v0.5.0 h1:gRF7/x8cKt8qzAosYGsBNyirta+F8fvYDlJrgXws9 github.com/mssola/user_agent v0.5.0/go.mod h1:UFiKPVaShrJGW93n4uo8dpPdg1BSVpw2P9bneo0Mtp8= github.com/pariz/gountries v0.0.0-20171019111738-adb00f6513a3 h1:lmQNznFSupyfCDE9d7wdKOU8UiVwWEoYwv8wo6rSgy0= github.com/pariz/gountries v0.0.0-20171019111738-adb00f6513a3/go.mod h1:U0ETmPPEsfd7CpUKNMYi68xIOL8Ww4jPZlaqNngcwqs= -github.com/pkg/profile v1.3.0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= -github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= github.com/russross/blackfriday v2.0.0+incompatible h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk= github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM= @@ -256,24 +197,20 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3 h1:hBSHahWMEgzwRyS6dRpxY0XyjZsHyQ61s084wo5PJe0= -github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo= -github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT56Uf6o3Mcz9CEsg8USYs= github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38= github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ= github.com/tdewolff/test v1.0.0 h1:jOwzqCXr5ePXEPGJaq2ivoR6HOCi+D5TPfpoyg8yvmU= github.com/tdewolff/test v1.0.0/go.mod h1:DiQUlutnqlEvdvhSn2LPGy4TFwRauAaYDsL+683RNX4= github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf h1:Z2X3Os7oRzpdJ75iPqWZc0HeJWFYNCvKsfpQwFpRNTA= github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= -github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc= -github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/ungerik/go-gravatar v0.0.0-20120802094239-6ab22628222a h1:TZyMbJbyPL+4/ndyXns8aNDrmUJn5a6aV8lj3qEM7fM= github.com/ungerik/go-gravatar v0.0.0-20120802094239-6ab22628222a/go.mod h1:cmQAsXze586z5DHYfoVO9jZBampncP3iuhVgujPqdxk= github.com/ventu-io/go-shortid v0.0.0-20171029131806-771a37caa5cf h1:cgAKVljim9RJRcJNGjnBUajXj1FupBSdWwW4JaQG7vk= @@ -285,8 +222,8 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -316,31 +253,23 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190428183149-804c0c7841b5 h1:m0i9YywO9THhxmJvLEwKJDD/pD8ljCB+EaT/wYS41Is= golang.org/x/sys v0.0.0-20190428183149-804c0c7841b5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug= golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190515120540-06a5c4944438 h1:khxRGsvPk4n2y8I/mLLjp7e5dMTJmH75wvqS6nMwUtY= golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190516014833-cab07311ab81 h1:5Q88vZAfC0WB8T1GHRLttQaZdCNeQHM40n41gMUeFlI= golang.org/x/sys v0.0.0-20190516014833-cab07311ab81/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190516102723-cedb8e16d18a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190516110030-61b9204099cb h1:k07iPOt0d6nEnwXF+kHB+iEg+WSuKe/SOQuFM2QoD+E= -golang.org/x/sys v0.0.0-20190516110030-61b9204099cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5 h1:sM3evRHxE/1RuMe1FYAL3j7C7fUfIjkbE+NiDAYUF8U= golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09 h1:IlD35wZE03o2qJy2o37WIskL33b7PT6cHdGnE8bieZs= -golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2 h1:T5DasATyLQfmbTpfEXx/IOL9vfjzW6up+ZDkmHvIf2s= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= diff --git a/layout/layout.go b/layout/layout.go index a46d0c97..6e8aa176 100644 --- a/layout/layout.go +++ b/layout/layout.go @@ -4,15 +4,16 @@ import ( "sort" "github.com/aerogo/aero" - "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Render layout. -func Render(ctx *aero.Context, content string) string { +func Render(ctx aero.Context, content string) string { user := utils.GetUser(ctx) - openGraph, _ := ctx.Data.(*arn.OpenGraph) + customCtx := ctx.(*middleware.OpenGraphContext) + openGraph := customCtx.OpenGraph // Make output order deterministic to profit from Aero caching. // To do this, we need to create slices and sort the tags. diff --git a/layout/layout.pixy b/layout/layout.pixy index 18e867aa..47ce06d1 100644 --- a/layout/layout.pixy +++ b/layout/layout.pixy @@ -1,4 +1,4 @@ -component Layout(ctx *aero.Context, user *arn.User, openGraph *arn.OpenGraph, meta, tags []string, content string) +component Layout(ctx aero.Context, user *arn.User, openGraph *arn.OpenGraph, meta, tags []string, content string) html(lang="en") head link(rel="stylesheet", href="/styles", importance="high") @@ -6,7 +6,7 @@ component Layout(ctx *aero.Context, user *arn.User, openGraph *arn.OpenGraph, me if openGraph != nil title= openGraph.Tags["og:title"] else - title= ctx.App.Config.Title + title= assets.Manifest.Name //- Viewport meta(name="viewport", content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes") diff --git a/main.go b/main.go index 2a220a4c..5128e1ee 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "github.com/aerogo/aero" nanostore "github.com/aerogo/session-store-nano" + "github.com/akyoto/color" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/auth" @@ -44,9 +45,10 @@ func configure(app *aero.Application) *aero.Application { // Middleware app.Use( - middleware.Log(), - middleware.Session(), - middleware.UserInfo(), + middleware.OpenGraph, + middleware.Log, + middleware.Session, + middleware.UserInfo, ) // API @@ -54,9 +56,8 @@ func configure(app *aero.Application) *aero.Application { // Development server configuration if arn.IsDevelopment() { - app.Config.Domain = "beta.notify.moe" - app.Config.Title += " - Beta" - assets.Manifest.Name = app.Config.Title + assets.Domain = "beta.notify.moe" + assets.Manifest.Name += " - Beta" } // Authentication @@ -68,6 +69,11 @@ func configure(app *aero.Application) *aero.Application { // Close the database node on shutdown app.OnEnd(arn.Node.Close) + // Show errors in the console + app.OnError(func(ctx aero.Context, err error) { + color.Red(err.Error()) + }) + // Check that this is the server if !arn.Node.IsServer() && !arn.IsTest() { panic("Another program is currently running as the database server") @@ -77,13 +83,13 @@ func configure(app *aero.Application) *aero.Application { arn.DB.Prefetch() // Do not use HTTP/2 push on service worker requests - app.AddPushCondition(func(ctx *aero.Context) bool { - return !strings.Contains(ctx.Request().Header().Get("Referer"), "/service-worker") + app.AddPushCondition(func(ctx aero.Context) bool { + return !strings.Contains(ctx.Request().Header("Referer"), "/service-worker") }) // Specify test routes for route, examples := range routetests.All() { - app.Test(route, examples) + app.Test(route, examples...) } return app diff --git a/main_test.go b/main_test.go index 9273e852..ce1e3143 100644 --- a/main_test.go +++ b/main_test.go @@ -112,7 +112,7 @@ func testRoute(t *testing.T, app *aero.Application, route string) { // Record the response responseRecorder := httptest.NewRecorder() - app.Handler().ServeHTTP(responseRecorder, request) + app.ServeHTTP(responseRecorder, request) status := responseRecorder.Code switch status { diff --git a/makefile b/makefile index 9f629ee1..a6a1e6eb 100644 --- a/makefile +++ b/makefile @@ -47,9 +47,9 @@ test: bench: $(GOTEST) -bench . pack: - go install github.com/aerogo/pack + go install github.com/aerogo/pack/... run: - go install github.com/aerogo/run + go install github.com/aerogo/run/... tools: ifeq ($(OSNAME),OSX) brew install coreutils diff --git a/middleware/Firewall.go b/middleware/Firewall.go index 9af192ef..a8e3ebf1 100644 --- a/middleware/Firewall.go +++ b/middleware/Firewall.go @@ -20,10 +20,10 @@ package middleware // // Firewall middleware detects malicious requests. // func Firewall() aero.Middleware { -// return func(ctx *aero.Context, next func()) { +// return func(ctx aero.Context, next func()) { // var stats *IPStats -// ip := ctx.RealIP() +// ip := ctx.IP() // // Allow localhost // if ip == "127.0.0.1" { @@ -44,7 +44,7 @@ package middleware // } // // Add requested URI to the list of requests -// stats.Requests = append(stats.Requests, ctx.URI()) +// stats.Requests = append(stats.Requests, ctx.Path()) // if len(stats.Requests) > requestThreshold { // stats.Requests = stats.Requests[len(stats.Requests)-requestThreshold:] @@ -69,7 +69,7 @@ package middleware // } // // Disallow request -// request.Error("[guest]", ip, "BLOCKED BY FIREWALL", ctx.URI()) +// request.Error("[guest]", ip, "BLOCKED BY FIREWALL", ctx.Path()) // return // } diff --git a/middleware/HTTPSRedirect.go b/middleware/HTTPSRedirect.go index 501d182b..8ff84516 100644 --- a/middleware/HTTPSRedirect.go +++ b/middleware/HTTPSRedirect.go @@ -2,15 +2,15 @@ package middleware // // HTTPSRedirect middleware redirects to HTTPS if needed. // func HTTPSRedirect() aero.Middleware { -// return func(ctx *aero.Context, next func()) { +// return func(ctx aero.Context, next func()) { // request := ctx.Request() // userAgent := request.Header().Get("User-Agent") // isBrowser := strings.Contains(userAgent, "Mozilla/") || strings.Contains(userAgent, "Chrome/") || strings.Contains(userAgent, "AppleWebKit/") // if !strings.HasPrefix(request.Protocol(), "HTTP/2") && isBrowser { // fmt.Println("Redirect to HTTPS") -// ctx.Redirect("https://" + request.Host() + request.URL().Path) -// ctx.Response().WriteHeader(ctx.StatusCode) +// ctx.Redirect(http.StatusFound, "https://" + request.Host() + request.URL().Path) +// ctx.Response().WriteHeader(ctx.Status()) // return // } diff --git a/middleware/Log.go b/middleware/Log.go index db398e82..b5b4f6fe 100644 --- a/middleware/Log.go +++ b/middleware/Log.go @@ -32,18 +32,19 @@ func init() { } // Log middleware logs every request into logs/request.log and errors into logs/error.log. -func Log() aero.Middleware { - return func(ctx *aero.Context, next func()) { +func Log(next aero.Handler) aero.Handler { + return func(ctx aero.Context) error { start := time.Now() - next() + err := next(ctx) responseTime := time.Since(start) go logRequest(ctx, responseTime) + return err } } // Logs a single request -func logRequest(ctx *aero.Context, responseTime time.Duration) { +func logRequest(ctx aero.Context, responseTime time.Duration) { responseTimeString := strconv.Itoa(int(responseTime.Nanoseconds()/1000000)) + " ms" repeatSpaceCount := 8 - len(responseTimeString) @@ -54,7 +55,7 @@ func logRequest(ctx *aero.Context, responseTime time.Duration) { responseTimeString = strings.Repeat(" ", repeatSpaceCount) + responseTimeString user := utils.GetUser(ctx) - ip := ctx.RealIP() + ip := ctx.IP() hostNames, cached := GetHostsForIP(ip) if !cached && len(hostNames) > 0 { @@ -70,20 +71,20 @@ func logRequest(ctx *aero.Context, responseTime time.Duration) { nick = user.Nick } - requestLog.Info("%s | %s | %s | %s | %d | %s", nick, id, ip, responseTimeString, ctx.StatusCode, ctx.URI()) + requestLog.Info("%s | %s | %s | %s | %d | %s", nick, id, ip, responseTimeString, ctx.Status(), ctx.Path()) // Log all requests that failed - switch ctx.StatusCode { + switch ctx.Status() { case http.StatusOK, http.StatusFound, http.StatusMovedPermanently, http.StatusPermanentRedirect, http.StatusTemporaryRedirect: // Ok. default: - errorLog.Error("%s | %s | %s | %s | %d | %s (%s)", nick, id, ip, responseTimeString, ctx.StatusCode, ctx.URI(), ctx.ErrorMessage) + errorLog.Error("%s | %s | %s | %s | %d | %s", nick, id, ip, responseTimeString, ctx.Status(), ctx.Path()) } // Notify us about long requests. // However ignore requests under /auth/ because those depend on 3rd party servers. - if responseTime >= 500*time.Millisecond && !strings.HasPrefix(ctx.URI(), "/auth/") && !strings.HasPrefix(ctx.URI(), "/sitemap/") && !strings.HasPrefix(ctx.URI(), "/api/sse/") { - errorLog.Error("%s | %s | %s | %s | %d | %s (long response time)", nick, id, ip, responseTimeString, ctx.StatusCode, ctx.URI()) + if responseTime >= 500*time.Millisecond && !strings.HasPrefix(ctx.Path(), "/auth/") && !strings.HasPrefix(ctx.Path(), "/sitemap/") && !strings.HasPrefix(ctx.Path(), "/api/sse/") { + errorLog.Error("%s | %s | %s | %s | %d | %s (long response time)", nick, id, ip, responseTimeString, ctx.Status(), ctx.Path()) } } diff --git a/middleware/OpenGraph.go b/middleware/OpenGraph.go new file mode 100644 index 00000000..6c84b79e --- /dev/null +++ b/middleware/OpenGraph.go @@ -0,0 +1,24 @@ +package middleware + +import ( + "github.com/aerogo/aero" + "github.com/animenotifier/arn" +) + +// OpenGraphContext is a context with open graph data. +type OpenGraphContext struct { + aero.Context + *arn.OpenGraph +} + +// OpenGraph middleware modifies the context to be an OpenGraphContext. +func OpenGraph(next aero.Handler) aero.Handler { + return func(ctx aero.Context) error { + ctx = &OpenGraphContext{ + Context: ctx, + OpenGraph: nil, + } + + return next(ctx) + } +} diff --git a/middleware/Recover.go b/middleware/Recover.go new file mode 100644 index 00000000..8f6fa6a8 --- /dev/null +++ b/middleware/Recover.go @@ -0,0 +1,34 @@ +package middleware + +import ( + "fmt" + "net/http" + "runtime" + + "github.com/aerogo/aero" +) + +// Recover recovers from panics and shows them as the response body. +func Recover(next aero.Handler) aero.Handler { + return func(ctx aero.Context) error { + defer func() { + r := recover() + + if r == nil { + return + } + + err, ok := r.(error) + + if !ok { + err = fmt.Errorf("%v", r) + } + + stack := make([]byte, 4096) + length := runtime.Stack(stack, true) + _ = ctx.Error(http.StatusInternalServerError, err, stack[:length]) + }() + + return next(ctx) + } +} diff --git a/middleware/Session.go b/middleware/Session.go index b3838916..c93e032c 100644 --- a/middleware/Session.go +++ b/middleware/Session.go @@ -3,14 +3,16 @@ package middleware import "github.com/aerogo/aero" // Session middleware saves an existing session if it has been modified. -func Session() aero.Middleware { - return func(ctx *aero.Context, next func()) { +func Session(next aero.Handler) aero.Handler { + return func(ctx aero.Context) error { // Handle the request first - next() + err := next(ctx) // Update session if it has been modified if ctx.HasSession() && ctx.Session().Modified() { - ctx.App.Sessions.Store.Set(ctx.Session().ID(), ctx.Session()) + _ = ctx.App().Sessions.Store.Set(ctx.Session().ID(), ctx.Session()) } + + return err } } diff --git a/middleware/UserInfo.go b/middleware/UserInfo.go index 5b3c612f..01c26456 100644 --- a/middleware/UserInfo.go +++ b/middleware/UserInfo.go @@ -14,33 +14,35 @@ import ( ) // UserInfo updates user related information after each request. -func UserInfo() aero.Middleware { - return func(ctx *aero.Context, next func()) { - next() +func UserInfo(next aero.Handler) aero.Handler { + return func(ctx aero.Context) error { + err := next(ctx) // Ignore non-HTML requests - contentType := ctx.Response().Header().Get("Content-Type") + contentType := ctx.Response().Header("Content-Type") if !strings.HasPrefix(contentType, "text/html") { - return + return nil } user := utils.GetUser(ctx) // When there's no user logged in, nothing to update if user == nil { - return + return nil } // This works asynchronously so it doesn't block the response go updateUserInfo(ctx, user) + + return err } } // Update browser and OS data -func updateUserInfo(ctx *aero.Context, user *arn.User) { - newIP := ctx.RealIP() - newUserAgent := ctx.UserAgent() +func updateUserInfo(ctx aero.Context, user *arn.User) { + newIP := ctx.IP() + newUserAgent := ctx.Request().Header("User-Agent") if user.UserAgent != newUserAgent { user.UserAgent = newUserAgent @@ -91,7 +93,12 @@ func updateUserLocation(user *arn.User, newIP string) { } newLocation := arn.IPInfoDBLocation{} - response.Unmarshal(&newLocation) + err = response.Unmarshal(&newLocation) + + if err != nil { + color.Red("Couldn't deserialize location data | Status: %d | IP: %s", response.StatusCode, user.IP) + return + } if newLocation.CountryName != "-" { user.Location.CountryName = newLocation.CountryName diff --git a/pages/activity/activity.go b/pages/activity/activity.go index 17d3e651..5854be99 100644 --- a/pages/activity/activity.go +++ b/pages/activity/activity.go @@ -7,14 +7,14 @@ import ( ) // Global activity page. -func Global(ctx *aero.Context) string { +func Global(ctx aero.Context) error { user := utils.GetUser(ctx) activities := fetchActivities(user, false) return render(ctx, activities) } // Followed activity page. -func Followed(ctx *aero.Context) string { +func Followed(ctx aero.Context) error { user := utils.GetUser(ctx) activities := fetchActivities(user, true) return render(ctx, activities) diff --git a/pages/activity/render.go b/pages/activity/render.go index 95ba94b6..3eedb23f 100644 --- a/pages/activity/render.go +++ b/pages/activity/render.go @@ -14,7 +14,7 @@ const ( ) // render renders the activities page with the given activities. -func render(ctx *aero.Context, allActivities []arn.Activity) string { +func render(ctx aero.Context, allActivities []arn.Activity) error { user := utils.GetUser(ctx) index, _ := ctx.GetInt("index") diff --git a/pages/admin/admin.go b/pages/admin/admin.go index eb1a907f..33d7512f 100644 --- a/pages/admin/admin.go +++ b/pages/admin/admin.go @@ -1,6 +1,7 @@ package admin import ( + "net/http" "runtime" "strings" @@ -14,11 +15,11 @@ import ( ) // Get admin page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil || (user.Role != "admin" && user.Role != "editor") { - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } // // CPU diff --git a/pages/admin/clienterrors.go b/pages/admin/clienterrors.go index f2e2771b..cf1fa50c 100644 --- a/pages/admin/clienterrors.go +++ b/pages/admin/clienterrors.go @@ -11,7 +11,7 @@ import ( const maxReports = 80 // ClientErrors shows client-side errors. -func ClientErrors(ctx *aero.Context) string { +func ClientErrors(ctx aero.Context) error { reports := arn.AllClientErrorReports() sort.Slice(reports, func(i, j int) bool { diff --git a/pages/admin/payments.go b/pages/admin/payments.go index 3d66ecf7..9e0553d9 100644 --- a/pages/admin/payments.go +++ b/pages/admin/payments.go @@ -11,7 +11,7 @@ import ( ) // PaymentHistory ... -func PaymentHistory(ctx *aero.Context) string { +func PaymentHistory(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/admin/purchases.go b/pages/admin/purchases.go index 23eca5dd..2ff51d34 100644 --- a/pages/admin/purchases.go +++ b/pages/admin/purchases.go @@ -11,7 +11,7 @@ import ( ) // PurchaseHistory ... -func PurchaseHistory(ctx *aero.Context) string { +func PurchaseHistory(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/admin/registrations.go b/pages/admin/registrations.go index c6005358..7d59753f 100644 --- a/pages/admin/registrations.go +++ b/pages/admin/registrations.go @@ -12,7 +12,7 @@ import ( ) // UserRegistrations ... -func UserRegistrations(ctx *aero.Context) string { +func UserRegistrations(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/admin/webdev.go b/pages/admin/webdev.go index 15d7c97c..d1d61bbe 100644 --- a/pages/admin/webdev.go +++ b/pages/admin/webdev.go @@ -4,6 +4,6 @@ import "github.com/aerogo/aero" import "github.com/animenotifier/notify.moe/components" // WebDev ... -func WebDev(ctx *aero.Context) string { +func WebDev(ctx aero.Context) error { return ctx.HTML(components.WebDev()) } diff --git a/pages/amv/amv.go b/pages/amv/amv.go index 2da00154..5a35772b 100644 --- a/pages/amv/amv.go +++ b/pages/amv/amv.go @@ -6,11 +6,12 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Get a single AMV. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { id := ctx.Get("id") amv, err := arn.GetAMV(id) user := utils.GetUser(ctx) @@ -19,6 +20,7 @@ func Get(ctx *aero.Context) string { return ctx.Error(http.StatusNotFound, "AMV not found", err) } - ctx.Data = getOpenGraph(ctx, amv) + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = getOpenGraph(ctx, amv) return ctx.HTML(components.AMVPage(amv, user)) } diff --git a/pages/amv/edit.go b/pages/amv/edit.go index a89c6929..00b2d928 100644 --- a/pages/amv/edit.go +++ b/pages/amv/edit.go @@ -11,7 +11,7 @@ import ( ) // Edit track. -func Edit(ctx *aero.Context) string { +func Edit(ctx aero.Context) error { id := ctx.Get("id") amv, err := arn.GetAMV(id) user := utils.GetUser(ctx) diff --git a/pages/amv/opengraph.go b/pages/amv/opengraph.go index c2834643..02992755 100644 --- a/pages/amv/opengraph.go +++ b/pages/amv/opengraph.go @@ -5,14 +5,15 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" ) -func getOpenGraph(ctx *aero.Context, amv *arn.AMV) *arn.OpenGraph { +func getOpenGraph(ctx aero.Context, amv *arn.AMV) *arn.OpenGraph { openGraph := &arn.OpenGraph{ Tags: map[string]string{ "og:title": amv.Title.ByUser(nil) + " (AMV)", - "og:url": "https://" + ctx.App.Config.Domain + amv.Link(), - "og:site_name": ctx.App.Config.Domain, + "og:url": "https://" + assets.Domain + amv.Link(), + "og:site_name": assets.Domain, "og:type": "video.other", }, Meta: map[string]string{}, @@ -21,7 +22,7 @@ func getOpenGraph(ctx *aero.Context, amv *arn.AMV) *arn.OpenGraph { openGraph.Tags["og:description"] = strings.Join(amv.Tags, ", ") if amv.File != "" { - openGraph.Tags["og:video"] = "https://" + ctx.App.Config.Domain + "/videos/amvs/" + amv.File + openGraph.Tags["og:video"] = "https://" + assets.Domain + "/videos/amvs/" + amv.File openGraph.Tags["og:video:type"] = "video/webm" openGraph.Tags["og:video:width"] = "640" openGraph.Tags["og:video:height"] = "360" diff --git a/pages/amvs/best.go b/pages/amvs/best.go index b6c1b0be..92bf7509 100644 --- a/pages/amvs/best.go +++ b/pages/amvs/best.go @@ -7,7 +7,7 @@ import ( ) // Best AMVs. -func Best(ctx *aero.Context) string { +func Best(ctx aero.Context) error { amvs := fetchAll() sort.Slice(amvs, func(i, j int) bool { diff --git a/pages/amvs/latest.go b/pages/amvs/latest.go index b3db602e..bafc0c83 100644 --- a/pages/amvs/latest.go +++ b/pages/amvs/latest.go @@ -7,7 +7,7 @@ import ( ) // Latest AMVs. -func Latest(ctx *aero.Context) string { +func Latest(ctx aero.Context) error { amvs := fetchAll() sort.Slice(amvs, func(i, j int) bool { diff --git a/pages/amvs/render.go b/pages/amvs/render.go index ecc97b50..7eed6354 100644 --- a/pages/amvs/render.go +++ b/pages/amvs/render.go @@ -14,7 +14,7 @@ const ( ) // render renders the AMVs page with the given AMVs. -func render(ctx *aero.Context, allAMVs []*arn.AMV) string { +func render(ctx aero.Context, allAMVs []*arn.AMV) error { user := utils.GetUser(ctx) index, _ := ctx.GetInt("index") tag := ctx.Get("tag") diff --git a/pages/anime/anime.go b/pages/anime/anime.go index 50376ad0..95d92e09 100644 --- a/pages/anime/anime.go +++ b/pages/anime/anime.go @@ -6,7 +6,9 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) @@ -18,7 +20,7 @@ const ( ) // Get anime page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) anime, err := arn.GetAnime(id) @@ -120,12 +122,13 @@ func Get(ctx *aero.Context) string { }) // Open Graph - ctx.Data = getOpenGraph(ctx, anime) + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = getOpenGraph(ctx, anime) return ctx.HTML(components.Anime(anime, animeListItem, tracks, amvs, amvAppearances, episodes, friends, friendsAnimeListItems, episodeToFriends, user)) } -func getOpenGraph(ctx *aero.Context, anime *arn.Anime) *arn.OpenGraph { +func getOpenGraph(ctx aero.Context, anime *arn.Anime) *arn.OpenGraph { description := anime.Summary if len(description) > maxDescriptionLength { @@ -136,7 +139,7 @@ func getOpenGraph(ctx *aero.Context, anime *arn.Anime) *arn.OpenGraph { Tags: map[string]string{ "og:title": anime.Title.Canonical, "og:image": "https:" + anime.ImageLink("large"), - "og:url": "https://" + ctx.App.Config.Domain + anime.Link(), + "og:url": "https://" + assets.Domain + anime.Link(), "og:site_name": "notify.moe", "og:description": description, }, diff --git a/pages/anime/characters.go b/pages/anime/characters.go index 22da7b25..743d91f0 100644 --- a/pages/anime/characters.go +++ b/pages/anime/characters.go @@ -12,7 +12,7 @@ import ( ) // Characters ... -func Characters(ctx *aero.Context) string { +func Characters(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) anime, err := arn.GetAnime(id) diff --git a/pages/anime/comments.go b/pages/anime/comments.go index d9006f66..10dbaad4 100644 --- a/pages/anime/comments.go +++ b/pages/anime/comments.go @@ -11,7 +11,7 @@ import ( ) // Comments ... -func Comments(ctx *aero.Context) string { +func Comments(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") anime, err := arn.GetAnime(id) diff --git a/pages/anime/editanime/editanime.go b/pages/anime/editanime/editanime.go index 95a1e0ae..e12d373e 100644 --- a/pages/anime/editanime/editanime.go +++ b/pages/anime/editanime/editanime.go @@ -11,7 +11,7 @@ import ( ) // Main anime edit page. -func Main(ctx *aero.Context) string { +func Main(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) @@ -29,7 +29,7 @@ func Main(ctx *aero.Context) string { } // Images anime images edit page. -func Images(ctx *aero.Context) string { +func Images(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) @@ -47,7 +47,7 @@ func Images(ctx *aero.Context) string { } // Characters anime characters edit page. -func Characters(ctx *aero.Context) string { +func Characters(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) @@ -71,7 +71,7 @@ func Characters(ctx *aero.Context) string { } // Relations anime relations edit page. -func Relations(ctx *aero.Context) string { +func Relations(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) @@ -95,7 +95,7 @@ func Relations(ctx *aero.Context) string { } // Episodes anime episodes edit page. -func Episodes(ctx *aero.Context) string { +func Episodes(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) diff --git a/pages/anime/episodes.go b/pages/anime/episodes.go index a448874e..daa6c259 100644 --- a/pages/anime/episodes.go +++ b/pages/anime/episodes.go @@ -11,7 +11,7 @@ import ( ) // Episodes ... -func Episodes(ctx *aero.Context) string { +func Episodes(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") anime, err := arn.GetAnime(id) diff --git a/pages/anime/redirect.go b/pages/anime/redirect.go index 747f3ff0..381aee0b 100644 --- a/pages/anime/redirect.go +++ b/pages/anime/redirect.go @@ -9,8 +9,8 @@ import ( ) // RedirectByMapping redirects to the anime with the given mapping ID. -func RedirectByMapping(mappingName string) func(*aero.Context) string { - return func(ctx *aero.Context) string { +func RedirectByMapping(mappingName string) func(aero.Context) error { + return func(ctx aero.Context) error { id := ctx.Get("id") finder := arn.NewAnimeFinder(mappingName) anime := finder.GetAnime(id) diff --git a/pages/anime/relations.go b/pages/anime/relations.go index e3e8a455..df10e882 100644 --- a/pages/anime/relations.go +++ b/pages/anime/relations.go @@ -10,7 +10,7 @@ import ( ) // Relations ... -func Relations(ctx *aero.Context) string { +func Relations(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") diff --git a/pages/anime/tracks.go b/pages/anime/tracks.go index 014dea3e..9d07bdfb 100644 --- a/pages/anime/tracks.go +++ b/pages/anime/tracks.go @@ -12,7 +12,7 @@ import ( ) // Tracks ... -func Tracks(ctx *aero.Context) string { +func Tracks(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) diff --git a/pages/animeimport/deletekitsu.go b/pages/animeimport/deletekitsu.go index c06bc1a2..fa46ef23 100644 --- a/pages/animeimport/deletekitsu.go +++ b/pages/animeimport/deletekitsu.go @@ -10,7 +10,7 @@ import ( ) // DeleteKitsu marks an anime for deletion. -func DeleteKitsu(ctx *aero.Context) string { +func DeleteKitsu(ctx aero.Context) error { id := ctx.Get("id") // Is the user allowed to delete? @@ -39,5 +39,5 @@ func DeleteKitsu(ctx *aero.Context) string { // Save in database arn.DB.Set("IDList", "deleted kitsu anime", &deletedKitsuAnime) - return "" + return nil } diff --git a/pages/animeimport/kitsu.go b/pages/animeimport/kitsu.go index a97e387a..81a971df 100644 --- a/pages/animeimport/kitsu.go +++ b/pages/animeimport/kitsu.go @@ -14,7 +14,7 @@ import ( ) // Kitsu anime import. -func Kitsu(ctx *aero.Context) string { +func Kitsu(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) @@ -45,5 +45,5 @@ func Kitsu(ctx *aero.Context) string { // Log fmt.Println(color.GreenString("✔"), anime.ID, anime.Title.Canonical) - return "" + return nil } diff --git a/pages/animelist/animelist.go b/pages/animelist/animelist.go index 9847334e..09ed70e4 100644 --- a/pages/animelist/animelist.go +++ b/pages/animelist/animelist.go @@ -6,7 +6,9 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" "github.com/animenotifier/notify.moe/utils/infinitescroll" ) @@ -17,15 +19,15 @@ const ( ) // FilterByStatus returns a handler for the given anime list item status. -func FilterByStatus(status string) aero.Handle { - return func(ctx *aero.Context) string { +func FilterByStatus(status string) aero.Handler { + return func(ctx aero.Context) error { user := utils.GetUser(ctx) return AnimeList(ctx, user, status) } } // AnimeList renders the anime list items. -func AnimeList(ctx *aero.Context, user *arn.User, status string) string { +func AnimeList(ctx aero.Context, user *arn.User, status string) error { nick := ctx.Get("nick") index, _ := ctx.GetInt("index") viewUser, err := arn.GetUserByNick(nick) @@ -70,11 +72,12 @@ func AnimeList(ctx *aero.Context, user *arn.User, status string) string { nextIndex := infinitescroll.NextIndex(ctx, len(allItems), maxLength, index) // OpenGraph data - ctx.Data = &arn.OpenGraph{ + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = &arn.OpenGraph{ Tags: map[string]string{ "og:title": viewUser.Nick + "'s anime list", "og:image": "https:" + viewUser.AvatarLink("large"), - "og:url": "https://" + ctx.App.Config.Domain + viewUser.Link(), + "og:url": "https://" + assets.Domain + viewUser.Link(), "og:site_name": "notify.moe", "og:description": strconv.Itoa(len(animeList.Items)) + " anime", diff --git a/pages/animelist/redirect.go b/pages/animelist/redirect.go index 0d0e7488..e296146e 100644 --- a/pages/animelist/redirect.go +++ b/pages/animelist/redirect.go @@ -8,12 +8,12 @@ import ( ) // Redirect to the full URL including the user nick. -func Redirect(ctx *aero.Context) string { +func Redirect(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { return ctx.Error(http.StatusUnauthorized, "Not logged in") } - return ctx.Redirect("/+" + user.Nick + ctx.URI()) + return ctx.Redirect(http.StatusFound, "/+" + user.Nick + ctx.Path()) } diff --git a/pages/animelistitem/animelistitem.go b/pages/animelistitem/animelistitem.go index 97365146..778dd01d 100644 --- a/pages/animelistitem/animelistitem.go +++ b/pages/animelistitem/animelistitem.go @@ -11,7 +11,7 @@ import ( ) // Get anime page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) nick := ctx.Get("nick") viewUser, err := arn.GetUserByNick(nick) diff --git a/pages/apiview/api.go b/pages/apiview/api.go index f1772c3a..d091458a 100644 --- a/pages/apiview/api.go +++ b/pages/apiview/api.go @@ -12,7 +12,7 @@ import ( ) // Get api page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { types := []*autodocs.Type{} for typeName := range arn.DB.Types() { diff --git a/pages/apiview/apidocs/apidocs.go b/pages/apiview/apidocs/apidocs.go index ba4b1630..77e7a066 100644 --- a/pages/apiview/apidocs/apidocs.go +++ b/pages/apiview/apidocs/apidocs.go @@ -13,8 +13,8 @@ import ( ) // ByType renders the api docs page for the given type. -func ByType(typeName string) func(*aero.Context) string { - return func(ctx *aero.Context) string { +func ByType(typeName string) func(aero.Context) error { + return func(ctx aero.Context) error { t := arn.API.Type(typeName) fields := []*utils.APIField{} diff --git a/pages/calendar/calendar.go b/pages/calendar/calendar.go index 320bde74..570df7ce 100644 --- a/pages/calendar/calendar.go +++ b/pages/calendar/calendar.go @@ -22,7 +22,7 @@ var weekdayNames = []string{ } // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) oneWeek := 7 * 24 * time.Hour diff --git a/pages/character/character.go b/pages/character/character.go index d7b20bad..03078cea 100644 --- a/pages/character/character.go +++ b/pages/character/character.go @@ -7,7 +7,9 @@ import ( "github.com/aerogo/aero" "github.com/akyoto/color" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) @@ -16,7 +18,7 @@ const ( ) // Get character. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") character, err := arn.GetCharacter(id) @@ -101,11 +103,12 @@ func Get(ctx *aero.Context) string { // Set OpenGraph attributes description := utils.CutLongDescription(character.Description) - ctx.Data = &arn.OpenGraph{ + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = &arn.OpenGraph{ Tags: map[string]string{ "og:title": character.Name.Canonical, "og:image": "https:" + character.ImageLink("large"), - "og:url": "https://" + ctx.App.Config.Domain + character.Link(), + "og:url": "https://" + assets.Domain + character.Link(), "og:site_name": "notify.moe", "og:description": description, diff --git a/pages/character/edit.go b/pages/character/edit.go index 87cc4bec..04518f3f 100644 --- a/pages/character/edit.go +++ b/pages/character/edit.go @@ -11,7 +11,7 @@ import ( ) // Edit character. -func Edit(ctx *aero.Context) string { +func Edit(ctx aero.Context) error { id := ctx.Get("id") character, err := arn.GetCharacter(id) user := utils.GetUser(ctx) @@ -24,7 +24,7 @@ func Edit(ctx *aero.Context) string { } // EditImages renders the form to edit the character images. -func EditImages(ctx *aero.Context) string { +func EditImages(ctx aero.Context) error { id := ctx.Get("id") character, err := arn.GetCharacter(id) user := utils.GetUser(ctx) diff --git a/pages/character/ranking.go b/pages/character/ranking.go index 61bb2edb..7187c1cf 100644 --- a/pages/character/ranking.go +++ b/pages/character/ranking.go @@ -8,7 +8,7 @@ import ( ) // Ranking returns the ranking information for the character via the API. -func Ranking(ctx *aero.Context) string { +func Ranking(ctx aero.Context) error { // Check character ID id := ctx.Get("id") _, err := arn.GetCharacter(id) @@ -35,7 +35,7 @@ func Ranking(ctx *aero.Context) string { arn.SortCharactersByLikes(characters) // Allow CORS - ctx.Response().Header().Set("Access-Control-Allow-Origin", "*") + ctx.Response().SetHeader("Access-Control-Allow-Origin", "*") // Return ranking for index, character := range characters { diff --git a/pages/characters/best.go b/pages/characters/best.go index 87773f58..08e9e5fb 100644 --- a/pages/characters/best.go +++ b/pages/characters/best.go @@ -6,7 +6,7 @@ import ( ) // Best characters. -func Best(ctx *aero.Context) string { +func Best(ctx aero.Context) error { characters := fetchAll() arn.SortCharactersByLikes(characters) diff --git a/pages/characters/latest.go b/pages/characters/latest.go index 5d30f49b..3098cd07 100644 --- a/pages/characters/latest.go +++ b/pages/characters/latest.go @@ -7,7 +7,7 @@ import ( ) // Latest characters. -func Latest(ctx *aero.Context) string { +func Latest(ctx aero.Context) error { characters := fetchAll() sort.Slice(characters, func(i, j int) bool { diff --git a/pages/characters/render.go b/pages/characters/render.go index 141a5df2..c2f0f814 100644 --- a/pages/characters/render.go +++ b/pages/characters/render.go @@ -14,7 +14,7 @@ const ( ) // render renders the characters page with the given characters. -func render(ctx *aero.Context, allCharacters []*arn.Character) string { +func render(ctx aero.Context, allCharacters []*arn.Character) error { user := utils.GetUser(ctx) index, _ := ctx.GetInt("index") tag := ctx.Get("tag") diff --git a/pages/charge/charge.go b/pages/charge/charge.go index 859eb0a8..0789c61f 100644 --- a/pages/charge/charge.go +++ b/pages/charge/charge.go @@ -10,7 +10,7 @@ import ( ) // Get charge page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/companies/all.go b/pages/companies/all.go index ce5ee1cc..b4ac64ee 100644 --- a/pages/companies/all.go +++ b/pages/companies/all.go @@ -12,7 +12,7 @@ import ( ) // All renders an index of all companies. -func All(ctx *aero.Context) string { +func All(ctx aero.Context) error { user := utils.GetUser(ctx) companies := arn.FilterCompanies(func(company *arn.Company) bool { diff --git a/pages/companies/popular.go b/pages/companies/popular.go index 0ae924bf..fabd230b 100644 --- a/pages/companies/popular.go +++ b/pages/companies/popular.go @@ -11,7 +11,7 @@ import ( const maxPopularCompanies = 10 // Popular renders the best companies. -func Popular(ctx *aero.Context) string { +func Popular(ctx aero.Context) error { user := utils.GetUser(ctx) index, _ := ctx.GetInt("index") diff --git a/pages/company/company.go b/pages/company/company.go index de7e9cad..664b228f 100644 --- a/pages/company/company.go +++ b/pages/company/company.go @@ -6,12 +6,14 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Get renders a company page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") company, err := arn.GetCompany(id) @@ -25,7 +27,7 @@ func Get(ctx *aero.Context) string { openGraph := &arn.OpenGraph{ Tags: map[string]string{ "og:title": company.Name.English, - "og:url": "https://" + ctx.App.Config.Domain + company.Link(), + "og:url": "https://" + assets.Domain + company.Link(), "og:site_name": "notify.moe", "og:type": "article", }, @@ -41,7 +43,8 @@ func Get(ctx *aero.Context) string { openGraph.Tags["og:description"] = company.Name.English + " company information." } - ctx.Data = openGraph + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = openGraph studioAnime, producedAnime, licensedAnime := company.Anime() diff --git a/pages/company/edit.go b/pages/company/edit.go index 1b1e7135..61dee65c 100644 --- a/pages/company/edit.go +++ b/pages/company/edit.go @@ -5,13 +5,15 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" "github.com/animenotifier/notify.moe/utils/editform" ) // Edit company. -func Edit(ctx *aero.Context) string { +func Edit(ctx aero.Context) error { id := ctx.Get("id") company, err := arn.GetCompany(id) user := utils.GetUser(ctx) @@ -20,10 +22,11 @@ func Edit(ctx *aero.Context) string { return ctx.Error(http.StatusNotFound, "Company not found", err) } - ctx.Data = &arn.OpenGraph{ + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = &arn.OpenGraph{ Tags: map[string]string{ "og:title": company.Name.English, - "og:url": "https://" + ctx.App.Config.Domain + company.Link(), + "og:url": "https://" + assets.Domain + company.Link(), "og:site_name": "notify.moe", // "og:image": company.Image, }, diff --git a/pages/compare/animelist.go b/pages/compare/animelist.go index eb7b7249..0ec0cee0 100644 --- a/pages/compare/animelist.go +++ b/pages/compare/animelist.go @@ -12,7 +12,7 @@ import ( ) // AnimeList ... -func AnimeList(ctx *aero.Context) string { +func AnimeList(ctx aero.Context) error { user := utils.GetUser(ctx) nickA := ctx.Get("nick-1") nickB := ctx.Get("nick-2") diff --git a/pages/editlog/editlog.go b/pages/editlog/editlog.go index 24114fc9..66d14164 100644 --- a/pages/editlog/editlog.go +++ b/pages/editlog/editlog.go @@ -18,7 +18,7 @@ const ( ) // Get edit log. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) index, _ := ctx.GetInt("index") nick := ctx.Get("nick") diff --git a/pages/editor/editor.go b/pages/editor/editor.go index 058593cc..99d46cf4 100644 --- a/pages/editor/editor.go +++ b/pages/editor/editor.go @@ -1,6 +1,7 @@ package editor import ( + "net/http" "strconv" "github.com/aerogo/aero" @@ -10,11 +11,11 @@ import ( ) // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil || (user.Role != "admin" && user.Role != "editor") { - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } ignoreDifferences := arn.FilterIgnoreAnimeDifferences(func(entry *arn.IgnoreAnimeDifference) bool { @@ -43,5 +44,5 @@ func Get(ctx *aero.Context) string { scoreTitle += objectType + ": " + strconv.Itoa(score) + "\n" } - return ctx.HTML(components.Editor(ctx.URI(), score, scoreTitle, scoreTypes, user)) + return ctx.HTML(components.Editor(ctx.Path(), score, scoreTitle, scoreTypes, user)) } diff --git a/pages/editor/filteranime/all.go b/pages/editor/filteranime/all.go index 9b221a34..793c219c 100644 --- a/pages/editor/filteranime/all.go +++ b/pages/editor/filteranime/all.go @@ -6,7 +6,7 @@ import ( ) // All ... -func All(ctx *aero.Context) string { +func All(ctx aero.Context) error { return editorList( ctx, "All anime", diff --git a/pages/editor/filteranime/anilist.go b/pages/editor/filteranime/anilist.go index f643a5dc..e7a784f5 100644 --- a/pages/editor/filteranime/anilist.go +++ b/pages/editor/filteranime/anilist.go @@ -6,7 +6,7 @@ import ( ) // AniList ... -func AniList(ctx *aero.Context) string { +func AniList(ctx aero.Context) error { return editorList( ctx, "Anime without Anilist mappings", diff --git a/pages/editor/filteranime/characters.go b/pages/editor/filteranime/characters.go index a1a7e98a..cf494d47 100644 --- a/pages/editor/filteranime/characters.go +++ b/pages/editor/filteranime/characters.go @@ -6,7 +6,7 @@ import ( ) // Characters ... -func Characters(ctx *aero.Context) string { +func Characters(ctx aero.Context) error { return editorList( ctx, "Anime without characters", diff --git a/pages/editor/filteranime/duplicatemappings.go b/pages/editor/filteranime/duplicatemappings.go index f1072af2..2418eb19 100644 --- a/pages/editor/filteranime/duplicatemappings.go +++ b/pages/editor/filteranime/duplicatemappings.go @@ -6,7 +6,7 @@ import ( ) // DuplicateMappings ... -func DuplicateMappings(ctx *aero.Context) string { +func DuplicateMappings(ctx aero.Context) error { return editorList( ctx, "Anime with duplicate mappings", diff --git a/pages/editor/filteranime/episodelength.go b/pages/editor/filteranime/episodelength.go index a0cad5cc..00c2d281 100644 --- a/pages/editor/filteranime/episodelength.go +++ b/pages/editor/filteranime/episodelength.go @@ -6,7 +6,7 @@ import ( ) // EpisodeLength ... -func EpisodeLength(ctx *aero.Context) string { +func EpisodeLength(ctx aero.Context) error { return editorList( ctx, "Anime without an episode length", diff --git a/pages/editor/filteranime/genres.go b/pages/editor/filteranime/genres.go index 24623413..044df7ae 100644 --- a/pages/editor/filteranime/genres.go +++ b/pages/editor/filteranime/genres.go @@ -6,7 +6,7 @@ import ( ) // Genres ... -func Genres(ctx *aero.Context) string { +func Genres(ctx aero.Context) error { return editorList( ctx, "Anime without genres", diff --git a/pages/editor/filteranime/licensors.go b/pages/editor/filteranime/licensors.go index 8e56b9e1..a3103080 100644 --- a/pages/editor/filteranime/licensors.go +++ b/pages/editor/filteranime/licensors.go @@ -6,7 +6,7 @@ import ( ) // Licensors ... -func Licensors(ctx *aero.Context) string { +func Licensors(ctx aero.Context) error { return editorList( ctx, "Anime without licensors", diff --git a/pages/editor/filteranime/lowresimages.go b/pages/editor/filteranime/lowresimages.go index 85dd78b8..e437bd5b 100644 --- a/pages/editor/filteranime/lowresimages.go +++ b/pages/editor/filteranime/lowresimages.go @@ -6,16 +6,16 @@ import ( ) // LowResolutionAnimeImages filters anime with low resolution images. -func LowResolutionAnimeImages(ctx *aero.Context) string { +func LowResolutionAnimeImages(ctx aero.Context) error { return filterAnimeImages(ctx, "Anime with low resolution images", arn.AnimeImageLargeWidth, arn.AnimeImageLargeHeight) } // UltraLowResolutionAnimeImages filters anime with ultra low resolution images. -func UltraLowResolutionAnimeImages(ctx *aero.Context) string { +func UltraLowResolutionAnimeImages(ctx aero.Context) error { return filterAnimeImages(ctx, "Anime with ultra low resolution images", arn.AnimeImageLargeWidth/2, arn.AnimeImageLargeHeight/2) } -func filterAnimeImages(ctx *aero.Context, title string, minExpectedWidth int, minExpectedHeight int) string { +func filterAnimeImages(ctx aero.Context, title string, minExpectedWidth int, minExpectedHeight int) error { return editorList( ctx, title, diff --git a/pages/editor/filteranime/mal.go b/pages/editor/filteranime/mal.go index 0af5732f..4277a832 100644 --- a/pages/editor/filteranime/mal.go +++ b/pages/editor/filteranime/mal.go @@ -6,7 +6,7 @@ import ( ) // MAL ... -func MAL(ctx *aero.Context) string { +func MAL(ctx aero.Context) error { return editorList( ctx, "Anime without MAL mappings", diff --git a/pages/editor/filteranime/producers.go b/pages/editor/filteranime/producers.go index 3ab3b6c5..58bd6cd6 100644 --- a/pages/editor/filteranime/producers.go +++ b/pages/editor/filteranime/producers.go @@ -6,7 +6,7 @@ import ( ) // Producers ... -func Producers(ctx *aero.Context) string { +func Producers(ctx aero.Context) error { return editorList( ctx, "Anime without producers", diff --git a/pages/editor/filteranime/relations.go b/pages/editor/filteranime/relations.go index 80f9d74c..7a01be9a 100644 --- a/pages/editor/filteranime/relations.go +++ b/pages/editor/filteranime/relations.go @@ -6,7 +6,7 @@ import ( ) // Relations ... -func Relations(ctx *aero.Context) string { +func Relations(ctx aero.Context) error { return editorList( ctx, "Anime without relations", diff --git a/pages/editor/filteranime/shoboi.go b/pages/editor/filteranime/shoboi.go index 3324b2c2..3352e347 100644 --- a/pages/editor/filteranime/shoboi.go +++ b/pages/editor/filteranime/shoboi.go @@ -6,7 +6,7 @@ import ( ) // Shoboi ... -func Shoboi(ctx *aero.Context) string { +func Shoboi(ctx aero.Context) error { return editorList( ctx, "Anime without Shoboi mappings", diff --git a/pages/editor/filteranime/source.go b/pages/editor/filteranime/source.go index 53426587..8d20cd8a 100644 --- a/pages/editor/filteranime/source.go +++ b/pages/editor/filteranime/source.go @@ -6,7 +6,7 @@ import ( ) // Source ... -func Source(ctx *aero.Context) string { +func Source(ctx aero.Context) error { return editorList( ctx, "Anime without a source", diff --git a/pages/editor/filteranime/startdate.go b/pages/editor/filteranime/startdate.go index feac3e12..e796127f 100644 --- a/pages/editor/filteranime/startdate.go +++ b/pages/editor/filteranime/startdate.go @@ -8,7 +8,7 @@ import ( ) // StartDate ... -func StartDate(ctx *aero.Context) string { +func StartDate(ctx aero.Context) error { return editorList( ctx, "Anime without a valid start date", diff --git a/pages/editor/filteranime/studios.go b/pages/editor/filteranime/studios.go index 8db7f3d5..c946de3a 100644 --- a/pages/editor/filteranime/studios.go +++ b/pages/editor/filteranime/studios.go @@ -6,7 +6,7 @@ import ( ) // Studios ... -func Studios(ctx *aero.Context) string { +func Studios(ctx aero.Context) error { return editorList( ctx, "Anime without studios", diff --git a/pages/editor/filteranime/synopsis.go b/pages/editor/filteranime/synopsis.go index 2ef19acf..9a210282 100644 --- a/pages/editor/filteranime/synopsis.go +++ b/pages/editor/filteranime/synopsis.go @@ -6,7 +6,7 @@ import ( ) // Synopsis ... -func Synopsis(ctx *aero.Context) string { +func Synopsis(ctx aero.Context) error { return editorList( ctx, "Anime without a long synopsis", diff --git a/pages/editor/filteranime/trailers.go b/pages/editor/filteranime/trailers.go index 6ba28812..917b910b 100644 --- a/pages/editor/filteranime/trailers.go +++ b/pages/editor/filteranime/trailers.go @@ -8,7 +8,7 @@ import ( ) // Trailers ... -func Trailers(ctx *aero.Context) string { +func Trailers(ctx aero.Context) error { return editorList( ctx, "Anime without trailers", diff --git a/pages/editor/filteranime/utils.go b/pages/editor/filteranime/utils.go index 6d96f800..360fa1ad 100644 --- a/pages/editor/filteranime/utils.go +++ b/pages/editor/filteranime/utils.go @@ -13,7 +13,7 @@ import ( const maxAnimeEntries = 70 // editorList renders the anime list with the given title and filter. -func editorList(ctx *aero.Context, title string, filter func(*arn.Anime) bool, searchLink func(*arn.Anime) string) string { +func editorList(ctx aero.Context, title string, filter func(*arn.Anime) bool, searchLink func(*arn.Anime) string) error { user := utils.GetUser(ctx) if user == nil || (user.Role != "admin" && user.Role != "editor") { @@ -23,7 +23,7 @@ func editorList(ctx *aero.Context, title string, filter func(*arn.Anime) bool, s animes, count := filterAnime(ctx, user, filter) // Determine URL - url := strings.TrimPrefix(ctx.URI(), "/_") + url := strings.TrimPrefix(ctx.Path(), "/_") urlParts := strings.Split(url, "/") urlParts = urlParts[:len(urlParts)-4] url = strings.Join(urlParts, "/") @@ -40,7 +40,7 @@ func editorList(ctx *aero.Context, title string, filter func(*arn.Anime) bool, s // filterAnime filters anime by the given filter function and // additionally applies year and types filters if specified. -func filterAnime(ctx *aero.Context, user *arn.User, filter func(*arn.Anime) bool) ([]*arn.Anime, int) { +func filterAnime(ctx aero.Context, user *arn.User, filter func(*arn.Anime) bool) ([]*arn.Anime, int) { year := ctx.Get("year") status := ctx.Get("status") season := ctx.Get("season") diff --git a/pages/editor/filtercompanies/filtercompanies.go b/pages/editor/filtercompanies/filtercompanies.go index dd4eb34d..004c50ac 100644 --- a/pages/editor/filtercompanies/filtercompanies.go +++ b/pages/editor/filtercompanies/filtercompanies.go @@ -1,6 +1,8 @@ package filtercompanies import ( + "net/http" + "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" @@ -10,11 +12,11 @@ import ( const maxEntries = 70 // NoDescription ... -func NoDescription(ctx *aero.Context) string { +func NoDescription(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil || (user.Role != "admin" && user.Role != "editor") { - return ctx.Redirect("/") + return ctx.Redirect(http.StatusFound, "/") } companies := arn.FilterCompanies(func(company *arn.Company) bool { @@ -29,5 +31,5 @@ func NoDescription(ctx *aero.Context) string { companies = companies[:maxEntries] } - return ctx.HTML(components.CompaniesEditorList(companies, count, ctx.URI(), user)) + return ctx.HTML(components.CompaniesEditorList(companies, count, ctx.Path(), user)) } diff --git a/pages/editor/filtersoundtracks/file.go b/pages/editor/filtersoundtracks/file.go index 078726de..651f4ba3 100644 --- a/pages/editor/filtersoundtracks/file.go +++ b/pages/editor/filtersoundtracks/file.go @@ -6,7 +6,7 @@ import ( ) // File shows soundtracks without an audio file. -func File(ctx *aero.Context) string { +func File(ctx aero.Context) error { return editorList( ctx, "Soundtracks without an audio file", diff --git a/pages/editor/filtersoundtracks/links.go b/pages/editor/filtersoundtracks/links.go index 3b873703..b8ec6d54 100644 --- a/pages/editor/filtersoundtracks/links.go +++ b/pages/editor/filtersoundtracks/links.go @@ -6,7 +6,7 @@ import ( ) // Links shows soundtracks without links. -func Links(ctx *aero.Context) string { +func Links(ctx aero.Context) error { return editorList( ctx, "Soundtracks without links", diff --git a/pages/editor/filtersoundtracks/lyrics.go b/pages/editor/filtersoundtracks/lyrics.go index 82f68364..b4a3e604 100644 --- a/pages/editor/filtersoundtracks/lyrics.go +++ b/pages/editor/filtersoundtracks/lyrics.go @@ -8,7 +8,7 @@ import ( ) // MissingLyrics shows soundtracks without lyrics. -func MissingLyrics(ctx *aero.Context) string { +func MissingLyrics(ctx aero.Context) error { return editorList( ctx, "Soundtracks without lyrics", @@ -26,7 +26,7 @@ func MissingLyrics(ctx *aero.Context) string { } // UnalignedLyrics shows soundtracks with unaligned lyrics. -func UnalignedLyrics(ctx *aero.Context) string { +func UnalignedLyrics(ctx aero.Context) error { return editorList( ctx, "Soundtracks with unaligned lyrics", diff --git a/pages/editor/filtersoundtracks/tags.go b/pages/editor/filtersoundtracks/tags.go index b00d6f90..0e5241f1 100644 --- a/pages/editor/filtersoundtracks/tags.go +++ b/pages/editor/filtersoundtracks/tags.go @@ -6,7 +6,7 @@ import ( ) // Tags shows soundtracks with less than 3 tags. -func Tags(ctx *aero.Context) string { +func Tags(ctx aero.Context) error { return editorList( ctx, "Soundtracks with less than 3 tags", diff --git a/pages/editor/filtersoundtracks/utils.go b/pages/editor/filtersoundtracks/utils.go index d9e1029e..c28d04d9 100644 --- a/pages/editor/filtersoundtracks/utils.go +++ b/pages/editor/filtersoundtracks/utils.go @@ -13,7 +13,7 @@ import ( const maxSoundTrackEntries = 70 // editorList renders the soundtrack list with the given title and filter. -func editorList(ctx *aero.Context, title string, filter func(*arn.SoundTrack) bool, searchLink func(*arn.SoundTrack) string) string { +func editorList(ctx aero.Context, title string, filter func(*arn.SoundTrack) bool, searchLink func(*arn.SoundTrack) string) error { user := utils.GetUser(ctx) if user == nil || (user.Role != "admin" && user.Role != "editor") { @@ -21,7 +21,7 @@ func editorList(ctx *aero.Context, title string, filter func(*arn.SoundTrack) bo } tracks, count := filterSoundTracks(ctx, user, filter) - url := strings.TrimPrefix(ctx.URI(), "/_") + url := strings.TrimPrefix(ctx.Path(), "/_") return ctx.HTML(components.SoundTracksEditorListFull( title, @@ -34,7 +34,7 @@ func editorList(ctx *aero.Context, title string, filter func(*arn.SoundTrack) bo } // filterSoundTracks filters soundtracks by the given filter function. -func filterSoundTracks(ctx *aero.Context, user *arn.User, filter func(*arn.SoundTrack) bool) ([]*arn.SoundTrack, int) { +func filterSoundTracks(ctx aero.Context, user *arn.User, filter func(*arn.SoundTrack) bool) ([]*arn.SoundTrack, int) { // Filter tracks := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool { return !track.IsDraft && filter(track) diff --git a/pages/editor/jobs/jobs.go b/pages/editor/jobs/jobs.go index 827fceb0..5f4b4bb2 100644 --- a/pages/editor/jobs/jobs.go +++ b/pages/editor/jobs/jobs.go @@ -29,7 +29,7 @@ var jobInfo = map[string]*utils.JobInfo{ var jobLogs = []string{} // Overview shows all background jobs. -func Overview(ctx *aero.Context) string { +func Overview(ctx aero.Context) error { user := utils.GetUser(ctx) jobs := []*utils.JobInfo{} @@ -41,5 +41,5 @@ func Overview(ctx *aero.Context) string { return jobs[i].Name < jobs[j].Name }) - return ctx.HTML(components.EditorJobs(jobs, jobLogs, ctx.URI(), user)) + return ctx.HTML(components.EditorJobs(jobs, jobLogs, ctx.Path(), user)) } diff --git a/pages/editor/jobs/start.go b/pages/editor/jobs/start.go index b4b881b6..12cd34b5 100644 --- a/pages/editor/jobs/start.go +++ b/pages/editor/jobs/start.go @@ -14,7 +14,7 @@ import ( var jobStartMutex sync.Mutex // Start will start the specified background job. -func Start(ctx *aero.Context) string { +func Start(ctx aero.Context) error { jobStartMutex.Lock() defer jobStartMutex.Unlock() @@ -38,5 +38,5 @@ func Start(ctx *aero.Context) string { job.Start() jobLogs = append(jobLogs, user.Nick+" started "+job.Name+" job ("+arn.DateTimeUTC()+").") - return "ok" + return nil } diff --git a/pages/editor/kitsu.go b/pages/editor/kitsu.go index e61fb68b..e2334887 100644 --- a/pages/editor/kitsu.go +++ b/pages/editor/kitsu.go @@ -11,7 +11,7 @@ import ( ) // NewKitsuAnime ... -func NewKitsuAnime(ctx *aero.Context) string { +func NewKitsuAnime(ctx aero.Context) error { user := utils.GetUser(ctx) finder := arn.NewAnimeFinder("kitsu/anime") deletedIDs, err := arn.GetIDList("deleted kitsu anime") @@ -31,5 +31,5 @@ func NewKitsuAnime(ctx *aero.Context) string { return a.ID > b.ID }) - return ctx.HTML(components.NewKitsuAnime(animes, ctx.URI(), user)) + return ctx.HTML(components.NewKitsuAnime(animes, ctx.Path(), user)) } diff --git a/pages/editor/mal.go b/pages/editor/mal.go index b0a606ea..5d9919ac 100644 --- a/pages/editor/mal.go +++ b/pages/editor/mal.go @@ -18,7 +18,7 @@ const maxCompareMALEntries = 15 type diffFunction func(*arn.Anime, *mal.Anime) []animediff.Difference // CompareMAL ... -func CompareMAL(ctx *aero.Context) string { +func CompareMAL(ctx aero.Context) error { user := utils.GetUser(ctx) year := ctx.Get("year") status := ctx.Get("status") diff --git a/pages/embed/embed.go b/pages/embed/embed.go index a175975f..4c2a2336 100644 --- a/pages/embed/embed.go +++ b/pages/embed/embed.go @@ -9,21 +9,21 @@ import ( ) // Get anime list in the browser extension. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { - return utils.AllowEmbed(ctx, ctx.HTML(components.Login("_blank"))) + return ctx.HTML(components.Login("_blank")) } if !user.HasBasicInfo() { - return utils.AllowEmbed(ctx, ctx.HTML(components.ExtensionEnterBasicInfo())) + return ctx.HTML(components.ExtensionEnterBasicInfo()) } // Extension is enabled as long as the site isn't finished yet. // --- // if !user.IsPro() && user.TimeSinceRegistered() > 14*24*time.Hour { - // return utils.AllowEmbed(ctx, ctx.HTML(components.EmbedProNotice(user))) + // return ctx.HTML(components.EmbedProNotice(user)) // } animeList := user.AnimeList() @@ -35,5 +35,5 @@ func Get(ctx *aero.Context) string { watchingList := animeList.Watching() watchingList.Sort() - return utils.AllowEmbed(ctx, ctx.HTML(components.BrowserExtension(watchingList, animeList.User(), user))) + return ctx.HTML(components.BrowserExtension(watchingList, animeList.User(), user)) } diff --git a/pages/episode/episode.go b/pages/episode/episode.go index bcfadf3e..46e9652e 100644 --- a/pages/episode/episode.go +++ b/pages/episode/episode.go @@ -34,7 +34,7 @@ func init() { } // Get renders the anime episode. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") episodeNumber, err := ctx.GetInt("episode-number") diff --git a/pages/episode/subtitles.go b/pages/episode/subtitles.go index e3c5dc94..45689b6a 100644 --- a/pages/episode/subtitles.go +++ b/pages/episode/subtitles.go @@ -10,7 +10,7 @@ import ( ) // Subtitles returns the subtitles. -func Subtitles(ctx *aero.Context) string { +func Subtitles(ctx aero.Context) error { id := ctx.Get("id") language := ctx.Get("language") episodeNumber, err := ctx.GetInt("episode-number") @@ -26,8 +26,8 @@ func Subtitles(ctx *aero.Context) string { return ctx.Error(http.StatusNotFound, "Anime not found", err) } - ctx.Response().Header().Set("Access-Control-Allow-Origin", "*") - ctx.Response().Header().Set("Content-Type", "text/vtt; charset=utf-8") + ctx.Response().SetHeader("Access-Control-Allow-Origin", "*") + ctx.Response().SetHeader("Content-Type", "text/vtt; charset=utf-8") obj, err := spaces.GetObject("arn", fmt.Sprintf("videos/anime/%s/%d.%s.vtt", anime.ID, episodeNumber, language), minio.GetObjectOptions{}) diff --git a/pages/explore/explore.go b/pages/explore/explore.go index 00653540..5732915a 100644 --- a/pages/explore/explore.go +++ b/pages/explore/explore.go @@ -11,7 +11,7 @@ import ( ) // Filter ... -func Filter(ctx *aero.Context) string { +func Filter(ctx aero.Context) error { year := ctx.Get("year") season := ctx.Get("season") status := ctx.Get("status") diff --git a/pages/explore/explorecolor/explorecolor.go b/pages/explore/explorecolor/explorecolor.go index e6129b67..e8f18296 100644 --- a/pages/explore/explorecolor/explorecolor.go +++ b/pages/explore/explorecolor/explorecolor.go @@ -18,7 +18,7 @@ const ( ) // AnimeByAverageColor returns all anime with an image in the given color. -func AnimeByAverageColor(ctx *aero.Context) string { +func AnimeByAverageColor(ctx aero.Context) error { user := utils.GetUser(ctx) color := ctx.Get("color") index, _ := ctx.GetInt("index") diff --git a/pages/explore/explorerelations/sequels.go b/pages/explore/explorerelations/sequels.go index 41933be5..5a9032d2 100644 --- a/pages/explore/explorerelations/sequels.go +++ b/pages/explore/explorerelations/sequels.go @@ -12,7 +12,7 @@ import ( ) // Sequels ... -func Sequels(ctx *aero.Context) string { +func Sequels(ctx aero.Context) error { nick := ctx.Get("nick") user := utils.GetUser(ctx) viewUser, err := arn.GetUserByNick(nick) diff --git a/pages/explore/halloffame/halloffame.go b/pages/explore/halloffame/halloffame.go index faed67b9..555490dc 100644 --- a/pages/explore/halloffame/halloffame.go +++ b/pages/explore/halloffame/halloffame.go @@ -13,7 +13,7 @@ import ( const minYear = 1963 // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) maxYear := time.Now().Year() - 1 hallOfFameEntries := []*utils.HallOfFameEntry{} diff --git a/pages/forum/forum.go b/pages/forum/forum.go index 49eaf27b..a238b0bb 100644 --- a/pages/forum/forum.go +++ b/pages/forum/forum.go @@ -10,7 +10,7 @@ import ( const ThreadsPerPage = 20 // Get forum category. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { tag := ctx.Get("tag") threads := arn.GetThreadsByTag(tag) arn.SortThreads(threads) diff --git a/pages/frontpage/frontpage.go b/pages/frontpage/frontpage.go index bf83455e..52ae83ef 100644 --- a/pages/frontpage/frontpage.go +++ b/pages/frontpage/frontpage.go @@ -3,20 +3,23 @@ package frontpage import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" ) // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { description := "Anime list, tracker, database and notifier for new anime episodes. Create your own anime list and keep track of your progress as you watch." - ctx.Data = &arn.OpenGraph{ + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = &arn.OpenGraph{ Tags: map[string]string{ - "og:title": ctx.App.Config.Title, + "og:title": assets.Manifest.Name, "og:description": description, "og:type": "website", - "og:url": "https://" + ctx.App.Config.Domain, - "og:image": "https://" + ctx.App.Config.Domain + "/images/brand/220.png", + "og:url": "https://" + assets.Domain, + "og:image": "https://" + assets.Domain + "/images/brand/220.png", }, Meta: map[string]string{ "description": description, diff --git a/pages/genre/genre.go b/pages/genre/genre.go index 01283d46..8c3c52d5 100644 --- a/pages/genre/genre.go +++ b/pages/genre/genre.go @@ -13,7 +13,7 @@ const animePerPage = 100 const animeRatingCountThreshold = 5 // Get renders the genre page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) genreName := ctx.Get("name") animes := []*arn.Anime{} diff --git a/pages/genres/genres.go b/pages/genres/genres.go index e2b812cc..b67d3e46 100644 --- a/pages/genres/genres.go +++ b/pages/genres/genres.go @@ -8,7 +8,7 @@ import ( ) // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) genres := []string{} genreToAnime := map[string]*arn.Anime{} diff --git a/pages/group/edit.go b/pages/group/edit.go index e203897e..e460c583 100644 --- a/pages/group/edit.go +++ b/pages/group/edit.go @@ -11,7 +11,7 @@ import ( ) // Edit ... -func Edit(ctx *aero.Context) string { +func Edit(ctx aero.Context) error { id := ctx.Get("id") group, err := arn.GetGroup(id) user := utils.GetUser(ctx) @@ -30,7 +30,7 @@ func Edit(ctx *aero.Context) string { } // EditImage renders the form to edit the group images. -func EditImage(ctx *aero.Context) string { +func EditImage(ctx aero.Context) error { id := ctx.Get("id") group, err := arn.GetGroup(id) user := utils.GetUser(ctx) diff --git a/pages/group/feed.go b/pages/group/feed.go index 765405c2..a22dba49 100644 --- a/pages/group/feed.go +++ b/pages/group/feed.go @@ -6,11 +6,12 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Feed shows the group front page. -func Feed(ctx *aero.Context) string { +func Feed(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") group, err := arn.GetGroup(id) @@ -25,6 +26,7 @@ func Feed(ctx *aero.Context) string { member = group.FindMember(user.ID) } - ctx.Data = getOpenGraph(ctx, group) + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = getOpenGraph(ctx, group) return ctx.HTML(components.GroupFeed(group, member, user)) } diff --git a/pages/group/info.go b/pages/group/info.go index 0ec32855..783ba94c 100644 --- a/pages/group/info.go +++ b/pages/group/info.go @@ -6,11 +6,12 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Info shows the group information page. -func Info(ctx *aero.Context) string { +func Info(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") group, err := arn.GetGroup(id) @@ -25,6 +26,7 @@ func Info(ctx *aero.Context) string { member = group.FindMember(user.ID) } - ctx.Data = getOpenGraph(ctx, group) + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = getOpenGraph(ctx, group) return ctx.HTML(components.GroupInfo(group, member, user)) } diff --git a/pages/group/members.go b/pages/group/members.go index a0a1a7eb..b4ecf6ab 100644 --- a/pages/group/members.go +++ b/pages/group/members.go @@ -6,11 +6,12 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Members shows the group members. -func Members(ctx *aero.Context) string { +func Members(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") group, err := arn.GetGroup(id) @@ -25,6 +26,7 @@ func Members(ctx *aero.Context) string { member = group.FindMember(user.ID) } - ctx.Data = getOpenGraph(ctx, group) + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = getOpenGraph(ctx, group) return ctx.HTML(components.GroupMembers(group, member, user)) } diff --git a/pages/group/opengraph.go b/pages/group/opengraph.go index b50b7c60..d356b064 100644 --- a/pages/group/opengraph.go +++ b/pages/group/opengraph.go @@ -3,15 +3,16 @@ package group import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" ) -func getOpenGraph(ctx *aero.Context, group *arn.Group) *arn.OpenGraph { +func getOpenGraph(ctx aero.Context, group *arn.Group) *arn.OpenGraph { return &arn.OpenGraph{ Tags: map[string]string{ "og:title": group.Name, "og:description": group.Tagline, "og:image": "https:" + group.ImageLink("large"), - "og:url": "https://" + ctx.App.Config.Domain + group.Link(), + "og:url": "https://" + assets.Domain + group.Link(), "og:site_name": "notify.moe", }, } diff --git a/pages/groups/joined.go b/pages/groups/joined.go index 5de003c1..4c047a62 100644 --- a/pages/groups/joined.go +++ b/pages/groups/joined.go @@ -10,7 +10,7 @@ import ( ) // Joined shows the most popular joined groups. -func Joined(ctx *aero.Context) string { +func Joined(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/groups/latest.go b/pages/groups/latest.go index 1fbf074f..c09fdd5e 100644 --- a/pages/groups/latest.go +++ b/pages/groups/latest.go @@ -7,7 +7,7 @@ import ( ) // Latest shows the latest groups. -func Latest(ctx *aero.Context) string { +func Latest(ctx aero.Context) error { groups := fetchGroups("") sort.Slice(groups, func(i, j int) bool { diff --git a/pages/groups/popular.go b/pages/groups/popular.go index bfc52941..e43128b4 100644 --- a/pages/groups/popular.go +++ b/pages/groups/popular.go @@ -7,7 +7,7 @@ import ( ) // Popular shows the most popular groups. -func Popular(ctx *aero.Context) string { +func Popular(ctx aero.Context) error { groups := fetchGroups("") sort.Slice(groups, func(i, j int) bool { diff --git a/pages/groups/render.go b/pages/groups/render.go index 4bf29c7d..b7c51968 100644 --- a/pages/groups/render.go +++ b/pages/groups/render.go @@ -14,7 +14,7 @@ const ( ) // render renders the groups page with the given groups. -func render(ctx *aero.Context, allGroups []*arn.Group) string { +func render(ctx aero.Context, allGroups []*arn.Group) error { user := utils.GetUser(ctx) index, _ := ctx.GetInt("index") diff --git a/pages/home/home.go b/pages/home/home.go index 7cad055d..158e4edb 100644 --- a/pages/home/home.go +++ b/pages/home/home.go @@ -7,7 +7,7 @@ import ( ) // Get the anime list or the frontpage when logged out. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/index/staffroutes/staffroutes.go b/pages/index/staffroutes/staffroutes.go index 995cedf0..85d50566 100644 --- a/pages/index/staffroutes/staffroutes.go +++ b/pages/index/staffroutes/staffroutes.go @@ -18,7 +18,7 @@ func Register(l *layout.Layout) { l.Page("/editor", editor.Get) // Editor links can be filtered by year, status and type - editorFilterable := func(route string, handler func(ctx *aero.Context) string) { + editorFilterable := func(route string, handler func(ctx aero.Context) error) { l.Page(route+"/:year/:season/:status/:type", handler) } diff --git a/pages/inventory/inventory.go b/pages/inventory/inventory.go index a51730df..71c5eca8 100644 --- a/pages/inventory/inventory.go +++ b/pages/inventory/inventory.go @@ -12,7 +12,7 @@ import ( ) // Get inventory page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) viewUser := user diff --git a/pages/listimport/listimport.go b/pages/listimport/listimport.go index f4a0843b..57a0322d 100644 --- a/pages/listimport/listimport.go +++ b/pages/listimport/listimport.go @@ -9,7 +9,7 @@ import ( ) // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/listimport/listimportanilist/anilist.go b/pages/listimport/listimportanilist/anilist.go index 5f359349..bf8800d4 100644 --- a/pages/listimport/listimportanilist/anilist.go +++ b/pages/listimport/listimportanilist/anilist.go @@ -1,6 +1,8 @@ package listimportanilist import ( + "errors" + "fmt" "net/http" "strconv" @@ -12,34 +14,34 @@ import ( ) // Preview shows an import preview. -func Preview(ctx *aero.Context) string { +func Preview(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { return ctx.Error(http.StatusBadRequest, "Not logged in") } - matches, response := getMatches(ctx) + matches, err := getMatches(ctx) - if response != "" { - return response + if err != nil { + return ctx.Error(http.StatusBadRequest, err) } return ctx.HTML(components.ImportAnilist(user, matches)) } // Finish ... -func Finish(ctx *aero.Context) string { +func Finish(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { return ctx.Error(http.StatusBadRequest, "Not logged in") } - matches, response := getMatches(ctx) + matches, err := getMatches(ctx) - if response != "" { - return response + if err != nil { + return ctx.Error(http.StatusBadRequest, err) } animeList := user.AnimeList() @@ -71,31 +73,29 @@ func Finish(ctx *aero.Context) string { } // getMatches finds and returns all matches for the logged in user. -func getMatches(ctx *aero.Context) ([]*arn.AniListMatch, string) { +func getMatches(ctx aero.Context) ([]*arn.AniListMatch, error) { user := utils.GetUser(ctx) if user == nil { - return nil, ctx.Error(http.StatusBadRequest, "Not logged in") + return nil, errors.New("Not logged in") } - // Get user anilistUser, err := anilist.GetUser(user.Accounts.AniList.Nick) if err != nil { - return nil, ctx.Error(http.StatusBadRequest, "User doesn't exist on AniList", err) + return nil, fmt.Errorf("User doesn't exist on AniList: %s", err.Error()) } - // Get anime list anilistAnimeList, err := anilist.GetAnimeList(anilistUser.ID) if err != nil { - return nil, ctx.Error(http.StatusBadRequest, "Couldn't load your anime list from AniList", err) + return nil, fmt.Errorf("Couldn't load your anime list from AniList: %s", err.Error()) } // Find matches matches := findAllMatches(anilistAnimeList) - return matches, "" + return matches, nil } // findAllMatches returns all matches for the anime inside an anilist anime list. diff --git a/pages/listimport/listimportkitsu/kitsu.go b/pages/listimport/listimportkitsu/kitsu.go index 58503b00..7d9e393b 100644 --- a/pages/listimport/listimportkitsu/kitsu.go +++ b/pages/listimport/listimportkitsu/kitsu.go @@ -1,6 +1,8 @@ package listimportkitsu import ( + "errors" + "fmt" "net/http" "github.com/aerogo/aero" @@ -11,34 +13,34 @@ import ( ) // Preview shows an import preview. -func Preview(ctx *aero.Context) string { +func Preview(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { return ctx.Error(http.StatusBadRequest, "Not logged in") } - matches, response := getMatches(ctx) + matches, err := getMatches(ctx) - if response != "" { - return response + if err != nil { + return ctx.Error(http.StatusBadRequest, err) } return ctx.HTML(components.ImportKitsu(user, matches)) } // Finish ... -func Finish(ctx *aero.Context) string { +func Finish(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { return ctx.Error(http.StatusBadRequest, "Not logged in") } - matches, response := getMatches(ctx) + matches, err := getMatches(ctx) - if response != "" { - return response + if err != nil { + return ctx.Error(http.StatusBadRequest, err) } animeList := user.AnimeList() @@ -82,23 +84,23 @@ func Finish(ctx *aero.Context) string { } // getMatches finds and returns all matches for the logged in user. -func getMatches(ctx *aero.Context) ([]*arn.KitsuMatch, string) { +func getMatches(ctx aero.Context) ([]*arn.KitsuMatch, error) { user := utils.GetUser(ctx) if user == nil { - return nil, ctx.Error(http.StatusBadRequest, "Not logged in") + return nil, errors.New("Not logged in") } kitsuUser, err := kitsu.GetUser(user.Accounts.Kitsu.Nick) if err != nil { - return nil, ctx.Error(http.StatusBadRequest, "Couldn't load your user info from Kitsu", err) + return nil, fmt.Errorf("Couldn't load your user info from Kitsu: %s", err.Error()) } library := kitsuUser.StreamLibraryEntries() matches := findAllMatches(library) - return matches, "" + return matches, nil } // findAllMatches returns all matches for the anime inside an anilist anime list. diff --git a/pages/listimport/listimportmyanimelist/myanimelist.go b/pages/listimport/listimportmyanimelist/myanimelist.go index 071f9761..c3178ab5 100644 --- a/pages/listimport/listimportmyanimelist/myanimelist.go +++ b/pages/listimport/listimportmyanimelist/myanimelist.go @@ -1,6 +1,8 @@ package listimportmyanimelist import ( + "errors" + "fmt" "net/http" "strconv" @@ -12,34 +14,34 @@ import ( ) // Preview shows an import preview. -func Preview(ctx *aero.Context) string { +func Preview(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { return ctx.Error(http.StatusBadRequest, "Not logged in") } - matches, response := getMatches(ctx) + matches, err := getMatches(ctx) - if response != "" { - return response + if err != nil { + return ctx.Error(http.StatusBadRequest, err) } return ctx.HTML(components.ImportMyAnimeList(user, matches)) } // Finish ... -func Finish(ctx *aero.Context) string { +func Finish(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { return ctx.Error(http.StatusBadRequest, "Not logged in") } - matches, response := getMatches(ctx) + matches, err := getMatches(ctx) - if response != "" { - return response + if err != nil { + return ctx.Error(http.StatusBadRequest, err) } animeList := user.AnimeList() @@ -76,22 +78,22 @@ func Finish(ctx *aero.Context) string { } // getMatches finds and returns all matches for the logged in user. -func getMatches(ctx *aero.Context) ([]*arn.MyAnimeListMatch, string) { +func getMatches(ctx aero.Context) ([]*arn.MyAnimeListMatch, error) { user := utils.GetUser(ctx) if user == nil { - return nil, ctx.Error(http.StatusBadRequest, "Not logged in") + return nil, errors.New("Not logged in") } malAnimeList, err := mal.GetAnimeList(user.Accounts.MyAnimeList.Nick) if err != nil { - return nil, ctx.Error(http.StatusBadRequest, "Couldn't load your anime list from MyAnimeList", err) + return nil, fmt.Errorf("Couldn't load your anime list from MyAnimeList: %s", err.Error()) } matches := findAllMatches(malAnimeList) - return matches, "" + return matches, nil } // findAllMatches returns all matches for the anime inside an anilist anime list. diff --git a/pages/login/login.go b/pages/login/login.go index 6ce8450b..f2c62913 100644 --- a/pages/login/login.go +++ b/pages/login/login.go @@ -6,6 +6,6 @@ import ( ) // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { return ctx.HTML(components.Login("")) } diff --git a/pages/me/me.go b/pages/me/me.go index 51a42c9b..b68600da 100644 --- a/pages/me/me.go +++ b/pages/me/me.go @@ -6,7 +6,7 @@ import ( ) // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/newthread/newthread.go b/pages/newthread/newthread.go index 29e7b3a1..6a98065b 100644 --- a/pages/newthread/newthread.go +++ b/pages/newthread/newthread.go @@ -9,7 +9,7 @@ import ( ) // Get forums page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/notifications/all.go b/pages/notifications/all.go index e8d781e7..93baf0d1 100644 --- a/pages/notifications/all.go +++ b/pages/notifications/all.go @@ -12,7 +12,7 @@ import ( const maxAllNotifications = 150 // All shows all notifications. -func All(ctx *aero.Context) string { +func All(ctx aero.Context) error { notifications, err := arn.AllNotifications() if err != nil { diff --git a/pages/notifications/api.go b/pages/notifications/api.go index 9ea5b346..b72dd646 100644 --- a/pages/notifications/api.go +++ b/pages/notifications/api.go @@ -7,11 +7,12 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/utils" ) // CountUnseen sends the number of unseen notifications. -func CountUnseen(ctx *aero.Context) string { +func CountUnseen(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { @@ -24,7 +25,7 @@ func CountUnseen(ctx *aero.Context) string { } // MarkNotificationsAsSeen marks all notifications as seen. -func MarkNotificationsAsSeen(ctx *aero.Context) string { +func MarkNotificationsAsSeen(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { @@ -44,11 +45,11 @@ func MarkNotificationsAsSeen(ctx *aero.Context) string { Data: 0, }) - return "ok" + return nil } // Latest returns the latest notifications. -func Latest(ctx *aero.Context) string { +func Latest(ctx aero.Context) error { userID := ctx.Get("id") user, err := arn.GetUser(userID) @@ -71,7 +72,7 @@ func Latest(ctx *aero.Context) string { } // Test sends a test notification to the logged in user. -func Test(ctx *aero.Context) string { +func Test(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { @@ -81,9 +82,9 @@ func Test(ctx *aero.Context) string { user.SendNotification(&arn.PushNotification{ Title: "Anime Notifier", Message: "Yay, it works!", - Icon: "https://" + ctx.App.Config.Domain + "/images/brand/220.png", + Icon: "https://" + assets.Domain + "/images/brand/220.png", Type: arn.NotificationTypeTest, }) - return "ok" + return nil } diff --git a/pages/notifications/notifications.go b/pages/notifications/notifications.go index 7ef16113..e9a45afb 100644 --- a/pages/notifications/notifications.go +++ b/pages/notifications/notifications.go @@ -14,7 +14,7 @@ import ( const maxNotifications = 30 // ByUser shows all notifications sent to the given user. -func ByUser(ctx *aero.Context) string { +func ByUser(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/paypal/cancel.go b/pages/paypal/cancel.go index 3bd33809..4658dcd6 100644 --- a/pages/paypal/cancel.go +++ b/pages/paypal/cancel.go @@ -7,7 +7,7 @@ import ( ) // Cancel ... -func Cancel(ctx *aero.Context) string { +func Cancel(ctx aero.Context) error { token := ctx.Query("token") fmt.Println("cancel", token) diff --git a/pages/paypal/paypal.go b/pages/paypal/paypal.go index fdb55106..fe8631a8 100644 --- a/pages/paypal/paypal.go +++ b/pages/paypal/paypal.go @@ -5,12 +5,13 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/utils" paypalsdk "github.com/logpacker/PayPal-Go-SDK" ) // CreatePayment creates the PayPal payment, typically via a JSON API route. -func CreatePayment(ctx *aero.Context) string { +func CreatePayment(ctx aero.Context) error { // Make sure the user is logged in user := utils.GetUser(ctx) @@ -60,8 +61,8 @@ func CreatePayment(ctx *aero.Context) string { Description: "Top Up Balance", }}, RedirectURLs: &paypalsdk.RedirectURLs{ - ReturnURL: "https://" + ctx.App.Config.Domain + "/paypal/success", - CancelURL: "https://" + ctx.App.Config.Domain + "/paypal/cancel", + ReturnURL: "https://" + assets.Domain + "/paypal/success", + CancelURL: "https://" + assets.Domain + "/paypal/cancel", }, } diff --git a/pages/paypal/success.go b/pages/paypal/success.go index e1b1046c..64539131 100644 --- a/pages/paypal/success.go +++ b/pages/paypal/success.go @@ -8,6 +8,7 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/arn/stringutils" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" "github.com/animenotifier/notify.moe/utils" ) @@ -16,7 +17,7 @@ const adminID = "4J6qpK1ve" // Success is called once the payment has been confirmed by the user on the PayPal website. // However, the actual payment still needs to be executed and can fail. -func Success(ctx *aero.Context) string { +func Success(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { @@ -90,7 +91,7 @@ func Success(ctx *aero.Context) string { Title: user.Nick + " bought " + strconv.Itoa(payment.Gems()) + " gems", Message: user.Nick + " paid " + payment.Amount + " " + payment.Currency + " making his new balance " + strconv.Itoa(user.Balance), Icon: user.AvatarLink("large"), - Link: "https://" + ctx.App.Config.Domain + "/api/paypalpayment/" + payment.ID, + Link: "https://" + assets.Domain + "/api/paypalpayment/" + payment.ID, Type: arn.NotificationTypePurchase, }) }() diff --git a/pages/popular/animetitles.go b/pages/popular/animetitles.go index 4e8c4803..8b765596 100644 --- a/pages/popular/animetitles.go +++ b/pages/popular/animetitles.go @@ -9,7 +9,7 @@ import ( ) // AnimeTitles returns a list of the 500 most popular anime titles. -func AnimeTitles(ctx *aero.Context) string { +func AnimeTitles(ctx aero.Context) error { maxLength, err := ctx.GetInt("count") if err != nil { diff --git a/pages/post/editpost/editpost.go b/pages/post/editpost/editpost.go index 6ae3837a..60a05a46 100644 --- a/pages/post/editpost/editpost.go +++ b/pages/post/editpost/editpost.go @@ -11,7 +11,7 @@ import ( ) // Get post edit page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) diff --git a/pages/post/opengraph.go b/pages/post/opengraph.go index 13058d57..99b3f169 100644 --- a/pages/post/opengraph.go +++ b/pages/post/opengraph.go @@ -3,16 +3,17 @@ package post import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/utils" ) -func getOpenGraph(ctx *aero.Context, post *arn.Post) *arn.OpenGraph { +func getOpenGraph(ctx aero.Context, post *arn.Post) *arn.OpenGraph { openGraph := &arn.OpenGraph{ Tags: map[string]string{ "og:title": post.TitleByUser(nil), "og:description": utils.CutLongDescription(post.Text), - "og:url": "https://" + ctx.App.Config.Domain + post.Link(), - "og:site_name": ctx.App.Config.Domain, + "og:url": "https://" + assets.Domain + post.Link(), + "og:site_name": assets.Domain, "og:type": "article", }, } diff --git a/pages/post/post.go b/pages/post/post.go index 420019e2..108144f7 100644 --- a/pages/post/post.go +++ b/pages/post/post.go @@ -6,11 +6,12 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Get post. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) post, err := arn.GetPost(id) @@ -19,6 +20,7 @@ func Get(ctx *aero.Context) string { return ctx.Error(http.StatusNotFound, "Post not found", err) } - ctx.Data = getOpenGraph(ctx, post) + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = getOpenGraph(ctx, post) return ctx.HTML(components.Post(post, user)) } diff --git a/pages/post/reply-ui.go b/pages/post/reply-ui.go index 04d3b8f6..172b2c44 100644 --- a/pages/post/reply-ui.go +++ b/pages/post/reply-ui.go @@ -10,7 +10,7 @@ import ( ) // ReplyUI renders a new post area. -func ReplyUI(ctx *aero.Context) string { +func ReplyUI(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) post, err := arn.GetPost(id) diff --git a/pages/profile/followers.go b/pages/profile/followers.go index 02c61b16..9eee1af0 100644 --- a/pages/profile/followers.go +++ b/pages/profile/followers.go @@ -10,7 +10,7 @@ package profile // ) // // GetFollowers shows the followers of a particular user. -// func GetFollowers(ctx *aero.Context) string { +// func GetFollowers(ctx aero.Context) error { // nick := ctx.Get("nick") // viewUser, err := arn.GetUserByNick(nick) @@ -21,6 +21,6 @@ package profile // followers := viewUser.Followers() // arn.SortUsersLastSeenFirst(followers) -// return ctx.HTML(components.ProfileFollowers(followers, viewUser, utils.GetUser(ctx), ctx.URI())) +// return ctx.HTML(components.ProfileFollowers(followers, viewUser, utils.GetUser(ctx), ctx.Path())) // } diff --git a/pages/profile/posts.go b/pages/profile/posts.go index ee62c43e..9650a378 100644 --- a/pages/profile/posts.go +++ b/pages/profile/posts.go @@ -12,7 +12,7 @@ package profile // const postLimit = 10 // // GetPostsByUser shows all forum posts of a particular user. -// func GetPostsByUser(ctx *aero.Context) string { +// func GetPostsByUser(ctx aero.Context) error { // nick := ctx.Get("nick") // viewUser, err := arn.GetUserByNick(nick) @@ -27,6 +27,6 @@ package profile // posts = posts[:postLimit] // } -// return ctx.HTML(components.LatestPosts(arn.ToPostables(posts), viewUser, utils.GetUser(ctx), ctx.URI())) +// return ctx.HTML(components.LatestPosts(arn.ToPostables(posts), viewUser, utils.GetUser(ctx), ctx.Path())) // } diff --git a/pages/profile/profile.go b/pages/profile/profile.go index e4843966..2b931160 100644 --- a/pages/profile/profile.go +++ b/pages/profile/profile.go @@ -6,7 +6,9 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) @@ -17,7 +19,7 @@ const ( ) // Get user profile page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { nick := ctx.Get("nick") viewUser, err := arn.GetUserByNick(nick) @@ -29,7 +31,7 @@ func Get(ctx *aero.Context) string { } // Profile renders the user profile page of the given viewUser. -func Profile(ctx *aero.Context, viewUser *arn.User) string { +func Profile(ctx aero.Context, viewUser *arn.User) error { user := utils.GetUser(ctx) // Anime list @@ -99,7 +101,7 @@ func Profile(ctx *aero.Context, viewUser *arn.User) string { Tags: map[string]string{ "og:title": viewUser.Nick, "og:image": viewUser.AvatarLink("large"), - "og:url": "https://" + ctx.App.Config.Domain + viewUser.Link(), + "og:url": "https://" + assets.Domain + viewUser.Link(), "og:site_name": "notify.moe", "og:description": utils.CutLongDescription(viewUser.Introduction), "og:type": "profile", @@ -177,7 +179,8 @@ func Profile(ctx *aero.Context, viewUser *arn.User) string { characters = characters[:maxCharacters] } - ctx.Data = openGraph + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = openGraph return ctx.HTML(components.Profile( viewUser, @@ -190,6 +193,6 @@ func Profile(ctx *aero.Context, viewUser *arn.User) string { topStudios, animeWatchingTime, dayToActivityCount, - ctx.URI(), + ctx.Path(), )) } diff --git a/pages/profile/profilecharacters/liked.go b/pages/profile/profilecharacters/liked.go index e99bb11b..c9d8a4c6 100644 --- a/pages/profile/profilecharacters/liked.go +++ b/pages/profile/profilecharacters/liked.go @@ -11,7 +11,7 @@ import ( ) // Liked shows all liked characters of a particular user. -func Liked(ctx *aero.Context) string { +func Liked(ctx aero.Context) error { nick := ctx.Get("nick") viewUser, err := arn.GetUserByNick(nick) @@ -40,5 +40,5 @@ func Liked(ctx *aero.Context) string { // return aLikes > bLikes }) - return ctx.HTML(components.ProfileCharacters(characters, viewUser, utils.GetUser(ctx), ctx.URI())) + return ctx.HTML(components.ProfileCharacters(characters, viewUser, utils.GetUser(ctx), ctx.Path())) } diff --git a/pages/profile/profilequotes/added.go b/pages/profile/profilequotes/added.go index f475ccf2..2cc13f97 100644 --- a/pages/profile/profilequotes/added.go +++ b/pages/profile/profilequotes/added.go @@ -6,7 +6,7 @@ package profilequotes // ) // // Added shows all quotes added by a particular user. -// func Added(ctx *aero.Context) string { +// func Added(ctx aero.Context) error { // return render(ctx, addedQuotes) // } diff --git a/pages/profile/profilequotes/liked.go b/pages/profile/profilequotes/liked.go index 6be9196f..8a94159d 100644 --- a/pages/profile/profilequotes/liked.go +++ b/pages/profile/profilequotes/liked.go @@ -6,7 +6,7 @@ package profilequotes // ) // // Liked shows all quotes liked by a particular user. -// func Liked(ctx *aero.Context) string { +// func Liked(ctx aero.Context) error { // return render(ctx, likedQuotes) // } diff --git a/pages/profile/profilequotes/render.go b/pages/profile/profilequotes/render.go index 033a4d04..ee39c0ab 100644 --- a/pages/profile/profilequotes/render.go +++ b/pages/profile/profilequotes/render.go @@ -16,7 +16,7 @@ package profilequotes // ) // // render renders the quotes on user profiles. -// func render(ctx *aero.Context, fetch func(userID string) []*arn.Quote) string { +// func render(ctx aero.Context, fetch func(userID string) []*arn.Quote) string { // nick := ctx.Get("nick") // index, _ := ctx.GetInt("index") // user := utils.GetUser(ctx) @@ -53,5 +53,5 @@ package profilequotes // } // // Otherwise, send the full page -// return ctx.HTML(components.ProfileQuotes(quotes, viewUser, nextIndex, user, ctx.URI())) +// return ctx.HTML(components.ProfileQuotes(quotes, viewUser, nextIndex, user, ctx.Path())) // } diff --git a/pages/profile/profiletracks/added.go b/pages/profile/profiletracks/added.go index e70af786..8cb941a1 100644 --- a/pages/profile/profiletracks/added.go +++ b/pages/profile/profiletracks/added.go @@ -6,7 +6,7 @@ package profiletracks // ) // // Added shows all soundtracks added by a particular user. -// func Added(ctx *aero.Context) string { +// func Added(ctx aero.Context) error { // return render(ctx, addedTracks) // } diff --git a/pages/profile/profiletracks/liked.go b/pages/profile/profiletracks/liked.go index f75293d4..c6dc9121 100644 --- a/pages/profile/profiletracks/liked.go +++ b/pages/profile/profiletracks/liked.go @@ -6,7 +6,7 @@ package profiletracks // ) // // Liked shows all soundtracks liked by a particular user. -// func Liked(ctx *aero.Context) string { +// func Liked(ctx aero.Context) error { // return render(ctx, likedTracks) // } diff --git a/pages/profile/profiletracks/render.go b/pages/profile/profiletracks/render.go index ed6a300f..e016fbc8 100644 --- a/pages/profile/profiletracks/render.go +++ b/pages/profile/profiletracks/render.go @@ -16,7 +16,7 @@ package profiletracks // ) // // render renders the soundtracks on user profiles. -// func render(ctx *aero.Context, fetch func(userID string) []*arn.SoundTrack) string { +// func render(ctx aero.Context, fetch func(userID string) []*arn.SoundTrack) string { // nick := ctx.Get("nick") // index, _ := ctx.GetInt("index") // user := utils.GetUser(ctx) @@ -53,5 +53,5 @@ package profiletracks // } // // Otherwise, send the full page -// return ctx.HTML(components.ProfileSoundTracks(tracks, viewUser, nextIndex, user, ctx.URI())) +// return ctx.HTML(components.ProfileSoundTracks(tracks, viewUser, nextIndex, user, ctx.Path())) // } diff --git a/pages/profile/stats.go b/pages/profile/stats.go index b9ef65b7..fe2d0f49 100644 --- a/pages/profile/stats.go +++ b/pages/profile/stats.go @@ -15,7 +15,7 @@ package profile // type stats map[string]float64 // // GetStatsByUser shows statistics for a given user. -// func GetStatsByUser(ctx *aero.Context) string { +// func GetStatsByUser(ctx aero.Context) error { // nick := ctx.Get("nick") // viewUser, err := arn.GetUserByNick(nick) // userStats := utils.UserStats{} @@ -98,5 +98,5 @@ package profile // arn.NewPieChart("Soundtracks", trackTags), // } -// return ctx.HTML(components.ProfileStats(&userStats, viewUser, utils.GetUser(ctx), ctx.URI())) +// return ctx.HTML(components.ProfileStats(&userStats, viewUser, utils.GetUser(ctx), ctx.Path())) // } diff --git a/pages/profile/threads.go b/pages/profile/threads.go index fb0f6863..d4d1fcbb 100644 --- a/pages/profile/threads.go +++ b/pages/profile/threads.go @@ -12,7 +12,7 @@ package profile // const maxThreads = 20 // // GetThreadsByUser shows all forum threads of a particular user. -// func GetThreadsByUser(ctx *aero.Context) string { +// func GetThreadsByUser(ctx aero.Context) error { // nick := ctx.Get("nick") // viewUser, err := arn.GetUserByNick(nick) @@ -27,5 +27,5 @@ package profile // threads = threads[:maxThreads] // } -// return ctx.HTML(components.ProfileThreads(threads, viewUser, utils.GetUser(ctx), ctx.URI())) +// return ctx.HTML(components.ProfileThreads(threads, viewUser, utils.GetUser(ctx), ctx.Path())) // } diff --git a/pages/quote/edit.go b/pages/quote/edit.go index 515bc3a3..2f8ee9b4 100644 --- a/pages/quote/edit.go +++ b/pages/quote/edit.go @@ -3,15 +3,18 @@ package quote import ( "net/http" + "github.com/animenotifier/notify.moe/middleware" + "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" "github.com/animenotifier/notify.moe/utils" "github.com/animenotifier/notify.moe/utils/editform" ) // Edit quote. -func Edit(ctx *aero.Context) string { +func Edit(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") quote, err := arn.GetQuote(id) @@ -20,16 +23,17 @@ func Edit(ctx *aero.Context) string { return ctx.Error(http.StatusNotFound, "Quote not found", err) } - ctx.Data = &arn.OpenGraph{ + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = &arn.OpenGraph{ Tags: map[string]string{ "og:title": quote.Text.English, - "og:url": "https://" + ctx.App.Config.Domain + quote.Link(), + "og:url": "https://" + assets.Domain + quote.Link(), "og:site_name": "notify.moe", }, } if quote.Character() != nil { - ctx.Data.(*arn.OpenGraph).Tags["og:image"] = quote.Character().ImageLink("large") + customCtx.OpenGraph.Tags["og:image"] = quote.Character().ImageLink("large") } return ctx.HTML(components.QuoteTabs(quote, user) + editform.Render(quote, "Edit quote", user)) diff --git a/pages/quote/quote.go b/pages/quote/quote.go index e4b4ec07..6c49fa23 100644 --- a/pages/quote/quote.go +++ b/pages/quote/quote.go @@ -5,12 +5,14 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Get quote. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) id := ctx.Get("id") quote, err := arn.GetQuote(id) @@ -23,7 +25,7 @@ func Get(ctx *aero.Context) string { Tags: map[string]string{ "og:title": "Quote", "og:description": quote.Text.English, - "og:url": "https://" + ctx.App.Config.Domain + quote.Link(), + "og:url": "https://" + assets.Domain + quote.Link(), "og:site_name": "notify.moe", "og:type": "article", }, @@ -36,6 +38,7 @@ func Get(ctx *aero.Context) string { openGraph.Tags["og:image"] = "https:" + character.ImageLink("large") } - ctx.Data = openGraph + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = openGraph return ctx.HTML(components.QuotePage(quote, character, user)) } diff --git a/pages/quotes/best.go b/pages/quotes/best.go index 3ac8d453..4fbc960f 100644 --- a/pages/quotes/best.go +++ b/pages/quotes/best.go @@ -9,7 +9,7 @@ import ( ) // Best renders the best quotes. -func Best(ctx *aero.Context) string { +func Best(ctx aero.Context) error { user := utils.GetUser(ctx) index, _ := ctx.GetInt("index") diff --git a/pages/quotes/quotes.go b/pages/quotes/quotes.go index 84002c5c..80233b76 100644 --- a/pages/quotes/quotes.go +++ b/pages/quotes/quotes.go @@ -11,7 +11,7 @@ import ( const maxQuotes = 12 // Latest renders the latest quotes. -func Latest(ctx *aero.Context) string { +func Latest(ctx aero.Context) error { user := utils.GetUser(ctx) index, _ := ctx.GetInt("index") diff --git a/pages/recommended/anime.go b/pages/recommended/anime.go index b8785fb3..4f9551d6 100644 --- a/pages/recommended/anime.go +++ b/pages/recommended/anime.go @@ -17,7 +17,7 @@ const ( ) // Anime shows a list of recommended anime. -func Anime(ctx *aero.Context) string { +func Anime(ctx aero.Context) error { user := utils.GetUser(ctx) nick := ctx.Get("nick") viewUser, err := arn.GetUserByNick(nick) diff --git a/pages/search/multisearch/multisearch.go b/pages/search/multisearch/multisearch.go index 01adee1f..df959ffb 100644 --- a/pages/search/multisearch/multisearch.go +++ b/pages/search/multisearch/multisearch.go @@ -6,6 +6,6 @@ import ( ) // Anime search page. -func Anime(ctx *aero.Context) string { +func Anime(ctx aero.Context) error { return ctx.HTML(components.MultiSearch()) } diff --git a/pages/search/search.go b/pages/search/search.go index a988d206..aec49a1d 100644 --- a/pages/search/search.go +++ b/pages/search/search.go @@ -22,7 +22,7 @@ const ( ) // Get search page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { term := ctx.Get("term") term = strings.TrimPrefix(term, "/") user := utils.GetUser(ctx) @@ -43,12 +43,12 @@ func Get(ctx *aero.Context) string { } // GetEmptySearch renders the search page with no contents. -func GetEmptySearch(ctx *aero.Context) string { +func GetEmptySearch(ctx aero.Context) error { return ctx.HTML(components.SearchResults("", nil, nil, nil, nil, nil, nil, nil, nil, nil, utils.GetUser(ctx))) } // Anime search. -func Anime(ctx *aero.Context) string { +func Anime(ctx aero.Context) error { term := ctx.Get("term") term = strings.TrimPrefix(term, "/") user := utils.GetUser(ctx) @@ -58,7 +58,7 @@ func Anime(ctx *aero.Context) string { } // Characters search. -func Characters(ctx *aero.Context) string { +func Characters(ctx aero.Context) error { term := ctx.Get("term") term = strings.TrimPrefix(term, "/") user := utils.GetUser(ctx) @@ -68,7 +68,7 @@ func Characters(ctx *aero.Context) string { } // Posts search. -func Posts(ctx *aero.Context) string { +func Posts(ctx aero.Context) error { term := ctx.Get("term") term = strings.TrimPrefix(term, "/") user := utils.GetUser(ctx) @@ -78,7 +78,7 @@ func Posts(ctx *aero.Context) string { } // Threads search. -func Threads(ctx *aero.Context) string { +func Threads(ctx aero.Context) error { term := ctx.Get("term") term = strings.TrimPrefix(term, "/") user := utils.GetUser(ctx) @@ -88,7 +88,7 @@ func Threads(ctx *aero.Context) string { } // SoundTracks search. -func SoundTracks(ctx *aero.Context) string { +func SoundTracks(ctx aero.Context) error { term := ctx.Get("term") term = strings.TrimPrefix(term, "/") user := utils.GetUser(ctx) @@ -98,7 +98,7 @@ func SoundTracks(ctx *aero.Context) string { } // AMVs search. -func AMVs(ctx *aero.Context) string { +func AMVs(ctx aero.Context) error { term := ctx.Get("term") term = strings.TrimPrefix(term, "/") user := utils.GetUser(ctx) @@ -108,7 +108,7 @@ func AMVs(ctx *aero.Context) string { } // Users search. -func Users(ctx *aero.Context) string { +func Users(ctx aero.Context) error { term := ctx.Get("term") term = strings.TrimPrefix(term, "/") @@ -117,7 +117,7 @@ func Users(ctx *aero.Context) string { } // Companies search. -func Companies(ctx *aero.Context) string { +func Companies(ctx aero.Context) error { term := ctx.Get("term") term = strings.TrimPrefix(term, "/") diff --git a/pages/settings/settings.go b/pages/settings/settings.go index f4a4b31a..bc7f0910 100644 --- a/pages/settings/settings.go +++ b/pages/settings/settings.go @@ -9,8 +9,8 @@ import ( ) // Get settings. -func Get(component func(*arn.User) string) func(*aero.Context) string { - return func(ctx *aero.Context) string { +func Get(component func(*arn.User) string) func(aero.Context) error { + return func(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/shop/buyitem.go b/pages/shop/buyitem.go index f9296952..7bc7b04c 100644 --- a/pages/shop/buyitem.go +++ b/pages/shop/buyitem.go @@ -12,7 +12,7 @@ import ( var itemBuyMutex sync.Mutex // BuyItem ... -func BuyItem(ctx *aero.Context) string { +func BuyItem(ctx aero.Context) error { // Lock via mutex to prevent race conditions itemBuyMutex.Lock() defer itemBuyMutex.Unlock() @@ -57,5 +57,5 @@ func BuyItem(ctx *aero.Context) string { purchase := arn.NewPurchase(user.ID, itemID, quantity, int(item.Price), "gem") purchase.Save() - return "ok" + return nil } diff --git a/pages/shop/history.go b/pages/shop/history.go index 9960b8f0..3751ac50 100644 --- a/pages/shop/history.go +++ b/pages/shop/history.go @@ -11,7 +11,7 @@ import ( ) // PurchaseHistory ... -func PurchaseHistory(ctx *aero.Context) string { +func PurchaseHistory(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/shop/shop.go b/pages/shop/shop.go index d2f3495b..b86a3ee1 100644 --- a/pages/shop/shop.go +++ b/pages/shop/shop.go @@ -12,7 +12,7 @@ import ( ) // Get shop page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/soundtrack/download.go b/pages/soundtrack/download.go index 9e82fbc8..8a7bccbe 100644 --- a/pages/soundtrack/download.go +++ b/pages/soundtrack/download.go @@ -9,7 +9,7 @@ import ( ) // Download tries to refresh the soundtrack file. -func Download(ctx *aero.Context) string { +func Download(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) @@ -24,6 +24,5 @@ func Download(ctx *aero.Context) string { } track.Download() - - return "" + return nil } diff --git a/pages/soundtrack/edit.go b/pages/soundtrack/edit.go index 475f21a6..94cb12a5 100644 --- a/pages/soundtrack/edit.go +++ b/pages/soundtrack/edit.go @@ -3,7 +3,9 @@ package soundtrack import ( "net/http" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" "github.com/animenotifier/notify.moe/utils/editform" @@ -12,7 +14,7 @@ import ( ) // Edit track. -func Edit(ctx *aero.Context) string { +func Edit(ctx aero.Context) error { id := ctx.Get("id") track, err := arn.GetSoundTrack(id) user := utils.GetUser(ctx) @@ -21,17 +23,18 @@ func Edit(ctx *aero.Context) string { return ctx.Error(http.StatusNotFound, "Track not found", err) } - ctx.Data = &arn.OpenGraph{ + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = &arn.OpenGraph{ Tags: map[string]string{ "og:title": track.Title.ByUser(user), - "og:url": "https://" + ctx.App.Config.Domain + track.Link(), + "og:url": "https://" + assets.Domain + track.Link(), "og:site_name": "notify.moe", "og:type": "music.song", }, } if track.MainAnime() != nil { - ctx.Data.(*arn.OpenGraph).Tags["og:image"] = track.MainAnime().ImageLink("large") + customCtx.OpenGraph.Tags["og:image"] = track.MainAnime().ImageLink("large") } return ctx.HTML(components.SoundTrackTabs(track, user) + editform.Render(track, "Edit soundtrack", user)) diff --git a/pages/soundtrack/lyrics.go b/pages/soundtrack/lyrics.go index 24aae57a..bf173503 100644 --- a/pages/soundtrack/lyrics.go +++ b/pages/soundtrack/lyrics.go @@ -6,11 +6,12 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Lyrics of a soundtrack. -func Lyrics(ctx *aero.Context) string { +func Lyrics(ctx aero.Context) error { id := ctx.Get("id") track, err := arn.GetSoundTrack(id) user := utils.GetUser(ctx) @@ -29,6 +30,7 @@ func Lyrics(ctx *aero.Context) string { openGraph.Tags["og:description"] = utils.CutLongDescription(track.Lyrics.Romaji) } - ctx.Data = openGraph + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = openGraph return ctx.HTML(components.SoundTrackLyricsPage(track, user)) } diff --git a/pages/soundtrack/opengraph.go b/pages/soundtrack/opengraph.go index 7295468a..65f11acb 100644 --- a/pages/soundtrack/opengraph.go +++ b/pages/soundtrack/opengraph.go @@ -5,14 +5,15 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" ) -func getOpenGraph(ctx *aero.Context, track *arn.SoundTrack) *arn.OpenGraph { +func getOpenGraph(ctx aero.Context, track *arn.SoundTrack) *arn.OpenGraph { openGraph := &arn.OpenGraph{ Tags: map[string]string{ "og:title": track.Title.ByUser(nil), - "og:url": "https://" + ctx.App.Config.Domain + track.Link(), - "og:site_name": ctx.App.Config.Domain, + "og:url": "https://" + assets.Domain + track.Link(), + "og:site_name": assets.Domain, "og:type": "music.song", }, } @@ -33,7 +34,7 @@ func getOpenGraph(ctx *aero.Context, track *arn.SoundTrack) *arn.OpenGraph { } if track.File != "" { - openGraph.Tags["og:audio"] = "https://" + ctx.App.Config.Domain + "/audio/" + track.File + openGraph.Tags["og:audio"] = "https://" + assets.Domain + "/audio/" + track.File openGraph.Tags["og:audio:type"] = "audio/vnd.facebook.bridge" } diff --git a/pages/soundtrack/random.go b/pages/soundtrack/random.go index 2578da76..d1583000 100644 --- a/pages/soundtrack/random.go +++ b/pages/soundtrack/random.go @@ -8,7 +8,7 @@ import ( ) // Random returns a random soundtrack. -func Random(ctx *aero.Context) string { +func Random(ctx aero.Context) error { tracks := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool { return !track.IsDraft }) @@ -20,7 +20,7 @@ func Random(ctx *aero.Context) string { } // Next returns the next soundtrack for the audio player. -func Next(ctx *aero.Context) string { +func Next(ctx aero.Context) error { tracks := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool { return !track.IsDraft && track.File != "" }) diff --git a/pages/soundtrack/soundtrack.go b/pages/soundtrack/soundtrack.go index de1cdc80..4c09fa00 100644 --- a/pages/soundtrack/soundtrack.go +++ b/pages/soundtrack/soundtrack.go @@ -6,11 +6,12 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Get track. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { id := ctx.Get("id") track, err := arn.GetSoundTrack(id) user := utils.GetUser(ctx) @@ -19,6 +20,7 @@ func Get(ctx *aero.Context) string { return ctx.Error(http.StatusNotFound, "Track not found", err) } - ctx.Data = getOpenGraph(ctx, track) + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = getOpenGraph(ctx, track) return ctx.HTML(components.SoundTrackPage(track, user)) } diff --git a/pages/soundtracks/best.go b/pages/soundtracks/best.go index 1abcca67..d96bb891 100644 --- a/pages/soundtracks/best.go +++ b/pages/soundtracks/best.go @@ -6,7 +6,7 @@ import ( ) // Best renders the best soundtracks. -func Best(ctx *aero.Context) string { +func Best(ctx aero.Context) error { // Fetch all eligible tracks tracks := fetchAll() diff --git a/pages/soundtracks/latest.go b/pages/soundtracks/latest.go index 2c7207b0..bbb4a39f 100644 --- a/pages/soundtracks/latest.go +++ b/pages/soundtracks/latest.go @@ -6,7 +6,7 @@ import ( ) // Latest renders the latest soundtracks. -func Latest(ctx *aero.Context) string { +func Latest(ctx aero.Context) error { // Fetch all eligible tracks tracks := fetchAll() diff --git a/pages/soundtracks/render.go b/pages/soundtracks/render.go index 5375b3f6..4db36a70 100644 --- a/pages/soundtracks/render.go +++ b/pages/soundtracks/render.go @@ -14,7 +14,7 @@ const ( ) // render renders the soundracks page with the given tracks. -func render(ctx *aero.Context, allTracks []*arn.SoundTrack) string { +func render(ctx aero.Context, allTracks []*arn.SoundTrack) error { user := utils.GetUser(ctx) index, _ := ctx.GetInt("index") tag := ctx.Get("tag") diff --git a/pages/soundtracks/tag.go b/pages/soundtracks/tag.go index 097110e4..e35cb971 100644 --- a/pages/soundtracks/tag.go +++ b/pages/soundtracks/tag.go @@ -6,7 +6,7 @@ import ( ) // FilterByTag renders the best soundtracks filtered by tag. -func FilterByTag(ctx *aero.Context) string { +func FilterByTag(ctx aero.Context) error { tag := ctx.Get("tag") // Fetch all eligible tracks diff --git a/pages/sse/sse.go b/pages/sse/sse.go index 3a03b534..9776ebae 100644 --- a/pages/sse/sse.go +++ b/pages/sse/sse.go @@ -16,7 +16,7 @@ var ( ) // Events streams server events to the client. -func Events(ctx *aero.Context) string { +func Events(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/statistics/anime.go b/pages/statistics/anime.go index 1a1d3457..e402df9b 100644 --- a/pages/statistics/anime.go +++ b/pages/statistics/anime.go @@ -9,7 +9,7 @@ import ( ) // Anime ... -func Anime(ctx *aero.Context) string { +func Anime(ctx aero.Context) error { pieCharts := getAnimeStats() return ctx.HTML(components.Statistics(pieCharts)) } diff --git a/pages/statistics/statistics.go b/pages/statistics/statistics.go index 80141caf..762496ac 100644 --- a/pages/statistics/statistics.go +++ b/pages/statistics/statistics.go @@ -12,7 +12,7 @@ import ( type stats map[string]float64 // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { pieCharts := getUserStats() return ctx.HTML(components.Statistics(pieCharts)) } diff --git a/pages/support/support.go b/pages/support/support.go index ffc14835..ec822887 100644 --- a/pages/support/support.go +++ b/pages/support/support.go @@ -7,7 +7,7 @@ import ( ) // Get support page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) profileLink := "/" diff --git a/pages/terms/terms.go b/pages/terms/terms.go index dfd0465b..99f668f4 100644 --- a/pages/terms/terms.go +++ b/pages/terms/terms.go @@ -6,6 +6,6 @@ import ( ) // Get ... -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { return ctx.HTML(components.TermsOfService()) } diff --git a/pages/thread/editthread/editthread.go b/pages/thread/editthread/editthread.go index 2ce92604..f804533b 100644 --- a/pages/thread/editthread/editthread.go +++ b/pages/thread/editthread/editthread.go @@ -11,7 +11,7 @@ import ( ) // Get thread edit page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) diff --git a/pages/thread/opengraph.go b/pages/thread/opengraph.go index dffad9e0..6a61237a 100644 --- a/pages/thread/opengraph.go +++ b/pages/thread/opengraph.go @@ -3,16 +3,17 @@ package thread import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/assets" "github.com/animenotifier/notify.moe/utils" ) -func getOpenGraph(ctx *aero.Context, thread *arn.Thread) *arn.OpenGraph { +func getOpenGraph(ctx aero.Context, thread *arn.Thread) *arn.OpenGraph { openGraph := &arn.OpenGraph{ Tags: map[string]string{ "og:title": thread.Title, "og:description": utils.CutLongDescription(thread.Text), - "og:url": "https://" + ctx.App.Config.Domain + thread.Link(), - "og:site_name": ctx.App.Config.Domain, + "og:url": "https://" + assets.Domain + thread.Link(), + "og:site_name": assets.Domain, "og:type": "article", }, } diff --git a/pages/thread/reply-ui.go b/pages/thread/reply-ui.go index 986b82a3..d9d18bee 100644 --- a/pages/thread/reply-ui.go +++ b/pages/thread/reply-ui.go @@ -10,7 +10,7 @@ import ( ) // ReplyUI renders a new post area. -func ReplyUI(ctx *aero.Context) string { +func ReplyUI(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) thread, err := arn.GetThread(id) diff --git a/pages/thread/thread.go b/pages/thread/thread.go index c4e1aa03..5fca99af 100644 --- a/pages/thread/thread.go +++ b/pages/thread/thread.go @@ -6,11 +6,12 @@ import ( "github.com/aerogo/aero" "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/utils" ) // Get thread. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) @@ -21,6 +22,7 @@ func Get(ctx *aero.Context) string { return ctx.Error(http.StatusNotFound, "Thread not found", err) } - ctx.Data = getOpenGraph(ctx, thread) + customCtx := ctx.(*middleware.OpenGraphContext) + customCtx.OpenGraph = getOpenGraph(ctx, thread) return ctx.HTML(components.Thread(thread, user)) } diff --git a/pages/upload/amv.go b/pages/upload/amv.go index 716f8de8..ca119aff 100644 --- a/pages/upload/amv.go +++ b/pages/upload/amv.go @@ -10,7 +10,7 @@ import ( ) // AMVFile handles the video upload for AMV files. -func AMVFile(ctx *aero.Context) string { +func AMVFile(ctx aero.Context) error { user := utils.GetUser(ctx) amvID := ctx.Get("id") @@ -45,5 +45,5 @@ func AMVFile(ctx *aero.Context) string { logEntry := arn.NewEditLogEntry(user.ID, "edit", "AMV", amv.ID, "File", "", "") logEntry.Save() - return "ok" + return nil } diff --git a/pages/upload/anime-image.go b/pages/upload/anime-image.go index 28d17644..802503b0 100644 --- a/pages/upload/anime-image.go +++ b/pages/upload/anime-image.go @@ -10,7 +10,7 @@ import ( ) // AnimeImage handles the anime image upload. -func AnimeImage(ctx *aero.Context) string { +func AnimeImage(ctx aero.Context) error { user := utils.GetUser(ctx) animeID := ctx.Get("id") @@ -45,5 +45,5 @@ func AnimeImage(ctx *aero.Context) string { logEntry := arn.NewEditLogEntry(user.ID, "edit", "Anime", anime.ID, "Image", "", "") logEntry.Save() - return "ok" + return nil } diff --git a/pages/upload/avatar.go b/pages/upload/avatar.go index 53be2869..6a03abbe 100644 --- a/pages/upload/avatar.go +++ b/pages/upload/avatar.go @@ -8,7 +8,7 @@ import ( ) // Avatar handles the avatar upload. -func Avatar(ctx *aero.Context) string { +func Avatar(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { @@ -32,5 +32,5 @@ func Avatar(ctx *aero.Context) string { // Save avatar information user.Save() - return user.AvatarLink("small") + return ctx.Text(user.AvatarLink("small")) } diff --git a/pages/upload/character.go b/pages/upload/character.go index 76297e1d..c27ebaf7 100644 --- a/pages/upload/character.go +++ b/pages/upload/character.go @@ -10,7 +10,7 @@ import ( ) // CharacterImage handles the character image upload. -func CharacterImage(ctx *aero.Context) string { +func CharacterImage(ctx aero.Context) error { user := utils.GetUser(ctx) characterID := ctx.Get("id") @@ -45,5 +45,5 @@ func CharacterImage(ctx *aero.Context) string { logEntry := arn.NewEditLogEntry(user.ID, "edit", "Character", character.ID, "Image", "", "") logEntry.Save() - return "ok" + return nil } diff --git a/pages/upload/cover.go b/pages/upload/cover.go index ea895440..c305c954 100644 --- a/pages/upload/cover.go +++ b/pages/upload/cover.go @@ -8,7 +8,7 @@ import ( ) // Cover handles the cover image upload. -func Cover(ctx *aero.Context) string { +func Cover(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { @@ -36,5 +36,5 @@ func Cover(ctx *aero.Context) string { // Save cover image information user.Save() - return "ok" + return nil } diff --git a/pages/upload/group.go b/pages/upload/group.go index 924f7773..5347f4c2 100644 --- a/pages/upload/group.go +++ b/pages/upload/group.go @@ -9,7 +9,7 @@ import ( ) // GroupImage handles the group image upload. -func GroupImage(ctx *aero.Context) string { +func GroupImage(ctx aero.Context) error { user := utils.GetUser(ctx) groupID := ctx.Get("id") @@ -44,5 +44,5 @@ func GroupImage(ctx *aero.Context) string { logEntry := arn.NewEditLogEntry(user.ID, "edit", "Group", group.ID, "Image", "", "") logEntry.Save() - return "ok" + return nil } diff --git a/pages/user/edit.go b/pages/user/edit.go index b07355d7..a1fc24a3 100644 --- a/pages/user/edit.go +++ b/pages/user/edit.go @@ -10,7 +10,7 @@ import ( ) // Edit user. -func Edit(ctx *aero.Context) string { +func Edit(ctx aero.Context) error { nick := ctx.Get("nick") user := utils.GetUser(ctx) diff --git a/pages/user/user.go b/pages/user/user.go index 916609db..bcec6c6d 100644 --- a/pages/user/user.go +++ b/pages/user/user.go @@ -9,7 +9,7 @@ import ( ) // Get redirects /+ to /+UserName -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/pages/users/map.go b/pages/users/map.go index f660db8e..6ab8a3fb 100644 --- a/pages/users/map.go +++ b/pages/users/map.go @@ -6,6 +6,6 @@ import ( ) // Map shows a map of all users. -func Map(ctx *aero.Context) string { - return ctx.HTML(components.UserMap(ctx.URI())) +func Map(ctx aero.Context) error { + return ctx.HTML(components.UserMap(ctx.Path())) } diff --git a/pages/users/users.go b/pages/users/users.go index de4385e1..b461e0bf 100644 --- a/pages/users/users.go +++ b/pages/users/users.go @@ -11,17 +11,17 @@ import ( ) // Active ... -func Active(ctx *aero.Context) string { +func Active(ctx aero.Context) error { users := arn.FilterUsers(func(user *arn.User) bool { return user.HasAvatar() && user.HasNick() && user.IsActive() }) arn.SortUsersFollowers(users) - return ctx.HTML(components.Users(users, ctx.URI())) + return ctx.HTML(components.Users(users, ctx.Path())) } // Pro ... -func Pro(ctx *aero.Context) string { +func Pro(ctx aero.Context) error { users := arn.FilterUsers(func(user *arn.User) bool { return user.IsPro() }) @@ -30,11 +30,11 @@ func Pro(ctx *aero.Context) string { return users[i].Registered > users[j].Registered }) - return ctx.HTML(components.ProUsers(users, ctx.URI())) + return ctx.HTML(components.ProUsers(users, ctx.Path())) } // Editors ... -func Editors(ctx *aero.Context) string { +func Editors(ctx aero.Context) error { score := map[string]int{} users := []*arn.User{} @@ -73,11 +73,11 @@ func Editors(ctx *aero.Context) string { users = users[:10] } - return ctx.HTML(components.EditorRankingList(users, score, ctx.URI())) + return ctx.HTML(components.EditorRankingList(users, score, ctx.Path())) } // ActiveNoAvatar ... -func ActiveNoAvatar(ctx *aero.Context) string { +func ActiveNoAvatar(ctx aero.Context) error { users := arn.FilterUsers(func(user *arn.User) bool { return user.IsActive() && !user.HasAvatar() }) @@ -99,11 +99,11 @@ func ActiveNoAvatar(ctx *aero.Context) string { return followersA > followersB }) - return ctx.HTML(components.Users(users, ctx.URI())) + return ctx.HTML(components.Users(users, ctx.Path())) } // Osu ... -func Osu(ctx *aero.Context) string { +func Osu(ctx aero.Context) error { users := arn.FilterUsers(func(user *arn.User) bool { return user.HasAvatar() && user.HasNick() && user.IsActive() && user.Accounts.Osu.PP > 0 }) @@ -117,11 +117,11 @@ func Osu(ctx *aero.Context) string { users = users[:10] } - return ctx.HTML(components.OsuRankingList(users, ctx.URI())) + return ctx.HTML(components.OsuRankingList(users, ctx.Path())) } // Overwatch ... -func Overwatch(ctx *aero.Context) string { +func Overwatch(ctx aero.Context) error { users := arn.FilterUsers(func(user *arn.User) bool { return user.HasAvatar() && user.HasNick() && user.IsActive() && user.Accounts.Overwatch.SkillRating > 0 }) @@ -135,11 +135,11 @@ func Overwatch(ctx *aero.Context) string { users = users[:10] } - return ctx.HTML(components.OverwatchRankingList(users, ctx.URI())) + return ctx.HTML(components.OverwatchRankingList(users, ctx.Path())) } // FFXIV ... -func FFXIV(ctx *aero.Context) string { +func FFXIV(ctx aero.Context) error { users := arn.FilterUsers(func(user *arn.User) bool { return user.HasAvatar() && user.HasNick() && user.IsActive() && user.Accounts.FinalFantasyXIV.ItemLevel > 0 }) @@ -153,11 +153,11 @@ func FFXIV(ctx *aero.Context) string { users = users[:10] } - return ctx.HTML(components.FinalFantasyXIVRankingList(users, ctx.URI())) + return ctx.HTML(components.FinalFantasyXIVRankingList(users, ctx.Path())) } // ByCountry ... -func ByCountry(ctx *aero.Context) string { +func ByCountry(ctx aero.Context) error { countryName := ctx.Get("country") users := arn.FilterUsers(func(user *arn.User) bool { @@ -169,7 +169,7 @@ func ByCountry(ctx *aero.Context) string { } // Staff ... -func Staff(ctx *aero.Context) string { +func Staff(ctx aero.Context) error { users := arn.FilterUsers(func(user *arn.User) bool { return user.HasAvatar() && user.HasNick() && user.IsActive() && user.Role != "" }) @@ -226,5 +226,5 @@ func Staff(ctx *aero.Context) string { editors, } - return ctx.HTML(components.UserLists(userLists, ctx.URI()) + components.StaffRecruitment()) + return ctx.HTML(components.UserLists(userLists, ctx.Path()) + components.StaffRecruitment()) } diff --git a/pages/welcome/welcome.go b/pages/welcome/welcome.go index 6a1529c7..12fbeef9 100644 --- a/pages/welcome/welcome.go +++ b/pages/welcome/welcome.go @@ -9,7 +9,7 @@ import ( ) // Get returns the welcome page. -func Get(ctx *aero.Context) string { +func Get(ctx aero.Context) error { user := utils.GetUser(ctx) if user == nil { diff --git a/rewrite.go b/rewrite.go index 7c0b4e20..e5356bfb 100644 --- a/rewrite.go +++ b/rewrite.go @@ -7,27 +7,27 @@ import ( ) // rewrite will rewrite certain routes -func rewrite(ctx *aero.RewriteContext) { - requestURI := ctx.URI() +func rewrite(ctx aero.RewriteContext) { + requestURI := ctx.Path() // User profiles if strings.HasPrefix(requestURI, "/+") { newURI := "/user/" userName := requestURI[2:] - ctx.SetURI(newURI + userName) + ctx.SetPath(newURI + userName) return } if strings.HasPrefix(requestURI, "/_/+") { newURI := "/_/user/" userName := requestURI[4:] - ctx.SetURI(newURI + userName) + ctx.SetPath(newURI + userName) return } // Analytics if requestURI == "/dark-flame-master" { - ctx.SetURI("/api/new/analytics") + ctx.SetPath("/api/new/analytics") return } } diff --git a/scripts/Actions/Shop.ts b/scripts/Actions/Shop.ts index 26d5c47b..b4efe28e 100644 --- a/scripts/Actions/Shop.ts +++ b/scripts/Actions/Shop.ts @@ -74,7 +74,7 @@ export function buyItem(arn: AnimeNotifier, button: HTMLElement) { }) .then(response => response.text()) .then(body => { - if(body !== "ok") { + if(body !== "") { throw body } diff --git a/tools/tools.go b/tools/tools.go deleted file mode 100644 index 47558323..00000000 --- a/tools/tools.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build tools - -package tools - -import ( - _ "github.com/aerogo/pack" - _ "github.com/aerogo/run" -) diff --git a/utils/AllowEmbed.go b/utils/AllowEmbed.go deleted file mode 100644 index 0beac966..00000000 --- a/utils/AllowEmbed.go +++ /dev/null @@ -1,10 +0,0 @@ -package utils - -import "github.com/aerogo/aero" - -// AllowEmbed allows the page to be called by the browser extension. -func AllowEmbed(ctx *aero.Context, response string) string { - // This is a bit of a hack. - // ctx.SetResponseHeader("X-Frame-Options", "ALLOW-FROM chrome-extension://hjfcooigdelogjmniiahfiilcefdlpha/options.html") - return response -} diff --git a/utils/GetContainerClass.go b/utils/GetContainerClass.go index 33343873..316ba2b8 100644 --- a/utils/GetContainerClass.go +++ b/utils/GetContainerClass.go @@ -6,8 +6,8 @@ import ( // GetContainerClass returns the class for the "container" element. // In the browser extension it will get the "embedded" class. -func GetContainerClass(ctx *aero.Context) string { - if ctx.URI() == "/extension/embed" { +func GetContainerClass(ctx aero.Context) string { + if ctx.Path() == "/extension/embed" { return "embedded" } diff --git a/utils/GetUser.go b/utils/GetUser.go index 74d39297..2b628d39 100644 --- a/utils/GetUser.go +++ b/utils/GetUser.go @@ -6,7 +6,7 @@ import ( ) // GetUser returns the logged in user for the given context. -func GetUser(ctx *aero.Context) *arn.User { +func GetUser(ctx aero.Context) *arn.User { return arn.GetUserFromContext(ctx) } diff --git a/utils/SmartRedirect.go b/utils/SmartRedirect.go index ae5c5f0f..1afa5b94 100644 --- a/utils/SmartRedirect.go +++ b/utils/SmartRedirect.go @@ -1,19 +1,20 @@ package utils import ( + "net/http" "strings" "github.com/aerogo/aero" ) // SmartRedirect automatically adds the /_ prefix to the URI if required. -func SmartRedirect(ctx *aero.Context, uri string) string { +func SmartRedirect(ctx aero.Context, uri string) error { // Redirect prefix := "" - if strings.HasPrefix(ctx.URI(), "/_") { + if strings.HasPrefix(ctx.Path(), "/_") { prefix = "/_" } - return ctx.Redirect(prefix + uri) + return ctx.Redirect(http.StatusFound, prefix+uri) } diff --git a/utils/history/history.go b/utils/history/history.go index d74b32d5..9fd11c78 100644 --- a/utils/history/history.go +++ b/utils/history/history.go @@ -9,8 +9,8 @@ import ( ) // Handler returns a function that renders the history of any object. -func Handler(render func(interface{}, []*arn.EditLogEntry, *arn.User) string, typeNames ...string) func(ctx *aero.Context) string { - return func(ctx *aero.Context) string { +func Handler(render func(interface{}, []*arn.EditLogEntry, *arn.User) string, typeNames ...string) func(ctx aero.Context) error { + return func(ctx aero.Context) error { id := ctx.Get("id") user := utils.GetUser(ctx) obj, err := arn.DB.Get(typeNames[0], id) diff --git a/utils/infinitescroll/NextIndex.go b/utils/infinitescroll/NextIndex.go index de30ccaf..206a18ad 100644 --- a/utils/infinitescroll/NextIndex.go +++ b/utils/infinitescroll/NextIndex.go @@ -7,7 +7,7 @@ import ( ) // NextIndex calculates the next index and sends HTTP header -func NextIndex(ctx *aero.Context, allElementsLength int, elementsPerScroll int, index int) int { +func NextIndex(ctx aero.Context, allElementsLength int, elementsPerScroll int, index int) int { nextIndex := index + elementsPerScroll if nextIndex >= allElementsLength { @@ -15,7 +15,7 @@ func NextIndex(ctx *aero.Context, allElementsLength int, elementsPerScroll int, } // Send the index for the next request - ctx.Response().Header().Set("X-LoadMore-Index", strconv.Itoa(nextIndex)) + ctx.Response().SetHeader("X-LoadMore-Index", strconv.Itoa(nextIndex)) return nextIndex }