diff --git a/pages/wiki.go b/pages/wiki.go new file mode 100644 index 0000000..509e2ba --- /dev/null +++ b/pages/wiki.go @@ -0,0 +1,87 @@ +package pages + +import ( + "codeberg.org/gothub/gothub/utils" + "github.com/gocolly/colly" + "github.com/gofiber/fiber/v2" + "log" + "net/http" + "os" + "regexp" + "strings" +) + +type Wiki struct { + RepoUser string + RepoName string + Title string + LastEdit string + LastEditor string + RevisionNum string + PageNum string + PageContent string + Sidebar []Sidebar +} +type Sidebar struct { + Name string + Link string +} + +func WikiView(c *fiber.Ctx) error { + var wikiArray []Wiki + + resp, statusErr := http.Get("https://github.com/" + c.Params("user") + "/" + c.Params("repo") + "/wiki/" + c.Params("page")) + 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": "Wiki" + c.Params("page") + "not found", + }) + } + + // Scraping + Scrape := Wiki{} + + 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#repository-container-header", func(e *colly.HTMLElement) { + Scrape.RepoUser = e.ChildText("span.author a") + Scrape.RepoName = e.ChildText("strong a") + }) + sc.OnHTML("div#wiki-wrapper", func(e *colly.HTMLElement) { + Scrape.Title = e.ChildText("div.d-flex h1") + Scrape.LastEdit = e.ChildText("div.gh-header-meta relative-time") + re := regexp.MustCompile(`\ edited.*`) + Scrape.LastEditor = re.ReplaceAllString(strings.Replace(e.ChildText("div.gh-header-meta"), "\n", "", -1), "${1}") + Scrape.RevisionNum = strings.TrimSuffix(e.ChildText("a.Link--muted"), " revisions") + }) + sc.OnHTML("div.wiki-pages-box div.Box--condensed", func(e *colly.HTMLElement) { + Scrape.PageNum = e.ChildText("span.Counter--primary") + e.ForEach("ul.list-style-none li.Box-row", func(i int, el *colly.HTMLElement) { + Scrape.Sidebar = append(Scrape.Sidebar, Sidebar{ + Name: el.ChildText("summary span a.Truncate-text"), + Link: el.ChildAttr("summary span a.Truncate-text", "href"), + }) + }) + }) + sc.OnHTML("div#wiki-body > div.markdown-body", func(e *colly.HTMLElement) { + Content, _ := e.DOM.Html() + Scrape.PageContent = strings.Replace(strings.Replace(strings.Replace(strings.Replace(string(utils.UGCPolicy().SanitizeBytes([]byte(Content))), "https://github.com", "", -1), "user-content-", "", -1), "https://camo.githubusercontent.com", "/camo", -1), "https://raw.githubusercontent.com", "/raw", -1) + + }) + sc.Visit("https://github.com/" + c.Params("user") + "/" + c.Params("repo") + "/wiki/" + c.Params("page")) + // Add scrape-based info to wikiArray + wikiArray = append(wikiArray, Scrape) + + return c.Render("wiki", fiber.Map{ + "title": "Wiki page " + c.Params("page") + " | " + c.Params("user") + "/" + c.Params("repo"), + "wiki": wikiArray, + }) +} diff --git a/public/css/global.css b/public/css/global.css index b01effb..88b4889 100644 --- a/public/css/global.css +++ b/public/css/global.css @@ -6,12 +6,14 @@ --secondary-background: #353535; --background-darker: #151515; --accent: #00b7c3; - --yellow: #8B8000; + --yellow: #8b8000; color-scheme: dark; } body { - font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, + helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, + sans-serif; color: var(--text); background-color: var(--background-darker); transition: ease-in-out 0.25s; @@ -32,6 +34,20 @@ main { margin: 0 24vw; } +.margin-ow { + margin: 0 12vw; +} + +pre { + overflow: scroll; + background: var(--secondary-background); + border-radius: 4px; + padding: 4px; +} + +#wrap { + display: flex; +} .navbar { display: flex; align-items: center; @@ -73,7 +89,9 @@ main { background-color: var(--background); padding: 8px; border-radius: 4px; - font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, + helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, + sans-serif; color: var(--text); } @@ -95,7 +113,9 @@ a:hover { background-color: var(--yellow); padding: 8px; border-radius: 4px; - font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, + helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, + sans-serif; color: var(--text); } @@ -111,7 +131,8 @@ a:hover { /* URI: /explore */ -.explore-card, .user-repo-card { +.explore-card, +.user-repo-card { background-color: var(--background); padding: 8px; border-radius: 4px; @@ -125,7 +146,8 @@ a:hover { transition: ease-in-out 0.25s; } -.explore-card:hover, .user-repo-card:hover { +.explore-card:hover, +.user-repo-card:hover { background-color: var(--secondary-background); color: var(--text); } @@ -147,6 +169,7 @@ a:hover { margin: 4px; word-wrap: nowrap; text-overflow: ellipsis; + overflow-wrap: anywhere; } .user-profile h2 { @@ -266,6 +289,23 @@ a:hover { background-color: var(--secondary-background); } +/* Overwrite */ + +.no-margin { + margin: 0; +} + +.no-padding { + padding: 0; +} + +.float-right { + float: right; + display: grid; + flex: none; + align-self: flex-start; +} + @media screen and (prefers-color-scheme: light) { :root { --text: #000; @@ -293,6 +333,16 @@ a:hover { margin: 8px; } + #wrap { + display: flex; + flex-direction: column; + } + + .float-right { + float: none; + display: inline-grid; + } + .navbar-slogan { display: none; } @@ -312,5 +362,5 @@ a:hover { } } .cl { - padding-left: 8px + padding-left: 8px; } diff --git a/serve/serve.go b/serve/serve.go index f71d6f0..92309fc 100644 --- a/serve/serve.go +++ b/serve/serve.go @@ -152,6 +152,11 @@ func Serve(port string) { }) app.Get("/:user/:repo/blob/:branch/+", pages.FileView) app.Get("/:user/:repo/tree/:branch/+", pages.DirView) + app.Get("/:user/:repo/wiki", func(c *fiber.Ctx) error { + c.Redirect("/" + c.Params("user") + "/" + c.Params("repo") + "/wiki/Home") + return nil + }) + app.Get("/:user/:repo/wiki/:page", pages.WikiView) app.Get("/:user/:repo/tree/:branch", pages.HandleRepo) app.Get("/:user/:repo/archive/:branch", func(c *fiber.Ctx) error { if proxying == "true" { diff --git a/views/wiki.html b/views/wiki.html new file mode 100644 index 0000000..5e60e22 --- /dev/null +++ b/views/wiki.html @@ -0,0 +1,34 @@ +{{ template "header" .}} + + +
+ {{ if .wiki }} {{ range $key, $value := .wiki}} +
+
+

{{.Title}}

+

{{.RepoUser}}/{{.RepoName}}

+

+ {{.LastEditor}} edited this page on {{.LastEdit}} ยท {{.RevisionNum}} revisions +

+
+
+ {{ unescape .PageContent }} +
+
+
+

{{.PageNum}} pages

+
+ {{ range $key, $value := .Sidebar }} +
+

{{.Name}}

+ {{end}} +
+
+
+ {{ end }} + {{ else }} +

Wiki not found

+

That wiki doesn't exist.

+ {{ end }} +
+{{ template "footer" .}}