aboutsummaryrefslogtreecommitdiff
path: root/internal/admin/api_files.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-11 18:30:58 -0400
committerhistoria <[not public]>2026-07-11 18:30:58 -0400
commit2bacbb08d1ac67c4f63ee535728cd4e8760e3211 (patch)
treed8ee366b3d32b486eb05c5e10bc65cf194ae4c23 /internal/admin/api_files.go
parent131cbbe586463a7232f332650af5f0b2c13dc7e9 (diff)
downloadthehouseoficarus-2bacbb08d1ac67c4f63ee535728cd4e8760e3211.tar.gz
feat(admin): unify context menu, add context menu to files tab
Diffstat (limited to 'internal/admin/api_files.go')
-rw-r--r--internal/admin/api_files.go65
1 files changed, 65 insertions, 0 deletions
diff --git a/internal/admin/api_files.go b/internal/admin/api_files.go
index 2a87dd3..496b08d 100644
--- a/internal/admin/api_files.go
+++ b/internal/admin/api_files.go
@@ -8,6 +8,71 @@ import (
"strings"
)
+func (s *AdminServer) handleFileRename(w http.ResponseWriter, r *http.Request) {
+ if r.Method != http.MethodPost {
+ http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
+ return
+ }
+ var body struct {
+ Path string `json:"path"`
+ NewName string `json:"new_name"`
+ }
+ if err := readJSON(r, &body); err != nil || body.Path == "" || body.NewName == "" {
+ writeJSON(w, map[string]any{"error": "missing path or new_name"})
+ return
+ }
+
+ newName := strings.TrimSpace(body.NewName)
+ if newName == "" || newName == "." || newName == ".." || strings.ContainsAny(newName, "/\\") {
+ writeJSON(w, map[string]any{"error": "invalid file name"})
+ return
+ }
+ for _, c := range newName {
+ if c < 32 || c == 127 {
+ writeJSON(w, map[string]any{"error": "file name contains invalid characters"})
+ return
+ }
+ }
+
+ relPath := strings.TrimPrefix(body.Path, "/")
+ relPath = strings.TrimPrefix(relPath, "data/")
+ oldAbs := filepath.Join(s.dataDir, relPath)
+
+ oldContent, err := snapshotFile(oldAbs)
+ if err != nil {
+ writeJSON(w, map[string]any{"error": "file not found: " + relPath})
+ return
+ }
+
+ newAbs := filepath.Join(filepath.Dir(oldAbs), newName)
+ if _, err := os.Stat(newAbs); err == nil {
+ writeJSON(w, map[string]any{"error": "a file named " + newName + " already exists"})
+ return
+ }
+
+ if err := os.WriteFile(newAbs, oldContent, 0644); err != nil {
+ writeJSON(w, map[string]any{"error": "write error: " + err.Error()})
+ return
+ }
+ if err := os.Remove(oldAbs); err != nil {
+ writeJSON(w, map[string]any{"error": "remove error: " + err.Error()})
+ return
+ }
+
+ newRelPath := filepath.Join(filepath.Dir(relPath), newName)
+ if filepath.Dir(relPath) == "." {
+ newRelPath = newName
+ }
+ s.undoStack.Push(ChangeDesc{
+ Description: "Renamed file " + relPath + " to " + newRelPath,
+ FilePath: oldAbs,
+ NewFilePath: newAbs,
+ OldContent: oldContent,
+ NewContent: oldContent,
+ })
+ writeJSON(w, map[string]any{"ok": true, "path": newRelPath})
+}
+
func (s *AdminServer) handleFiles(w http.ResponseWriter, r *http.Request) {
relPath := r.URL.Query().Get("path")
relPath = strings.TrimPrefix(relPath, "/")