feat: Implement Analyze and Plan features, Smart Sync, Theming, and Optional Auth

This commit is contained in:
Moritz Graf
2026-01-01 14:22:48 +01:00
commit 8e55078c14
51 changed files with 5433 additions and 0 deletions
+66
View File
@@ -0,0 +1,66 @@
import sys
import os
# Add src to path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../src")))
from garmin.sync import GarminSync
from garmin.client import GarminClient
from garmin.workout import GarminWorkoutCreator, StrengthWorkout, WorkoutStep
def get_common_exercises():
"""Extract common exercises from local Garmin history."""
client = GarminClient() # path helper
sync = GarminSync(client)
history = sync.load_local_activities()
exercises = set()
for activity in history:
if "strength" in activity.get("activityType", {}).get("typeKey", "").lower():
# In a real scenario, we'd parse the 'steps' or 'exercises' in the JSON
# For now, we'll look for exercise names in the activity name or metadata
exercises.add(activity.get("activityName", "Unknown"))
return sorted(list(exercises))
def main():
print("💪 Local Strength Workout Creator")
common = get_common_exercises()
if common:
print("\nSuggested based on your history:")
for i, ex in enumerate(common[:5], 1):
print(f" {i}. {ex}")
name = input("\nEnter workout name: ")
steps = []
while True:
exercise = input("Enter exercise name (or press enter to finish): ")
if not exercise:
break
reps = int(input(f"Enter reps for {exercise}: "))
weight = input(f"Enter weight for {exercise} (optional): ")
weight = float(weight) if weight else None
steps.append(WorkoutStep(name=exercise, reps=reps, weight=weight))
print(f"✅ Added {exercise}")
if not steps:
print("❌ No steps added. Exiting.")
return
client = GarminClient()
if client.login() != "SUCCESS":
print("Failed to login to Garmin Connect.")
return
workout = StrengthWorkout(name=name, steps=steps)
creator = GarminWorkoutCreator()
path = creator.create_local_workout(workout)
print(f"🎉 Workout saved locally to: {path}")
print("Tip: Use the upload script (coming soon) to sync this to Garmin Connect.")
if __name__ == "__main__":
main()
+37
View File
@@ -0,0 +1,37 @@
import sys
import os
# Add src to path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../src")))
from garmin.sync import GarminSync
from garmin.client import GarminClient
from recommendations.engine import RecommendationEngine
def main():
print("🤖 Gemini Fitness AI")
# Try to load local data first
client = GarminClient()
if client.login() != "SUCCESS":
print("Failed to login to Garmin Connect. Proceeding with dummy data.")
history = []
else:
sync = GarminSync(client)
history = sync.load_local_activities()
if not history:
print("⚠️ No local history found. Running on empty profile.")
objective = "trained, strong and endurance"
engine = RecommendationEngine()
print("⏳ Analyzing your data...")
recommendation = engine.get_recommendation(history, objective)
print("\n--- Gemini's Advice ---")
print(recommendation)
print("------------------------\n")
if __name__ == "__main__":
main()
+24
View File
@@ -0,0 +1,24 @@
import sys
import os
from datetime import date
# Add src to path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../src")))
from garmin.client import GarminClient
from garmin.sync import GarminSync
def main():
print("🚀 Initializing Garmin Sync...")
client = GarminClient()
if client.login() != "SUCCESS":
print("Failed to login to Garmin Connect.")
return
sync = GarminSync(client)
print("⏳ Fetching activities...")
count = sync.sync_activities(days=30)
print(f"✅ Successfully synced {count} activities to data/local/garmin/")
if __name__ == "__main__":
main()