From b0318e1c752de8e310753aff5f7d4977a7f5b6cf Mon Sep 17 00:00:00 2001 From: Arya Kiran Date: Thu, 16 Mar 2023 14:58:53 +0530 Subject: [PATCH] Add support for viewing directories --- pages/dirview.go | 104 ++++++++++++++++++++++++++++++++++++++++++++++ pages/fileview.go | 1 + serve/serve.go | 1 + views/dir.html | 44 ++++++++++++++++++++ views/repo.html | 2 +- 5 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 pages/dirview.go create mode 100644 views/dir.html diff --git a/pages/dirview.go b/pages/dirview.go new file mode 100644 index 0000000..d1fdbf1 --- /dev/null +++ b/pages/dirview.go @@ -0,0 +1,104 @@ +package pages + +import ( + "codeberg.org/gothub/gothub/utils" + "context" + "github.com/carlmjohnson/requests" + "github.com/gocolly/colly" + "github.com/gofiber/fiber/v2" + "github.com/gomarkdown/markdown" + "log" + "net/http" + "os" +) + +type Dir struct { + Readme string + Fullname string + DirName string + Branch string +} + +type DirFiles struct { + Name string + Path string + Type string + Branch string + Fullname string + DirName string +} + +func DirView(c *fiber.Ctx) error { + var dirArray []Dir + var dirFilesArray []DirFiles + + resp, statusErr := http.Get("https://github.com/" + c.Params("user") + "/" + c.Params("repo") + "/tree/" + c.Params("branch") + "/" + c.Params("+")) + if statusErr != nil { + log.Println(statusErr) + } + if resp.StatusCode == 404 { + // I need a better way to do this + return c.Status(404).Render("error", fiber.Map{ + "title": "Error", + "error": "Directory" + c.Params("+") + "not found", + }) + } + + // Scraping + Scrape := Dir{} + Scrape.Fullname = c.Params("user") + "/" + c.Params("repo") + Scrape.DirName = c.Params("+") + Scrape.Branch = c.Params("branch") + + UserAgent, ok := os.LookupEnv("GOTHUB_USER_AGENT") + if !ok { + UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" + } + + sc := colly.NewCollector(colly.AllowedDomains("github.com"), colly.UserAgent(UserAgent)) + sc.OnHTML("div#readme", func(e *colly.HTMLElement) { + Scrape.Readme = e.ChildText("a[href*='#readme']") + }) + sc.OnHTML("div.js-details-container div.Details-content--hidden-not-important", func(e *colly.HTMLElement) { + e.ForEach("div.js-navigation-item", func(i int, el *colly.HTMLElement) { + var FileType string + if el.ChildAttr("div.flex-shrink-0 svg", "aria-label") == "Directory" { + FileType = "dir" + } else { + FileType = "file" + } + dirFilesArray = append(dirFilesArray, DirFiles{ + Name: el.ChildText("div.flex-auto span.d-block a.js-navigation-open"), + Path: el.ChildText("div.flex-auto span.d-block a.js-navigation-open"), + Type: FileType, + Fullname: Scrape.Fullname, + DirName: Scrape.DirName, + Branch: Scrape.Branch, + }) + }) + }) + sc.Visit("https://github.com/" + c.Params("user") + "/" + c.Params("repo") + "/tree/" + c.Params("branch") + "/" + c.Params("+")) + // Add scrape-based info to dirArray + dirArray = append(dirArray, Scrape) + + // README + var readmee string + err := requests. + URL("https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + c.Params("branch") + "/" + c.Params("+") + "/" + Scrape.Readme). + ToString(&readmee). + Fetch(context.Background()) + if err != nil { + readmee = "" + log.Println(err) + } + mightBeUnsafe := markdown.ToHTML([]byte(readmee), nil, nil) + // Trust Nobody + readmeOutput := utils.UGCPolicy().SanitizeBytes(mightBeUnsafe) + + return c.Render("dir", fiber.Map{ + "title": "Directory " + c.Params("+") + " | " + c.Params("user") + "/" + c.Params("repo"), + "dir": dirArray, + "files": dirFilesArray, + "readme": string(readmeOutput), + }) +} diff --git a/pages/fileview.go b/pages/fileview.go index b3ec43d..5d48b2e 100644 --- a/pages/fileview.go +++ b/pages/fileview.go @@ -56,6 +56,7 @@ func FileView(c *fiber.Ctx) error { writer.Flush() cssw.Flush() return c.Render("file", fiber.Map{ + "title": "File " + c.Params("+") + " | " + c.Params("user") + "/" + c.Params("repo"), "file": template.HTML(buf.String()), "css": template.CSS(cssbuf.String()), "fullname": c.Params("user") + "/" + c.Params("repo"), diff --git a/serve/serve.go b/serve/serve.go index 7f0cd04..d2553d6 100644 --- a/serve/serve.go +++ b/serve/serve.go @@ -107,6 +107,7 @@ func Serve() { }) app.Get("/:user/:repo", pages.HandleRepo) app.Get("/:user/:repo/blob/:branch/+", pages.FileView) + app.Get("/:user/:repo/tree/:branch/+", pages.DirView) app.Get("/download/:user/:repo/:branch", func(c *fiber.Ctx) error { utils.ProxyRequest(c, "https://github.com/"+c.Params("user")+"/"+c.Params("repo")+"/archive/"+c.Params("branch")+".zip") return nil diff --git a/views/dir.html b/views/dir.html new file mode 100644 index 0000000..b18523e --- /dev/null +++ b/views/dir.html @@ -0,0 +1,44 @@ +{{ template "header" .}} + +
+ {{ if .dir }} {{ range $key, $value := .dir}} + + +
+

{{.Fullname}} | {{.DirName}}

+
+ {{end}} {{ if .files}} +
+

Files

+
+ +
+
+ {{ end }} {{ if .readme}} +
+ {{ if .dir }} {{ range $key, $value := .dir }} +

{{.Readme}}

+ {{end}} {{end}} +
{{ unescape .readme}}
+
+ {{ end }} {{ else }} +

Directory not found

+

That directory doesn't exist.

+ {{ end }} +
+{{ template "footer" .}} diff --git a/views/repo.html b/views/repo.html index af1624b..b4fb0aa 100644 --- a/views/repo.html +++ b/views/repo.html @@ -36,7 +36,7 @@