this repo has no description
1package knotserver
2
3import (
4 "fmt"
5 "io/fs"
6 "log"
7 "net/http"
8 "os"
9 "path/filepath"
10 "strings"
11
12 "github.com/go-chi/chi/v5"
13 "github.com/icyphox/bild/auth"
14 "github.com/icyphox/bild/git"
15 "github.com/microcosm-cc/bluemonday"
16)
17
18func sanitize(content []byte) []byte {
19 return bluemonday.UGCPolicy().SanitizeBytes([]byte(content))
20}
21
22func displayRepoName(r *http.Request) string {
23 user := r.Context().Value("did").(string)
24 name := chi.URLParam(r, "name")
25
26 handle, err := auth.ResolveIdent(r.Context(), user)
27 if err != nil {
28 log.Printf("failed to resolve ident: %s: %s", user, err)
29 return fmt.Sprintf("%s/%s", user, name)
30 }
31
32 return fmt.Sprintf("@%s/%s", handle.Handle.String(), name)
33}
34
35func didPath(r *http.Request) string {
36 did := chi.URLParam(r, "did")
37 name := chi.URLParam(r, "name")
38 path := filepath.Join(did, name)
39 filepath.Clean(path)
40 return path
41}
42
43func getDescription(path string) (desc string) {
44 db, err := os.ReadFile(filepath.Join(path, "description"))
45 if err == nil {
46 desc = string(db)
47 } else {
48 desc = ""
49 }
50 return
51}
52
53func (h *Handle) isUnlisted(name string) bool {
54 for _, i := range h.c.Repo.Unlisted {
55 if name == i {
56 return true
57 }
58 }
59
60 return false
61}
62
63func (h *Handle) isIgnored(name string) bool {
64 for _, i := range h.c.Repo.Ignore {
65 if name == i {
66 return true
67 }
68 }
69
70 return false
71}
72
73type repoInfo struct {
74 Git *git.GitRepo
75 Path string
76 Category string
77}
78
79func (d *Handle) getAllRepos() ([]repoInfo, error) {
80 repos := []repoInfo{}
81 max := strings.Count(d.c.Repo.ScanPath, string(os.PathSeparator)) + 2
82
83 err := filepath.WalkDir(d.c.Repo.ScanPath, func(path string, de fs.DirEntry, err error) error {
84 if err != nil {
85 return err
86 }
87
88 if de.IsDir() {
89 // Check if we've exceeded our recursion depth
90 if strings.Count(path, string(os.PathSeparator)) > max {
91 return fs.SkipDir
92 }
93
94 if d.isIgnored(path) {
95 return fs.SkipDir
96 }
97
98 // A bare repo should always have at least a HEAD file, if it
99 // doesn't we can continue recursing
100 if _, err := os.Lstat(filepath.Join(path, "HEAD")); err == nil {
101 repo, err := git.Open(path, "")
102 if err != nil {
103 log.Println(err)
104 } else {
105 relpath, _ := filepath.Rel(d.c.Repo.ScanPath, path)
106 repos = append(repos, repoInfo{
107 Git: repo,
108 Path: relpath,
109 Category: d.category(path),
110 })
111 // Since we found a Git repo, we don't want to recurse
112 // further
113 return fs.SkipDir
114 }
115 }
116 }
117 return nil
118 })
119
120 return repos, err
121}
122
123func (d *Handle) category(path string) string {
124 return strings.TrimPrefix(filepath.Dir(strings.TrimPrefix(path, d.c.Repo.ScanPath)), string(os.PathSeparator))
125}
126
127func setContentDisposition(w http.ResponseWriter, name string) {
128 h := "inline; filename=\"" + name + "\""
129 w.Header().Add("Content-Disposition", h)
130}
131
132func setGZipMIME(w http.ResponseWriter) {
133 setMIME(w, "application/gzip")
134}
135
136func setMIME(w http.ResponseWriter, mime string) {
137 w.Header().Add("Content-Type", mime)
138}