Author | Jakob Wakeling <[email protected]> |
Date | 2023-07-25 12:53:25 |
Commit | 8e4646b2a71f4f8a862be7b31ff7ff9e0e294bc4 |
Parent | 64718e1cdc44c70854777e66c08401558ff0999c |
Implement repository tree page
Diffstat
M | main.go | | | 5 | +++-- |
M | res/repo/tree.html | | | 20 | ++++++++++++++------ |
M | src/repo.go | | | 8 | ++------ |
M | src/repo/log.go | | | 25 | +++++++++++-------------- |
A | src/repo/tree.go | | | 86 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | src/util/util.go | | | 14 | ++++++++++++++ |
6 files changed, 130 insertions, 28 deletions
diff --git a/main.go b/main.go index 9e714e5..2beaf53 100644 --- a/main.go +++ b/main.go @@ -25,7 +25,6 @@ func main() { h.StrictSlash(true) h.Path("/").HandlerFunc(goit.HandleIndex) - // h.Path("/user").Methods("GET").HandlerFunc(goit.HandleUserIndex) h.Path("/user/login").Methods("GET", "POST").HandlerFunc(goit.HandleUserLogin) h.Path("/user/logout").Methods("GET", "POST").HandlerFunc(goit.HandleUserLogout) h.Path("/user/sessions").Methods("GET", "POST").HandlerFunc(goit.HandleUserSessions) @@ -41,7 +40,9 @@ func main() { h.Path("/{repo:.+(?:\\.git)$}").Methods("GET").HandlerFunc(redirectDotGit) h.Path("/{repo}").Methods("GET").HandlerFunc(repo.HandleLog) h.Path("/{repo}/log").Methods("GET").HandlerFunc(repo.HandleLog) - h.Path("/{repo}/tree").Methods("GET").HandlerFunc(goit.HandleRepoTree) + h.Path("/{repo}/log/{path:.*}").Methods("GET").HandlerFunc(repo.HandleLog) + h.Path("/{repo}/tree").Methods("GET").HandlerFunc(repo.HandleTree) + h.Path("/{repo}/tree/{path:.*}").Methods("GET").HandlerFunc(repo.HandleTree) h.Path("/{repo}/refs").Methods("GET").HandlerFunc(goit.HandleRepoRefs) h.Path("/{repo}/info/refs").Methods("GET").HandlerFunc(goit.HandleInfoRefs) h.Path("/{repo}/git-upload-pack").Methods("POST").HandlerFunc(goit.HandleUploadPack) diff --git a/res/repo/tree.html b/res/repo/tree.html index 6dc6935..714fd31 100644 --- a/res/repo/tree.html +++ b/res/repo/tree.html @@ -6,17 +6,25 @@ <table> <thead> <tr> + <td><b>Mode</b></td> <td><b>Name</b></td> <td><b>Size</b></td> + <td></td> </tr> </thead> <tbody> - {{range .Files}} - <tr> - <td>{{.Name}}</a></td> - <td>{{.Size}}</td> - </tr> - {{end}} + {{if .Files}} + {{range .Files}} + <tr> + <td>{{.Mode}}</td> + <td><a href="/{{$.Name}}/tree/{{.Name}}">{{.Name}}</a></td> + <td align="right" {{if .B}}style="padding-right: calc(2ch + 0.4em);"{{end}}>{{.Size}}</td> + <td>log blame raw download</td> + </tr> + {{end}} + {{else}} + <tr><td colspan="4">No files</td></tr> + {{end}} </tbody> </table> </main> diff --git a/src/repo.go b/src/repo.go index 28c6169..3deed7c 100644 --- a/src/repo.go +++ b/src/repo.go @@ -126,10 +126,6 @@ func HandleRepoCreate(w http.ResponseWriter, r *http.Request) { } } -func HandleRepoTree(w http.ResponseWriter, r *http.Request) { - HttpError(w, http.StatusNoContent) -} - func HandleRepoRefs(w http.ResponseWriter, r *http.Request) { reponame := mux.Vars(r)["repo"] @@ -181,8 +177,8 @@ func HandleRepoRefs(w http.ResponseWriter, r *http.Request) { Branches []bra Tags []tag }{ - "Refs", reponame, repo.Description, util.If(Conf.UsesHttps, "https://", "http://") + r.Host + r.URL.Path, "", - "", bras, tags, + "Refs", reponame, repo.Description, util.If(Conf.UsesHttps, "https://", "http://") + r.Host + "/" + repo.Name, + "", "", bras, tags, }); err != nil { log.Println("[Repo:Refs]", err.Error()) } diff --git a/src/repo/log.go b/src/repo/log.go index d2a98a1..a971568 100644 --- a/src/repo/log.go +++ b/src/repo/log.go @@ -4,7 +4,6 @@ import ( "fmt" "log" "net/http" - "strconv" "strings" "time" @@ -27,17 +26,15 @@ func HandleLog(w http.ResponseWriter, r *http.Request) { return } - var offset uint64 = 0 - if o := r.URL.Query().Get("o"); o != "" { - if i, err := strconv.ParseUint(o, 10, 64); err != nil { - goit.HttpError(w, http.StatusBadRequest) - return - } else { - offset = i - } - } - - offset += 1 + // var offset uint64 = 0 + // if o := r.URL.Query().Get("o"); o != "" { + // if i, err := strconv.ParseUint(o, 10, 64); err != nil { + // goit.HttpError(w, http.StatusBadRequest) + // return + // } else { + // offset = i + // } + // } type row struct{ Hash, Date, Message, Author, Files, Additions, Deletions string } data := struct { @@ -45,8 +42,8 @@ func HandleLog(w http.ResponseWriter, r *http.Request) { Readme, Licence string Commits []row }{ - Title: repo.Name + " - Log", Name: repo.Name, - Description: repo.Description, Url: util.If(goit.Conf.UsesHttps, "https://", "http://") + r.Host + r.URL.Path, + Title: repo.Name + " - Log", Name: repo.Name, Description: repo.Description, + Url: util.If(goit.Conf.UsesHttps, "https://", "http://") + r.Host + "/" + repo.Name, } gr, err := git.PlainOpen(goit.RepoPath(repo.Name)) diff --git a/src/repo/tree.go b/src/repo/tree.go new file mode 100644 index 0000000..e3f22e1 --- /dev/null +++ b/src/repo/tree.go @@ -0,0 +1,86 @@ +package repo + +import ( + "log" + "net/http" + "strings" + + goit "github.com/Jamozed/Goit/src" + "github.com/Jamozed/Goit/src/util" + "github.com/dustin/go-humanize" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/gorilla/mux" +) + +func HandleTree(w http.ResponseWriter, r *http.Request) { + _, uid := goit.AuthCookie(w, r, true) + + repo, err := goit.GetRepoByName(mux.Vars(r)["repo"]) + if err != nil { + goit.HttpError(w, http.StatusInternalServerError) + return + } else if repo == nil || (repo.IsPrivate && repo.OwnerId != uid) { + goit.HttpError(w, http.StatusNotFound) + return + } + + type row struct { + Mode, Name, Size string + B bool + } + data := struct { + Title, Name, Description, Url string + Readme, Licence string + Files []row + }{ + Title: repo.Name + " - Tree", Name: repo.Name, Description: repo.Description, + Url: util.If(goit.Conf.UsesHttps, "https://", "http://") + r.Host + "/" + repo.Name, + } + + gr, err := git.PlainOpen(goit.RepoPath(repo.Name)) + if err != nil { + log.Println("[/repo/tree]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + ref, err := gr.Head() + if err != nil { + log.Println("[/repo/tree]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + commit, err := gr.CommitObject(ref.Hash()) + if err != nil { + log.Println("[/repo/tree]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + iter, err := commit.Tree() + if err != nil { + log.Println("[/repo/tree]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + if err := iter.Files().ForEach(func(f *object.File) error { + size := humanize.IBytes(uint64(f.Size)) + data.Files = append(data.Files, row{ + Mode: util.ModeString(uint32(f.Mode)), Name: f.Name, Size: size, + B: util.If(strings.HasSuffix(size, " B"), true, false), + }) + + return nil + }); err != nil { + log.Println("[/repo/tree]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + if err := goit.Tmpl.ExecuteTemplate(w, "repo/tree", data); err != nil { + log.Println("[/repo/tree]", err.Error()) + } +} diff --git a/src/util/util.go b/src/util/util.go index bc3e587..0a75dd8 100644 --- a/src/util/util.go +++ b/src/util/util.go @@ -35,3 +35,17 @@ func Cookie(r *http.Request, name string) *http.Cookie { return nil } + +func ModeString(mode uint32) string { + s := "-" + s += If((mode&0b100000000) != 0, "r", "-") + s += If((mode&0b010000000) != 0, "w", "-") + s += If((mode&0b001000000) != 0, "x", "-") + s += If((mode&0b000100000) != 0, "r", "-") + s += If((mode&0b000010000) != 0, "w", "-") + s += If((mode&0b000001000) != 0, "x", "-") + s += If((mode&0b000000100) != 0, "r", "-") + s += If((mode&0b000000010) != 0, "w", "-") + s += If((mode&0b000000001) != 0, "x", "-") + return s +}