Abschluss 9c #11

Merged
Lars merged 14 commits from develop into main 2026-03-21 21:20:10 +01:00
Showing only changes of commit a4bd738e6f - Show all commits

View File

@ -122,7 +122,9 @@ def get_training_type_for_apple_health(workout_type: str):
cur = get_cursor(conn)
# Mapping: Apple Health Workout Type → training_type subcategory
# Supports English and German workout names
mapping = {
# English
'running': 'running',
'walking': 'walk',
'hiking': 'walk',
@ -141,6 +143,33 @@ def get_training_type_for_apple_health(workout_type: str):
'cooldown': 'regeneration',
'meditation': 'meditation',
'mindfulness': 'mindfulness',
# German (Deutsch)
'laufen': 'running',
'gehen': 'walk',
'wandern': 'walk',
'outdoor spaziergang': 'walk',
'innenräume spaziergang': 'walk',
'spaziergang': 'walk',
'radfahren': 'cycling',
'schwimmen': 'swimming',
'traditionelles krafttraining': 'hypertrophy',
'funktionelles krafttraining': 'functional',
'hochintensives intervalltraining': 'hiit',
'yoga': 'yoga',
'kampfsport': 'technique',
'matrial arts': 'technique', # Common typo in Apple Health
'boxen': 'sparring',
'rudern': 'rowing',
'tanzen': 'dance',
'cardio dance': 'dance',
'core training': 'functional',
'flexibilität': 'static',
'abwärmen': 'regeneration',
'cooldown': 'regeneration',
'meditation': 'meditation',
'achtsamkeit': 'mindfulness',
'geist & körper': 'yoga', # Mind & Body → Yoga category
}
subcategory = mapping.get(workout_type.lower())
@ -255,16 +284,54 @@ async def import_activity_csv(file: UploadFile=File(...), x_profile_id: Optional
training_type_id, training_category, training_subcategory = get_training_type_for_apple_health(wtype)
try:
cur.execute("""INSERT INTO activity_log
(id,profile_id,date,start_time,end_time,activity_type,duration_min,kcal_active,kcal_resting,
hr_avg,hr_max,distance_km,source,training_type_id,training_category,training_subcategory,created)
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,'apple_health',%s,%s,%s,CURRENT_TIMESTAMP)""",
(str(uuid.uuid4()),pid,date,start,row.get('End',''),wtype,duration_min,
kj(row.get('Aktive Energie (kJ)','')),kj(row.get('Ruheeinträge (kJ)','')),
tf(row.get('Durchschn. Herzfrequenz (count/min)','')),
tf(row.get('Max. Herzfrequenz (count/min)','')),
tf(row.get('Distanz (km)','')),
training_type_id,training_category,training_subcategory))
inserted+=1
except: skipped+=1
# Check if entry already exists (duplicate detection by date + start_time)
cur.execute("""
SELECT id FROM activity_log
WHERE profile_id = %s AND date = %s AND start_time = %s
""", (pid, date, start))
existing = cur.fetchone()
if existing:
# Update existing entry (e.g., to add training type mapping)
cur.execute("""
UPDATE activity_log
SET end_time = %s,
activity_type = %s,
duration_min = %s,
kcal_active = %s,
kcal_resting = %s,
hr_avg = %s,
hr_max = %s,
distance_km = %s,
training_type_id = %s,
training_category = %s,
training_subcategory = %s
WHERE id = %s
""", (
row.get('End',''), wtype, duration_min,
kj(row.get('Aktive Energie (kJ)','')),
kj(row.get('Ruheeinträge (kJ)','')),
tf(row.get('Durchschn. Herzfrequenz (count/min)','')),
tf(row.get('Max. Herzfrequenz (count/min)','')),
tf(row.get('Distanz (km)','')),
training_type_id, training_category, training_subcategory,
existing['id']
))
skipped += 1 # Count as skipped (not newly inserted)
else:
# Insert new entry
cur.execute("""INSERT INTO activity_log
(id,profile_id,date,start_time,end_time,activity_type,duration_min,kcal_active,kcal_resting,
hr_avg,hr_max,distance_km,source,training_type_id,training_category,training_subcategory,created)
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,'apple_health',%s,%s,%s,CURRENT_TIMESTAMP)""",
(str(uuid.uuid4()),pid,date,start,row.get('End',''),wtype,duration_min,
kj(row.get('Aktive Energie (kJ)','')),kj(row.get('Ruheeinträge (kJ)','')),
tf(row.get('Durchschn. Herzfrequenz (count/min)','')),
tf(row.get('Max. Herzfrequenz (count/min)','')),
tf(row.get('Distanz (km)','')),
training_type_id,training_category,training_subcategory))
inserted+=1
except Exception as e:
logger.warning(f"Import row failed: {e}")
skipped+=1
return {"inserted":inserted,"skipped":skipped,"message":f"{inserted} Trainings importiert"}