PixivFEからいくつか輸入しました
リクエストリミッターを構成可能にする マニュアルページを更新する エラーページを改善する GoFiber v2.52.0 へのアップデート Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja> git-svn-id: https://svn.yakumo.dev/yakumo.izuru/mai/trunk@70 e410bdd4-646f-c54f-a7ce-fffcc4f439ae
This commit is contained in:
parent
439e8b9e02
commit
29e1e11c63
@ -1,6 +1,6 @@
|
||||
# List of known instances
|
||||
|
||||
* [tr.chaotic.ninja](https://tr.chaotic.ninja)
|
||||
* Location: Germany
|
||||
* Cloudflare: No
|
||||
|
||||
| Name | Cloudflare? | Country | URL | Engines supported |
|
||||
|---------------------------------------------|-------------|---------|--------------------------|-------------------|
|
||||
| Chaotic Ninja Communication Network Limited | No | Germany | https://tr.chaotic.ninja | Google, Reverso |
|
||||
| | | | | |
|
||||
|
@ -7,3 +7,8 @@ A privacy friendly frontend to multiple translation engines.
|
||||
|
||||
### Other projects
|
||||
* [Mozhi](https://codeberg.org/aryak/mozhi), also a fork of SimplyTranslate
|
||||
|
||||
### Credits
|
||||
* SimpleWeb (fattalion, ManeraKai, metalune)
|
||||
* [VnPower](https://vnpower.exozy.me) ([PixivFE](https://codeberg.org/VnPower/PixivFE) developer), for most of the stuff I borrowed from his project, as we both use [Fiber](https://gofiber.io)
|
||||
* [z3bra](http://z3bra.org), for the `.ini` loading function, and privilege dropping from [Partage](http://z3bra.org/partage/)
|
||||
|
@ -2,12 +2,14 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"time"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"marisa.chaotic.ninja/mai"
|
||||
@ -17,6 +19,7 @@ import (
|
||||
"github.com/gofiber/fiber/v2/middleware/favicon"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/gofiber/fiber/v2/middleware/limiter"
|
||||
"github.com/gofiber/fiber/v2/middleware/recover"
|
||||
"github.com/gofiber/template/html/v2"
|
||||
)
|
||||
var (
|
||||
@ -25,10 +28,17 @@ var (
|
||||
username string
|
||||
)
|
||||
var conf struct {
|
||||
danmaku int
|
||||
listen string
|
||||
staticpath string
|
||||
tmplpath string
|
||||
}
|
||||
func MaiSkipLimiter(c *fiber.Ctx) bool {
|
||||
// Paths listed here are not considered for rate limiting
|
||||
path := c.Path()
|
||||
return strings.HasPrefix(path, "/static") ||
|
||||
strings.HasPrefix(path, "/docs")
|
||||
}
|
||||
func main() {
|
||||
parseFlags()
|
||||
|
||||
@ -37,6 +47,7 @@ func main() {
|
||||
}
|
||||
|
||||
// Default settings
|
||||
conf.danmaku = 10
|
||||
conf.listen = "127.0.0.1:5000"
|
||||
conf.staticpath = "./static"
|
||||
conf.tmplpath = "./views"
|
||||
@ -44,8 +55,7 @@ func main() {
|
||||
if username != "" {
|
||||
uid, gid, err := usergroupids(username, groupname)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
log.Fatal(err)
|
||||
}
|
||||
syscall.Setuid(uid)
|
||||
syscall.Setgid(gid)
|
||||
@ -54,39 +64,52 @@ func main() {
|
||||
engine := html.New(conf.tmplpath, ".html")
|
||||
engine.AddFunc("inc", func(i int) int { return i + 1 })
|
||||
|
||||
app := fiber.New(
|
||||
server := fiber.New(
|
||||
fiber.Config{
|
||||
AppName: "Mai",
|
||||
ProxyHeader: fiber.HeaderXForwardedFor,
|
||||
TrustedProxies: []string{"0.0.0.0/0"},
|
||||
ServerHeader: "Mai (using Fiber v2.x)",
|
||||
Views: engine,
|
||||
})
|
||||
ErrorHandler: func(c *fiber.Ctx, err error) error {
|
||||
code := fiber.StatusInternalServerError
|
||||
err = c.Status(code).Render("pages/error", fiber.Map{"Title": "Error", "Error": err})
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
app.Use(favicon.New(
|
||||
server.Use(recover.New())
|
||||
|
||||
server.Use(favicon.New(
|
||||
favicon.Config{
|
||||
File: conf.staticpath + "/favicon.ico",
|
||||
},
|
||||
))
|
||||
|
||||
app.Use(logger.New(
|
||||
server.Use(logger.New(
|
||||
logger.Config{
|
||||
Format: "==> ${ip}:${port} ${status} - ${method} ${path}\n",
|
||||
DisableColors: true,
|
||||
Output: os.Stdout,
|
||||
Next: MaiSkipLimiter,
|
||||
},
|
||||
))
|
||||
|
||||
app.Use(limiter.New(limiter.Config{
|
||||
Max: 10,
|
||||
Expiration: 180 * time.Second,
|
||||
server.Use(limiter.New(limiter.Config{
|
||||
Next: MaiSkipLimiter,
|
||||
Max: conf.danmaku,
|
||||
Expiration: 30 * time.Second,
|
||||
LimiterMiddleware: limiter.SlidingWindow{},
|
||||
LimitReached: func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(429)
|
||||
return c.SendFile(conf.tmplpath + "/429.html")
|
||||
log.Println("Limit reached!")
|
||||
return errors.New("You're firing way too many danmaku really fast!")
|
||||
},
|
||||
}))
|
||||
|
||||
app.All("/", func(c *fiber.Ctx) error {
|
||||
server.All("/", func(c *fiber.Ctx) error {
|
||||
engine := c.Cookies("engine")
|
||||
if c.Query("engine") != "" {
|
||||
engine = c.Query("engine")
|
||||
@ -185,7 +208,7 @@ func main() {
|
||||
})
|
||||
})
|
||||
|
||||
app.All("/api/translate", func(c *fiber.Ctx) error {
|
||||
server.All("/api/translate", func(c *fiber.Ctx) error {
|
||||
from := ""
|
||||
to := ""
|
||||
engine := ""
|
||||
@ -216,7 +239,7 @@ func main() {
|
||||
}
|
||||
})
|
||||
|
||||
app.Get("/api/source_languages", func(c *fiber.Ctx) error {
|
||||
server.Get("/api/source_languages", func(c *fiber.Ctx) error {
|
||||
engine := c.Query("engine")
|
||||
if _, ok := engines.Engines[engine]; !ok || engine == "" {
|
||||
engine = "google"
|
||||
@ -228,7 +251,7 @@ func main() {
|
||||
}
|
||||
})
|
||||
|
||||
app.Get("/api/target_languages", func(c *fiber.Ctx) error {
|
||||
server.Get("/api/target_languages", func(c *fiber.Ctx) error {
|
||||
engine := c.Query("engine")
|
||||
if _, ok := engines.Engines[engine]; !ok || engine == "" {
|
||||
engine = "google"
|
||||
@ -240,7 +263,7 @@ func main() {
|
||||
}
|
||||
})
|
||||
|
||||
app.Get("/api/tts", func(c *fiber.Ctx) error {
|
||||
server.Get("/api/tts", func(c *fiber.Ctx) error {
|
||||
engine := c.Query("engine")
|
||||
if _, ok := engines.Engines[engine]; !ok || engine == "" {
|
||||
engine = "google"
|
||||
@ -267,17 +290,25 @@ func main() {
|
||||
}
|
||||
}
|
||||
})
|
||||
app.Get("/robots.txt", func(c *fiber.Ctx) error {
|
||||
|
||||
server.Get("/robots.txt", func(c *fiber.Ctx) error {
|
||||
return c.SendString("User-Agent: *\nDisallow: /\n")
|
||||
})
|
||||
app.Get("/version", func(c *fiber.Ctx) error {
|
||||
|
||||
server.Get("/toomanyrequests", func(c *fiber.Ctx) error {
|
||||
return c.SendFile(conf.tmplpath + "/429.html")
|
||||
return c.SendStatus(429)
|
||||
})
|
||||
|
||||
server.Get("/version", func(c *fiber.Ctx) error {
|
||||
return c.JSON(fiber.Map{
|
||||
"fiberversion": fiber.Version,
|
||||
"goversion": runtime.Version(),
|
||||
"maiversion": mai.FullVersion(),
|
||||
})
|
||||
})
|
||||
app.Post("/switchlanguages", func(c *fiber.Ctx) error {
|
||||
|
||||
server.Post("/switchlanguages", func(c *fiber.Ctx) error {
|
||||
if c.Cookies("from") != "" {
|
||||
fromCookie := new(fiber.Cookie)
|
||||
fromCookie.Name = "from"
|
||||
@ -294,11 +325,13 @@ func main() {
|
||||
}
|
||||
return c.Redirect("/")
|
||||
})
|
||||
app.Static("/static", conf.staticpath, fiber.Static{
|
||||
server.Static("/static", conf.staticpath, fiber.Static{
|
||||
Compress: true,
|
||||
ByteRange: true,
|
||||
Browse: true,
|
||||
})
|
||||
app.Static("/docs", "./docs", fiber.Static{})
|
||||
app.Listen(conf.listen)
|
||||
|
||||
server.Static("/docs", "./docs", fiber.Static{})
|
||||
|
||||
server.Listen(conf.listen)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ func readConf(file string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conf.danmaku, _ = cfg.Section("mai").Key("danmaku").Int()
|
||||
conf.listen = cfg.Section("mai").Key("listen").String()
|
||||
conf.staticpath = cfg.Section("mai").Key("static").String()
|
||||
conf.tmplpath = cfg.Section("mai").Key("templates").String()
|
||||
|
14
go.mod
14
go.mod
@ -4,7 +4,7 @@ go 1.20
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/goquery v1.8.1
|
||||
github.com/gofiber/fiber/v2 v2.50.0
|
||||
github.com/gofiber/fiber/v2 v2.52.0
|
||||
github.com/gofiber/template/html/v2 v2.0.5
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
)
|
||||
@ -14,18 +14,18 @@ require (
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
github.com/gofiber/template v1.8.2 // indirect
|
||||
github.com/gofiber/utils v1.1.0 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/google/uuid v1.5.0 // indirect
|
||||
github.com/klauspost/compress v1.17.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.50.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
)
|
||||
|
28
go.sum
28
go.sum
@ -5,23 +5,23 @@ github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG
|
||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/gofiber/fiber/v2 v2.50.0 h1:ia0JaB+uw3GpNSCR5nvC5dsaxXjRU5OEu36aytx+zGw=
|
||||
github.com/gofiber/fiber/v2 v2.50.0/go.mod h1:21eytvay9Is7S6z+OgPi7c7n4++tnClWmhpimVHMimw=
|
||||
github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE=
|
||||
github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||
github.com/gofiber/template v1.8.2 h1:PIv9s/7Uq6m+Fm2MDNd20pAFFKt5wWs7ZBd8iV9pWwk=
|
||||
github.com/gofiber/template v1.8.2/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
|
||||
github.com/gofiber/template/html/v2 v2.0.5 h1:BKLJ6Qr940NjntbGmpO3zVa4nFNGDCi/IfUiDB9OC20=
|
||||
github.com/gofiber/template/html/v2 v2.0.5/go.mod h1:RCF14eLeQDCSUPp0IGc2wbSSDv6yt+V54XB/+Unz+LM=
|
||||
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
|
||||
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
|
||||
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
|
||||
@ -35,8 +35,8 @@ github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
|
||||
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M=
|
||||
github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
|
||||
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
@ -50,8 +50,8 @@ golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -65,8 +65,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
|
@ -7,13 +7,16 @@
|
||||
.Sh OPTIONS
|
||||
.Ss [mai] section
|
||||
.Bl -tag -width 11n
|
||||
.It listen
|
||||
.It danmaku (int)
|
||||
Control the maximum amount of requests
|
||||
before a ratelimit happens
|
||||
.It listen (string)
|
||||
HTTP port for the server to listen.
|
||||
Default is "localhost:5000"
|
||||
.It static
|
||||
.It static (string)
|
||||
Directory where the static resources are located.
|
||||
Default is "./static"
|
||||
.It templates
|
||||
.It templates (string)
|
||||
Directory where the templates are located.
|
||||
Default is "./views"
|
||||
.El
|
||||
|
@ -1,21 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<title>Too many requests</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1" align="center">
|
||||
<thead>
|
||||
<img src="/static/displeased_mai.png">
|
||||
</thead>
|
||||
<tbody>
|
||||
<p>You have triggered a 429 error</p>
|
||||
<p>Try again later</p>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<i><a href="https://deviantart.com/view/1017571065">[image source]</a></i>
|
||||
</tfoot>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
48
views/pages/error.html
Normal file
48
views/pages/error.html
Normal file
@ -0,0 +1,48 @@
|
||||
<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #282c37;
|
||||
color: rgb(234, 136, 50);
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: rgb(34, 36, 42);
|
||||
}
|
||||
p {
|
||||
color: rgb(221, 209, 203);
|
||||
}
|
||||
img {
|
||||
height: 640px;
|
||||
width: 480px;
|
||||
}
|
||||
</style>
|
||||
<title>Mai | Error</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1">
|
||||
<thead>
|
||||
<img src="/static/displeased_mai.png">
|
||||
</thead>
|
||||
<tbody>
|
||||
<h2>Error</h2>
|
||||
<p>
|
||||
Something has happened and these may be the following causes:
|
||||
</p>
|
||||
<p>
|
||||
<ol>
|
||||
<li>You might have reached the rate limit</li>
|
||||
<li>There was an internal server error</li>
|
||||
<li>Any other client error such as a 404 Not Found</li>
|
||||
</ol>
|
||||
</p>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<p>
|
||||
<a href="https://deviantart.com/view/1017571065">[image source]</a>
|
||||
</p>
|
||||
</tfoot>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user