diff --git a/pages/branches.go b/pages/branches.go new file mode 100644 index 0000000..2eed7dc --- /dev/null +++ b/pages/branches.go @@ -0,0 +1,125 @@ +package pages + +import ( + "log" + "net/http" + "os" + "strings" + "time" + + "gitler.moe/suwako/gitlin/utils" + "github.com/gocolly/colly" + "github.com/gofiber/fiber/v2" +) + +type ( + BranchCat struct { + Id, Name string + Branch []Branch + } + CommitDiff struct { + Count, Width string + } + Branch struct { + Name, LastCommit, Username, Issue, Status, Activity, Compare string + CommitsAhead, CommitsBehind CommitDiff + } +) + +func HandleBranches (c *fiber.Ctx) error { + var branchesArray []BranchCat + cat := "/all" + if c.Params("cat") != "" { + cat = "/" + c.Params("cat") + } + + Scrape := BranchCat{} + + repoUrl := strings.TrimSuffix(c.Params("repo"), ".git") + resp, err := http.Get("https://github.com/" + c.Params("user") + "/" + repoUrl + "/branches" + cat) + if err != nil { + log.Println(err) + } + if resp.StatusCode == 404 { + return c.Status(404).Render("error", fiber.Map { + "title": "Error", + "ver": utils.Ver, + "ves": utils.Ves, + "error": "Repository " + c.Params("user") + "/" + repoUrl + "/branches" + cat + "not found", + }) + } + + ua, ok := os.LookupEnv("GITLIN_USER_AGENT") + if !ok { + ua = "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(ua)) + sc.Limit(&colly.LimitRule { + DomainGlob: "github.githubassets.com/*", + Delay: 30 * time.Second, + RandomDelay: 30 * time.Second, + }) + sc.OnRequest(func(r *colly.Request) { + r.Headers.Set("Cache-Control", "no-cache, no-store, must-revalidate") + r.Headers.Set("Pragma", "no-cache") + r.Headers.Set("Expires", "0") + }) + + sc.OnHTML(`div[data-target="branch-filter.result"]`, func (e *colly.HTMLElement) { + var branchArray []Branch + e.ForEach("div.Box--condensed", func (i int, el *colly.HTMLElement) { + Scrape.Name = el.ChildText("div.Box-header .Box-title") + Scrape.Id = strings.ToLower(strings.TrimSuffix(Scrape.Name, " ")) + var name, lcom, uname, issue, status, activity, compare string + var cahead, cbehind CommitDiff + el.ForEach("ul li.position-relative branch-filter-item.Details", func (ij int, elc *colly.HTMLElement) { + name = elc.ChildText("div.col-12 a.branch-name") + tdate := elc.ChildText("div.col-12 span.css-truncate-target relative-time") + td, e := time.Parse("Jan 2, 2006 16:09", tdate) + if e != nil { + log.Println(e) + } + lcom = td.Format("2006年01月02日 16:09") + uname = elc.ChildText("div.col-12 span.css-truncate-target a.Link--muted") + elc.ForEach("div.col-md-6 div.col-md-12 div div div.count-half", func (ijk int, elcb *colly.HTMLElement) { + cbehind.Count = elcb.ChildText("count-behind") + cbehind.Width = strings.ReplaceAll(elcb.ChildAttr("div.bar-behind", "style"), "width:", "") + cahead.Count = elcb.ChildText("count-after") + cahead.Width = strings.ReplaceAll(elcb.ChildAttr("div.bar-after", "style"), "width:", "") + }) + issue = strings.TrimPrefix(elc.ChildText(`div.col-md-6 div.Details-content--shown div.text-right a[data-hovercard-type="pull_request"]`), "#") + status = strings.TrimPrefix(elc.ChildAttr("div.col-md-6 div.Details-content--shown div.text-right span.State", "title"), "Status: ") + activity = elc.ChildAttr("div.col-md-6 div.Details-content--shown a.tooltipped", "href") + compare = elc.ChildAttr("div.col-md-6 div.Details-content--shown a.test-compare-link", "href") + }) + + branchArray = append(branchArray, Branch { + Name: name, + LastCommit: lcom, + Username: uname, + CommitsAhead: cahead, + CommitsBehind: cbehind, + Issue: issue, + Status: status, + Activity: activity, + Compare: compare, + }) + }) + Scrape.Branch = branchArray + branchesArray = append(branchesArray, Scrape) + }) + + sc.Visit("https://github.com/" + c.Params("user") + "/" + repoUrl + "/branches" + cat) + + return c.Render("branches", fiber.Map { + "title": c.Params("user") + "/" + repoUrl + "/branches" + cat, + "username": c.Params("user"), + "reponame": repoUrl, + "ver": utils.Ver, + "ves": utils.Ves, + "branches": branchesArray, + }) + + return nil +} diff --git a/public/css/global.css b/public/css/global.css index 451090f..60b10c2 100644 --- a/public/css/global.css +++ b/public/css/global.css @@ -348,3 +348,11 @@ a:hover { align-items: inherit; flex-direction: inherit; } + +.count-half { + position: relative; + float: left; + width: 90px; + padding-bottom: 4px; + text-align: right; +} diff --git a/serve/serve.go b/serve/serve.go index 71700fd..54619ea 100644 --- a/serve/serve.go +++ b/serve/serve.go @@ -204,6 +204,7 @@ func Serve(port string) { } }) app.Get("/:user/:repo/commits/:branch?", pages.HandleCommits) + app.Get("/:user/:repo/branches/:cat?", pages.HandleBranches) api := app.Group("/api") v1 := api.Group("/v1") diff --git a/views/branches.html b/views/branches.html new file mode 100644 index 0000000..3ad02cc --- /dev/null +++ b/views/branches.html @@ -0,0 +1,53 @@ +{{ template "header" . }} + +
+
+

+ {{.username}} + / + {{.reponame}} +

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

{{$value.Name}}

+
+ 詳細 + アクティブ + 中止 + ずべて +
+ + + {{range $k, $v := $value.Branch}} + + + + + + {{end}} + {{if ne "default" $value.Id}} + + + + {{end}} + +
+ {{$v.Name}}, + {{$v.Username}} @ {{$v.LastCommit}} + +
+ {{$value.CommitsBehind.Count}} + {{$value.CommitsAhead.Count}} +
+
+ {{if $value.Issue}}{{$value.Issue}}{{end}} + {{if $value.Compare}}比較{{end}} + {{if $value.Status}}{{$value.Status}}{{end}} +
+ 他の{{$value.Id}}ブランチを表示 +
+ {{end}} +
+
+ +{{ template "footer" . }} diff --git a/views/repo.html b/views/repo.html index 4af9010..5828f8e 100644 --- a/views/repo.html +++ b/views/repo.html @@ -3,6 +3,7 @@
{{ if .repo }} {{ range $key, $value := .repo}}
+ ブランチ ダウンロード (tar.gz) GitHubで確認