Signed-off-by: Odyssey <odyssey346@disroot.org>
このコミットが含まれているのは:
Odyssey 2022-12-03 13:40:03 +01:00
コミット 41a7fa5689
6個のファイルの変更202行の追加150行の削除

24
cmd/gothub/root.go ノーマルファイル
ファイルの表示

@ -0,0 +1,24 @@
package gothub
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "gothub",
Short: "An alternative front-end for GitHub.",
Long: `An alternative front-end for GitHub, written by Odyssey346 and Midou360.`,
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "Error running GotHub's CLI: %v", err)
os.Exit(1)
}
}

20
cmd/gothub/serve.go ノーマルファイル
ファイルの表示

@ -0,0 +1,20 @@
package gothub
import (
"github.com/spf13/cobra"
"codeberg.org/gothub/gothub/serve"
)
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Start the web server.",
Long: `Start the web server.`,
Run: func(cmd *cobra.Command, args []string) {
serve.Serve()
},
}
func init() {
rootCmd.AddCommand(serveCmd)
}

3
go.mod
ファイルの表示

@ -15,11 +15,14 @@ require (
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.15.12 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/spf13/cobra v1.6.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect

8
go.sum
ファイルの表示

@ -100,6 +100,7 @@ github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWH
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -246,6 +247,9 @@ github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@ -342,7 +346,10 @@ github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY52
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -815,6 +822,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

153
main.go
ファイルの表示

@ -1,155 +1,8 @@
package main
import (
"context"
"log"
"os"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/template/html"
"codeberg.org/gothub/gothub/pages"
"github.com/gofiber/fiber/v2/middleware/cache"
"time"
"github.com/gofiber/fiber/v2/middleware/proxy"
"github.com/gofiber/fiber/v2/middleware/compress"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/gofiber/fiber/v2/middleware/limiter"
"html/template"
"github.com/carlmjohnson/requests"
)
import "codeberg.org/gothub/gothub/cmd/gothub"
func main() {
engine := html.New("./views", ".html")
engine.AddFunc(
// add unescape function
"unescape", func(s string) template.HTML {
return template.HTML(s)
},
)
app := fiber.New(fiber.Config{
Views: engine,
Prefork: false,
AppName: "GotHub",
// fucked up way to fix rate limits
EnableTrustedProxyCheck: true,
TrustedProxies: []string{"0.0.0.0/0"},
ProxyHeader: fiber.HeaderXForwardedFor,
ErrorHandler: func(ctx *fiber.Ctx, err error) error {
code := fiber.StatusInternalServerError
if e, ok := err.(*fiber.Error); ok {
code = e.Code
}
err = ctx.Status(code).Render("error", fiber.Map{
"error": err,
})
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
}
return nil
},
})
app.Use(cache.New(cache.Config{
Expiration: 5 * time.Minute,
}))
app.Get("/", func(c *fiber.Ctx) error {
return c.Render("index", fiber.Map{
"host": c.Hostname(),
})
})
app.Use(compress.New(compress.Config{
Level: compress.LevelBestSpeed, // 1
}))
app.Use(recover.New())
ratelimiter := limiter.New(limiter.Config{
Max: 5,
Expiration: 5 * time.Minute,
LimitReached: func(c *fiber.Ctx) error {
return c.Status(429).Render("ratelimit_gt", fiber.Map{
"Title": "Rate limit exceeded",
})
},
})
app.Static("/css", "./public/css")
app.Static("/fonts", "./public/fonts")
app.Static("/robots.txt", "./public/robots.txt")
app.Static("/favicon.ico", "./public/assets/favicon.ico")
app.Static("/logo.svg", "./public/assets/logo.svg")
app.Get("/explore", ratelimiter, pages.HandleExplore)
app.Get("/:user", ratelimiter, pages.HandleUser)
app.Get("/:user/:repo", ratelimiter, pages.HandleRepo)
app.Get("/file/:user/:repo/:branch/:file", func(c *fiber.Ctx) error {
var file string
url := "https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + c.Params("branch") + "/" + c.Params("file")
err := requests.
URL(url).
ToString(&file).
Fetch(context.Background())
if err != nil {
return c.Status(404).Render("error", fiber.Map{
"error": err,
})
}
return c.Render("file", fiber.Map{
"file": file,
"fullname": c.Params("user") + "/" + c.Params("repo"),
"name": c.Params("file"),
"branch": c.Params("branch"),
})
})
app.Get("/avatar/:id", func(c *fiber.Ctx) error {
url := "https://avatars.githubusercontent.com/u/" + c.Params("id") + "?v=4"
if err := proxy.Do(c, url); err != nil {
return err
}
// Remove Server header from response
c.Response().Header.Del(fiber.HeaderServer)
return nil
})
app.Get("/download/:user/:repo/:branch", ratelimiter, func(c *fiber.Ctx) error {
url := "https://github.com/" + c.Params("user") + "/" + c.Params("repo") + "/archive/" + c.Params("branch") + ".zip"
if err := proxy.Do(c, url); err != nil {
return err
}
// Remove Server header from response
c.Response().Header.Del(fiber.HeaderServer)
return nil
})
app.Get("/raw/:user/:repo/:branch/:file", ratelimiter, func(c *fiber.Ctx) error {
url := "https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + c.Params("branch") + "/" + c.Params("file")
if err := proxy.Do(c, url); err != nil {
return err
}
// Remove Server header from response
c.Response().Header.Del(fiber.HeaderServer)
return nil
})
val, ok := os.LookupEnv("GOTHUB_PORT")
if !ok {
val = "3000"
} else {
log.Println("Using port from env variable")
}
log.Fatal(app.Listen(":" + val))
gothub.Execute()
// Looking for the Fiber server? It's in serve/serve.go.
}

