"keep data on the server" opt-in/out
This commit is contained in:
+10
-3
@@ -9,7 +9,7 @@ from __future__ import annotations
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
|
||||
# ── Shared constants (imported by edit/server.py and serve/server.py) ─────────
|
||||
|
||||
@@ -58,13 +58,20 @@ def apply_sidecar_edit(activity_id: str, payload: dict[str, Any], data_dir: Path
|
||||
merge_one(data_dir, activity_id)
|
||||
|
||||
|
||||
def run_strava_sync(data_dir: Path, client_id: str, client_secret: str) -> dict[str, Any]:
|
||||
def run_strava_sync(
|
||||
data_dir: Path,
|
||||
client_id: str,
|
||||
client_secret: str,
|
||||
originals_dir: Optional[Path] = None,
|
||||
) -> dict[str, Any]:
|
||||
"""Fetch new Strava activities and write them into data_dir.
|
||||
|
||||
Args:
|
||||
data_dir: Per-user data directory.
|
||||
client_id: Strava OAuth client ID.
|
||||
client_secret: Strava OAuth client secret.
|
||||
originals_dir: If set, raw Strava API data (meta + streams) is saved here
|
||||
as JSON files for potential future reprocessing.
|
||||
|
||||
Returns:
|
||||
Dict with keys: ok, imported, skipped, error_count, errors.
|
||||
@@ -75,7 +82,7 @@ def run_strava_sync(data_dir: Path, client_id: str, client_secret: str) -> dict[
|
||||
from bincio.extract.ingest import strava_sync as _strava_sync
|
||||
from bincio.render.merge import merge_all
|
||||
|
||||
result = _strava_sync(data_dir, client_id, client_secret)
|
||||
result = _strava_sync(data_dir, client_id, client_secret, originals_dir=originals_dir)
|
||||
if result["imported"]:
|
||||
merge_all(data_dir)
|
||||
|
||||
|
||||
+14
-3
@@ -7,7 +7,7 @@ import shutil
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from fastapi import FastAPI, File, HTTPException, Request, UploadFile
|
||||
from fastapi import FastAPI, File, Form, HTTPException, Request, UploadFile
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.middleware.gzip import GZipMiddleware
|
||||
from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse
|
||||
@@ -517,7 +517,10 @@ def _file_suffix(name: str) -> str:
|
||||
|
||||
|
||||
@app.post("/api/upload")
|
||||
async def upload_activity(file: UploadFile = File(...)) -> JSONResponse:
|
||||
async def upload_activity(
|
||||
file: UploadFile = File(...),
|
||||
store_original: bool = Form(False),
|
||||
) -> JSONResponse:
|
||||
"""Accept a FIT/GPX/TCX file, extract it, update index.json, and re-merge."""
|
||||
dd = _get_data_dir()
|
||||
|
||||
@@ -536,6 +539,7 @@ async def upload_activity(file: UploadFile = File(...)) -> JSONResponse:
|
||||
staged = staging / name
|
||||
staged.write_bytes(contents)
|
||||
|
||||
kept = False
|
||||
try:
|
||||
from bincio.extract.metrics import compute
|
||||
from bincio.extract.parsers.factory import parse_file
|
||||
@@ -563,6 +567,12 @@ async def upload_activity(file: UploadFile = File(...)) -> JSONResponse:
|
||||
existing[activity_id] = summary
|
||||
write_index(list(existing.values()), dd, owner)
|
||||
|
||||
if store_original:
|
||||
originals_dir = dd / "originals"
|
||||
originals_dir.mkdir(exist_ok=True)
|
||||
staged.rename(originals_dir / name)
|
||||
kept = True
|
||||
|
||||
from bincio.render.merge import merge_all
|
||||
merge_all(dd)
|
||||
|
||||
@@ -571,7 +581,8 @@ async def upload_activity(file: UploadFile = File(...)) -> JSONResponse:
|
||||
except Exception as exc:
|
||||
raise HTTPException(422, f"Failed to process activity file: {type(exc).__name__}")
|
||||
finally:
|
||||
staged.unlink(missing_ok=True)
|
||||
if not kept:
|
||||
staged.unlink(missing_ok=True)
|
||||
|
||||
return JSONResponse({"ok": True, "id": activity_id})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user