summaryrefslogtreecommitdiff
path: root/handlers.go
blob: 4b71b28ee64b2530552a95fabe9d6bb5d32dde51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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
		})
	}
}