syw/handlers.go

87 lines
2.6 KiB
Go

package syw
import (
"bytes"
"context"
"os"
"path"
"path/filepath"
"strings"
"text/template"
"tildegit.org/tjp/sliderule"
)
const (
repokey = "syw_repo"
reponamekey = "repository"
)
func rootDirHandler(proto protocol, repodir string, tmpl *template.Template, tmplname string) sliderule.Handler {
return sliderule.HandlerFunc(func(ctx context.Context, request *sliderule.Request) *sliderule.Response {
entries, err := os.ReadDir(repodir)
if err != nil {
return proto.TemporaryServerError(err)
}
names := []string{}
for _, item := range entries {
if Open(filepath.Join(repodir, item.Name())) != nil {
names = append(names, item.Name())
}
}
data := proto.TemplateBaseData(ctx, request)
data["Repos"] = names
buf := &bytes.Buffer{}
if err := tmpl.ExecuteTemplate(buf, tmplname, data); err != nil {
return proto.TemporaryServerError(err)
}
return proto.Success(tmplname, buf)
})
}
func repoRouteHandler(proto protocol, tmpl *template.Template, tmplname string) sliderule.Handler {
return sliderule.HandlerFunc(func(ctx context.Context, request *sliderule.Request) *sliderule.Response {
data := repoTmplData(proto, ctx, request)
buf := &bytes.Buffer{}
if err := tmpl.ExecuteTemplate(buf, tmplname, data); err != nil {
return proto.TemporaryServerError(err)
}
return proto.Success(tmplname, buf)
})
}
func treePathHandler(proto protocol, tmpl *template.Template, tmplname string) sliderule.Handler {
return sliderule.HandlerFunc(func(ctx context.Context, request *sliderule.Request) *sliderule.Response {
params := sliderule.RouteParams(ctx)
if params["path"] == "" || strings.HasSuffix(params["path"], "/") {
return repoRouteHandler(proto, tmpl, tmplname).Handle(ctx, request)
}
body, err := ctx.Value(repokey).(*Repository).Blob(ctx, params["ref"], params["path"])
if err != nil {
return proto.TemporaryServerError(err)
}
return proto.Success(path.Base(params["path"]), bytes.NewBuffer(body))
})
}
func repoTmplData(proto protocol, ctx context.Context, request *sliderule.Request) map[string]any {
data := proto.TemplateBaseData(ctx, request)
for k, v := range proto.TemplateRepoData(ctx, request) {
data[k] = v
}
return data
}
func assignRepo(repodir string) sliderule.Middleware {
return func(h sliderule.Handler) sliderule.Handler {
return sliderule.HandlerFunc(func(ctx context.Context, request *sliderule.Request) *sliderule.Response {
repo := Open(filepath.Join(repodir, sliderule.RouteParams(ctx)[reponamekey]))
return h.Handle(context.WithValue(ctx, repokey, repo), request) //nolint:staticcheck
})
}
}