diff --git a/data/garmin.db b/data/garmin.db index 4a84dbb..6c65413 100644 Binary files a/data/garmin.db and b/data/garmin.db differ diff --git a/garminsync/daemon.py b/garminsync/daemon.py index e33a403..664e2eb 100644 --- a/garminsync/daemon.py +++ b/garminsync/daemon.py @@ -56,40 +56,55 @@ class GarminSyncDaemon: try: self.log_operation("sync", "started") + # Import here to avoid circular imports + from .garmin import GarminClient + from .database import sync_database + # Perform sync and download client = GarminClient() - activities_before = self.count_missing() - # Sync database - session = get_session() - activities = client.get_activities(0, 1000) - for activity in activities: - activity_id = activity["activityId"] - existing = session.query(Activity).filter_by(activity_id=activity_id).first() - if not existing: - new_activity = Activity( - activity_id=activity_id, - start_time=activity["startTimeLocal"], - downloaded=False, - created_at=datetime.now().isoformat() - ) - session.add(new_activity) - session.commit() + # Sync database first + sync_database(client) # Download missing activities downloaded_count = 0 + session = get_session() missing_activities = session.query(Activity).filter_by(downloaded=False).all() + for activity in missing_activities: - if client.download_activity(activity.activity_id, activity.start_time): + try: + # Use the correct method name + fit_data = client.download_activity_fit(activity.activity_id) + + # Save the file + import os + from pathlib import Path + data_dir = Path(os.getenv("DATA_DIR", "data")) + data_dir.mkdir(parents=True, exist_ok=True) + + timestamp = activity.start_time.replace(":", "-").replace(" ", "_") + filename = f"activity_{activity.activity_id}_{timestamp}.fit" + filepath = data_dir / filename + + with open(filepath, "wb") as f: + f.write(fit_data) + + activity.filename = str(filepath) activity.downloaded = True activity.last_sync = datetime.now().isoformat() downloaded_count += 1 - session.commit() + session.commit() + + except Exception as e: + logger.error(f"Failed to download activity {activity.activity_id}: {e}") + session.rollback() + session.close() self.log_operation("sync", "success", f"Downloaded {downloaded_count} new activities") except Exception as e: + logger.error(f"Sync failed: {e}") self.log_operation("sync", "error", str(e)) def load_config(self): diff --git a/garminsync/database.py b/garminsync/database.py index d740504..23a0dbe 100644 --- a/garminsync/database.py +++ b/garminsync/database.py @@ -12,6 +12,7 @@ class Activity(Base): start_time = Column(String, nullable=False) filename = Column(String, unique=True, nullable=True) downloaded = Column(Boolean, default=False, nullable=False) + created_at = Column(String, nullable=False) # Add this line last_sync = Column(String, nullable=True) # ISO timestamp of last sync class DaemonConfig(Base): @@ -68,6 +69,7 @@ def sync_database(garmin_client): activity_id=activity_id, start_time=start_time, downloaded=False, + created_at=datetime.now().isoformat(), # Add this line last_sync=datetime.now().isoformat() ) session.add(new_activity) diff --git a/garminsync/web/static/app.js b/garminsync/web/static/app.js index bb329de..6609aa6 100644 --- a/garminsync/web/static/app.js +++ b/garminsync/web/static/app.js @@ -45,3 +45,8 @@ async function triggerSync() { // Initialize on page load document.addEventListener('DOMContentLoaded', updateStatus); + +async function toggleDaemon() { + // TODO: Implement daemon toggle functionality + alert('Daemon toggle functionality not yet implemented'); +} diff --git a/requirements.txt b/requirements.txt index 4e34d1a..946fd42 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,13 @@ typer==0.9.0 click==8.1.7 python-dotenv==1.0.0 -garminconnect==0.2.29 +garminconnect==0.2.28 sqlalchemy==2.0.23 tqdm==4.66.1 fastapi==0.104.1 uvicorn[standard]==0.24.0 apscheduler==3.10.4 -pydantic==2.5.0 +pydantic>=2.0.0,<2.5.0 jinja2==3.1.2 python-multipart==0.0.6 aiofiles==23.2.1