fix admin delete to wipe originals/edits/geojson; rename button to Reset data
The old DELETE /api/admin/users/{handle}/activities only removed *.json
files and _merged/, leaving originals/ (Strava FIT files) and edits/
untouched — causing the 968 MB disk usage after a delete.
_wipe_user_activities() now removes activities/, edits/, originals/,
_merged/, index.json, athlete.json, and .bincio_cache.json. Admin page
button renamed to "Reset data" with updated confirmation text.
This commit is contained in:
+37
-18
@@ -517,38 +517,57 @@ async def admin_rebuild(
|
||||
return JSONResponse({"ok": True})
|
||||
|
||||
|
||||
def _wipe_user_activities(user_dir: Path) -> int:
|
||||
"""Delete all extracted activity files and caches for a user.
|
||||
|
||||
Removes activities/ (JSON + GeoJSON + timeseries), edits/, originals/,
|
||||
_merged/, index.json, athlete.json, and the dedup cache.
|
||||
Leaves the user directory itself intact (account remains in the DB).
|
||||
Returns the number of files deleted.
|
||||
"""
|
||||
import shutil
|
||||
deleted = 0
|
||||
|
||||
for subdir in ("activities", "edits", "originals"):
|
||||
d = user_dir / subdir
|
||||
if d.exists():
|
||||
for f in d.rglob("*"):
|
||||
if f.is_file():
|
||||
deleted += 1
|
||||
shutil.rmtree(d)
|
||||
|
||||
for name in ("_merged", ):
|
||||
d = user_dir / name
|
||||
if d.exists():
|
||||
shutil.rmtree(d)
|
||||
|
||||
for name in ("index.json", "athlete.json", ".bincio_cache.json"):
|
||||
f = user_dir / name
|
||||
if f.exists():
|
||||
f.unlink()
|
||||
deleted += 1
|
||||
|
||||
return deleted
|
||||
|
||||
|
||||
@app.delete("/api/admin/users/{handle}/activities")
|
||||
async def admin_delete_activities(
|
||||
handle: str,
|
||||
bincio_session: Optional[str] = Cookie(default=None),
|
||||
) -> JSONResponse:
|
||||
"""Delete all activity JSON files for a user and wipe the merged cache."""
|
||||
"""Delete all activity data for a user and wipe the merged cache."""
|
||||
_require_admin(bincio_session)
|
||||
user_dir = _get_data_dir() / handle
|
||||
if not user_dir.is_dir():
|
||||
raise HTTPException(404, f"No data directory for user '{handle}'")
|
||||
|
||||
deleted = 0
|
||||
activities_dir = user_dir / "activities"
|
||||
if activities_dir.is_dir():
|
||||
for f in activities_dir.glob("*.json"):
|
||||
f.unlink()
|
||||
deleted += 1
|
||||
|
||||
# Wipe merged cache, top-level index, and dedup cache so re-uploads aren't blocked
|
||||
import shutil
|
||||
merged_dir = user_dir / "_merged"
|
||||
if merged_dir.exists():
|
||||
shutil.rmtree(merged_dir)
|
||||
for name in ("index.json", ".bincio_cache.json"):
|
||||
f = user_dir / name
|
||||
if f.exists():
|
||||
f.unlink()
|
||||
|
||||
deleted = _wipe_user_activities(user_dir)
|
||||
_trigger_rebuild(handle)
|
||||
return JSONResponse({"ok": True, "deleted": deleted})
|
||||
|
||||
|
||||
|
||||
|
||||
# ── Write API (ported from bincio edit, auth-gated) ───────────────────────────
|
||||
|
||||
def _user_data_dir(handle: str) -> Path:
|
||||
|
||||
@@ -33,10 +33,11 @@ import Base from '../../layouts/Base.astro';
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<dialog id="confirm-dialog" class="rounded-xl bg-zinc-900 border border-zinc-700 p-6 text-white max-w-sm w-full backdrop:bg-black/60">
|
||||
<p class="text-sm text-zinc-300 mb-5">Delete all activities for <strong id="confirm-handle" class="text-white"></strong>? This cannot be undone.</p>
|
||||
<p class="text-sm text-zinc-300 mb-1">Reset all data for <strong id="confirm-handle" class="text-white"></strong>?</p>
|
||||
<p class="text-xs text-zinc-500 mb-5">Removes all activities, originals, edits, and images. The account is kept. This cannot be undone.</p>
|
||||
<div class="flex gap-3 justify-end">
|
||||
<button id="confirm-cancel" class="px-4 py-2 rounded-lg text-sm bg-zinc-800 hover:bg-zinc-700 text-zinc-300 transition-colors">Cancel</button>
|
||||
<button id="confirm-ok" class="px-4 py-2 rounded-lg text-sm bg-red-700 hover:bg-red-600 text-white font-medium transition-colors">Delete</button>
|
||||
<button id="confirm-ok" class="px-4 py-2 rounded-lg text-sm bg-red-700 hover:bg-red-600 text-white font-medium transition-colors">Reset</button>
|
||||
</div>
|
||||
</dialog>
|
||||
</div>
|
||||
@@ -124,7 +125,8 @@ import Base from '../../layouts/Base.astro';
|
||||
<button
|
||||
class="delete-btn text-xs px-3 py-1.5 rounded-lg bg-zinc-800 hover:bg-red-900 hover:text-red-300 text-zinc-400 transition-colors"
|
||||
data-handle="${u.handle}"
|
||||
>Delete activities</button>
|
||||
title="Wipe all activities, originals, edits and images — account is kept"
|
||||
>Reset data</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user