Upgraded to latest aero version
This commit is contained in:
parent
ae591e5e7e
commit
28db818c37
@ -19,6 +19,7 @@ var (
|
|||||||
CSS string
|
CSS string
|
||||||
ServiceWorker string
|
ServiceWorker string
|
||||||
Organization string
|
Organization string
|
||||||
|
Domain = "notify.moe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// load loads all the necessary assets into memory.
|
// load loads all the necessary assets into memory.
|
||||||
@ -57,55 +58,55 @@ func load() {
|
|||||||
CSS = css.Bundle()
|
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) {
|
func Configure(app *aero.Application) {
|
||||||
load()
|
load()
|
||||||
|
|
||||||
app.Get("/scripts", func(ctx *aero.Context) string {
|
app.Get("/scripts", func(ctx aero.Context) error {
|
||||||
return ctx.JavaScript(JS)
|
return ctx.JavaScript(JS)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Get("/styles", func(ctx *aero.Context) string {
|
app.Get("/styles", func(ctx aero.Context) error {
|
||||||
return ctx.CSS(CSS)
|
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)
|
return ctx.JavaScript(ServiceWorker)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Web manifest
|
// Web manifest
|
||||||
app.Get("/manifest.json", func(ctx *aero.Context) string {
|
app.Get("/manifest.json", func(ctx aero.Context) error {
|
||||||
return ctx.JSON(Manifest)
|
return ctx.JSON(Manifest)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Favicon
|
// Favicon
|
||||||
app.Get("/favicon.ico", func(ctx *aero.Context) string {
|
app.Get("/favicon.ico", func(ctx aero.Context) error {
|
||||||
ctx.Response().Header().Set("Access-Control-Allow-Origin", "*")
|
ctx.Response().SetHeader("Access-Control-Allow-Origin", "*")
|
||||||
return ctx.File("images/brand/64.png")
|
return ctx.File("images/brand/64.png")
|
||||||
})
|
})
|
||||||
|
|
||||||
// Images
|
// Images
|
||||||
app.Get("/images/*file", func(ctx *aero.Context) string {
|
app.Get("/images/*file", func(ctx aero.Context) error {
|
||||||
ctx.Response().Header().Set("Access-Control-Allow-Origin", "*")
|
ctx.Response().SetHeader("Access-Control-Allow-Origin", "*")
|
||||||
return ctx.File("images/" + ctx.Get("file"))
|
return ctx.File("images/" + ctx.Get("file"))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Videos
|
// Videos
|
||||||
app.Get("/videos/*file", func(ctx *aero.Context) string {
|
app.Get("/videos/*file", func(ctx aero.Context) error {
|
||||||
ctx.Response().Header().Set("Access-Control-Allow-Origin", "*")
|
ctx.Response().SetHeader("Access-Control-Allow-Origin", "*")
|
||||||
return ctx.File("videos/" + ctx.Get("file"))
|
return ctx.File("videos/" + ctx.Get("file"))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
app.Get("/audio/*file", func(ctx *aero.Context) string {
|
app.Get("/audio/*file", func(ctx aero.Context) error {
|
||||||
ctx.Response().Header().Set("Access-Control-Allow-Origin", "*")
|
ctx.Response().SetHeader("Access-Control-Allow-Origin", "*")
|
||||||
return ctx.File("audio/" + ctx.Get("file"))
|
return ctx.File("audio/" + ctx.Get("file"))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Anime sitemap
|
// 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()
|
sitemap := sitemap.New()
|
||||||
prefix := "https://" + app.Config.Domain
|
prefix := "https://" + Domain
|
||||||
|
|
||||||
for anime := range arn.StreamAnime() {
|
for anime := range arn.StreamAnime() {
|
||||||
sitemap.Add(prefix + anime.Link())
|
sitemap.Add(prefix + anime.Link())
|
||||||
@ -115,9 +116,9 @@ func Configure(app *aero.Application) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Character sitemap
|
// 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()
|
sitemap := sitemap.New()
|
||||||
prefix := "https://" + app.Config.Domain
|
prefix := "https://" + Domain
|
||||||
|
|
||||||
for character := range arn.StreamCharacters() {
|
for character := range arn.StreamCharacters() {
|
||||||
sitemap.Add(prefix + character.Link())
|
sitemap.Add(prefix + character.Link())
|
||||||
@ -127,9 +128,9 @@ func Configure(app *aero.Application) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// User sitemap
|
// 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()
|
sitemap := sitemap.New()
|
||||||
prefix := "https://" + app.Config.Domain
|
prefix := "https://" + Domain
|
||||||
|
|
||||||
for user := range arn.StreamUsers() {
|
for user := range arn.StreamUsers() {
|
||||||
if !user.HasNick() {
|
if !user.HasNick() {
|
||||||
@ -143,9 +144,9 @@ func Configure(app *aero.Application) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// SoundTrack sitemap
|
// 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()
|
sitemap := sitemap.New()
|
||||||
prefix := "https://" + app.Config.Domain
|
prefix := "https://" + Domain
|
||||||
|
|
||||||
for soundTrack := range arn.StreamSoundTracks() {
|
for soundTrack := range arn.StreamSoundTracks() {
|
||||||
sitemap.Add(prefix + soundTrack.Link())
|
sitemap.Add(prefix + soundTrack.Link())
|
||||||
@ -155,9 +156,9 @@ func Configure(app *aero.Application) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Thread sitemap
|
// 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()
|
sitemap := sitemap.New()
|
||||||
prefix := "https://" + app.Config.Domain
|
prefix := "https://" + Domain
|
||||||
|
|
||||||
for thread := range arn.StreamThreads() {
|
for thread := range arn.StreamThreads() {
|
||||||
sitemap.Add(prefix + thread.Link())
|
sitemap.Add(prefix + thread.Link())
|
||||||
@ -167,9 +168,9 @@ func Configure(app *aero.Application) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Post sitemap
|
// 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()
|
sitemap := sitemap.New()
|
||||||
prefix := "https://" + app.Config.Domain
|
prefix := "https://" + Domain
|
||||||
|
|
||||||
for post := range arn.StreamPosts() {
|
for post := range arn.StreamPosts() {
|
||||||
sitemap.Add(prefix + post.Link())
|
sitemap.Add(prefix + post.Link())
|
||||||
@ -179,7 +180,7 @@ func Configure(app *aero.Application) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// For benchmarks
|
// For benchmarks
|
||||||
app.Get("/hello", func(ctx *aero.Context) string {
|
app.Get("/hello", func(ctx aero.Context) error {
|
||||||
return ctx.Text("Hello World")
|
return ctx.Text("Hello World")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
)
|
)
|
||||||
@ -19,17 +21,17 @@ func Install(app *aero.Application) {
|
|||||||
InstallTwitterAuth(app)
|
InstallTwitterAuth(app)
|
||||||
|
|
||||||
// Logout
|
// Logout
|
||||||
app.Get("/logout", func(ctx *aero.Context) string {
|
app.Get("/logout", func(ctx aero.Context) error {
|
||||||
if ctx.HasSession() {
|
if ctx.HasSession() {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user != nil {
|
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")
|
ctx.Session().Delete("userId")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.Redirect("/")
|
return ctx.Redirect(http.StatusFound, "/")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
|
"github.com/animenotifier/notify.moe/assets"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
@ -33,7 +34,7 @@ func InstallFacebookAuth(app *aero.Application) {
|
|||||||
config := &oauth2.Config{
|
config := &oauth2.Config{
|
||||||
ClientID: arn.APIKeys.Facebook.ID,
|
ClientID: arn.APIKeys.Facebook.ID,
|
||||||
ClientSecret: arn.APIKeys.Facebook.Secret,
|
ClientSecret: arn.APIKeys.Facebook.Secret,
|
||||||
RedirectURL: "https://" + app.Config.Domain + "/auth/facebook/callback",
|
RedirectURL: "https://" + assets.Domain + "/auth/facebook/callback",
|
||||||
Scopes: []string{
|
Scopes: []string{
|
||||||
"public_profile",
|
"public_profile",
|
||||||
"email",
|
"email",
|
||||||
@ -44,10 +45,10 @@ func InstallFacebookAuth(app *aero.Application) {
|
|||||||
// When a user visits /auth/facebook, we ask OAuth2 config for a URL
|
// 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,
|
// 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.
|
// 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()
|
state := ctx.Session().ID()
|
||||||
url := config.AuthCodeURL(state)
|
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.
|
// 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.
|
// 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.
|
// 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.
|
// 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() {
|
if !ctx.HasSession() {
|
||||||
return ctx.Error(http.StatusUnauthorized, "Facebook login failed", errors.New("Session does not exist"))
|
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()
|
user.Save()
|
||||||
|
|
||||||
// Log
|
// 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
|
var getErr error
|
||||||
@ -119,7 +120,7 @@ func InstallFacebookAuth(app *aero.Application) {
|
|||||||
user, getErr = arn.GetUserByFacebookID(fbUser.ID)
|
user, getErr = arn.GetUserByFacebookID(fbUser.ID)
|
||||||
|
|
||||||
if getErr == nil && user != nil {
|
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
|
// Add FacebookToUser reference
|
||||||
user.ConnectFacebook(fbUser.ID)
|
user.ConnectFacebook(fbUser.ID)
|
||||||
@ -128,20 +129,20 @@ func InstallFacebookAuth(app *aero.Application) {
|
|||||||
user.Save()
|
user.Save()
|
||||||
|
|
||||||
session.Set("userId", user.ID)
|
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
|
// Try to find an existing user via the associated e-mail address
|
||||||
user, getErr = arn.GetUserByEmail(fbUser.Email)
|
user, getErr = arn.GetUserByEmail(fbUser.Email)
|
||||||
|
|
||||||
if getErr == nil && user != nil {
|
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.LastLogin = arn.DateTimeUTC()
|
||||||
user.Save()
|
user.Save()
|
||||||
|
|
||||||
session.Set("userId", user.ID)
|
session.Set("userId", user.ID)
|
||||||
return ctx.Redirect("/")
|
return ctx.Redirect(http.StatusFound, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register new user
|
// Register new user
|
||||||
@ -169,9 +170,9 @@ func InstallFacebookAuth(app *aero.Application) {
|
|||||||
session.Set("userId", user.ID)
|
session.Set("userId", user.ID)
|
||||||
|
|
||||||
// Log
|
// 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
|
// Redirect to starting page for new users
|
||||||
return ctx.Redirect(newUserStartRoute)
|
return ctx.Redirect(http.StatusFound, newUserStartRoute)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
|
"github.com/animenotifier/notify.moe/assets"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
@ -38,7 +39,7 @@ func InstallGoogleAuth(app *aero.Application) {
|
|||||||
config := &oauth2.Config{
|
config := &oauth2.Config{
|
||||||
ClientID: arn.APIKeys.Google.ID,
|
ClientID: arn.APIKeys.Google.ID,
|
||||||
ClientSecret: arn.APIKeys.Google.Secret,
|
ClientSecret: arn.APIKeys.Google.Secret,
|
||||||
RedirectURL: "https://" + app.Config.Domain + "/auth/google/callback",
|
RedirectURL: "https://" + assets.Domain + "/auth/google/callback",
|
||||||
Scopes: []string{
|
Scopes: []string{
|
||||||
"https://www.googleapis.com/auth/userinfo.email",
|
"https://www.googleapis.com/auth/userinfo.email",
|
||||||
"https://www.googleapis.com/auth/userinfo.profile",
|
"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
|
// 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,
|
// 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.
|
// 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()
|
state := ctx.Session().ID()
|
||||||
url := config.AuthCodeURL(state)
|
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.
|
// 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.
|
// 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.
|
// 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.
|
// 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() {
|
if !ctx.HasSession() {
|
||||||
return ctx.Error(http.StatusUnauthorized, "Google login failed", errors.New("Session does not exist"))
|
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()
|
user.Save()
|
||||||
|
|
||||||
// Log
|
// 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
|
var getErr error
|
||||||
@ -130,20 +131,20 @@ func InstallGoogleAuth(app *aero.Application) {
|
|||||||
user, getErr = arn.GetUserByGoogleID(googleUser.Sub)
|
user, getErr = arn.GetUserByGoogleID(googleUser.Sub)
|
||||||
|
|
||||||
if getErr == nil && user != nil {
|
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.LastLogin = arn.DateTimeUTC()
|
||||||
user.Save()
|
user.Save()
|
||||||
|
|
||||||
session.Set("userId", user.ID)
|
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
|
// Try to find an existing user via the associated e-mail address
|
||||||
user, getErr = arn.GetUserByEmail(googleUser.Email)
|
user, getErr = arn.GetUserByEmail(googleUser.Email)
|
||||||
|
|
||||||
if getErr == nil && user != nil {
|
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
|
// Add GoogleToUser reference
|
||||||
user.ConnectGoogle(googleUser.Sub)
|
user.ConnectGoogle(googleUser.Sub)
|
||||||
@ -152,7 +153,7 @@ func InstallGoogleAuth(app *aero.Application) {
|
|||||||
user.Save()
|
user.Save()
|
||||||
|
|
||||||
session.Set("userId", user.ID)
|
session.Set("userId", user.ID)
|
||||||
return ctx.Redirect("/")
|
return ctx.Redirect(http.StatusFound, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register new user
|
// Register new user
|
||||||
@ -180,9 +181,9 @@ func InstallGoogleAuth(app *aero.Application) {
|
|||||||
session.Set("userId", user.ID)
|
session.Set("userId", user.ID)
|
||||||
|
|
||||||
// Log
|
// 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
|
// Redirect to starting page for new users
|
||||||
return ctx.Redirect(newUserStartRoute)
|
return ctx.Redirect(http.StatusFound, newUserStartRoute)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
|
"github.com/animenotifier/notify.moe/assets"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
"github.com/gomodule/oauth1/oauth"
|
"github.com/gomodule/oauth1/oauth"
|
||||||
jsoniter "github.com/json-iterator/go"
|
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.
|
// a request token and give us a URL to redirect the user to.
|
||||||
// Once the user has approved the application on that page,
|
// Once the user has approved the application on that page,
|
||||||
// he'll be redirected back to our servers to the callback page.
|
// he'll be redirected back to our servers to the callback page.
|
||||||
app.Get("/auth/twitter", func(ctx *aero.Context) string {
|
app.Get("/auth/twitter", func(ctx aero.Context) error {
|
||||||
callback := "https://" + ctx.App.Config.Domain + "/auth/twitter/callback"
|
callback := "https://" + assets.Domain + "/auth/twitter/callback"
|
||||||
tempCred, err := config.RequestTemporaryCredentials(nil, callback, nil)
|
tempCred, err := config.RequestTemporaryCredentials(nil, callback, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -52,7 +53,7 @@ func InstallTwitterAuth(app *aero.Application) {
|
|||||||
|
|
||||||
ctx.Session().Set("tempCred", tempCred)
|
ctx.Session().Set("tempCred", tempCred)
|
||||||
url := config.AuthorizationURL(tempCred, nil)
|
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.
|
// 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.
|
// 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.
|
// 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.
|
// 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() {
|
if !ctx.HasSession() {
|
||||||
return ctx.Error(http.StatusUnauthorized, "Twitter login failed", errors.New("Session does not exist"))
|
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()
|
user.Save()
|
||||||
|
|
||||||
// Log
|
// 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
|
var getErr error
|
||||||
@ -132,20 +133,20 @@ func InstallTwitterAuth(app *aero.Application) {
|
|||||||
user, getErr = arn.GetUserByTwitterID(twUser.ID)
|
user, getErr = arn.GetUserByTwitterID(twUser.ID)
|
||||||
|
|
||||||
if getErr == nil && user != nil {
|
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.LastLogin = arn.DateTimeUTC()
|
||||||
user.Save()
|
user.Save()
|
||||||
|
|
||||||
session.Set("userId", user.ID)
|
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
|
// Try to find an existing user via the associated e-mail address
|
||||||
user, getErr = arn.GetUserByEmail(twUser.Email)
|
user, getErr = arn.GetUserByEmail(twUser.Email)
|
||||||
|
|
||||||
if getErr == nil && user != nil {
|
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
|
// Add TwitterToUser reference
|
||||||
user.ConnectTwitter(twUser.ID)
|
user.ConnectTwitter(twUser.ID)
|
||||||
@ -155,7 +156,7 @@ func InstallTwitterAuth(app *aero.Application) {
|
|||||||
user.Save()
|
user.Save()
|
||||||
|
|
||||||
session.Set("userId", user.ID)
|
session.Set("userId", user.ID)
|
||||||
return ctx.Redirect("/")
|
return ctx.Redirect(http.StatusFound, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register new user
|
// Register new user
|
||||||
@ -187,9 +188,9 @@ func InstallTwitterAuth(app *aero.Application) {
|
|||||||
session.Set("userId", user.ID)
|
session.Set("userId", user.ID)
|
||||||
|
|
||||||
// Log
|
// 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
|
// Redirect to starting page for new users
|
||||||
return ctx.Redirect(newUserStartRoute)
|
return ctx.Redirect(http.StatusFound, newUserStartRoute)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
{
|
{
|
||||||
"domain": "notify.moe",
|
|
||||||
"title": "Anime Notifier",
|
|
||||||
"fonts": [
|
"fonts": [
|
||||||
"Ubuntu"
|
"Ubuntu"
|
||||||
],
|
],
|
||||||
|
@ -16,7 +16,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get returns the contents of our amazing page.
|
// 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!")
|
return ctx.HTML("Hey it's me, foobar!")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -73,7 +73,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get returns the contents of our amazing page.
|
// 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())
|
return ctx.HTML(components.FooBar())
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
23
go.mod
23
go.mod
@ -4,27 +4,25 @@ go 1.12
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.39.0 // indirect
|
cloud.google.com/go v0.39.0 // indirect
|
||||||
github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705 // indirect
|
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||||
github.com/aerogo/aero v1.2.5
|
github.com/aerogo/aero v1.3.2
|
||||||
github.com/aerogo/api v0.1.7
|
github.com/aerogo/api v0.2.0
|
||||||
github.com/aerogo/crawler v0.2.5
|
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/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/log v0.2.5
|
||||||
github.com/aerogo/manifest v0.1.4
|
github.com/aerogo/manifest v0.1.4
|
||||||
github.com/aerogo/markdown v0.1.8
|
github.com/aerogo/markdown v0.1.8
|
||||||
github.com/aerogo/nano v0.3.2
|
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/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/cache v1.0.2
|
||||||
github.com/akyoto/color v1.8.5
|
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/akyoto/stringutils v0.2.1
|
||||||
github.com/animenotifier/anilist v0.2.3
|
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/kitsu v0.2.3
|
||||||
github.com/animenotifier/mal v0.2.3
|
github.com/animenotifier/mal v0.2.3
|
||||||
github.com/animenotifier/shoboi 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/pariz/gountries v0.0.0-20171019111738-adb00f6513a3
|
||||||
github.com/shirou/gopsutil v2.18.12+incompatible
|
github.com/shirou/gopsutil v2.18.12+incompatible
|
||||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect
|
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/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
|
||||||
github.com/stretchr/testify v1.3.0
|
github.com/stretchr/testify v1.3.0
|
||||||
golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0
|
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
|
golang.org/x/text v0.3.2 // indirect
|
||||||
google.golang.org/appengine v1.6.0 // indirect
|
google.golang.org/appengine v1.6.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
@ -56,4 +53,6 @@ require (
|
|||||||
gopkg.in/yaml.v2 v2.2.2 // indirect
|
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
|
exclude github.com/logpacker/PayPal-Go-SDK v2.0.0+incompatible
|
||||||
|
115
go.sum
115
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=
|
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 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
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 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk=
|
||||||
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
|
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-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||||
github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/aerogo/aero v1.1.8 h1:bV87Q15IGJY4XZdZM6jBVBp/rnGjQGIMqUh+WTC4PAY=
|
github.com/aerogo/aero v1.3.1 h1:P4XS4ePrJWSJwHLXKkX5YjFsoywhWuXf3dPIX5XVAW0=
|
||||||
github.com/aerogo/aero v1.1.8/go.mod h1:Xpl5AFecG/cpx9As733/zM36UiPrpd4s12stfyx6i5w=
|
github.com/aerogo/aero v1.3.1/go.mod h1:5rPhXo2DNMFQ7XhDsuZ3L7Zr6TH/349+WczUbrOUZvM=
|
||||||
github.com/aerogo/aero v1.1.9 h1:EB+oTljSIfQENZTVyvnZ24Pb2UsV+Ows04/HfzOJ/3c=
|
github.com/aerogo/aero v1.3.2 h1:Sj/2U860HLJG5iq5het6QFgo/ERQ7cS4Zdz38xPWSwQ=
|
||||||
github.com/aerogo/aero v1.1.9/go.mod h1:MvHPJcXZmZUu5mh4q6j5n3DijKmAMY6puhzCH1w22Vw=
|
github.com/aerogo/aero v1.3.2/go.mod h1:5rPhXo2DNMFQ7XhDsuZ3L7Zr6TH/349+WczUbrOUZvM=
|
||||||
github.com/aerogo/aero v1.1.13 h1:e+FXHaSRZ2a/xrLwF1Yeujh5yHBovdLfHxJYtZvPpWw=
|
github.com/aerogo/api v0.2.0 h1:mIc/y381e+Qc85eSc2cKPdpDDOmT0hlnEeCw2Dcf7no=
|
||||||
github.com/aerogo/aero v1.1.13/go.mod h1:jcHCf+a3vExpo1SKRPrmkspO9VWiDZHC5/ITss/Sz6Y=
|
github.com/aerogo/api v0.2.0/go.mod h1:6objJn5XiKpYpywQUPrFjxZIXD4NVI2LwcBNYCEcS3Y=
|
||||||
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/aerogo/cluster v0.1.6 h1:9HYjJwo19uuh9thIc80T3caap9t9b4BXZ1iN8aztjlU=
|
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.6/go.mod h1:XzYmY5MqNxASmYQWFMh5iCl4tcm1ekReaCQQXVCpJtY=
|
||||||
github.com/aerogo/cluster v0.1.7 h1:hMG7oPzYmo4TPtzn4zJc291YzNRrnoSPWSKVaDS4ODA=
|
github.com/aerogo/cluster v0.1.7 h1:hMG7oPzYmo4TPtzn4zJc291YzNRrnoSPWSKVaDS4ODA=
|
||||||
github.com/aerogo/cluster v0.1.7/go.mod h1:XzYmY5MqNxASmYQWFMh5iCl4tcm1ekReaCQQXVCpJtY=
|
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 h1:tsaRViwBKNJAotzjEmGOln7quzka4f0goiEZVg4Fdxc=
|
||||||
github.com/aerogo/crawler v0.2.5/go.mod h1:nyFPwxOFm3gy5cvif8rG1ogXO0fTDVrxsQHwicJz1F8=
|
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 h1:C2OpzPZHY1S5H+Dz0Or+YgVSfXT36avJw9e1smrIWUY=
|
||||||
github.com/aerogo/csp v0.1.6/go.mod h1:KNqnTFffuDwIPJxBEFTl3baBx+x3Vw+9kcMfu5APFJA=
|
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 h1:fZ3V7Bo7jwBjqnM1mWxYbg5O/FlQX2XovzMZU2D+o5M=
|
||||||
github.com/aerogo/flow v0.1.2/go.mod h1:xXIb7GY0AKouhbp4/ViCsiOmvvgRGonqPG30d6FnACI=
|
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 h1:BCb+nF58tj41xx3aJcxCLsNcGzZH6CGrodRMOIXYfOE=
|
||||||
github.com/aerogo/flow v0.1.4/go.mod h1:xXIb7GY0AKouhbp4/ViCsiOmvvgRGonqPG30d6FnACI=
|
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.4.0 h1:b5OyqzMNdskH6cKxRCLG6hKEpNYKCpxuad3tLjodox8=
|
||||||
github.com/aerogo/graphql v0.3.6/go.mod h1:bcAaQk3IGODFLF2gFwVszP3hyumWOhwKKuOh1xClSeI=
|
github.com/aerogo/graphql v0.4.0/go.mod h1:yAY/KPoBejdN41JUGyK50pPZexFcGp//UMk/GjxqjZc=
|
||||||
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/http v1.0.3 h1:vf6A+Igme5OHQPaP3a00uPDS0oxsx3puMA23d1NsWDM=
|
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.3/go.mod h1:B1igUmMLpE6KabMpc9reHCJJNUOJ2U/PR9s1fF3TpPQ=
|
||||||
github.com/aerogo/http v1.0.6 h1:+aswlcWlUxjVcokF8hUjNJmGIEZuhbFbHi8uSadEvtc=
|
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/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 h1:pYsmUd8jp6CVrFx+YNo9Gfdf222CKG2gCVjp8cljZNY=
|
||||||
github.com/aerogo/linter-performance v1.0.3/go.mod h1:po6XSSbSgR30lazzqSRGV++a2omxYr2qjqFvcvUCH40=
|
github.com/aerogo/linter-performance v1.0.3/go.mod h1:po6XSSbSgR30lazzqSRGV++a2omxYr2qjqFvcvUCH40=
|
||||||
github.com/aerogo/log v0.2.5 h1:LGeElbLqyaD8r8Ls9HuG7tYF6YV4kP56IxJWl/b4cZQ=
|
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/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 h1:X/FlyuBqdVaFflggxDbXcqGCQNInLKwU/tvyNhg+mQw=
|
||||||
github.com/aerogo/markdown v0.1.8/go.mod h1:8+ZWJnLT2rxY75TEd/Y5+rV89Sw9NOh5WiGSjptGNYk=
|
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 h1:mV4Bse2o2HiRN7rNntE6mOtWQLiLgTLkIrlt9vUoPD8=
|
||||||
github.com/aerogo/mirror v0.2.3/go.mod h1:Un87Jq8RIRrb2bU1CxVToJjVZgSMLUQXxVLCXln4rUU=
|
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 h1:YDGytzYoswid2x8cR5yAc9TmjgR+wEMF8+HowR1UCKI=
|
||||||
github.com/aerogo/nano v0.2.1/go.mod h1:1xgPREJH6aW5sE91AwYkvxMDg5YCbAaIYpAL7T1+JgA=
|
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 h1:1JWaZX8e+dtKZuPWC7Ls1AuzN33auCw7hPjZ8JCjjjE=
|
||||||
github.com/aerogo/nano v0.3.2/go.mod h1:o86DA68cpXx5inh8tygTJBF+8sXQ0eoOm36NHIN86YI=
|
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 h1:+J9VyVGlXnmaynukktwc7d+/nGxX7hBSNSj/7X8tg90=
|
||||||
github.com/aerogo/packet v0.1.5/go.mod h1:/t25yF9WG8B5/QB7wTiHLqwCEQ+nAze7uNm/JJNDQbQ=
|
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 h1:P9TwEV9xcyWxsjQQAXDfM3jItX4xEqRFNGXWMqH9j3Q=
|
||||||
github.com/aerogo/packet v0.1.6/go.mod h1:/t25yF9WG8B5/QB7wTiHLqwCEQ+nAze7uNm/JJNDQbQ=
|
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 h1:k/gBdAX/yecGW2xWJXt6dpg4Jb84xZScRPExt2rW+hY=
|
||||||
github.com/aerogo/packet v0.1.7/go.mod h1:/t25yF9WG8B5/QB7wTiHLqwCEQ+nAze7uNm/JJNDQbQ=
|
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 h1:4OgQyUm3wxSsjNRReZhYdHX8X5lXnFp1W+M3EXr4a3E=
|
||||||
github.com/aerogo/session v0.1.4/go.mod h1:aM3FUclBU+wt8kwSs3leTByuaBu0sXrw4P+HwKVkSSw=
|
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 h1:l4uBDs4cVkByTE1N/IVSpU6oIrgx+4abtjztxk13zcI=
|
||||||
github.com/aerogo/session-store-memory v0.1.5/go.mod h1:Agy7YibR8yxUePqcl2rFyIGIwvXJiNsV1yaLtJHnnrI=
|
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 h1:klabo+Hyh1GKhpYJExdGvXDxNCxW7sSJevFGGzIqVCo=
|
||||||
github.com/aerogo/session-store-nano v0.1.5/go.mod h1:HEm80cLszsfh7yUsX1zbddznPhz2sPWhsHRXNLo9tJs=
|
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.3 h1:HjiyvMCFvoB8a8Lm1+3LaA6B5EeP/f5CChrsAYjAFSQ=
|
||||||
github.com/aerogo/sitemap v0.1.2/go.mod h1:/1NT13qIsTm/ydlZHEMd8m014E2yyQkI5coimmIfqc0=
|
github.com/aerogo/sitemap v0.1.3/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/akyoto/cache v1.0.2 h1:YNaLbfbfBRr21dReBErQxfnVPBsVR/aeFpIKxsF88n8=
|
github.com/akyoto/cache v1.0.2 h1:YNaLbfbfBRr21dReBErQxfnVPBsVR/aeFpIKxsF88n8=
|
||||||
github.com/akyoto/cache v1.0.2/go.mod h1:MgYroBUaHREY9mmTcavctH4NDzQohCr4WMWPUKv7pq4=
|
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 h1:d+xQM5ra9aCxUzchbxSX2Szkd7cQwuJARSQMzNb3aLM=
|
||||||
github.com/akyoto/color v1.8.3/go.mod h1:wiwOfYJb0XdHYznfIes7wjr79A/EjGPZ64FfbwJv4RY=
|
github.com/akyoto/color v1.8.3/go.mod h1:wiwOfYJb0XdHYznfIes7wjr79A/EjGPZ64FfbwJv4RY=
|
||||||
github.com/akyoto/color v1.8.4 h1:XS1AL8/JmDHNgN9JRMd1epsQADQF7UXMzUz0nx0kTvY=
|
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/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 h1:HgoCAkeWrGjYr0FZr3yCzAIkXuOGRiVil7Ul329lm+A=
|
||||||
github.com/akyoto/go-matroska v0.1.1/go.mod h1:x+GUVwyby6HN/MKKNP4BvGqP9VrHuEznfBf288gehek=
|
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.5 h1:5EJGHx6RfE9aHrEzWU3pfLGFUWMvPVqtsxt7mSON+mY=
|
||||||
github.com/akyoto/hash v0.3.2/go.mod h1:t6CqUCKqLvd1QfbNSt9yfv9BiOY+qPsZABimD86fNPY=
|
github.com/akyoto/hash v0.3.5/go.mod h1:uPmnZyhBJIyLON8V9LNi0CcqtwYaH2RiKLFQg67fwq0=
|
||||||
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/imageserver v0.3.6 h1:Sxcbgo45Lh7afcSmcU8OS49VYbqh4kE3DK0Lxuuxf74=
|
github.com/akyoto/imageserver v0.3.6 h1:Sxcbgo45Lh7afcSmcU8OS49VYbqh4kE3DK0Lxuuxf74=
|
||||||
github.com/akyoto/imageserver v0.3.6/go.mod h1:9AuMUxIt5CPlTmJre4ETwWxRnThOkkE1EhavC8HX4U8=
|
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 h1:86gMW/31LO7zc8mGGWB4gLqyFzrNHMZYyj6ebSQbpH4=
|
||||||
github.com/akyoto/stringutils v0.2.0/go.mod h1:EigXf5ZaULP6f5CNjqIIo0fjDHbRe8P4BQwlqCsvi9k=
|
github.com/akyoto/stringutils v0.2.0/go.mod h1:EigXf5ZaULP6f5CNjqIIo0fjDHbRe8P4BQwlqCsvi9k=
|
||||||
github.com/akyoto/stringutils v0.2.1 h1:4St8vcRnNFuCNSMEJ34TeLb7/FfsvZaSU8/Scr6Zymg=
|
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/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 h1:409h1m4m59EBTQHc/F2U5PGY3lIWlvD/kRXxY1oTl5Q=
|
||||||
github.com/animenotifier/anilist v0.2.3/go.mod h1:WmivLHBTIs+zmqENjiVXH66laTYB8vT5d+8q1yzLX9I=
|
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.2.0 h1:BsWB6CXUFRgPKeh8MtNtgi8TPwDoqpAkgV8ah+bDTR8=
|
||||||
github.com/animenotifier/arn v1.1.25/go.mod h1:qf9Uq5lsw3uIgFFrfOSu1L9hjtHer9VcmgIWWcuN/Jo=
|
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 h1:gV5h47skizAWLJQb+M3CmExy1hlqDuKmNxkOpn3JwF0=
|
||||||
github.com/animenotifier/ffxiv v0.2.1/go.mod h1:9p0z9iQIT8nIlwH4xHUvdo0qFvJ4pVnFbBQ0G/JiY0k=
|
github.com/animenotifier/ffxiv v0.2.1/go.mod h1:9p0z9iQIT8nIlwH4xHUvdo0qFvJ4pVnFbBQ0G/JiY0k=
|
||||||
github.com/animenotifier/japanese v0.2.3 h1:fGX3CcX5lGzRC+JkokDCwJqRniPOmM44FLm7aqdnOEo=
|
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/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 h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
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 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
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/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 h1:YXfHvkDLMKkdmHmeusBum45MMG4n3iJeeQ9mZPWPAUQ=
|
||||||
github.com/logpacker/PayPal-Go-SDK v1.1.4/go.mod h1:DUf5ncyG0n3jFnU9VsuQqe/Vo6KHtWQ6HYf80JwP4rY=
|
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 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
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=
|
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/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 h1:lmQNznFSupyfCDE9d7wdKOU8UiVwWEoYwv8wo6rSgy0=
|
||||||
github.com/pariz/gountries v0.0.0-20171019111738-adb00f6513a3/go.mod h1:U0ETmPPEsfd7CpUKNMYi68xIOL8Ww4jPZlaqNngcwqs=
|
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
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 h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk=
|
||||||
github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
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=
|
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/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 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-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3 h1:hBSHahWMEgzwRyS6dRpxY0XyjZsHyQ61s084wo5PJe0=
|
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||||
github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
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 h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
|
||||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
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.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
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 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
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 h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38=
|
||||||
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
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 h1:jOwzqCXr5ePXEPGJaq2ivoR6HOCi+D5TPfpoyg8yvmU=
|
||||||
github.com/tdewolff/test v1.0.0/go.mod h1:DiQUlutnqlEvdvhSn2LPGy4TFwRauAaYDsL+683RNX4=
|
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 h1:Z2X3Os7oRzpdJ75iPqWZc0HeJWFYNCvKsfpQwFpRNTA=
|
||||||
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0=
|
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 h1:TZyMbJbyPL+4/ndyXns8aNDrmUJn5a6aV8lj3qEM7fM=
|
||||||
github.com/ungerik/go-gravatar v0.0.0-20120802094239-6ab22628222a/go.mod h1:cmQAsXze586z5DHYfoVO9jZBampncP3iuhVgujPqdxk=
|
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=
|
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-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 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
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-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc=
|
||||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
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/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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
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-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 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-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-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-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 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
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-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 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-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 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug=
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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 h1:khxRGsvPk4n2y8I/mLLjp7e5dMTJmH75wvqS6nMwUtY=
|
||||||
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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 h1:5Q88vZAfC0WB8T1GHRLttQaZdCNeQHM40n41gMUeFlI=
|
||||||
golang.org/x/sys v0.0.0-20190516014833-cab07311ab81/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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 h1:sM3evRHxE/1RuMe1FYAL3j7C7fUfIjkbE+NiDAYUF8U=
|
||||||
golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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-20190531175056-4c3a928424d2 h1:T5DasATyLQfmbTpfEXx/IOL9vfjzW6up+ZDkmHvIf2s=
|
||||||
golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
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=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
|
||||||
|
@ -4,15 +4,16 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
|
||||||
"github.com/animenotifier/notify.moe/components"
|
"github.com/animenotifier/notify.moe/components"
|
||||||
|
"github.com/animenotifier/notify.moe/middleware"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Render layout.
|
// Render layout.
|
||||||
func Render(ctx *aero.Context, content string) string {
|
func Render(ctx aero.Context, content string) string {
|
||||||
user := utils.GetUser(ctx)
|
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.
|
// Make output order deterministic to profit from Aero caching.
|
||||||
// To do this, we need to create slices and sort the tags.
|
// To do this, we need to create slices and sort the tags.
|
||||||
|
@ -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")
|
html(lang="en")
|
||||||
head
|
head
|
||||||
link(rel="stylesheet", href="/styles", importance="high")
|
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
|
if openGraph != nil
|
||||||
title= openGraph.Tags["og:title"]
|
title= openGraph.Tags["og:title"]
|
||||||
else
|
else
|
||||||
title= ctx.App.Config.Title
|
title= assets.Manifest.Name
|
||||||
|
|
||||||
//- Viewport
|
//- Viewport
|
||||||
meta(name="viewport", content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes")
|
meta(name="viewport", content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes")
|
||||||
|
24
main.go
24
main.go
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
nanostore "github.com/aerogo/session-store-nano"
|
nanostore "github.com/aerogo/session-store-nano"
|
||||||
|
"github.com/akyoto/color"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
"github.com/animenotifier/notify.moe/assets"
|
"github.com/animenotifier/notify.moe/assets"
|
||||||
"github.com/animenotifier/notify.moe/auth"
|
"github.com/animenotifier/notify.moe/auth"
|
||||||
@ -44,9 +45,10 @@ func configure(app *aero.Application) *aero.Application {
|
|||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
app.Use(
|
app.Use(
|
||||||
middleware.Log(),
|
middleware.OpenGraph,
|
||||||
middleware.Session(),
|
middleware.Log,
|
||||||
middleware.UserInfo(),
|
middleware.Session,
|
||||||
|
middleware.UserInfo,
|
||||||
)
|
)
|
||||||
|
|
||||||
// API
|
// API
|
||||||
@ -54,9 +56,8 @@ func configure(app *aero.Application) *aero.Application {
|
|||||||
|
|
||||||
// Development server configuration
|
// Development server configuration
|
||||||
if arn.IsDevelopment() {
|
if arn.IsDevelopment() {
|
||||||
app.Config.Domain = "beta.notify.moe"
|
assets.Domain = "beta.notify.moe"
|
||||||
app.Config.Title += " - Beta"
|
assets.Manifest.Name += " - Beta"
|
||||||
assets.Manifest.Name = app.Config.Title
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
@ -68,6 +69,11 @@ func configure(app *aero.Application) *aero.Application {
|
|||||||
// Close the database node on shutdown
|
// Close the database node on shutdown
|
||||||
app.OnEnd(arn.Node.Close)
|
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
|
// Check that this is the server
|
||||||
if !arn.Node.IsServer() && !arn.IsTest() {
|
if !arn.Node.IsServer() && !arn.IsTest() {
|
||||||
panic("Another program is currently running as the database server")
|
panic("Another program is currently running as the database server")
|
||||||
@ -77,13 +83,13 @@ func configure(app *aero.Application) *aero.Application {
|
|||||||
arn.DB.Prefetch()
|
arn.DB.Prefetch()
|
||||||
|
|
||||||
// Do not use HTTP/2 push on service worker requests
|
// Do not use HTTP/2 push on service worker requests
|
||||||
app.AddPushCondition(func(ctx *aero.Context) bool {
|
app.AddPushCondition(func(ctx aero.Context) bool {
|
||||||
return !strings.Contains(ctx.Request().Header().Get("Referer"), "/service-worker")
|
return !strings.Contains(ctx.Request().Header("Referer"), "/service-worker")
|
||||||
})
|
})
|
||||||
|
|
||||||
// Specify test routes
|
// Specify test routes
|
||||||
for route, examples := range routetests.All() {
|
for route, examples := range routetests.All() {
|
||||||
app.Test(route, examples)
|
app.Test(route, examples...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
@ -112,7 +112,7 @@ func testRoute(t *testing.T, app *aero.Application, route string) {
|
|||||||
|
|
||||||
// Record the response
|
// Record the response
|
||||||
responseRecorder := httptest.NewRecorder()
|
responseRecorder := httptest.NewRecorder()
|
||||||
app.Handler().ServeHTTP(responseRecorder, request)
|
app.ServeHTTP(responseRecorder, request)
|
||||||
status := responseRecorder.Code
|
status := responseRecorder.Code
|
||||||
|
|
||||||
switch status {
|
switch status {
|
||||||
|
4
makefile
4
makefile
@ -47,9 +47,9 @@ test:
|
|||||||
bench:
|
bench:
|
||||||
$(GOTEST) -bench .
|
$(GOTEST) -bench .
|
||||||
pack:
|
pack:
|
||||||
go install github.com/aerogo/pack
|
go install github.com/aerogo/pack/...
|
||||||
run:
|
run:
|
||||||
go install github.com/aerogo/run
|
go install github.com/aerogo/run/...
|
||||||
tools:
|
tools:
|
||||||
ifeq ($(OSNAME),OSX)
|
ifeq ($(OSNAME),OSX)
|
||||||
brew install coreutils
|
brew install coreutils
|
||||||
|
@ -20,10 +20,10 @@ package middleware
|
|||||||
|
|
||||||
// // Firewall middleware detects malicious requests.
|
// // Firewall middleware detects malicious requests.
|
||||||
// func Firewall() aero.Middleware {
|
// func Firewall() aero.Middleware {
|
||||||
// return func(ctx *aero.Context, next func()) {
|
// return func(ctx aero.Context, next func()) {
|
||||||
// var stats *IPStats
|
// var stats *IPStats
|
||||||
|
|
||||||
// ip := ctx.RealIP()
|
// ip := ctx.IP()
|
||||||
|
|
||||||
// // Allow localhost
|
// // Allow localhost
|
||||||
// if ip == "127.0.0.1" {
|
// if ip == "127.0.0.1" {
|
||||||
@ -44,7 +44,7 @@ package middleware
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// // Add requested URI to the list of requests
|
// // 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 {
|
// if len(stats.Requests) > requestThreshold {
|
||||||
// stats.Requests = stats.Requests[len(stats.Requests)-requestThreshold:]
|
// stats.Requests = stats.Requests[len(stats.Requests)-requestThreshold:]
|
||||||
@ -69,7 +69,7 @@ package middleware
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// // Disallow request
|
// // Disallow request
|
||||||
// request.Error("[guest]", ip, "BLOCKED BY FIREWALL", ctx.URI())
|
// request.Error("[guest]", ip, "BLOCKED BY FIREWALL", ctx.Path())
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -2,15 +2,15 @@ package middleware
|
|||||||
|
|
||||||
// // HTTPSRedirect middleware redirects to HTTPS if needed.
|
// // HTTPSRedirect middleware redirects to HTTPS if needed.
|
||||||
// func HTTPSRedirect() aero.Middleware {
|
// func HTTPSRedirect() aero.Middleware {
|
||||||
// return func(ctx *aero.Context, next func()) {
|
// return func(ctx aero.Context, next func()) {
|
||||||
// request := ctx.Request()
|
// request := ctx.Request()
|
||||||
// userAgent := request.Header().Get("User-Agent")
|
// userAgent := request.Header().Get("User-Agent")
|
||||||
// isBrowser := strings.Contains(userAgent, "Mozilla/") || strings.Contains(userAgent, "Chrome/") || strings.Contains(userAgent, "AppleWebKit/")
|
// isBrowser := strings.Contains(userAgent, "Mozilla/") || strings.Contains(userAgent, "Chrome/") || strings.Contains(userAgent, "AppleWebKit/")
|
||||||
|
|
||||||
// if !strings.HasPrefix(request.Protocol(), "HTTP/2") && isBrowser {
|
// if !strings.HasPrefix(request.Protocol(), "HTTP/2") && isBrowser {
|
||||||
// fmt.Println("Redirect to HTTPS")
|
// fmt.Println("Redirect to HTTPS")
|
||||||
// ctx.Redirect("https://" + request.Host() + request.URL().Path)
|
// ctx.Redirect(http.StatusFound, "https://" + request.Host() + request.URL().Path)
|
||||||
// ctx.Response().WriteHeader(ctx.StatusCode)
|
// ctx.Response().WriteHeader(ctx.Status())
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -32,18 +32,19 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log middleware logs every request into logs/request.log and errors into logs/error.log.
|
// Log middleware logs every request into logs/request.log and errors into logs/error.log.
|
||||||
func Log() aero.Middleware {
|
func Log(next aero.Handler) aero.Handler {
|
||||||
return func(ctx *aero.Context, next func()) {
|
return func(ctx aero.Context) error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
next()
|
err := next(ctx)
|
||||||
responseTime := time.Since(start)
|
responseTime := time.Since(start)
|
||||||
|
|
||||||
go logRequest(ctx, responseTime)
|
go logRequest(ctx, responseTime)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logs a single request
|
// 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"
|
responseTimeString := strconv.Itoa(int(responseTime.Nanoseconds()/1000000)) + " ms"
|
||||||
repeatSpaceCount := 8 - len(responseTimeString)
|
repeatSpaceCount := 8 - len(responseTimeString)
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ func logRequest(ctx *aero.Context, responseTime time.Duration) {
|
|||||||
responseTimeString = strings.Repeat(" ", repeatSpaceCount) + responseTimeString
|
responseTimeString = strings.Repeat(" ", repeatSpaceCount) + responseTimeString
|
||||||
|
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
ip := ctx.RealIP()
|
ip := ctx.IP()
|
||||||
hostNames, cached := GetHostsForIP(ip)
|
hostNames, cached := GetHostsForIP(ip)
|
||||||
|
|
||||||
if !cached && len(hostNames) > 0 {
|
if !cached && len(hostNames) > 0 {
|
||||||
@ -70,20 +71,20 @@ func logRequest(ctx *aero.Context, responseTime time.Duration) {
|
|||||||
nick = user.Nick
|
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
|
// Log all requests that failed
|
||||||
switch ctx.StatusCode {
|
switch ctx.Status() {
|
||||||
case http.StatusOK, http.StatusFound, http.StatusMovedPermanently, http.StatusPermanentRedirect, http.StatusTemporaryRedirect:
|
case http.StatusOK, http.StatusFound, http.StatusMovedPermanently, http.StatusPermanentRedirect, http.StatusTemporaryRedirect:
|
||||||
// Ok.
|
// Ok.
|
||||||
|
|
||||||
default:
|
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.
|
// Notify us about long requests.
|
||||||
// However ignore requests under /auth/ because those depend on 3rd party servers.
|
// 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/") {
|
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.StatusCode, ctx.URI())
|
errorLog.Error("%s | %s | %s | %s | %d | %s (long response time)", nick, id, ip, responseTimeString, ctx.Status(), ctx.Path())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
middleware/OpenGraph.go
Normal file
24
middleware/OpenGraph.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
34
middleware/Recover.go
Normal file
34
middleware/Recover.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -3,14 +3,16 @@ package middleware
|
|||||||
import "github.com/aerogo/aero"
|
import "github.com/aerogo/aero"
|
||||||
|
|
||||||
// Session middleware saves an existing session if it has been modified.
|
// Session middleware saves an existing session if it has been modified.
|
||||||
func Session() aero.Middleware {
|
func Session(next aero.Handler) aero.Handler {
|
||||||
return func(ctx *aero.Context, next func()) {
|
return func(ctx aero.Context) error {
|
||||||
// Handle the request first
|
// Handle the request first
|
||||||
next()
|
err := next(ctx)
|
||||||
|
|
||||||
// Update session if it has been modified
|
// Update session if it has been modified
|
||||||
if ctx.HasSession() && ctx.Session().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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,33 +14,35 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UserInfo updates user related information after each request.
|
// UserInfo updates user related information after each request.
|
||||||
func UserInfo() aero.Middleware {
|
func UserInfo(next aero.Handler) aero.Handler {
|
||||||
return func(ctx *aero.Context, next func()) {
|
return func(ctx aero.Context) error {
|
||||||
next()
|
err := next(ctx)
|
||||||
|
|
||||||
// Ignore non-HTML requests
|
// Ignore non-HTML requests
|
||||||
contentType := ctx.Response().Header().Get("Content-Type")
|
contentType := ctx.Response().Header("Content-Type")
|
||||||
|
|
||||||
if !strings.HasPrefix(contentType, "text/html") {
|
if !strings.HasPrefix(contentType, "text/html") {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
// When there's no user logged in, nothing to update
|
// When there's no user logged in, nothing to update
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This works asynchronously so it doesn't block the response
|
// This works asynchronously so it doesn't block the response
|
||||||
go updateUserInfo(ctx, user)
|
go updateUserInfo(ctx, user)
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update browser and OS data
|
// Update browser and OS data
|
||||||
func updateUserInfo(ctx *aero.Context, user *arn.User) {
|
func updateUserInfo(ctx aero.Context, user *arn.User) {
|
||||||
newIP := ctx.RealIP()
|
newIP := ctx.IP()
|
||||||
newUserAgent := ctx.UserAgent()
|
newUserAgent := ctx.Request().Header("User-Agent")
|
||||||
|
|
||||||
if user.UserAgent != newUserAgent {
|
if user.UserAgent != newUserAgent {
|
||||||
user.UserAgent = newUserAgent
|
user.UserAgent = newUserAgent
|
||||||
@ -91,7 +93,12 @@ func updateUserLocation(user *arn.User, newIP string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
newLocation := arn.IPInfoDBLocation{}
|
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 != "-" {
|
if newLocation.CountryName != "-" {
|
||||||
user.Location.CountryName = newLocation.CountryName
|
user.Location.CountryName = newLocation.CountryName
|
||||||
|
@ -7,14 +7,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Global activity page.
|
// Global activity page.
|
||||||
func Global(ctx *aero.Context) string {
|
func Global(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
activities := fetchActivities(user, false)
|
activities := fetchActivities(user, false)
|
||||||
return render(ctx, activities)
|
return render(ctx, activities)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Followed activity page.
|
// Followed activity page.
|
||||||
func Followed(ctx *aero.Context) string {
|
func Followed(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
activities := fetchActivities(user, true)
|
activities := fetchActivities(user, true)
|
||||||
return render(ctx, activities)
|
return render(ctx, activities)
|
||||||
|
@ -14,7 +14,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// render renders the activities page with the given activities.
|
// 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)
|
user := utils.GetUser(ctx)
|
||||||
index, _ := ctx.GetInt("index")
|
index, _ := ctx.GetInt("index")
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -14,11 +15,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get admin page.
|
// Get admin page.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil || (user.Role != "admin" && user.Role != "editor") {
|
if user == nil || (user.Role != "admin" && user.Role != "editor") {
|
||||||
return ctx.Redirect("/")
|
return ctx.Redirect(http.StatusFound, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// // CPU
|
// // CPU
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
const maxReports = 80
|
const maxReports = 80
|
||||||
|
|
||||||
// ClientErrors shows client-side errors.
|
// ClientErrors shows client-side errors.
|
||||||
func ClientErrors(ctx *aero.Context) string {
|
func ClientErrors(ctx aero.Context) error {
|
||||||
reports := arn.AllClientErrorReports()
|
reports := arn.AllClientErrorReports()
|
||||||
|
|
||||||
sort.Slice(reports, func(i, j int) bool {
|
sort.Slice(reports, func(i, j int) bool {
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// PaymentHistory ...
|
// PaymentHistory ...
|
||||||
func PaymentHistory(ctx *aero.Context) string {
|
func PaymentHistory(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// PurchaseHistory ...
|
// PurchaseHistory ...
|
||||||
func PurchaseHistory(ctx *aero.Context) string {
|
func PurchaseHistory(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UserRegistrations ...
|
// UserRegistrations ...
|
||||||
func UserRegistrations(ctx *aero.Context) string {
|
func UserRegistrations(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
|
@ -4,6 +4,6 @@ import "github.com/aerogo/aero"
|
|||||||
import "github.com/animenotifier/notify.moe/components"
|
import "github.com/animenotifier/notify.moe/components"
|
||||||
|
|
||||||
// WebDev ...
|
// WebDev ...
|
||||||
func WebDev(ctx *aero.Context) string {
|
func WebDev(ctx aero.Context) error {
|
||||||
return ctx.HTML(components.WebDev())
|
return ctx.HTML(components.WebDev())
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,12 @@ import (
|
|||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
"github.com/animenotifier/notify.moe/components"
|
"github.com/animenotifier/notify.moe/components"
|
||||||
|
"github.com/animenotifier/notify.moe/middleware"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get a single AMV.
|
// Get a single AMV.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
amv, err := arn.GetAMV(id)
|
amv, err := arn.GetAMV(id)
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
@ -19,6 +20,7 @@ func Get(ctx *aero.Context) string {
|
|||||||
return ctx.Error(http.StatusNotFound, "AMV not found", err)
|
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))
|
return ctx.HTML(components.AMVPage(amv, user))
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Edit track.
|
// Edit track.
|
||||||
func Edit(ctx *aero.Context) string {
|
func Edit(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
amv, err := arn.GetAMV(id)
|
amv, err := arn.GetAMV(id)
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
@ -5,14 +5,15 @@ import (
|
|||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"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{
|
openGraph := &arn.OpenGraph{
|
||||||
Tags: map[string]string{
|
Tags: map[string]string{
|
||||||
"og:title": amv.Title.ByUser(nil) + " (AMV)",
|
"og:title": amv.Title.ByUser(nil) + " (AMV)",
|
||||||
"og:url": "https://" + ctx.App.Config.Domain + amv.Link(),
|
"og:url": "https://" + assets.Domain + amv.Link(),
|
||||||
"og:site_name": ctx.App.Config.Domain,
|
"og:site_name": assets.Domain,
|
||||||
"og:type": "video.other",
|
"og:type": "video.other",
|
||||||
},
|
},
|
||||||
Meta: map[string]string{},
|
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, ", ")
|
openGraph.Tags["og:description"] = strings.Join(amv.Tags, ", ")
|
||||||
|
|
||||||
if amv.File != "" {
|
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:type"] = "video/webm"
|
||||||
openGraph.Tags["og:video:width"] = "640"
|
openGraph.Tags["og:video:width"] = "640"
|
||||||
openGraph.Tags["og:video:height"] = "360"
|
openGraph.Tags["og:video:height"] = "360"
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Best AMVs.
|
// Best AMVs.
|
||||||
func Best(ctx *aero.Context) string {
|
func Best(ctx aero.Context) error {
|
||||||
amvs := fetchAll()
|
amvs := fetchAll()
|
||||||
|
|
||||||
sort.Slice(amvs, func(i, j int) bool {
|
sort.Slice(amvs, func(i, j int) bool {
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Latest AMVs.
|
// Latest AMVs.
|
||||||
func Latest(ctx *aero.Context) string {
|
func Latest(ctx aero.Context) error {
|
||||||
amvs := fetchAll()
|
amvs := fetchAll()
|
||||||
|
|
||||||
sort.Slice(amvs, func(i, j int) bool {
|
sort.Slice(amvs, func(i, j int) bool {
|
||||||
|
@ -14,7 +14,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// render renders the AMVs page with the given AMVs.
|
// 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)
|
user := utils.GetUser(ctx)
|
||||||
index, _ := ctx.GetInt("index")
|
index, _ := ctx.GetInt("index")
|
||||||
tag := ctx.Get("tag")
|
tag := ctx.Get("tag")
|
||||||
|
@ -6,7 +6,9 @@ import (
|
|||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
|
"github.com/animenotifier/notify.moe/assets"
|
||||||
"github.com/animenotifier/notify.moe/components"
|
"github.com/animenotifier/notify.moe/components"
|
||||||
|
"github.com/animenotifier/notify.moe/middleware"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get anime page.
|
// Get anime page.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
anime, err := arn.GetAnime(id)
|
anime, err := arn.GetAnime(id)
|
||||||
@ -120,12 +122,13 @@ func Get(ctx *aero.Context) string {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Open Graph
|
// 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))
|
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
|
description := anime.Summary
|
||||||
|
|
||||||
if len(description) > maxDescriptionLength {
|
if len(description) > maxDescriptionLength {
|
||||||
@ -136,7 +139,7 @@ func getOpenGraph(ctx *aero.Context, anime *arn.Anime) *arn.OpenGraph {
|
|||||||
Tags: map[string]string{
|
Tags: map[string]string{
|
||||||
"og:title": anime.Title.Canonical,
|
"og:title": anime.Title.Canonical,
|
||||||
"og:image": "https:" + anime.ImageLink("large"),
|
"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:site_name": "notify.moe",
|
||||||
"og:description": description,
|
"og:description": description,
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Characters ...
|
// Characters ...
|
||||||
func Characters(ctx *aero.Context) string {
|
func Characters(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
anime, err := arn.GetAnime(id)
|
anime, err := arn.GetAnime(id)
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Comments ...
|
// Comments ...
|
||||||
func Comments(ctx *aero.Context) string {
|
func Comments(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
anime, err := arn.GetAnime(id)
|
anime, err := arn.GetAnime(id)
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Main anime edit page.
|
// Main anime edit page.
|
||||||
func Main(ctx *aero.Context) string {
|
func Main(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ func Main(ctx *aero.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Images anime images edit page.
|
// Images anime images edit page.
|
||||||
func Images(ctx *aero.Context) string {
|
func Images(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ func Images(ctx *aero.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Characters anime characters edit page.
|
// Characters anime characters edit page.
|
||||||
func Characters(ctx *aero.Context) string {
|
func Characters(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ func Characters(ctx *aero.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Relations anime relations edit page.
|
// Relations anime relations edit page.
|
||||||
func Relations(ctx *aero.Context) string {
|
func Relations(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ func Relations(ctx *aero.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Episodes anime episodes edit page.
|
// Episodes anime episodes edit page.
|
||||||
func Episodes(ctx *aero.Context) string {
|
func Episodes(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Episodes ...
|
// Episodes ...
|
||||||
func Episodes(ctx *aero.Context) string {
|
func Episodes(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
anime, err := arn.GetAnime(id)
|
anime, err := arn.GetAnime(id)
|
||||||
|
@ -9,8 +9,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// RedirectByMapping redirects to the anime with the given mapping ID.
|
// RedirectByMapping redirects to the anime with the given mapping ID.
|
||||||
func RedirectByMapping(mappingName string) func(*aero.Context) string {
|
func RedirectByMapping(mappingName string) func(aero.Context) error {
|
||||||
return func(ctx *aero.Context) string {
|
return func(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
finder := arn.NewAnimeFinder(mappingName)
|
finder := arn.NewAnimeFinder(mappingName)
|
||||||
anime := finder.GetAnime(id)
|
anime := finder.GetAnime(id)
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Relations ...
|
// Relations ...
|
||||||
func Relations(ctx *aero.Context) string {
|
func Relations(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Tracks ...
|
// Tracks ...
|
||||||
func Tracks(ctx *aero.Context) string {
|
func Tracks(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// DeleteKitsu marks an anime for deletion.
|
// DeleteKitsu marks an anime for deletion.
|
||||||
func DeleteKitsu(ctx *aero.Context) string {
|
func DeleteKitsu(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
|
|
||||||
// Is the user allowed to delete?
|
// Is the user allowed to delete?
|
||||||
@ -39,5 +39,5 @@ func DeleteKitsu(ctx *aero.Context) string {
|
|||||||
// Save in database
|
// Save in database
|
||||||
arn.DB.Set("IDList", "deleted kitsu anime", &deletedKitsuAnime)
|
arn.DB.Set("IDList", "deleted kitsu anime", &deletedKitsuAnime)
|
||||||
|
|
||||||
return ""
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Kitsu anime import.
|
// Kitsu anime import.
|
||||||
func Kitsu(ctx *aero.Context) string {
|
func Kitsu(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
@ -45,5 +45,5 @@ func Kitsu(ctx *aero.Context) string {
|
|||||||
// Log
|
// Log
|
||||||
fmt.Println(color.GreenString("✔"), anime.ID, anime.Title.Canonical)
|
fmt.Println(color.GreenString("✔"), anime.ID, anime.Title.Canonical)
|
||||||
|
|
||||||
return ""
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,9 @@ import (
|
|||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
|
"github.com/animenotifier/notify.moe/assets"
|
||||||
"github.com/animenotifier/notify.moe/components"
|
"github.com/animenotifier/notify.moe/components"
|
||||||
|
"github.com/animenotifier/notify.moe/middleware"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
"github.com/animenotifier/notify.moe/utils/infinitescroll"
|
"github.com/animenotifier/notify.moe/utils/infinitescroll"
|
||||||
)
|
)
|
||||||
@ -17,15 +19,15 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// FilterByStatus returns a handler for the given anime list item status.
|
// FilterByStatus returns a handler for the given anime list item status.
|
||||||
func FilterByStatus(status string) aero.Handle {
|
func FilterByStatus(status string) aero.Handler {
|
||||||
return func(ctx *aero.Context) string {
|
return func(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
return AnimeList(ctx, user, status)
|
return AnimeList(ctx, user, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnimeList renders the anime list items.
|
// 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")
|
nick := ctx.Get("nick")
|
||||||
index, _ := ctx.GetInt("index")
|
index, _ := ctx.GetInt("index")
|
||||||
viewUser, err := arn.GetUserByNick(nick)
|
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)
|
nextIndex := infinitescroll.NextIndex(ctx, len(allItems), maxLength, index)
|
||||||
|
|
||||||
// OpenGraph data
|
// OpenGraph data
|
||||||
ctx.Data = &arn.OpenGraph{
|
customCtx := ctx.(*middleware.OpenGraphContext)
|
||||||
|
customCtx.OpenGraph = &arn.OpenGraph{
|
||||||
Tags: map[string]string{
|
Tags: map[string]string{
|
||||||
"og:title": viewUser.Nick + "'s anime list",
|
"og:title": viewUser.Nick + "'s anime list",
|
||||||
"og:image": "https:" + viewUser.AvatarLink("large"),
|
"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:site_name": "notify.moe",
|
||||||
"og:description": strconv.Itoa(len(animeList.Items)) + " anime",
|
"og:description": strconv.Itoa(len(animeList.Items)) + " anime",
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Redirect to the full URL including the user nick.
|
// 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)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return ctx.Error(http.StatusUnauthorized, "Not logged in")
|
return ctx.Error(http.StatusUnauthorized, "Not logged in")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.Redirect("/+" + user.Nick + ctx.URI())
|
return ctx.Redirect(http.StatusFound, "/+" + user.Nick + ctx.Path())
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get anime page.
|
// Get anime page.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
nick := ctx.Get("nick")
|
nick := ctx.Get("nick")
|
||||||
viewUser, err := arn.GetUserByNick(nick)
|
viewUser, err := arn.GetUserByNick(nick)
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get api page.
|
// Get api page.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
types := []*autodocs.Type{}
|
types := []*autodocs.Type{}
|
||||||
|
|
||||||
for typeName := range arn.DB.Types() {
|
for typeName := range arn.DB.Types() {
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ByType renders the api docs page for the given type.
|
// ByType renders the api docs page for the given type.
|
||||||
func ByType(typeName string) func(*aero.Context) string {
|
func ByType(typeName string) func(aero.Context) error {
|
||||||
return func(ctx *aero.Context) string {
|
return func(ctx aero.Context) error {
|
||||||
t := arn.API.Type(typeName)
|
t := arn.API.Type(typeName)
|
||||||
fields := []*utils.APIField{}
|
fields := []*utils.APIField{}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ var weekdayNames = []string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get ...
|
// Get ...
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
oneWeek := 7 * 24 * time.Hour
|
oneWeek := 7 * 24 * time.Hour
|
||||||
|
|
||||||
|
@ -7,7 +7,9 @@ import (
|
|||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/akyoto/color"
|
"github.com/akyoto/color"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
|
"github.com/animenotifier/notify.moe/assets"
|
||||||
"github.com/animenotifier/notify.moe/components"
|
"github.com/animenotifier/notify.moe/components"
|
||||||
|
"github.com/animenotifier/notify.moe/middleware"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,7 +18,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get character.
|
// Get character.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
character, err := arn.GetCharacter(id)
|
character, err := arn.GetCharacter(id)
|
||||||
@ -101,11 +103,12 @@ func Get(ctx *aero.Context) string {
|
|||||||
// Set OpenGraph attributes
|
// Set OpenGraph attributes
|
||||||
description := utils.CutLongDescription(character.Description)
|
description := utils.CutLongDescription(character.Description)
|
||||||
|
|
||||||
ctx.Data = &arn.OpenGraph{
|
customCtx := ctx.(*middleware.OpenGraphContext)
|
||||||
|
customCtx.OpenGraph = &arn.OpenGraph{
|
||||||
Tags: map[string]string{
|
Tags: map[string]string{
|
||||||
"og:title": character.Name.Canonical,
|
"og:title": character.Name.Canonical,
|
||||||
"og:image": "https:" + character.ImageLink("large"),
|
"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:site_name": "notify.moe",
|
||||||
"og:description": description,
|
"og:description": description,
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Edit character.
|
// Edit character.
|
||||||
func Edit(ctx *aero.Context) string {
|
func Edit(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
character, err := arn.GetCharacter(id)
|
character, err := arn.GetCharacter(id)
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
@ -24,7 +24,7 @@ func Edit(ctx *aero.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EditImages renders the form to edit the character images.
|
// 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")
|
id := ctx.Get("id")
|
||||||
character, err := arn.GetCharacter(id)
|
character, err := arn.GetCharacter(id)
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Ranking returns the ranking information for the character via the API.
|
// 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
|
// Check character ID
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
_, err := arn.GetCharacter(id)
|
_, err := arn.GetCharacter(id)
|
||||||
@ -35,7 +35,7 @@ func Ranking(ctx *aero.Context) string {
|
|||||||
arn.SortCharactersByLikes(characters)
|
arn.SortCharactersByLikes(characters)
|
||||||
|
|
||||||
// Allow CORS
|
// Allow CORS
|
||||||
ctx.Response().Header().Set("Access-Control-Allow-Origin", "*")
|
ctx.Response().SetHeader("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
// Return ranking
|
// Return ranking
|
||||||
for index, character := range characters {
|
for index, character := range characters {
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Best characters.
|
// Best characters.
|
||||||
func Best(ctx *aero.Context) string {
|
func Best(ctx aero.Context) error {
|
||||||
characters := fetchAll()
|
characters := fetchAll()
|
||||||
|
|
||||||
arn.SortCharactersByLikes(characters)
|
arn.SortCharactersByLikes(characters)
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Latest characters.
|
// Latest characters.
|
||||||
func Latest(ctx *aero.Context) string {
|
func Latest(ctx aero.Context) error {
|
||||||
characters := fetchAll()
|
characters := fetchAll()
|
||||||
|
|
||||||
sort.Slice(characters, func(i, j int) bool {
|
sort.Slice(characters, func(i, j int) bool {
|
||||||
|
@ -14,7 +14,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// render renders the characters page with the given characters.
|
// 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)
|
user := utils.GetUser(ctx)
|
||||||
index, _ := ctx.GetInt("index")
|
index, _ := ctx.GetInt("index")
|
||||||
tag := ctx.Get("tag")
|
tag := ctx.Get("tag")
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get charge page.
|
// Get charge page.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// All renders an index of all companies.
|
// All renders an index of all companies.
|
||||||
func All(ctx *aero.Context) string {
|
func All(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
companies := arn.FilterCompanies(func(company *arn.Company) bool {
|
companies := arn.FilterCompanies(func(company *arn.Company) bool {
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
const maxPopularCompanies = 10
|
const maxPopularCompanies = 10
|
||||||
|
|
||||||
// Popular renders the best companies.
|
// Popular renders the best companies.
|
||||||
func Popular(ctx *aero.Context) string {
|
func Popular(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
index, _ := ctx.GetInt("index")
|
index, _ := ctx.GetInt("index")
|
||||||
|
|
||||||
|
@ -6,12 +6,14 @@ import (
|
|||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
|
"github.com/animenotifier/notify.moe/assets"
|
||||||
"github.com/animenotifier/notify.moe/components"
|
"github.com/animenotifier/notify.moe/components"
|
||||||
|
"github.com/animenotifier/notify.moe/middleware"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get renders a company page.
|
// Get renders a company page.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
company, err := arn.GetCompany(id)
|
company, err := arn.GetCompany(id)
|
||||||
@ -25,7 +27,7 @@ func Get(ctx *aero.Context) string {
|
|||||||
openGraph := &arn.OpenGraph{
|
openGraph := &arn.OpenGraph{
|
||||||
Tags: map[string]string{
|
Tags: map[string]string{
|
||||||
"og:title": company.Name.English,
|
"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:site_name": "notify.moe",
|
||||||
"og:type": "article",
|
"og:type": "article",
|
||||||
},
|
},
|
||||||
@ -41,7 +43,8 @@ func Get(ctx *aero.Context) string {
|
|||||||
openGraph.Tags["og:description"] = company.Name.English + " company information."
|
openGraph.Tags["og:description"] = company.Name.English + " company information."
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data = openGraph
|
customCtx := ctx.(*middleware.OpenGraphContext)
|
||||||
|
customCtx.OpenGraph = openGraph
|
||||||
|
|
||||||
studioAnime, producedAnime, licensedAnime := company.Anime()
|
studioAnime, producedAnime, licensedAnime := company.Anime()
|
||||||
|
|
||||||
|
@ -5,13 +5,15 @@ import (
|
|||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
|
"github.com/animenotifier/notify.moe/assets"
|
||||||
"github.com/animenotifier/notify.moe/components"
|
"github.com/animenotifier/notify.moe/components"
|
||||||
|
"github.com/animenotifier/notify.moe/middleware"
|
||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
"github.com/animenotifier/notify.moe/utils/editform"
|
"github.com/animenotifier/notify.moe/utils/editform"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Edit company.
|
// Edit company.
|
||||||
func Edit(ctx *aero.Context) string {
|
func Edit(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
company, err := arn.GetCompany(id)
|
company, err := arn.GetCompany(id)
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
@ -20,10 +22,11 @@ func Edit(ctx *aero.Context) string {
|
|||||||
return ctx.Error(http.StatusNotFound, "Company not found", err)
|
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{
|
Tags: map[string]string{
|
||||||
"og:title": company.Name.English,
|
"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:site_name": "notify.moe",
|
||||||
// "og:image": company.Image,
|
// "og:image": company.Image,
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// AnimeList ...
|
// AnimeList ...
|
||||||
func AnimeList(ctx *aero.Context) string {
|
func AnimeList(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
nickA := ctx.Get("nick-1")
|
nickA := ctx.Get("nick-1")
|
||||||
nickB := ctx.Get("nick-2")
|
nickB := ctx.Get("nick-2")
|
||||||
|
@ -18,7 +18,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get edit log.
|
// Get edit log.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
index, _ := ctx.GetInt("index")
|
index, _ := ctx.GetInt("index")
|
||||||
nick := ctx.Get("nick")
|
nick := ctx.Get("nick")
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package editor
|
package editor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
@ -10,11 +11,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get ...
|
// Get ...
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil || (user.Role != "admin" && user.Role != "editor") {
|
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 {
|
ignoreDifferences := arn.FilterIgnoreAnimeDifferences(func(entry *arn.IgnoreAnimeDifference) bool {
|
||||||
@ -43,5 +44,5 @@ func Get(ctx *aero.Context) string {
|
|||||||
scoreTitle += objectType + ": " + strconv.Itoa(score) + "\n"
|
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))
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// All ...
|
// All ...
|
||||||
func All(ctx *aero.Context) string {
|
func All(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"All anime",
|
"All anime",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// AniList ...
|
// AniList ...
|
||||||
func AniList(ctx *aero.Context) string {
|
func AniList(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without Anilist mappings",
|
"Anime without Anilist mappings",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Characters ...
|
// Characters ...
|
||||||
func Characters(ctx *aero.Context) string {
|
func Characters(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without characters",
|
"Anime without characters",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// DuplicateMappings ...
|
// DuplicateMappings ...
|
||||||
func DuplicateMappings(ctx *aero.Context) string {
|
func DuplicateMappings(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime with duplicate mappings",
|
"Anime with duplicate mappings",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// EpisodeLength ...
|
// EpisodeLength ...
|
||||||
func EpisodeLength(ctx *aero.Context) string {
|
func EpisodeLength(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without an episode length",
|
"Anime without an episode length",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Genres ...
|
// Genres ...
|
||||||
func Genres(ctx *aero.Context) string {
|
func Genres(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without genres",
|
"Anime without genres",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Licensors ...
|
// Licensors ...
|
||||||
func Licensors(ctx *aero.Context) string {
|
func Licensors(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without licensors",
|
"Anime without licensors",
|
||||||
|
@ -6,16 +6,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// LowResolutionAnimeImages filters anime with low resolution images.
|
// 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)
|
return filterAnimeImages(ctx, "Anime with low resolution images", arn.AnimeImageLargeWidth, arn.AnimeImageLargeHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UltraLowResolutionAnimeImages filters anime with ultra low resolution images.
|
// 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)
|
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(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
title,
|
title,
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// MAL ...
|
// MAL ...
|
||||||
func MAL(ctx *aero.Context) string {
|
func MAL(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without MAL mappings",
|
"Anime without MAL mappings",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Producers ...
|
// Producers ...
|
||||||
func Producers(ctx *aero.Context) string {
|
func Producers(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without producers",
|
"Anime without producers",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Relations ...
|
// Relations ...
|
||||||
func Relations(ctx *aero.Context) string {
|
func Relations(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without relations",
|
"Anime without relations",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Shoboi ...
|
// Shoboi ...
|
||||||
func Shoboi(ctx *aero.Context) string {
|
func Shoboi(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without Shoboi mappings",
|
"Anime without Shoboi mappings",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Source ...
|
// Source ...
|
||||||
func Source(ctx *aero.Context) string {
|
func Source(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without a source",
|
"Anime without a source",
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// StartDate ...
|
// StartDate ...
|
||||||
func StartDate(ctx *aero.Context) string {
|
func StartDate(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without a valid start date",
|
"Anime without a valid start date",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Studios ...
|
// Studios ...
|
||||||
func Studios(ctx *aero.Context) string {
|
func Studios(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without studios",
|
"Anime without studios",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Synopsis ...
|
// Synopsis ...
|
||||||
func Synopsis(ctx *aero.Context) string {
|
func Synopsis(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without a long synopsis",
|
"Anime without a long synopsis",
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Trailers ...
|
// Trailers ...
|
||||||
func Trailers(ctx *aero.Context) string {
|
func Trailers(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Anime without trailers",
|
"Anime without trailers",
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
const maxAnimeEntries = 70
|
const maxAnimeEntries = 70
|
||||||
|
|
||||||
// editorList renders the anime list with the given title and filter.
|
// 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)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil || (user.Role != "admin" && user.Role != "editor") {
|
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)
|
animes, count := filterAnime(ctx, user, filter)
|
||||||
|
|
||||||
// Determine URL
|
// Determine URL
|
||||||
url := strings.TrimPrefix(ctx.URI(), "/_")
|
url := strings.TrimPrefix(ctx.Path(), "/_")
|
||||||
urlParts := strings.Split(url, "/")
|
urlParts := strings.Split(url, "/")
|
||||||
urlParts = urlParts[:len(urlParts)-4]
|
urlParts = urlParts[:len(urlParts)-4]
|
||||||
url = strings.Join(urlParts, "/")
|
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
|
// filterAnime filters anime by the given filter function and
|
||||||
// additionally applies year and types filters if specified.
|
// 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")
|
year := ctx.Get("year")
|
||||||
status := ctx.Get("status")
|
status := ctx.Get("status")
|
||||||
season := ctx.Get("season")
|
season := ctx.Get("season")
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package filtercompanies
|
package filtercompanies
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/aerogo/aero"
|
"github.com/aerogo/aero"
|
||||||
"github.com/animenotifier/arn"
|
"github.com/animenotifier/arn"
|
||||||
"github.com/animenotifier/notify.moe/components"
|
"github.com/animenotifier/notify.moe/components"
|
||||||
@ -10,11 +12,11 @@ import (
|
|||||||
const maxEntries = 70
|
const maxEntries = 70
|
||||||
|
|
||||||
// NoDescription ...
|
// NoDescription ...
|
||||||
func NoDescription(ctx *aero.Context) string {
|
func NoDescription(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil || (user.Role != "admin" && user.Role != "editor") {
|
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 {
|
companies := arn.FilterCompanies(func(company *arn.Company) bool {
|
||||||
@ -29,5 +31,5 @@ func NoDescription(ctx *aero.Context) string {
|
|||||||
companies = companies[:maxEntries]
|
companies = companies[:maxEntries]
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.HTML(components.CompaniesEditorList(companies, count, ctx.URI(), user))
|
return ctx.HTML(components.CompaniesEditorList(companies, count, ctx.Path(), user))
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// File shows soundtracks without an audio file.
|
// File shows soundtracks without an audio file.
|
||||||
func File(ctx *aero.Context) string {
|
func File(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Soundtracks without an audio file",
|
"Soundtracks without an audio file",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Links shows soundtracks without links.
|
// Links shows soundtracks without links.
|
||||||
func Links(ctx *aero.Context) string {
|
func Links(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Soundtracks without links",
|
"Soundtracks without links",
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// MissingLyrics shows soundtracks without lyrics.
|
// MissingLyrics shows soundtracks without lyrics.
|
||||||
func MissingLyrics(ctx *aero.Context) string {
|
func MissingLyrics(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Soundtracks without lyrics",
|
"Soundtracks without lyrics",
|
||||||
@ -26,7 +26,7 @@ func MissingLyrics(ctx *aero.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UnalignedLyrics shows soundtracks with unaligned lyrics.
|
// UnalignedLyrics shows soundtracks with unaligned lyrics.
|
||||||
func UnalignedLyrics(ctx *aero.Context) string {
|
func UnalignedLyrics(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Soundtracks with unaligned lyrics",
|
"Soundtracks with unaligned lyrics",
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Tags shows soundtracks with less than 3 tags.
|
// Tags shows soundtracks with less than 3 tags.
|
||||||
func Tags(ctx *aero.Context) string {
|
func Tags(ctx aero.Context) error {
|
||||||
return editorList(
|
return editorList(
|
||||||
ctx,
|
ctx,
|
||||||
"Soundtracks with less than 3 tags",
|
"Soundtracks with less than 3 tags",
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
const maxSoundTrackEntries = 70
|
const maxSoundTrackEntries = 70
|
||||||
|
|
||||||
// editorList renders the soundtrack list with the given title and filter.
|
// 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)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil || (user.Role != "admin" && user.Role != "editor") {
|
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)
|
tracks, count := filterSoundTracks(ctx, user, filter)
|
||||||
url := strings.TrimPrefix(ctx.URI(), "/_")
|
url := strings.TrimPrefix(ctx.Path(), "/_")
|
||||||
|
|
||||||
return ctx.HTML(components.SoundTracksEditorListFull(
|
return ctx.HTML(components.SoundTracksEditorListFull(
|
||||||
title,
|
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.
|
// 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
|
// Filter
|
||||||
tracks := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool {
|
tracks := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool {
|
||||||
return !track.IsDraft && filter(track)
|
return !track.IsDraft && filter(track)
|
||||||
|
@ -29,7 +29,7 @@ var jobInfo = map[string]*utils.JobInfo{
|
|||||||
var jobLogs = []string{}
|
var jobLogs = []string{}
|
||||||
|
|
||||||
// Overview shows all background jobs.
|
// Overview shows all background jobs.
|
||||||
func Overview(ctx *aero.Context) string {
|
func Overview(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
jobs := []*utils.JobInfo{}
|
jobs := []*utils.JobInfo{}
|
||||||
|
|
||||||
@ -41,5 +41,5 @@ func Overview(ctx *aero.Context) string {
|
|||||||
return jobs[i].Name < jobs[j].Name
|
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))
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
var jobStartMutex sync.Mutex
|
var jobStartMutex sync.Mutex
|
||||||
|
|
||||||
// Start will start the specified background job.
|
// Start will start the specified background job.
|
||||||
func Start(ctx *aero.Context) string {
|
func Start(ctx aero.Context) error {
|
||||||
jobStartMutex.Lock()
|
jobStartMutex.Lock()
|
||||||
defer jobStartMutex.Unlock()
|
defer jobStartMutex.Unlock()
|
||||||
|
|
||||||
@ -38,5 +38,5 @@ func Start(ctx *aero.Context) string {
|
|||||||
job.Start()
|
job.Start()
|
||||||
jobLogs = append(jobLogs, user.Nick+" started "+job.Name+" job ("+arn.DateTimeUTC()+").")
|
jobLogs = append(jobLogs, user.Nick+" started "+job.Name+" job ("+arn.DateTimeUTC()+").")
|
||||||
|
|
||||||
return "ok"
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewKitsuAnime ...
|
// NewKitsuAnime ...
|
||||||
func NewKitsuAnime(ctx *aero.Context) string {
|
func NewKitsuAnime(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
finder := arn.NewAnimeFinder("kitsu/anime")
|
finder := arn.NewAnimeFinder("kitsu/anime")
|
||||||
deletedIDs, err := arn.GetIDList("deleted 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 a.ID > b.ID
|
||||||
})
|
})
|
||||||
|
|
||||||
return ctx.HTML(components.NewKitsuAnime(animes, ctx.URI(), user))
|
return ctx.HTML(components.NewKitsuAnime(animes, ctx.Path(), user))
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ const maxCompareMALEntries = 15
|
|||||||
type diffFunction func(*arn.Anime, *mal.Anime) []animediff.Difference
|
type diffFunction func(*arn.Anime, *mal.Anime) []animediff.Difference
|
||||||
|
|
||||||
// CompareMAL ...
|
// CompareMAL ...
|
||||||
func CompareMAL(ctx *aero.Context) string {
|
func CompareMAL(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
year := ctx.Get("year")
|
year := ctx.Get("year")
|
||||||
status := ctx.Get("status")
|
status := ctx.Get("status")
|
||||||
|
@ -9,21 +9,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Get anime list in the browser extension.
|
// Get anime list in the browser extension.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return utils.AllowEmbed(ctx, ctx.HTML(components.Login("_blank")))
|
return ctx.HTML(components.Login("_blank"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !user.HasBasicInfo() {
|
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.
|
// Extension is enabled as long as the site isn't finished yet.
|
||||||
// ---
|
// ---
|
||||||
// if !user.IsPro() && user.TimeSinceRegistered() > 14*24*time.Hour {
|
// 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()
|
animeList := user.AnimeList()
|
||||||
@ -35,5 +35,5 @@ func Get(ctx *aero.Context) string {
|
|||||||
watchingList := animeList.Watching()
|
watchingList := animeList.Watching()
|
||||||
watchingList.Sort()
|
watchingList.Sort()
|
||||||
|
|
||||||
return utils.AllowEmbed(ctx, ctx.HTML(components.BrowserExtension(watchingList, animeList.User(), user)))
|
return ctx.HTML(components.BrowserExtension(watchingList, animeList.User(), user))
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get renders the anime episode.
|
// Get renders the anime episode.
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
episodeNumber, err := ctx.GetInt("episode-number")
|
episodeNumber, err := ctx.GetInt("episode-number")
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Subtitles returns the subtitles.
|
// Subtitles returns the subtitles.
|
||||||
func Subtitles(ctx *aero.Context) string {
|
func Subtitles(ctx aero.Context) error {
|
||||||
id := ctx.Get("id")
|
id := ctx.Get("id")
|
||||||
language := ctx.Get("language")
|
language := ctx.Get("language")
|
||||||
episodeNumber, err := ctx.GetInt("episode-number")
|
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)
|
return ctx.Error(http.StatusNotFound, "Anime not found", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Response().Header().Set("Access-Control-Allow-Origin", "*")
|
ctx.Response().SetHeader("Access-Control-Allow-Origin", "*")
|
||||||
ctx.Response().Header().Set("Content-Type", "text/vtt; charset=utf-8")
|
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{})
|
obj, err := spaces.GetObject("arn", fmt.Sprintf("videos/anime/%s/%d.%s.vtt", anime.ID, episodeNumber, language), minio.GetObjectOptions{})
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Filter ...
|
// Filter ...
|
||||||
func Filter(ctx *aero.Context) string {
|
func Filter(ctx aero.Context) error {
|
||||||
year := ctx.Get("year")
|
year := ctx.Get("year")
|
||||||
season := ctx.Get("season")
|
season := ctx.Get("season")
|
||||||
status := ctx.Get("status")
|
status := ctx.Get("status")
|
||||||
|
@ -18,7 +18,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// AnimeByAverageColor returns all anime with an image in the given color.
|
// 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)
|
user := utils.GetUser(ctx)
|
||||||
color := ctx.Get("color")
|
color := ctx.Get("color")
|
||||||
index, _ := ctx.GetInt("index")
|
index, _ := ctx.GetInt("index")
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Sequels ...
|
// Sequels ...
|
||||||
func Sequels(ctx *aero.Context) string {
|
func Sequels(ctx aero.Context) error {
|
||||||
nick := ctx.Get("nick")
|
nick := ctx.Get("nick")
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
viewUser, err := arn.GetUserByNick(nick)
|
viewUser, err := arn.GetUserByNick(nick)
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
const minYear = 1963
|
const minYear = 1963
|
||||||
|
|
||||||
// Get ...
|
// Get ...
|
||||||
func Get(ctx *aero.Context) string {
|
func Get(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
maxYear := time.Now().Year() - 1
|
maxYear := time.Now().Year() - 1
|
||||||
hallOfFameEntries := []*utils.HallOfFameEntry{}
|
hallOfFameEntries := []*utils.HallOfFameEntry{}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user