diff options
Diffstat (limited to 'handlers.go')
-rw-r--r-- | handlers.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/handlers.go b/handlers.go new file mode 100644 index 0000000..4b71b28 --- /dev/null +++ b/handlers.go @@ -0,0 +1,86 @@ +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 + }) + } +} |