Safer subfolders
This commit is contained in:
@@ -87,14 +87,22 @@ def scan(root: Path) -> List[Item]:
|
||||
return items
|
||||
|
||||
def children(items: List[Item], rel_folder: str) -> Iterable[Item]:
|
||||
prefix = (rel_folder.strip("/") + "/") if rel_folder else ""
|
||||
depth = 0 if rel_folder == "" else rel_folder.count("/") + 1
|
||||
"""
|
||||
Yield direct children (files or dirs) inside rel_folder.
|
||||
Works reliably even with spaces, parentheses, and deep trees.
|
||||
"""
|
||||
base = rel_folder.strip("/")
|
||||
prefix = (base + "/") if base else ""
|
||||
for it in items:
|
||||
if not it.rel.startswith(prefix):
|
||||
rel = it.rel
|
||||
if base == "":
|
||||
# top-level direct children have no slash in rel
|
||||
if "/" not in rel and rel != "":
|
||||
yield it
|
||||
continue
|
||||
if it.rel == rel_folder:
|
||||
if not rel.startswith(prefix) or rel == base:
|
||||
continue
|
||||
if it.is_dir and it.rel.count("/") == depth:
|
||||
yield it
|
||||
elif not it.is_dir and it.rel.count("/") == depth:
|
||||
remainder = rel[len(prefix):]
|
||||
# only direct children have no "/" in the remainder
|
||||
if "/" not in remainder and remainder != "":
|
||||
yield it
|
||||
|
||||
11
app/main.py
11
app/main.py
@@ -153,12 +153,13 @@ def browse(path: str = Query("", description="Relative folder path"), page: int
|
||||
return (0, it.name.lower(), 0)
|
||||
meta = it.meta or {}
|
||||
series = meta.get("series") or ""
|
||||
# force numeric-ish, shove non-numeric to end
|
||||
try:
|
||||
num = int(float(meta.get("number","0")))
|
||||
num = int(float(meta.get("number", "0")))
|
||||
except ValueError:
|
||||
num = 10**9
|
||||
return (1, series.lower() or it.name.lower(), num)
|
||||
children.sort(key=sort_key)
|
||||
|
||||
|
||||
start=(page-1)*PAGE_SIZE
|
||||
end=start+PAGE_SIZE
|
||||
@@ -373,3 +374,9 @@ def stats(_=Depends(require_basic)):
|
||||
"top_writers": { "labels": w_labels, "values": w_values },
|
||||
}
|
||||
return JSONResponse(payload)
|
||||
|
||||
# ---------- debug ----------
|
||||
@app.get("/debug/children", response_class=JSONResponse)
|
||||
def debug_children(path: str = ""):
|
||||
ch = list(fs_index.children(INDEX, path.strip("/")))
|
||||
return JSONResponse([{"rel": it.rel, "is_dir": it.is_dir, "name": it.name} for it in ch])
|
||||
Reference in New Issue
Block a user