mirror of
https://github.com/zoffline/zwift-offline.git
synced 2026-06-12 11:01:32 -07:00
79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
import os
|
|
import re
|
|
|
|
|
|
PARTNER_ACCESS_MESSAGE = (
|
|
'TrainingPeaks automatic sync requires approved partner API access and app credentials. '
|
|
'This provider is scaffolded but not yet live-configured.'
|
|
)
|
|
|
|
|
|
def slugify_filename(value):
|
|
value = (value or '').strip().lower()
|
|
value = re.sub(r'[^a-z0-9]+', '-', value)
|
|
return value.strip('-')
|
|
|
|
|
|
def build_workout_filename(workout):
|
|
workout_id = workout.get('id', 'workout')
|
|
name = slugify_filename(workout.get('name') or workout.get('title') or f'workout-{workout_id}')
|
|
if not name:
|
|
name = f'workout-{workout_id}'
|
|
return f'trainingpeaks-{workout_id}-{name}.zwo'
|
|
|
|
|
|
def build_exported_filename(path):
|
|
base = os.path.splitext(os.path.basename(path))[0]
|
|
slug = slugify_filename(base)
|
|
if not slug:
|
|
slug = 'workout'
|
|
return f'trainingpeaks-{slug}.zwo'
|
|
|
|
|
|
def sync_exported_workouts(folder, store_workout):
|
|
if not folder or not os.path.isdir(folder):
|
|
return {
|
|
'status': 'missing_folder',
|
|
'message': 'TrainingPeaks bridge folder is missing or unreadable.',
|
|
}
|
|
entries = []
|
|
for name in sorted(os.listdir(folder), key=lambda item: item.lower()):
|
|
path = os.path.join(folder, name)
|
|
if not os.path.isfile(path) or not name.lower().endswith('.zwo'):
|
|
continue
|
|
with open(path, 'rb') as fd:
|
|
content = fd.read()
|
|
filename = build_exported_filename(path)
|
|
workout = {'title': os.path.splitext(name)[0], 'source_path': path}
|
|
store_workout(filename, content, workout)
|
|
entries.append(filename)
|
|
if not entries:
|
|
return {
|
|
'status': 'no_workout',
|
|
'message': 'No .zwo workouts were found in the TrainingPeaks bridge folder.',
|
|
'count': 0,
|
|
}
|
|
return {
|
|
'status': 'synced',
|
|
'message': f'Imported {len(entries)} TrainingPeaks workout(s) from bridge folder.',
|
|
'count': len(entries),
|
|
'filenames': entries,
|
|
}
|
|
|
|
|
|
def sync_workout(credentials=None, **kwargs):
|
|
return {
|
|
'status': 'unsupported',
|
|
'message': PARTNER_ACCESS_MESSAGE,
|
|
'credentials_present': bool(credentials),
|
|
}
|
|
|
|
|
|
def upload_activity(credentials=None, activity=None, **kwargs):
|
|
return {
|
|
'status': 'unsupported',
|
|
'message': PARTNER_ACCESS_MESSAGE,
|
|
'credentials_present': bool(credentials),
|
|
'activity_present': activity is not None,
|
|
}
|