From 069d3c1c81d71042706372df153254487a765dfc Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Mon, 29 Jun 2026 22:31:11 -0400 Subject: feat: wip web admin for mapping and crud --- internal/admin/id_alloc.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 internal/admin/id_alloc.go (limited to 'internal/admin/id_alloc.go') diff --git a/internal/admin/id_alloc.go b/internal/admin/id_alloc.go new file mode 100644 index 0000000..d79718b --- /dev/null +++ b/internal/admin/id_alloc.go @@ -0,0 +1,64 @@ +package admin + +import ( + "os" + "path/filepath" + "strconv" +) + +func nextRoomIDInDir(dataDir string, fromRoomID int) (int, string, error) { + base := filepath.Join(dataDir, "rooms") + subdir, err := findRoomSubdir(base, fromRoomID) + if err != nil { + subdir = base + } + used := map[int]bool{} + scanDir(subdir, used) + if len(used) == 0 { + return 1, subdir, nil + } + minID := 1<<31 - 1 + for id := range used { + if id < minID { + minID = id + } + } + id := minID + for used[id] { + id++ + } + return id, subdir, nil +} + +func findRoomSubdir(base string, roomID int) (string, error) { + fileName := strconv.Itoa(roomID) + ".yaml" + var found string + filepath.WalkDir(base, func(path string, d os.DirEntry, err error) error { + if err != nil || found != "" { + return nil + } + if !d.IsDir() && d.Name() == fileName { + found = filepath.Dir(path) + } + return nil + }) + if found == "" { + return "", os.ErrNotExist + } + return found, nil +} + +func scanDir(dir string, used map[int]bool) { + entries, err := os.ReadDir(dir) + if err != nil { + return + } + for _, e := range entries { + if !e.IsDir() && filepath.Ext(e.Name()) == ".yaml" { + idStr := e.Name()[:len(e.Name())-5] + if id, err := strconv.Atoi(idStr); err == nil && id > 0 { + used[id] = true + } + } + } +} -- cgit v1.2.3