gitlin/pages/repo.go

133 行
4.4 KiB
Go
Raw 通常表示 履歴

package pages
import (
2022-12-01 02:47:59 +09:00
"codeberg.org/gothub/gothub/utils"
2023-02-14 23:54:33 +09:00
"context"
"github.com/carlmjohnson/requests"
2023-02-14 23:54:33 +09:00
"github.com/gocolly/colly"
"github.com/gofiber/fiber/v2"
"github.com/gomarkdown/markdown"
2023-02-14 23:54:33 +09:00
"log"
"net/http"
"os"
2023-03-16 18:55:17 +09:00
"strings"
)
type Repo struct {
Fullname string
Description string
Parent string
2023-02-14 23:54:33 +09:00
Stars string
Forks string
Watchers string
2023-02-15 00:21:44 +09:00
Language []string
License string
DefaultBranch string
2023-02-14 23:54:33 +09:00
Readme string
2023-03-16 18:55:17 +09:00
Link string
Tags []string
}
type RepoFiles struct {
Name string
Path string
Type string
Fullname string
DefaultBranch string
}
func HandleRepo(c *fiber.Ctx) error {
var repoArray []Repo
var repoFilesArray []RepoFiles
2023-02-14 23:54:33 +09:00
resp, statusErr := http.Get("https://github.com/" + c.Params("user") + "/" + c.Params("repo"))
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": "Repository " + c.Params("user") + "/" + c.Params("repo") + " not found",
})
}
2023-02-14 23:54:33 +09:00
// Scraping
2023-02-15 00:21:44 +09:00
Scrape := Repo{}
2023-02-14 23:54:33 +09:00
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"
}
2023-02-14 23:54:33 +09:00
sc := colly.NewCollector(colly.AllowedDomains("github.com"), colly.UserAgent(UserAgent))
sc.OnHTML("div.Layout-sidebar", func(e *colly.HTMLElement) {
Scrape.Fullname = c.Params("user") + "/" + c.Params("repo")
Scrape.Description = e.ChildText("p.f4")
Scrape.Stars = e.ChildText("a[href*='/" + c.Params("user") + "/" + c.Params("repo") + "/stargazers' i] strong")
Scrape.Watchers = e.ChildText("a[href*='/" + c.Params("user") + "/" + c.Params("repo") + "/watchers' i] strong")
2023-03-16 18:55:17 +09:00
Scrape.Forks = e.ChildText("a[href*='/" + c.Params("user") + "/" + c.Params("repo") + "/forks' i] strong")
Scrape.Link = e.ChildAttr("span.css-truncate a.text-bold", "href")
2023-02-14 23:54:33 +09:00
Scrape.License = e.ChildText("a[data-analytics-event*='{\"category\":\"Repository Overview\",\"action\":\"click\",\"label\":\"location:sidebar;file:license\"}']")
2023-03-16 18:55:17 +09:00
e.ForEach("a.topic-tag", func(i int, el *colly.HTMLElement) {
Scrape.Tags = append(Scrape.Tags, strings.TrimPrefix(el.Attr("data-octo-dimensions"), "topic:"))
})
2023-02-14 23:54:33 +09:00
})
sc.OnHTML("div#readme", func(e *colly.HTMLElement) {
Scrape.Readme = e.ChildText("a[href*='#readme']")
})
2023-02-15 00:21:44 +09:00
sc.OnHTML("div.BorderGrid-cell ul.list-style-none", func(e *colly.HTMLElement) {
e.ForEach("li.d-inline .d-inline-flex", func(i int, el *colly.HTMLElement) {
Scrape.Language = append(Scrape.Language, el.ChildText("span.text-bold")+" "+el.ChildText("span:contains('%')"))
})
})
2023-02-14 23:54:33 +09:00
sc.OnHTML("div#repository-container-header", func(e *colly.HTMLElement) {
Scrape.Parent = e.ChildText("span.text-small a")
})
sc.OnHTML("summary[title*='Switch branches or tags']", func(e *colly.HTMLElement) {
Scrape.DefaultBranch = e.ChildText("span.css-truncate-target")
})
2023-02-15 21:32:48 +09:00
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"
}
repoFilesArray = append(repoFilesArray, RepoFiles{
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,
DefaultBranch: Scrape.DefaultBranch,
})
})
})
2023-02-14 23:54:33 +09:00
sc.Visit("https://github.com/" + c.Params("user") + "/" + c.Params("repo") + "/")
// Add scrape-based info to repoArray
repoArray = append(repoArray, Scrape)
// README
var readmee string
err := requests.
2023-02-14 23:54:33 +09:00
URL("https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + Scrape.DefaultBranch + "/" + Scrape.Readme).
ToString(&readmee).
Fetch(context.Background())
if err != nil {
readmee = ""
log.Println(err)
}
mightBeUnsafe := markdown.ToHTML([]byte(readmee), nil, nil)
// Trust Nobody
2023-02-13 18:25:39 +09:00
readmeOutput := utils.UGCPolicy().SanitizeBytes(mightBeUnsafe)
return c.Render("repo", fiber.Map{
"title": "Repository " + c.Params("user") + "/" + c.Params("repo"),
"repo": repoArray,
"files": repoFilesArray,
"readme": string(readmeOutput),
})
}