feat: some updates

This commit is contained in:
Max Richter
2025-09-24 18:18:57 +02:00
parent b3c01bb43d
commit 26c303d9cf
32 changed files with 464 additions and 263 deletions

View File

@@ -0,0 +1,93 @@
package handlers
import (
"errors"
"fmt"
"net/http"
"os"
"path/filepath"
"time"
"git.max-richter.dev/max/marka/server/internal/fsx"
"git.max-richter.dev/max/marka/server/internal/httpx"
)
func (h *File) get(w http.ResponseWriter, r *http.Request, target string) {
fi, err := os.Stat(target)
if err != nil {
if os.IsNotExist(err) {
httpx.WriteError(w, http.StatusNotFound, errors.New("not found"))
} else {
httpx.WriteError(w, http.StatusInternalServerError, err)
}
return
}
if fi.IsDir() {
h.handleDir(w, r, target)
} else {
h.handleFile(w, r, target, fi)
}
}
func (h *File) handleDir(w http.ResponseWriter, r *http.Request, dirPath string) {
entries, err := os.ReadDir(dirPath)
if err != nil {
httpx.WriteError(w, http.StatusInternalServerError, err)
return
}
type item struct {
Name string `json:"name"`
Path string `json:"path"`
Content any `json:"content,omitempty"`
IsDir bool `json:"isDir"`
Size int64 `json:"size"`
ModTime time.Time `json:"modTime"`
}
out := make([]item, 0, len(entries))
for _, e := range entries {
info, _ := e.Info() // As in original, ignore error to get partial info
entryPath := filepath.Join(dirPath, e.Name())
var content any
if !e.IsDir() && fsx.ContentTypeFor(e.Name()) == "application/markdown" {
content, _ = parseMarkdownFile(entryPath) // As in original, ignore error
}
out = append(out, item{
Name: e.Name(),
Path: fsx.ResponsePath(h.root, entryPath),
IsDir: e.IsDir(),
Content: content,
Size: sizeOrZero(info),
ModTime: modTimeOrZero(info),
})
}
httpx.WriteJSON(w, http.StatusOK, out)
}
func (h *File) handleFile(w http.ResponseWriter, r *http.Request, target string, fi os.FileInfo) {
contentType := fsx.ContentTypeFor(target)
if contentType == "application/markdown" {
res, err := parseMarkdownFile(target)
if err != nil {
httpx.WriteError(w, http.StatusInternalServerError, fmt.Errorf("failed to parse markdown: %w", err))
return
}
httpx.WriteJSON(w, http.StatusOK, res)
return
}
f, err := os.Open(target)
if err != nil {
httpx.WriteError(w, http.StatusInternalServerError, err)
return
}
defer f.Close()
w.Header().Set("Content-Type", contentType)
http.ServeContent(w, r, filepath.Base(target), fi.ModTime(), f)
}