upload strava zip

This commit is contained in:
Davide Scaini
2026-04-10 22:01:44 +02:00
parent e5eadc69f2
commit 3b8bc159c5
8 changed files with 313 additions and 3 deletions
+49
View File
@@ -587,6 +587,55 @@ async def upload_activity(
return JSONResponse({"ok": True, "added": len(added), "results": results})
@app.post("/api/upload/strava-zip")
async def upload_strava_zip(
file: UploadFile = File(...),
bincio_session: Optional[str] = Cookie(default=None),
) -> StreamingResponse:
"""Accept a Strava bulk export ZIP and stream SSE progress while processing.
The ZIP is written to a temp file, processed activity-by-activity, then deleted.
Originals are never kept — the UI informs the user of this upfront.
"""
user = _require_user(bincio_session)
if not file.filename or not file.filename.lower().endswith(".zip"):
raise HTTPException(400, "Please upload a .zip file")
dd = _get_data_dir() / user.handle
import tempfile
tmp = tempfile.NamedTemporaryFile(suffix=".zip", delete=False, dir=dd)
zip_path = Path(tmp.name)
try:
while chunk := await file.read(1024 * 1024): # 1 MB chunks
tmp.write(chunk)
finally:
tmp.close()
from bincio.extract.strava_zip import strava_zip_iter
from bincio.render.merge import merge_all
def event_stream():
any_imported = False
try:
for event in strava_zip_iter(zip_path, dd):
yield f"data: {json.dumps(event)}\n\n"
if event.get("type") == "progress" and event.get("status") == "imported":
any_imported = True
if event.get("type") == "done":
if any_imported:
merge_all(dd)
_trigger_rebuild(user.handle)
except Exception as exc:
zip_path.unlink(missing_ok=True)
yield f"data: {json.dumps({'type': 'error', 'message': str(exc)})}\n\n"
return StreamingResponse(
event_stream(),
media_type="text/event-stream",
headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"},
)
# ── Feedback ──────────────────────────────────────────────────────────────────
_FEEDBACK_IMAGE_SUFFIXES = {".jpg", ".jpeg", ".png", ".gif", ".webp", ".heic"}