From 78f6bb8c7ee33547d2f716d33594f1ad99019595 Mon Sep 17 00:00:00 2001 From: Chase Sterling Date: Tue, 26 Oct 2021 14:51:21 -0400 Subject: [PATCH] Fix issue where workout id is `[email protected]` --- pyproject.toml | 2 +- trainaspower/trainasone.py | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 43384b5..258a97f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "trainaspower" -version = "0.6.4" +version = "0.6.5" description = "Convert TrainAsOne plans to power and upload to Final Surge for use with Stryd pod." authors = ["Chase Sterling "] license = "MIT" diff --git a/trainaspower/trainasone.py b/trainaspower/trainasone.py index e6730f3..cf29357 100644 --- a/trainaspower/trainasone.py +++ b/trainaspower/trainasone.py @@ -56,6 +56,20 @@ def get_next_workouts(config) -> Generator[models.Workout, None, None]: ) from exc +def decode_cloudflare_email(encoded_email): + """ + The workout id gets protected as if it was an email address by cloudflare. :eyeroll: + """ + decoded = "" + chunks = [encoded_email[i:i+2] for i in range(0, len(encoded_email), 2)] + k = int(chunks[0], 16) + + for chunk in chunks[1:]: + decoded += chr(int(chunk, 16) ^ k) + + return decoded + + def get_workout(workout_url: str, date: datetime.date, config: models.Config) -> models.Workout: r = tao_session.get(workout_url) try: @@ -64,7 +78,14 @@ def get_workout(workout_url: str, date: datetime.date, config: models.Config) -> w = models.Workout() w.date = date name = workout_html.find(".summary span", first=True).text - number = workout_html.find(".summary sup", first=True).text + number_element = workout_html.find(".summary sup", first=True) + cf_email = number_element.find(".__cf_email__", first=True) + if cf_email: + number = decode_cloudflare_email(cf_email.attrs['data-cfemail']) + else: + number = number_element.text + number = number.rstrip("@") + w.duration = parse_duration(workout_html.find(".detail>span", first=True).text) w.distance = parse_distance(workout_html.find(".detail", first=True).text) w.id = number