144
serve/serve.go ノーマルファイル
ファイルの表示

@ -0,0 +1,144 @@
package serve
import (
"context"
"html/template"
"log"
"os"
"time"
"codeberg.org/gothub/gothub/pages"
"github.com/carlmjohnson/requests"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cache"
"github.com/gofiber/fiber/v2/middleware/compress"
"github.com/gofiber/fiber/v2/middleware/limiter"
"github.com/gofiber/fiber/v2/middleware/proxy"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/gofiber/template/html"
)
func Serve() {
engine := html.New("./views", ".html")
engine.AddFunc(
// add unescape function
"unescape", func(s string) template.HTML {
return template.HTML(s)
},
)
app := fiber.New(fiber.Config{
Views: engine,
Prefork: false,
AppName: "GotHub",
// fucked up way to fix rate limits
EnableTrustedProxyCheck: true,
TrustedProxies: []string{"0.0.0.0/0"},
ProxyHeader: fiber.HeaderXForwardedFor,
ErrorHandler: func(ctx *fiber.Ctx, err error) error {
code := fiber.StatusInternalServerError
if e, ok := err.(*fiber.Error); ok {
code = e.Code
}
err = ctx.Status(code).Render("error", fiber.Map{
"error": err,
})
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
}
return nil
},
})
app.Use(cache.New(cache.Config{
Expiration: 5 * time.Minute,
}))
app.Get("/", func(c *fiber.Ctx) error {
return c.Render("index", fiber.Map{
"host": c.Hostname(),
})
})
app.Use(compress.New(compress.Config{
Level: compress.LevelBestSpeed, // 1
}))
app.Use(recover.New())
ratelimiter := limiter.New(limiter.Config{
Max: 5,
Expiration: 5 * time.Minute,
LimitReached: func(c *fiber.Ctx) error {
return c.Status(429).Render("ratelimit_gt", fiber.Map{
"Title": "Rate limit exceeded",
})
},
})
app.Static("/css", "./public/css")
app.Static("/fonts", "./public/fonts")
app.Static("/robots.txt", "./public/robots.txt")
app.Static("/favicon.ico", "./public/assets/favicon.ico")
app.Static("/logo.svg", "./public/assets/logo.svg")
app.Get("/explore", ratelimiter, pages.HandleExplore)
app.Get("/:user", ratelimiter, pages.HandleUser)
app.Get("/avatar/:id", func(c *fiber.Ctx) error {
url := "https://avatars.githubusercontent.com/u/" + c.Params("id") + "?v=4"
if err := proxy.Do(c, url); err != nil {
return err
}
// Remove Server header from response
c.Response().Header.Del(fiber.HeaderServer)
return nil
})
app.Get("/:user/:repo", ratelimiter, pages.HandleRepo)
app.Get("/file/:user/:repo/:branch/:file", func(c *fiber.Ctx) error {
var file string
url := "https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + c.Params("branch") + "/" + c.Params("file")
err := requests.
URL(url).
ToString(&file).
Fetch(context.Background())
if err != nil {
return c.Status(404).Render("error", fiber.Map{
"error": err,
})
}
return c.Render("file", fiber.Map{
"file": file,
"fullname": c.Params("user") + "/" + c.Params("repo"),
"name": c.Params("file"),
"branch": c.Params("branch"),
})
})
app.Get("/download/:user/:repo/:branch", ratelimiter, func(c *fiber.Ctx) error {
url := "https://github.com/" + c.Params("user") + "/" + c.Params("repo") + "/archive/" + c.Params("branch") + ".zip"
if err := proxy.Do(c, url); err != nil {
return err
}
// Remove Server header from response
c.Response().Header.Del(fiber.HeaderServer)
return nil
})
app.Get("/raw/:user/:repo/:branch/:file", ratelimiter, func(c *fiber.Ctx) error {
url := "https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + c.Params("branch") + "/" + c.Params("file")
if err := proxy.Do(c, url); err != nil {
return err
}
// Remove Server header from response
c.Response().Header.Del(fiber.HeaderServer)
return nil
})
val, ok := os.LookupEnv("GOTHUB_PORT")
if !ok {
val = "3000"
} else {
log.Println("Using port from env variable")
}
log.Fatal(app.Listen(":" + val))
}