all repos

mugit @ 01d1381

🐮 git server that your cow will love

mugit/internal/handlers/handlers.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
ui: format time, 3 months ago
1
package handlers
2
3
import (
4
	"html/template"
5
	"net/http"
6
	"path/filepath"
7
	"strings"
8
	"time"
9
10
	"olexsmir.xyz/mugit/internal/cache"
11
	"olexsmir.xyz/mugit/internal/config"
12
	"olexsmir.xyz/mugit/internal/git"
13
	"olexsmir.xyz/mugit/internal/humanize"
14
	"olexsmir.xyz/mugit/web"
15
)
16
17
type handlers struct {
18
	c *config.Config
19
	t *template.Template
20
21
	repoListCache cache.Cacher[[]repoList]
22
	readmeCache   cache.Cacher[template.HTML]
23
	diffCache     cache.Cacher[*git.NiceDiff]
24
}
25
26
func InitRoutes(cfg *config.Config) http.Handler {
27
	tmpls := template.Must(template.New("").
28
		Funcs(templateFuncs).
29
		ParseFS(web.TemplatesFS, "*"))
30
	h := handlers{
31
		cfg, tmpls,
32
		cache.NewInMemory[[]repoList](cfg.Cache.HomePage),
33
		cache.NewInMemory[template.HTML](cfg.Cache.Readme),
34
		cache.NewInMemory[*git.NiceDiff](cfg.Cache.Diff),
35
	}
36
37
	mux := http.NewServeMux()
38
	mux.HandleFunc("GET /", h.indexHandler)
39
	mux.HandleFunc("GET /index.xml", h.indexFeedHandler)
40
	mux.HandleFunc("GET /static/{file}", h.serveStaticHandler)
41
	mux.HandleFunc("GET /{name}", h.multiplex)
42
	mux.HandleFunc("POST /{name}", h.multiplex)
43
	mux.HandleFunc("GET /{name}/{rest...}", h.multiplex)
44
	mux.HandleFunc("POST /{name}/{rest...}", h.multiplex)
45
	mux.HandleFunc("GET /{name}/feed/{$}", h.repoFeedHandler)
46
	mux.HandleFunc("GET /{name}/tree/{ref}/{rest...}", h.repoTreeHandler)
47
	mux.HandleFunc("GET /{name}/blob/{ref}/{rest...}", h.fileContentsHandler)
48
	mux.HandleFunc("GET /{name}/log/{ref}", h.logHandler)
49
	mux.HandleFunc("GET /{name}/commit/{ref}", h.commitHandler)
50
	mux.HandleFunc("GET /{name}/refs/{$}", h.refsHandler)
51
	mux.HandleFunc("GET /{name}/archive/{ref}", h.archiveHandler)
52
53
	handler := h.recoverMiddleware(mux)
54
	return h.loggingMiddleware(handler)
55
}
56
57
func (h *handlers) serveStaticHandler(w http.ResponseWriter, r *http.Request) {
58
	f := filepath.Clean(r.PathValue("file"))
59
	http.ServeFileFS(w, r, web.StaticFS, f)
60
}
61
62
var templateFuncs = template.FuncMap{
63
	"humanizeRelTime": func(t time.Time) string { return humanize.Time(t) },
64
	"humanizeTime":    func(t time.Time) string { return t.Format("2006-01-02 15:04:05 MST") },
65
	"commitSummary": func(s string) string {
66
		before, after, found := strings.Cut(s, "\n")
67
		first := strings.TrimSuffix(before, "\r")
68
		if !found {
69
			return first
70
		}
71
72
		if strings.Contains(after, "\n") {
73
			return first + "..."
74
		}
75
76
		return first
77
	},
78
}