Files
jukebox_maker/internal/api/handlers_sources.go

67 lines
1.3 KiB
Go

package api
import (
"errors"
"net/http"
"os"
"path/filepath"
"sort"
"strings"
)
func (s *Server) handleSources(w http.ResponseWriter, r *http.Request) {
absPath, err := normalizeSourcePathQuery(r.URL.Query().Get("path"))
if err != nil {
jsonErr(w, http.StatusBadRequest, err.Error())
return
}
if absPath == "" {
jsonOK(w, map[string]any{"path": "", "items": []map[string]string{}})
return
}
entries, err := os.ReadDir(absPath)
if err != nil {
jsonOK(w, map[string]any{"path": absPath, "items": []map[string]string{}})
return
}
type item struct {
Name string `json:"name"`
Path string `json:"path"`
}
var items []item
for _, e := range entries {
if !e.IsDir() || strings.HasPrefix(e.Name(), ".") {
continue
}
childPath := filepath.Join(absPath, e.Name())
items = append(items, item{
Name: e.Name(),
Path: childPath,
})
}
sort.Slice(items, func(i, j int) bool {
return strings.ToLower(items[i].Name) < strings.ToLower(items[j].Name)
})
jsonOK(w, map[string]any{
"path": absPath,
"items": items,
})
}
func normalizeSourcePathQuery(raw string) (string, error) {
raw = strings.TrimSpace(raw)
if raw == "" || raw == "." {
return "", nil
}
clean := filepath.Clean(raw)
if !filepath.IsAbs(clean) {
return "", errors.New("invalid source path")
}
return clean, nil
}