forked from tangled.org/core
this repo has no description

appview: repo log

Changed files
+125 -66
appview
pages
templates
state
knotserver
types
+25 -3
appview/pages/pages.go
···
return p.execute("user/profile", w, params)
}
+
type RepoInfo struct {
+
Name string
+
OwnerDid string
+
OwnerHandle string
+
}
+
+
func (r RepoInfo) OwnerWithAt() string {
+
if r.OwnerHandle != "" {
+
return fmt.Sprintf("@%s", r.OwnerHandle)
+
} else {
+
return r.OwnerDid
+
}
+
}
+
type RepoIndexParams struct {
LoggedInUser *auth.User
-
Name string
-
UserDid string
-
UserHandle string
+
RepoInfo RepoInfo
types.RepoIndexResponse
}
func (p *Pages) RepoIndexPage(w io.Writer, params RepoIndexParams) error {
return p.execute("repo/index", w, params)
}
+
+
type RepoLogParams struct {
+
LoggedInUser *auth.User
+
RepoInfo RepoInfo
+
types.RepoLogResponse
+
}
+
+
func (p *Pages) RepoLog(w io.Writer, params RepoLogParams) error {
+
return p.execute("repo/log", w, params)
+
}
+4 -10
appview/pages/templates/repo/index.html
···
-
{{define "title"}} {{ or .UserHandle .UserDid }} / {{ .Name }} {{end}}
+
{{define "title"}} {{ .RepoInfo.OwnerWithAt }} / {{ .RepoInfo.Name }} {{end}}
{{define "content"}}
-
{{- $id := "" -}}
-
{{- if .UserHandle -}}
-
{{- $id = printf "@%s" .UserHandle -}}
-
{{- else -}}
-
{{- $id = .UserDid -}}
-
{{- end -}}
<h1>
-
{{ $id }} / {{ .Name }}
+
{{ .RepoInfo.OwnerWithAt }} / {{ .RepoInfo.Name }}
</h1>
<main>
<div class="log">
{{ range .Commits }}
<div>
-
<div><a href="/{{ $id }}/{{ $.Name }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
+
<div><a href="/{{ $.RepoInfo.OwnerWithAt }}/{{ $.RepoInfo.Name }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
<pre>{{ .Message }}</pre>
</div>
<div class="commit-info">
···
<div class="clone-url">
<strong>clone</strong>
<pre>
-
git clone https://tangled.sh/{{ $id }}/{{ .Name }}
+
git clone https://tangled.sh/{{ .RepoInfo.OwnerWithAt }}/{{ .RepoInfo.Name }}
</pre>
</div>
</main>
+9 -10
appview/pages/templates/repo/log.html
···
-
<html>
-
{{ template "layouts/head" . }}
+
{{define "title"}} log | {{ .RepoInfo.OwnerWithAt }} / {{ .RepoInfo.Name }} {{end}}
-
{{ template "layouts/repo-header" . }}
-
<body>
-
{{ template "layouts/nav" . }}
+
{{define "content"}}
+
+
<h1>
+
log | {{ .RepoInfo.OwnerWithAt }} / {{ .RepoInfo.Name }}
+
</h1>
<main>
-
{{ $repo := .name }}
<div class="log">
-
{{ range .commits }}
+
{{ range .Commits }}
<div>
-
<div><a href="/{{ $repo }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
+
<div><a href="/{{ $.RepoInfo.OwnerWithAt }}/{{ $.RepoInfo.Name }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
<pre>{{ .Message }}</pre>
</div>
<div class="commit-info">
···
{{ end }}
</div>
</main>
-
</body>
-
</html>
+
{{end}}
+64 -20
appview/state/repo.go
···
)
func (s *State) RepoIndex(w http.ResponseWriter, r *http.Request) {
-
ctx := r.Context()
-
repoName := chi.URLParam(r, "repo")
-
-
knot, ok := ctx.Value("knot").(string)
-
if !ok {
-
log.Println("malformed middleware")
-
w.WriteHeader(http.StatusInternalServerError)
-
return
-
}
-
-
id, ok := ctx.Value("resolvedId").(identity.Identity)
-
if !ok {
-
log.Println("malformed middleware")
-
w.WriteHeader(http.StatusInternalServerError)
+
repoName, knot, id, err := repoKnotAndId(r)
+
if err != nil {
+
log.Println("failed to get repo and knot", err)
return
}
···
}
defer resp.Body.Close()
-
// Read the response body
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Error reading response body: %v", err)
···
log.Println(resp.Status, result)
-
user := s.auth.GetUser(r)
s.pages.RepoIndexPage(w, pages.RepoIndexParams{
-
LoggedInUser: user,
-
UserDid: id.DID.String(),
-
UserHandle: id.Handle.String(),
-
Name: repoName,
+
LoggedInUser: s.auth.GetUser(r),
+
RepoInfo: pages.RepoInfo{
+
OwnerDid: id.DID.String(),
+
OwnerHandle: id.Handle.String(),
+
Name: repoName,
+
},
RepoIndexResponse: result,
})
return
}
+
+
func (s *State) RepoLog(w http.ResponseWriter, r *http.Request) {
+
repoName, knot, id, err := repoKnotAndId(r)
+
if err != nil {
+
log.Println("failed to get repo and knot", err)
+
return
+
}
+
+
ref := chi.URLParam(r, "ref")
+
resp, err := http.Get(fmt.Sprintf("http://%s/%s/%s/log/%s", knot, id.DID.String(), repoName, ref))
+
if err != nil {
+
log.Println("failed to reach knotserver", err)
+
return
+
}
+
+
body, err := io.ReadAll(resp.Body)
+
if err != nil {
+
log.Fatalf("Error reading response body: %v", err)
+
return
+
}
+
+
var result types.RepoLogResponse
+
err = json.Unmarshal(body, &result)
+
if err != nil {
+
log.Println("failed to parse json response", err)
+
return
+
}
+
+
s.pages.RepoLog(w, pages.RepoLogParams{
+
LoggedInUser: s.auth.GetUser(r),
+
RepoInfo: pages.RepoInfo{
+
OwnerDid: id.DID.String(),
+
OwnerHandle: id.Handle.String(),
+
Name: repoName,
+
},
+
RepoLogResponse: result,
+
})
+
return
+
}
+
+
func repoKnotAndId(r *http.Request) (string, string, identity.Identity, error) {
+
repoName := chi.URLParam(r, "repo")
+
knot, ok := r.Context().Value("knot").(string)
+
if !ok {
+
log.Println("malformed middleware")
+
return "", "", identity.Identity{}, fmt.Errorf("malformed middleware")
+
}
+
id, ok := r.Context().Value("resolvedId").(identity.Identity)
+
if !ok {
+
log.Println("malformed middleware")
+
return "", "", identity.Identity{}, fmt.Errorf("malformed middleware")
+
}
+
+
return repoName, knot, id, nil
+
}
-14
appview/state/signer.go
···
return s.client.Do(req)
}
-
-
func (s *SignedClient) RepoIndex(did, repo string) (*http.Response, error) {
-
const (
-
Method = "GET"
-
)
-
endpoint := fmt.Sprint("/%s/%s", did, repo)
-
-
req, err := s.newRequest(Method, endpoint, nil)
-
if err != nil {
-
return nil, err
-
}
-
-
return s.client.Do(req)
-
}
+3
appview/state/state.go
···
r.Get("/", s.ProfilePage)
r.With(ResolveRepoKnot(s)).Route("/{repo}", func(r chi.Router) {
r.Get("/", s.RepoIndex)
+
r.Get("/log/{ref}", s.RepoLog)
+
// These routes get proxied to the knot
r.Get("/info/refs", s.InfoRefs)
r.Post("/git-upload-pack", s.UploadPack)
+
})
})
+10 -9
knotserver/routes.go
···
commits = commits[start:end]
}
-
data := make(map[string]interface{})
-
data["commits"] = commits
-
data["ref"] = ref
-
data["desc"] = getDescription(path)
-
data["log"] = true
-
data["total"] = total
-
data["page"] = page
-
data["per_page"] = pageSize
+
resp := types.RepoLogResponse{
+
Commits: commits,
+
Ref: ref,
+
Description: getDescription(path),
+
Log: true,
+
Total: total,
+
Page: page,
+
PerPage: pageSize,
+
}
-
writeJSON(w, data)
+
writeJSON(w, resp)
return
}
+10
types/repo.go
···
Commits []*object.Commit `json:"commits,omitempty"`
Description string `json:"description,omitempty"`
}
+
+
type RepoLogResponse struct {
+
Commits []*object.Commit `json:"commits,omitempty"`
+
Ref string `json:"ref,omitempty"`
+
Description string `json:"description,omitempty"`
+
Log bool `json:"log,omitempty"`
+
Total int `json:"total,omitempty"`
+
Page int `json:"page,omitempty"`
+
PerPage int `json:"per_page,omitempty"`
+
}