diff --git a/data/garmin.db b/data/garmin.db index bd5918c..6abdc40 100644 Binary files a/data/garmin.db and b/data/garmin.db differ diff --git a/garminsync/web/routes.py b/garminsync/web/routes.py index 13bd05a..2c3b3ff 100644 --- a/garminsync/web/routes.py +++ b/garminsync/web/routes.py @@ -148,6 +148,55 @@ async def get_logs(limit: int = 50): finally: session.close() +@router.post("/daemon/start") +async def start_daemon(): + """Start the daemon process""" + from garminsync.daemon import daemon_instance + try: + # Start the daemon in a separate thread to avoid blocking + import threading + daemon_thread = threading.Thread(target=daemon_instance.start) + daemon_thread.daemon = True + daemon_thread.start() + + # Update daemon status in database + session = get_session() + config = session.query(DaemonConfig).first() + if not config: + config = DaemonConfig() + session.add(config) + config.status = "running" + session.commit() + + return {"message": "Daemon started successfully"} + except Exception as e: + session.rollback() + raise HTTPException(status_code=500, detail=f"Failed to start daemon: {str(e)}") + finally: + session.close() + +@router.post("/daemon/stop") +async def stop_daemon(): + """Stop the daemon process""" + from garminsync.daemon import daemon_instance + try: + # Stop the daemon + daemon_instance.stop() + + # Update daemon status in database + session = get_session() + config = session.query(DaemonConfig).first() + if config: + config.status = "stopped" + session.commit() + + return {"message": "Daemon stopped successfully"} + except Exception as e: + session.rollback() + raise HTTPException(status_code=500, detail=f"Failed to stop daemon: {str(e)}") + finally: + session.close() + @router.delete("/logs") async def clear_logs(): """Clear all sync logs""" @@ -160,4 +209,4 @@ async def clear_logs(): session.rollback() raise HTTPException(status_code=500, detail=f"Failed to clear logs: {str(e)}") finally: - session.close() \ No newline at end of file + session.close() diff --git a/garminsync/web/static/app.js b/garminsync/web/static/app.js index 6609aa6..9103358 100644 --- a/garminsync/web/static/app.js +++ b/garminsync/web/static/app.js @@ -11,6 +11,7 @@ async function updateStatus() {

Status: ${data.daemon.running ? 'Running' : 'Stopped'}

+

Last Run: ${data.daemon.last_run || 'Never'}

Next Run: ${data.daemon.next_run || 'Not scheduled'}

Schedule: ${data.daemon.schedule || 'Not configured'}

`; @@ -23,6 +24,7 @@ async function updateStatus() { ${log.status} ${log.operation}: ${log.message || ''} + ${log.activities_downloaded > 0 ? `Downloaded ${log.activities_downloaded} activities` : ''} `).join(''); @@ -43,10 +45,54 @@ async function triggerSync() { } } +async function toggleDaemon() { + try { + const statusResponse = await fetch('/api/status'); + const statusData = await statusResponse.json(); + const isRunning = statusData.daemon.running; + + if (isRunning) { + await fetch('/api/daemon/stop', { method: 'POST' }); + alert('Daemon stopped successfully'); + } else { + await fetch('/api/daemon/start', { method: 'POST' }); + alert('Daemon started successfully'); + } + + updateStatus(); + } catch (error) { + alert('Failed to toggle daemon: ' + error.message); + } +} + +// Schedule form handling +document.getElementById('schedule-form')?.addEventListener('submit', async function(e) { + e.preventDefault(); + + const enabled = document.getElementById('schedule-enabled').checked; + const cronSchedule = document.getElementById('cron-schedule').value; + + try { + const response = await fetch('/api/schedule', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + enabled: enabled, + cron_schedule: cronSchedule + }) + }); + + if (response.ok) { + alert('Schedule updated successfully'); + updateStatus(); + } else { + const error = await response.json(); + alert(`Error: ${error.detail}`); + } + } catch (error) { + alert('Failed to update schedule: ' + error.message); + } +}); + // Initialize on page load document.addEventListener('DOMContentLoaded', updateStatus); - -async function toggleDaemon() { - // TODO: Implement daemon toggle functionality - alert('Daemon toggle functionality not yet implemented'); -}