コミットを比較

...

3 コミット

作成者 SHA1 メッセージ 日付
守矢諏訪子 8742c84e47 コミット履歴( #6 2023-06-11 19:23:20 +09:00
守矢諏訪子 5bd624af13 面倒くさい… 2023-06-11 19:21:28 +09:00
守矢諏訪子 bf46a0665e CSSの枠 2023-06-11 19:21:06 +09:00
4個のファイルの変更221行の追加6行の削除

150
pages/commits.go ノーマルファイル
ファイルの表示

@ -0,0 +1,150 @@
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 := ""
if (branch != "") {
endurl = "/" + branch
if (c.Query("after") != "") {
endurl += "?after=" + url.QueryEscape(c.Query("after")) + "&branch=" + url.QueryEscape(c.Query("branch")) + "&qualified_name=" + url.QueryEscape(c.Query("qualified_name"))
} else if (c.Query("before") != "") {
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") != "") {
if (c.Query("after") != "") {
endurl = "?after=" + url.QueryEscape(c.Query("after")) + "&author=" + url.QueryEscape(c.Query("author"))
} else if (c.Query("before") != "") {
endurl = "?before=" + url.QueryEscape(c.Query("before")) + "&author=" + url.QueryEscape(c.Query("author"))
} else {
endurl = "?author=" + url.QueryEscape(c.Query("author"))
}
}
log.Println(endurl)
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,
})
}

ファイルの表示

@ -7,6 +7,7 @@
--accent: #00b7c3;
--yellow: #8B8000;
--repo-hover: #b762b7;
--border: #d76aff;
color-scheme: dark;
}
@ -26,6 +27,7 @@ body {
::-webkit-scrollbar-thumb {
border-radius: 8px;
background: var(--background);
border: 1px solid var(--border);
}
main {
@ -44,6 +46,7 @@ main {
padding: 8px;
margin-bottom: 8px;
background-color: var(--background);
border-bottom: 1px solid var(--border);
}
.navbar .item {
@ -59,6 +62,7 @@ main {
.index-gh {
background: var(--background);
border: 1px solid var(--border);
color: var(--text);
padding: 4px;
border-radius: 8px;
@ -84,6 +88,7 @@ main {
.error {
background-color: var(--background);
border: 1px solid var(--border);
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;
@ -127,6 +132,7 @@ a:hover {
.explore-card, .user-repo-card {
background-color: var(--background);
border: 1px solid var(--border);
padding: 8px;
border-radius: 4px;
margin: 8px 0 8px 0;
@ -148,6 +154,7 @@ a:hover {
.user-profile {
background-color: var(--background);
border: 1px solid var(--border);
padding: 8px;
border-radius: 4px;
margin: 8px;
@ -179,6 +186,7 @@ a:hover {
.user-bio,
.user-readme {
background-color: var(--background);
border: 1px solid var(--border);
padding: 8px;
border-radius: 4px;
margin: 8px;
@ -245,6 +253,7 @@ a:hover {
/* URI: /:user/:repo */
.button {
background-color: var(--background);
border: 1px solid var(--border);
padding: 8px;
border-radius: 4px;
margin: 8px;

ファイルの表示

@ -12,7 +12,6 @@ import (
"gitler.moe/suwako/gitlin/utils"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cache"
"github.com/gofiber/fiber/v2/middleware/compress"
"github.com/gofiber/fiber/v2/middleware/limiter"
// For debugging purposes
@ -62,9 +61,6 @@ func Serve(port string) {
},
})
app.Use(cache.New(cache.Config{
Expiration: 5 * time.Minute,
}))
// For debugging purposes
// app.Use(logger.New(logger.Config{
// Format: "[${ip}]:${port} ${status} - ${method} ${path} ${queryParams}\n",
@ -186,13 +182,14 @@ func Serve(port string) {
app.Get("/gist/:user/:gistID", pages.HandleGist)
app.Get("/download/gist/:user/:gistID/:revision", func(c *fiber.Ctx) error {
if proxying == "true" {
utils.ProxyRequest(c, "https://gist.github.com/"+c.Params("user")+"/"+c.Params("gistID")+"/archive/"+c.Params("revision")+".zip")
utils.ProxyRequest(c, "https://gist.github.com/"+c.Params("user")+"/"+c.Params("gistID")+"/archive/"+c.Params("revision")+".tar.gz")
return nil
} else {
c.Redirect("https://gist.github.com/" + c.Params("user") + "/" + c.Params("gistID") + "/archive/" + c.Params("revision") + ".zip")
c.Redirect("https://gist.github.com/" + c.Params("user") + "/" + c.Params("gistID") + "/archive/" + c.Params("revision") + ".tar.gz")
return nil
}
})
app.Get("/:user/:repo/commits/:branch?", pages.HandleCommits)
api := app.Group("/api")
v1 := api.Group("/v1")

59
views/commits.html ノーマルファイル
ファイルの表示

@ -0,0 +1,59 @@
{{ template "header" . }}
<style>
td {
padding: 16px 0;
}
</style>
<main>
<div class="user-profile">
<h1>
<a href="/{{.username}}">{{.username}}</a>
/
<a href="/{{.username}}/{{.reponame}}">{{.reponame}}</a>
</h1>
<h2>
{{if ne "" .branch}}
{{.branch}}で
{{else}}
{{.author}}さん
{{end}}のコミット
</h2>
{{if .commits}}
{{range $key, $value := .commits}}
<h3>{{$value.Date}}</h3>
<table class="user-readme-text file-table">
<tbody>
{{range $k, $v := $value.Commit}}
<tr class="file-u-list">
<td>
<a href="/{{$.username}}/{{$.reponame}}/commit/{{$v.Id}}">{{$v.Mess}}</a><br />
<a href="/{{$.username}}/{{$.reponame}}/commits?author={{$v.User}}">{{$v.User}}</a>さんは{{$value.Date}}でコミットしました
</td>
<td width="70" style="vertical-align: top;">
{{if $v.Issue}}
<a href="/{{$.username}}/{{$.reponame}}/pull/{{$v.Issue}}">#{{$v.Issue}}</a>
{{end}}
</td>
<td width="80" style="vertical-align: top;">
<a href="/{{$.username}}/{{$.reponame}}/commit/{{$v.Id}}">{{.IdShort}}</a>
</td>
</tr>
{{end}}
</tbody>
</table>
{{end}}
{{end}}
</div>
{{if .commits}}
{{if or (ne "" .prev) (ne "" .next)}}
<div class="button-parent">
{{if ne "" .next}}<a class="button" href="{{.next}}"></a>{{end}}
{{if ne "" .prev}}<a class="button" href="{{.prev}}">戻る</a>{{end}}
</div>
{{end}}
{{end}}
</main>
{{ template "footer" . }}