routes/template.go (view raw)
1package routes
2
3import (
4 "bytes"
5 "html/template"
6 "io"
7 "log"
8 "net/http"
9 "path/filepath"
10 "strings"
11
12 "git.icyphox.sh/legit/git"
13)
14
15func (d *deps) Write404(w http.ResponseWriter) {
16 tpath := filepath.Join(d.c.Dirs.Templates, "*")
17 t := template.Must(template.ParseGlob(tpath))
18 w.WriteHeader(404)
19 if err := t.ExecuteTemplate(w, "404", nil); err != nil {
20 log.Printf("404 template: %s", err)
21 }
22}
23
24func (d *deps) Write500(w http.ResponseWriter) {
25 tpath := filepath.Join(d.c.Dirs.Templates, "*")
26 t := template.Must(template.ParseGlob(tpath))
27 w.WriteHeader(500)
28 if err := t.ExecuteTemplate(w, "500", nil); err != nil {
29 log.Printf("500 template: %s", err)
30 }
31}
32
33func (d *deps) listFiles(files []git.NiceTree, data map[string]any, w http.ResponseWriter) {
34 tpath := filepath.Join(d.c.Dirs.Templates, "*")
35 t := template.Must(template.ParseGlob(tpath))
36
37 data["files"] = files
38 data["meta"] = d.c.Meta
39
40 if err := t.ExecuteTemplate(w, "tree", data); err != nil {
41 log.Println(err)
42 return
43 }
44}
45
46func countLines(r io.Reader) (int, error) {
47 buf := make([]byte, 32*1024)
48 bufLen := 0
49 count := 0
50 nl := []byte{'\n'}
51
52 for {
53 c, err := r.Read(buf)
54 if c > 0 {
55 bufLen += c
56 }
57 count += bytes.Count(buf[:c], nl)
58
59 switch {
60 case err == io.EOF:
61 /* handle last line not having a newline at the end */
62 if bufLen >= 1 && buf[(bufLen-1)%(32*1024)] != '\n' {
63 count++
64 }
65 return count, nil
66 case err != nil:
67 return 0, err
68 }
69 }
70}
71
72func (d *deps) showFile(content string, data map[string]any, w http.ResponseWriter) {
73 tpath := filepath.Join(d.c.Dirs.Templates, "*")
74 t := template.Must(template.ParseGlob(tpath))
75
76 lc, err := countLines(strings.NewReader(content))
77 if err != nil {
78 // Non-fatal, we'll just skip showing line numbers in the template.
79 log.Printf("counting lines: %s", err)
80 }
81
82 lines := make([]int, lc)
83 if lc > 0 {
84 for i := range lines {
85 lines[i] = i + 1
86 }
87 }
88
89 data["linecount"] = lines
90 data["content"] = content
91 data["meta"] = d.c.Meta
92
93 if err := t.ExecuteTemplate(w, "file", data); err != nil {
94 log.Println(err)
95 return
96 }
97}
98
99func (d *deps) showRaw(content string, w http.ResponseWriter) {
100 w.WriteHeader(http.StatusOK)
101 w.Header().Set("Content-Type", "text/plain")
102 w.Write([]byte(content))
103 return
104}