Reviewed-on: https://codeberg.org/gothub/gothub/pulls/3 Reviewed-by: Midou36O <midou36o@noreply.codeberg.org>
このコミットが含まれているのは:
コミット
3070266d8d
2
go.mod
2
go.mod
|
@ -1,4 +1,4 @@
|
|||
module codeberg.org/Odyssium/gothub
|
||||
module codeberg.org/gothub/gothub
|
||||
|
||||
go 1.19
|
||||
|
||||
|
|
33
main.go
33
main.go
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"os"
|
||||
|
@ -9,7 +10,7 @@ import (
|
|||
|
||||
"github.com/gofiber/template/html"
|
||||
|
||||
"codeberg.org/Odyssium/gothub/pages"
|
||||
"codeberg.org/gothub/gothub/pages"
|
||||
|
||||
"github.com/gofiber/fiber/v2/middleware/cache"
|
||||
|
||||
|
@ -24,6 +25,8 @@ import (
|
|||
"github.com/gofiber/fiber/v2/middleware/limiter"
|
||||
|
||||
"html/template"
|
||||
|
||||
"github.com/carlmjohnson/requests"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -96,6 +99,25 @@ func main() {
|
|||
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 {
|
||||
|
@ -114,6 +136,15 @@ func main() {
|
|||
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"
|
||||
|
|
|
@ -3,7 +3,7 @@ package pages
|
|||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
|
||||
"codeberg.org/Odyssium/gothub/utils"
|
||||
"codeberg.org/gothub/gothub/utils"
|
||||
)
|
||||
|
||||
type Items struct {
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package pages
|
||||
|
||||
import (
|
||||
"codeberg.org/Odyssium/gothub/utils"
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"codeberg.org/gothub/gothub/utils"
|
||||
"github.com/carlmjohnson/requests"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gomarkdown/markdown"
|
||||
)
|
||||
|
||||
type Repo struct {
|
||||
|
@ -20,15 +25,51 @@ type Repo struct {
|
|||
}
|
||||
|
||||
type RepoFiles struct {
|
||||
Name string
|
||||
Path string
|
||||
Type string
|
||||
Name string
|
||||
Path string
|
||||
Type string
|
||||
Fullname string
|
||||
DefaultBranch string
|
||||
}
|
||||
|
||||
func HandleRepo(c *fiber.Ctx) error {
|
||||
var repoArray []Repo
|
||||
var repoFilesArray []RepoFiles
|
||||
// get repo
|
||||
repo := utils.GetRequest("https://api.github.com/repos/" + c.Params("user") + "/" + c.Params("repo"))
|
||||
if repo.Get("message").String() == "Not Found" {
|
||||
return c.Status(404).Render("error", fiber.Map{
|
||||
"error": "Repository " + c.Params("user") + "/" + c.Params("repo") + " not found",
|
||||
})
|
||||
}
|
||||
repoFiles := utils.GetRequest("https://api.github.com/repos/" + c.Params("user") + "/" + c.Params("repo") + "/contents")
|
||||
bruh := repoFiles.Get("#.@pretty").Array()
|
||||
for _, item := range bruh {
|
||||
repoFilesArray = append(repoFilesArray, RepoFiles{
|
||||
Name: item.Get("path").String(),
|
||||
Path: item.Get("path").String(),
|
||||
Type: item.Get("type").String(),
|
||||
Fullname: repo.Get("full_name").String(),
|
||||
DefaultBranch: repo.Get("default_branch").String(),
|
||||
})
|
||||
}
|
||||
|
||||
var readmee string
|
||||
|
||||
err := requests.
|
||||
URL("https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + repo.Get("default_branch").String() + "/README.md").
|
||||
ToString(&readmee).
|
||||
Fetch(context.Background())
|
||||
if err != nil {
|
||||
readmee = ""
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
mightBeUnsafe := markdown.ToHTML([]byte(readmee), nil, nil)
|
||||
|
||||
// Trust Nobody
|
||||
readmeOutput := UGCPolicy().SanitizeBytes(mightBeUnsafe)
|
||||
|
||||
repoArray = append(repoArray, Repo{
|
||||
Fullname: repo.Get("full_name").String(),
|
||||
Description: repo.Get("description").String(),
|
||||
|
@ -44,6 +85,8 @@ func HandleRepo(c *fiber.Ctx) error {
|
|||
})
|
||||
|
||||
return c.Render("repo", fiber.Map{
|
||||
"repo": repoArray,
|
||||
"repo": repoArray,
|
||||
"files": repoFilesArray,
|
||||
"readme": string(readmeOutput),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/gomarkdown/markdown"
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
|
||||
"codeberg.org/Odyssium/gothub/utils"
|
||||
"codeberg.org/gothub/gothub/utils"
|
||||
|
||||
"context"
|
||||
"regexp"
|
||||
|
|
|
@ -174,6 +174,28 @@ a:hover {
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.filesList {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.filesUList {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
/* URI: /file/:user/:repo/:file */
|
||||
.filePre {
|
||||
background-color: var(--background-darker);
|
||||
color: var(--text);
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--text: #000;
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
<h1 style="color: red;">Error</h1>
|
||||
<h2>Someone pushed to production. Just kidding, that's probably not what happened. Here's the error:</h2>
|
||||
<pre class="error">{{.error}}</pre>
|
||||
<h3>Think this is a bug? <a href="https://codeberg.org/Odyssium/gothub/issues" target="_blank">Create an issue on Codeberg.</a></h3>
|
||||
<h3>Think this is a bug? <a href="https://codeberg.org/gothub/gothub/issues" target="_blank">Create an issue on Codeberg.</a></h3>
|
||||
</div>
|
||||
</main>
|
||||
</main>
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
{{ template "header" .}}
|
||||
|
||||
<main>
|
||||
{{ if .file }}
|
||||
<div class="downloadParent">
|
||||
<a href="/{{.fullname}}" class="downloadButton">Back to {{.fullname}}</a>
|
||||
</div>
|
||||
|
||||
<div class="userReadme">
|
||||
<h3>{{.name}}</h3>
|
||||
<pre class="filePre">{{ .file}}</pre>
|
||||
</div>
|
||||
<div class="downloadParent">
|
||||
<a href="/raw/{{.fullname}}/{{.branch}}/{{.name}}" class="downloadButton">Download</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</main>
|
|
@ -12,9 +12,9 @@
|
|||
<a href="/" style="text-decoration: none;" class="brand"><img src="/logo.svg" class="navbarImg" alt="GotHub" /><b class="navbarSlogan">GotHub (alpha)</b></a>
|
||||
<div class="navbarLinks">
|
||||
<a href="/explore">Explore</a>
|
||||
<a href="https://codeberg.org/Odyssium/gothub">Source code</a>
|
||||
<a href="https://codeberg.org/gothub/gothub">Source code</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -25,18 +25,30 @@
|
|||
{{ end }}
|
||||
</div>
|
||||
{{end}}
|
||||
<!-- {{ if .files}}
|
||||
{{ if .files}}
|
||||
<div class="userReadme">
|
||||
<h3>Files</h3>
|
||||
<div class="userReadmeText">
|
||||
<ul>
|
||||
<ul class="filesUList">
|
||||
{{ range $key, $value := .files}}
|
||||
<li><a href="/{{.Fullname}}/{{.Path}}">{{.Path}}</a></li>
|
||||
{{ if eq .Type "dir" }}
|
||||
<li class="filesList"><a href="#" class="filesA">{{.Path}} (directory)</a></li>
|
||||
{{ else }}
|
||||
<li class="filesList"><a href="/file/{{.Fullname}}/{{.DefaultBranch}}/{{.Path}}">{{.Path}}</a></li>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }} -->
|
||||
{{ end }}
|
||||
{{ if .readme}}
|
||||
<div class="userReadme">
|
||||
<h3>README.md</h3>
|
||||
<div class="userReadmeText">
|
||||
{{ unescape .readme}}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<h2>Repository not found</h2>
|
||||
<p>That repository doesn't exist.</p>
|
||||
|
|
読み込み中…
新しいイシューから参照