Files
zwift-offline/workout_state.py
2026-04-22 13:00:26 +08:00

81 lines
2.5 KiB
Python

import datetime
import json
import os
import re
def normalize_provider_name(provider):
return re.sub(r'[^a-z0-9]+', '_', provider.lower()).strip('_') or 'provider'
def metadata_file(storage_dir, player_id, provider):
return os.path.join(storage_dir, str(player_id), f'{normalize_provider_name(provider)}_workout.json')
def build_metadata(provider, workout, filename):
return {
'provider': provider,
'event_id': workout.get('event_id', workout.get('id')),
'name': workout.get('name', workout.get('title')),
'filename': filename,
'start_date_local': workout.get('start_date_local'),
'start_date': workout.get('start_date'),
'synced_at': datetime.datetime.now(datetime.timezone.utc).isoformat(),
}
def save_metadata(storage_dir, player_id, provider, workout, filename):
payload = build_metadata(provider, workout, filename)
file = metadata_file(storage_dir, player_id, provider)
os.makedirs(os.path.dirname(file), exist_ok=True)
with open(file, 'w') as fd:
json.dump(payload, fd)
return payload
def load_metadata(storage_dir, player_id, provider):
file = metadata_file(storage_dir, player_id, provider)
if not os.path.exists(file):
return None
try:
with open(file) as fd:
return json.load(fd)
except Exception:
return None
def clear_metadata(storage_dir, player_id, provider):
file = metadata_file(storage_dir, player_id, provider)
if os.path.exists(file):
os.remove(file)
def active_provider_file(storage_dir, player_id):
return os.path.join(storage_dir, str(player_id), 'active_workout_provider.txt')
def save_active_provider(storage_dir, player_id, provider):
file = active_provider_file(storage_dir, player_id)
os.makedirs(os.path.dirname(file), exist_ok=True)
with open(file, 'w') as fd:
fd.write((provider or '').strip())
def load_active_provider(storage_dir, player_id):
file = active_provider_file(storage_dir, player_id)
if not os.path.exists(file):
return None
with open(file) as fd:
provider = fd.read().strip()
return provider or None
def resolve_active_provider(saved_provider, available_providers):
available = set(available_providers or set())
if saved_provider and saved_provider in available:
return saved_provider
for candidate in ('intervals-icu', 'trainingpeaks'):
if candidate in available:
return candidate
return None