F14: add per-activity delete (DELETE /api/activity/{id} + drawer button)
Server endpoint removes the activity JSON, GeoJSON, timeseries, sidecar edit, and images directory. Also purges the dedup cache entry so the file can be re-uploaded if needed. Runs merge_all + rebuild afterwards. EditDrawer: two-click delete button (click once → "Confirm delete?", click again → deletes). On success, dispatches 'deleted' event. ActivityDetail navigates back to the feed on delete.
This commit is contained in:
@@ -597,6 +597,56 @@ async def post_activity(
|
||||
return JSONResponse({"ok": True})
|
||||
|
||||
|
||||
@app.delete("/api/activity/{activity_id}")
|
||||
async def delete_activity(
|
||||
activity_id: str,
|
||||
bincio_session: Optional[str] = Cookie(default=None),
|
||||
) -> JSONResponse:
|
||||
"""Delete a single activity and all associated files for the logged-in user."""
|
||||
user = _require_user(bincio_session)
|
||||
_check_id(activity_id)
|
||||
dd = _get_data_dir() / user.handle
|
||||
acts_dir = dd / "activities"
|
||||
|
||||
json_path = acts_dir / f"{activity_id}.json"
|
||||
if not json_path.exists():
|
||||
raise HTTPException(404, "Activity not found")
|
||||
|
||||
import shutil
|
||||
|
||||
# Remove the source files (activities dir)
|
||||
for suffix in (".json", ".geojson", ".timeseries.json"):
|
||||
p = acts_dir / f"{activity_id}{suffix}"
|
||||
p.unlink(missing_ok=True)
|
||||
|
||||
# Remove sidecar edit and images
|
||||
sidecar = dd / "edits" / f"{activity_id}.md"
|
||||
sidecar.unlink(missing_ok=True)
|
||||
images_dir = dd / "edits" / "images" / activity_id
|
||||
if images_dir.exists():
|
||||
shutil.rmtree(images_dir)
|
||||
|
||||
# Remove from dedup cache so the file can be re-uploaded if needed
|
||||
cache_path = dd / ".bincio_cache.json"
|
||||
if cache_path.exists():
|
||||
try:
|
||||
cache = json.loads(cache_path.read_text(encoding="utf-8"))
|
||||
if isinstance(cache, dict) and "activities" in cache:
|
||||
cache["activities"] = [
|
||||
a for a in cache["activities"] if a.get("id") != activity_id
|
||||
]
|
||||
cache_path.write_text(json.dumps(cache, indent=2, ensure_ascii=False))
|
||||
except Exception:
|
||||
pass # corrupt cache — leave it; next extract will rebuild
|
||||
|
||||
# Full merge needed: activity removed from index
|
||||
from bincio.render.merge import merge_all
|
||||
merge_all(dd)
|
||||
_trigger_rebuild(user.handle)
|
||||
|
||||
return JSONResponse({"ok": True})
|
||||
|
||||
|
||||
@app.get("/api/activity/{activity_id}/images")
|
||||
async def list_images(
|
||||
activity_id: str,
|
||||
|
||||
Reference in New Issue
Block a user