2023-06-11 19:23:20 +09:00
|
|
|
package pages
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"gitler.moe/suwako/gitlin/utils"
|
|
|
|
"github.com/gocolly/colly"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
Commits struct {
|
|
|
|
Date, Next, Prev string
|
|
|
|
Commit []Commit
|
|
|
|
}
|
|
|
|
Commit struct {
|
|
|
|
Mess, User, Id, IdShort, Issue, Ava string
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
func HandleCommits (c *fiber.Ctx) error {
|
|
|
|
var commitsArray []Commits
|
|
|
|
branch := ""
|
|
|
|
if strings.Count(c.Params("branch"), "")-1 > 0 {
|
|
|
|
branch = c.Params("branch")
|
|
|
|
}
|
|
|
|
repoUrl := strings.TrimSuffix(c.Params("repo"), ".git")
|
|
|
|
endurl := ""
|
2023-06-22 12:32:57 +09:00
|
|
|
if branch != "" {
|
2023-06-11 19:23:20 +09:00
|
|
|
endurl = "/" + branch
|
2023-06-22 12:32:57 +09:00
|
|
|
if c.Query("after") != "" {
|
2023-06-11 19:23:20 +09:00
|
|
|
endurl += "?after=" + url.QueryEscape(c.Query("after")) + "&branch=" + url.QueryEscape(c.Query("branch")) + "&qualified_name=" + url.QueryEscape(c.Query("qualified_name"))
|
2023-06-22 12:32:57 +09:00
|
|
|
} else if c.Query("before") != "" {
|
2023-06-11 19:23:20 +09:00
|
|
|
endurl += "?before=" + url.QueryEscape(c.Query("before")) + "&branch=" + url.QueryEscape(c.Query("branch")) + "&qualified_name=" + url.QueryEscape(c.Query("qualified_name"))
|
|
|
|
}
|
|
|
|
} else if (c.Query("author") != "") {
|
2023-06-22 12:32:57 +09:00
|
|
|
if c.Query("after") != "" {
|
2023-06-11 19:23:20 +09:00
|
|
|
endurl = "?after=" + url.QueryEscape(c.Query("after")) + "&author=" + url.QueryEscape(c.Query("author"))
|
2023-06-22 12:32:57 +09:00
|
|
|
} else if c.Query("before") != "" {
|
2023-06-11 19:23:20 +09:00
|
|
|
endurl = "?before=" + url.QueryEscape(c.Query("before")) + "&author=" + url.QueryEscape(c.Query("author"))
|
|
|
|
} else {
|
|
|
|
endurl = "?author=" + url.QueryEscape(c.Query("author"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := http.Get("https://github.com/" + c.Params("user") + "/" + repoUrl + "/commits" + endurl)
|
|
|
|
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 + "/commits" + endurl + " not found",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
Scrape := Commits{}
|
|
|
|
|
|
|
|
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.repository-content div.container-xl div.js-navigation-container", func (e *colly.HTMLElement) {
|
|
|
|
e.ForEach("div.TimelineItem div.TimelineItem-body", func (i int, el *colly.HTMLElement) {
|
|
|
|
tdate := strings.TrimPrefix(el.ChildText("h2.f5"), "Commits on ")
|
|
|
|
td, e := time.Parse("Jan 2, 2006", tdate)
|
|
|
|
if e != nil {
|
|
|
|
log.Println(e)
|
|
|
|
}
|
|
|
|
Scrape.Date = td.Format("2006年01月02日")
|
|
|
|
el.ForEach("ol.Box", func (ij int, eli *colly.HTMLElement) {
|
|
|
|
var mess, id, issue, idshort, user, ava string
|
|
|
|
var commitArray []Commit
|
|
|
|
|
|
|
|
eli.ForEach("li.Box-row", func (ijk int, elin *colly.HTMLElement) {
|
|
|
|
mess, id, issue, idshort, user, ava = "", "", "", "", "", ""
|
|
|
|
mess += elin.ChildText("div.Details p.mb-1 a")
|
|
|
|
issue = strings.ReplaceAll(elin.ChildAttr("div.Details p.mb-1 a.issue-link", "href"), "https://github.com/" + c.Params("user") + "/" + repoUrl + "/pull/", "")
|
|
|
|
id = strings.TrimPrefix(elin.ChildAttr("div.Details p.mb-1 a", "href"), "/" + c.Params("user") + "/" + repoUrl + "/commit/")
|
|
|
|
idshort = id[:7]
|
|
|
|
eli.ForEach("div.Details div.mt-1 div.f6", func (iju int, eliu *colly.HTMLElement) {
|
|
|
|
user = eliu.ChildText("a")
|
|
|
|
})
|
|
|
|
eli.ForEach("div.Details div.d-flex div.AvatarStack div.AvatarStack-body a.avatar", func (ijh int, elia *colly.HTMLElement) {
|
|
|
|
ava = elia.ChildAttr("img", "src")
|
|
|
|
if (strings.Contains(ava, "https://avatars.githubusercontent.com/in")) {
|
|
|
|
ava = strings.ReplaceAll(ava, "https://avatars.githubusercontent.com/in", "/avatar")
|
|
|
|
} else {
|
|
|
|
ava = strings.ReplaceAll(ava, "https://avatars.githubusercontent.com/u", "/avatar")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
commitArray = append(commitArray, Commit{
|
|
|
|
Mess: mess,
|
|
|
|
User: user,
|
|
|
|
Id: id,
|
|
|
|
IdShort: idshort,
|
|
|
|
Issue: issue,
|
|
|
|
Ava: ava,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
Scrape.Commit = commitArray
|
|
|
|
})
|
|
|
|
commitsArray = append(commitsArray, Scrape)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
sc.OnHTML(`div.repository-content div.container-xl div.paginate-container div.BtnGroup a:contains("Newer")`, func(e *colly.HTMLElement) {
|
|
|
|
Scrape.Next = strings.TrimPrefix(e.Attr("href"), "https://github.com")
|
|
|
|
})
|
|
|
|
|
|
|
|
sc.OnHTML(`div.repository-content div.container-xl div.paginate-container div.BtnGroup a:contains("Older")`, func(e *colly.HTMLElement) {
|
|
|
|
Scrape.Prev = strings.TrimPrefix(e.Attr("href"), "https://github.com")
|
|
|
|
})
|
|
|
|
|
|
|
|
sc.Visit("https://github.com/" + c.Params("user") + "/" + repoUrl + "/commits" + endurl)
|
|
|
|
|
|
|
|
return c.Render("commits", fiber.Map{
|
|
|
|
"title": c.Params("user") + "/" + repoUrl + "/commits" + endurl,
|
|
|
|
"username": c.Params("user"),
|
|
|
|
"reponame": repoUrl,
|
|
|
|
"branch": branch,
|
|
|
|
"author": c.Query("author"),
|
|
|
|
"ver": utils.Ver,
|
|
|
|
"ves": utils.Ves,
|
|
|
|
"prev": Scrape.Prev,
|
|
|
|
"next": Scrape.Next,
|
|
|
|
"commits": commitsArray,
|
|
|
|
})
|
|
|
|
}
|