Explore: personal GPS heatmap tab under Athlete page
- bincio/explore.py: bake_tracks() simplifies GPS coords (RDP ε=0.0001), strips to [lng,lat], groups by sport type, writes per-handle tracks.json - bake-tracks CLI command; render CLI calls _bake_tracks() after each build; strava_zip runs it once at end of batch - /api/me/tracks endpoint serves the baked file; wipe_user cleans it up - Explore.svelte: MapLibre full-screen map with sidebar — type pills, year/month date filter, Lines / Heatmap (global or by-type) view modes - AthleteView: Explore tab visible only to profile owner (checks __bincioMe) - Base.astro: fullscreen prop + Planner nav link
This commit is contained in:
@@ -7,7 +7,7 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Cookie, HTTPException, Request
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.responses import JSONResponse, Response
|
||||
|
||||
from bincio.serve import deps, tasks
|
||||
from bincio.serve.db import (
|
||||
@@ -43,7 +43,7 @@ def _wipe_user_activities(user_dir: Path) -> int:
|
||||
if d.exists():
|
||||
shutil.rmtree(d)
|
||||
|
||||
for name in ("index.json", "athlete.json", ".bincio_cache.json"):
|
||||
for name in ("index.json", "athlete.json", ".bincio_cache.json", "tracks.json"):
|
||||
f = user_dir / name
|
||||
if f.exists():
|
||||
f.unlink()
|
||||
@@ -52,6 +52,16 @@ def _wipe_user_activities(user_dir: Path) -> int:
|
||||
return deleted
|
||||
|
||||
|
||||
@router.get("/api/me/tracks")
|
||||
async def me_tracks(bincio_session: str | None = Cookie(default=None)) -> Response:
|
||||
"""Return the pre-baked tracks.json for the logged-in user (Explore page)."""
|
||||
user = deps._require_user(bincio_session)
|
||||
tracks_path = deps._get_data_dir() / user.handle / "tracks.json"
|
||||
if not tracks_path.exists():
|
||||
raise HTTPException(404, "Tracks not yet baked — upload an activity first")
|
||||
return Response(content=tracks_path.read_bytes(), media_type="application/json")
|
||||
|
||||
|
||||
@router.get("/api/me/storage")
|
||||
async def me_storage(bincio_session: str | None = Cookie(default=None)) -> JSONResponse:
|
||||
"""Return per-category disk usage for the logged-in user."""
|
||||
|
||||
@@ -487,6 +487,11 @@ async def upload_strava_zip(
|
||||
user.handle, imported_count, error_count)
|
||||
if any_imported:
|
||||
merge_all(dd)
|
||||
try:
|
||||
from bincio.explore import bake_tracks
|
||||
bake_tracks(user.handle, deps._get_data_dir())
|
||||
except Exception as exc:
|
||||
log.warning("strava-zip[%s]: bake_tracks failed (non-fatal): %s", user.handle, exc)
|
||||
tasks._trigger_rebuild(user.handle)
|
||||
except Exception as exc:
|
||||
log.error("strava-zip[%s]: fatal error: %s", user.handle, exc, exc_info=True)
|
||||
|
||||
Reference in New Issue
Block a user