summaryrefslogtreecommitdiff
path: root/spartan.go
diff options
context:
space:
mode:
Diffstat (limited to 'spartan.go')
-rw-r--r--spartan.go102
1 files changed, 20 insertions, 82 deletions
diff --git a/spartan.go b/spartan.go
index beb001e..69db47d 100644
--- a/spartan.go
+++ b/spartan.go
@@ -1,13 +1,7 @@
package syw
import (
- "bytes"
"context"
- "mime"
- "os"
- "path"
- "path/filepath"
- "strings"
"text/template"
"tildegit.org/tjp/sliderule"
@@ -47,7 +41,8 @@ import (
// Repo: a *syw.Repository object corresponding to <repodir>/:repository
// Params: a map[string]string of the route parameters
//
-// The only exception is repo_root.gmi, which is rendered with a slice of the repo names instead.
+// The only exception is repo_root.gmi, which is rendered with an object containing a single name
+// "Repos", a slice of the string repository names.
func SpartanRouter(repodir string, overrides *template.Template) *sliderule.Router {
tmpl, err := addTemplates(geminiTemplate, overrides)
if err != nil {
@@ -56,90 +51,33 @@ func SpartanRouter(repodir string, overrides *template.Template) *sliderule.Rout
repoRouter := &sliderule.Router{}
repoRouter.Use(assignRepo(repodir))
- repoRouter.Route("/", sgmiTemplate(tmpl, "repo_home.gmi"))
- repoRouter.Route("/branches", sgmiTemplate(tmpl, "branch_list.gmi"))
- repoRouter.Route("/tags", sgmiTemplate(tmpl, "tag_list.gmi"))
- repoRouter.Route("/refs/:ref/", sgmiTemplate(tmpl, "ref.gmi"))
- repoRouter.Route("/refs/:ref/tree/*path", spartanTreePath(tmpl))
- repoRouter.Route("/diffstat/:fromref/:toref", runSpartanTemplate(tmpl, "diffstat.gmi.txt", "text/plain"))
- repoRouter.Route("/diff/:fromref/:toref", runSpartanTemplate(tmpl, "diff.gmi.txt", "text/x-diff"))
+ repoRouter.Route("/", repoRouteHandler(spartanProto, tmpl, "repo_home.gmi"))
+ repoRouter.Route("/branches", repoRouteHandler(spartanProto, tmpl, "branch_list.gmi"))
+ repoRouter.Route("/tags", repoRouteHandler(spartanProto, tmpl, "tag_list.gmi"))
+ repoRouter.Route("/refs/:ref/", repoRouteHandler(spartanProto, tmpl, "ref.gmi"))
+ repoRouter.Route("/refs/:ref/tree/*path", treePathHandler(spartanProto, tmpl, "tree.gmi"))
+ repoRouter.Route("/diffstat/:fromref/:toref", repoRouteHandler(spartanProto, tmpl, "diffstat.gmi.txt"))
+ repoRouter.Route("/diff/:fromref/:toref", repoRouteHandler(spartanProto, tmpl, "diff.gmi.txt"))
router := &sliderule.Router{}
- router.Route("/", spartanRoot(repodir, tmpl))
+ router.Route("/", rootDirHandler(spartanProto, repodir, tmpl, "repo_root.gmi"))
router.Mount("/:"+reponamekey, repoRouter)
return router
}
-func spartanRoot(repodir string, tmpl *template.Template) sliderule.Handler {
- return sliderule.HandlerFunc(func(ctx context.Context, request *sliderule.Request) *sliderule.Response {
- entries, err := os.ReadDir(repodir)
- if err != nil {
- return spartan.ServerError(err)
- }
+type spartanProtocol struct{ sliderule.ServerProtocol }
- names := []string{}
- for _, item := range entries {
- if Open(filepath.Join(repodir, item.Name())) != nil {
- names = append(names, item.Name())
- }
- }
-
- buf := &bytes.Buffer{}
- if err := tmpl.ExecuteTemplate(buf, "repo_root.gmi", names); err != nil {
- return spartan.ServerError(err)
- }
-
- return spartan.Success("text/gemini; charset=utf-8", buf)
- })
-}
-
-func spartanTreePath(tmpl *template.Template) 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 sgmiTemplate(tmpl, "tree.gmi").Handle(ctx, request)
- }
-
- repo := ctx.Value(repokey).(*Repository)
-
- body, err := repo.Blob(ctx, params["ref"], params["path"])
- if err != nil {
- return spartan.ServerError(err)
- }
-
- mediaType := ""
- ext := path.Ext(params["path"])
- if ext == ".gmi" {
- mediaType = "text/gemini; charset=utf-8"
- } else {
- mediaType = mime.TypeByExtension(ext)
- }
- if mediaType == "" {
- mediaType = "application/octet-stream"
- }
-
- return spartan.Success(mediaType, bytes.NewBuffer(body))
- })
+func (spartanProtocol) TemplateBaseData(_ context.Context, _ *sliderule.Request) map[string]any {
+ return map[string]any{}
}
-func sgmiTemplate(tmpl *template.Template, name string) sliderule.Handler {
- return runSpartanTemplate(tmpl, name, "text/gemini; charset=utf-8")
+func (spartanProtocol) TemplateRepoData(ctx context.Context, request *sliderule.Request) map[string]any {
+ return map[string]any{
+ "Ctx": ctx,
+ "Repo": ctx.Value(repokey),
+ "Params": sliderule.RouteParams(ctx),
+ }
}
-func runSpartanTemplate(tmpl *template.Template, name, mimetype string) sliderule.Handler {
- return sliderule.HandlerFunc(func(ctx context.Context, request *sliderule.Request) *sliderule.Response {
- obj := map[string]any{
- "Ctx": ctx,
- "Repo": ctx.Value(repokey),
- "Params": sliderule.RouteParams(ctx),
- }
- buf := &bytes.Buffer{}
-
- if err := tmpl.ExecuteTemplate(buf, name, obj); err != nil {
- return spartan.ServerError(err)
- }
-
- return spartan.Success(mimetype, buf)
- })
-}
+var spartanProto = spartanProtocol{spartan.ServerProtocol}