136 lines
3.5 KiB
Go
Executable File
136 lines
3.5 KiB
Go
Executable File
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"gitea.inhome.blapointe.com/local/notes-server/config"
|
|
"gitea.inhome.blapointe.com/local/notes-server/filetree"
|
|
"net/http"
|
|
"path"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
func (s *Server) notes(w http.ResponseWriter, r *http.Request) {
|
|
p := filetree.NewPathFromURL(r.URL.Path)
|
|
head(w, r)
|
|
notesHead(w, p)
|
|
defer foot(w, r)
|
|
if p.IsDir() {
|
|
s.dir(w, r)
|
|
} else if p.IsFile() {
|
|
s.file(w, r)
|
|
} else {
|
|
http.NotFound(w, r)
|
|
}
|
|
}
|
|
|
|
func notesHead(w http.ResponseWriter, p filetree.Path) {
|
|
fmt.Fprintln(w, h2(p.MultiLink()))
|
|
htmlSearch(w)
|
|
}
|
|
|
|
func (s *Server) dir(w http.ResponseWriter, r *http.Request) {
|
|
dirs, files, err := s.Notes.Dir(r.URL.Path)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
dirHead(w, filetree.NewPathFromURL(r.URL.Path).BaseHREF)
|
|
block(w, dirs)
|
|
block(w, files)
|
|
}
|
|
|
|
func dirHead(w http.ResponseWriter, baseHREF string) {
|
|
htmlCreate(w, baseHREF)
|
|
htmlDelete(w, baseHREF)
|
|
}
|
|
|
|
func (s *Server) file(w http.ResponseWriter, r *http.Request) {
|
|
file, err := s.Notes.File(r.URL.Path)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
s.fileHead(w, r.URL.Path)
|
|
fmt.Fprintln(w, file)
|
|
}
|
|
|
|
func (s *Server) fileHead(w http.ResponseWriter, path string) {
|
|
baseHREF := filetree.NewPathFromURL(path).BaseHREF
|
|
htmlEdit(w, baseHREF)
|
|
htmlDelete(w, baseHREF)
|
|
s.htmlAttachments(w, path)
|
|
}
|
|
|
|
func htmlEdit(w http.ResponseWriter, baseHREF string) {
|
|
if config.ReadOnly {
|
|
return
|
|
}
|
|
fmt.Fprintf(w, `<div style='display:inline-block; margin-top: .75em; margin-bottom: .75em;'>
|
|
<a href=%q class="button">Edit</a>
|
|
</div><br>`, path.Join("/edit/", baseHREF))
|
|
}
|
|
|
|
func htmlDelete(w http.ResponseWriter, baseHREF string) {
|
|
if config.ReadOnly {
|
|
return
|
|
}
|
|
fmt.Fprintf(w, `<div style='display:inline-block; margin-top: .75em; margin-bottom: .75em;'>
|
|
<a href=%q class="button" onclick="return confirm('Delete?');">Delete</a>
|
|
</div><br>`, path.Join("/delete/", baseHREF))
|
|
}
|
|
|
|
func (s *Server) htmlAttachments(w http.ResponseWriter, urlPath string) {
|
|
dir := path.Dir(urlPath)
|
|
f := "." + path.Base(urlPath) + ".attachments"
|
|
_, files, _ := s.Notes.Dir(path.Join(dir, f))
|
|
form := fmt.Sprintf(`
|
|
<form enctype="multipart/form-data" action="/attach/%s" method="post">
|
|
<input type="file" name="file" required/>
|
|
<input type="submit" value="+"/>
|
|
</form>
|
|
`, strings.TrimPrefix(urlPath, "/notes/"))
|
|
if config.ReadOnly {
|
|
form = ""
|
|
}
|
|
lines := strings.Split(files, "\n")
|
|
for i := range lines {
|
|
pattern := regexp.MustCompile(`\.(png|jpg|jpeg|gif)">`)
|
|
if !pattern.MatchString(lines[i]) {
|
|
lines[i] = strings.ReplaceAll(lines[i], "<a", "<a download")
|
|
}
|
|
lines[i] = strings.ReplaceAll(lines[i], `href="/notes`, `href="/raw`)
|
|
}
|
|
files = strings.Join(lines, "\n")
|
|
fmt.Fprintf(w, `<div style='display:inline-block' class="attachments">
|
|
<details>
|
|
<summary style="display: flex">
|
|
<span style="flex-grow: 2">Attachments</span>
|
|
</summary>
|
|
%s
|
|
%s
|
|
</details>
|
|
</div><br>`, form, files)
|
|
}
|
|
|
|
func htmlCreate(w http.ResponseWriter, baseHREF string) {
|
|
if config.ReadOnly {
|
|
return
|
|
}
|
|
fmt.Fprintf(w, `
|
|
<form action=%q method="get">
|
|
<input type="text" name="base"></input>
|
|
<button type="submit">Create</button>
|
|
</form>
|
|
`, path.Join("/create/", baseHREF))
|
|
}
|
|
|
|
func htmlSearch(w http.ResponseWriter) {
|
|
fmt.Fprintf(w, `
|
|
<form action=%q method="post" >
|
|
<input type="text" name="keywords"></input>
|
|
<button type="submit">Search</button>
|
|
</form>
|
|
`, "/search")
|
|
}
|