import requests from requests import RequestException import json import jinja2 from pathlib import Path class Athletico(): def fetch_episodes_for_access_code(self, access_code:str) -> dict: ''' Given a home access code, fetch exercise information :param access_code: the access code to a home excercise program from Athletico :return: a dict containing the exercise information ''' session = requests.Session() home_url = "https://athleticopt.medbridgego.com" fetch_episodes_url = "https://athleticopt.medbridgego.com/api/v4/lite/episodes/" session.get(home_url) csrf_token = session.cookies.get('csrf_cookie_name') session.post( url="https://athleticopt.medbridgego.com/register_token", data = { "token": access_code, "X-CSRF-Token": csrf_token, "verify_access_code": "Verify+Access+Code" } ) response = session.get(fetch_episodes_url) if response.ok and response.json() and response.json().get('status'): return response.json().get('episodes') else: raise RequestException(f'Request Failed, {response.status_code}: {response.reason}') def render(self, template: str, output: str, context: dict) -> str: ''' Renders an HTML page. :param template: Path to jinja template :param output: Destination for .html file :param context: The context to be passed to the render :return: Path to html file ''' output_filepath = Path(output) template_filepath = Path(output) environment = jinja2.Environment(loader=jinja2.FileSystemLoader()) template = environment.get_template(template_filepath) page = template.render(**context) output_filepath.mkdir(parents=True, exist_ok=True) with output_filepath.open('w') as f: f.write(page) return str(output_filepath) def save_episodes(self, episodes: list, destination: str= ".") -> None: ''' Outputs episodes to disk in a folder structure :param episodes: List of episode data, matches output of fetch_episodes_for_access_code :param destination: Filepath to save to, defaults to current directory :return: None ''' destination_filepath = Path(destination) destination_filepath.joinpath() for episode in episodes: episode_id = str(episode['id']) program = episode['program'] exercises = [] episode_filepath = destination_filepath.joinpath('programs',episode["token"],'episodes') episode_filepath.mkdir(parents=True, exist_ok=True) for exercise in program['program_exercises']: exercises.append(exercise) exercise_id = str(exercise['id']) exercise_filepath = destination_filepath.joinpath(destination,'exercises', exercise_id) thumbnails_filepath = exercise_filepath.joinpath('thumbnails') thumbnails_filepath.mkdir(parents=True, exist_ok=True) for i, image in enumerate(exercise['exercise']['thumbnails']): r = requests.get(image['image_filepath']) fname = image['image_filepath'].split('/')[-1] with thumbnails_filepath.joinpath(fname).open('wb') as f: f.write(r.content) with exercise_filepath.joinpath(exercise_id).with_suffix('.json').open('w') as f: json.dump(exercise, f) with exercise_filepath.joinpath(exercise_id).with_suffix('.txt').open('w') as f: f.write(exercise['name']) if exercise["exercise"]["video_file"]: with exercise_filepath.joinpath('video_file').with_suffix('.m3u8').open('wb') as f: try: r = requests.get("http:"+exercise["exercise"]["video_file"]) except: pass f.write(r.content) with exercise_filepath.joinpath('description').with_suffix('.html').open('w') as f: f.write(exercise["exercise"]["description"]) with episode_filepath.joinpath(episode_id).with_suffix('.json').open('w') as f: json.dump(episode, fp=f) return if __name__ == "__main__": pass