import os import re from typing import List, Tuple from datetime import datetime from obsidian.py_models import Approach, Exercise, Training from apple.mapper import unique_apple_exercises_mapper current_directory = os.path.dirname(os.path.abspath(__file__)) def get_current_path(): return current_directory def get_obsidian_examples_file(example_file_name: str): return os.path.join(get_current_path(), f"examples/{example_file_name}") def read_example_file(example_file_name: str): path_to_example: str = get_obsidian_examples_file(example_file_name) with open(path_to_example, "r") as f: content = f.read() return content def filter_training_data(training_data: str): cleaned_text = re.sub( r"^\|(\s+|-*|\s-*\s)\|(\s+|-*|\s-*\s)\|(\s+|-*|\s-*\s)\|$", "", training_data, flags=re.MULTILINE, ) cleaned_text = re.sub(r"^\n", "", cleaned_text, flags=re.MULTILINE) lines = cleaned_text.splitlines() redundant_lines = [ "| | | |", "|---|---|---|", "|**Упражнение**|**Вес**|**Подходы**|", ] filtered_lines = [line for line in lines if line not in redundant_lines] return "\n".join(filtered_lines) def parse_training_header( training_data_line: str, ) -> Tuple[bool, str, str, str]: pattern: str = ( r"^\*\*(?P\d+.\d+.\d+)\s\((?P.+)(-(?P.+))?\)\*\*" ) match = re.search(pattern, training_data_line) if match: date = match.group("date").strip() trainer = match.group("trainer").strip() if match.group("year_counter"): year_count = match.group("year_counter").strip() else: year_count = 0 return True, date, trainer, year_count return False, "", "", "" def serialize_exercise(reps: str, weight: str, name: str) -> Exercise: # Split reps into array of int's reps: List[int] = [int(rep) for rep in reps.split("-")] weight_splitted: bool = False if weight: weight: List[str] = [weight for weight in weight.split("-")] # Check if weight is splitted if any(split_anchor in weight[0] for split_anchor in ["x", "х"]): weight_splitted = True splitter = "x" if "x" in weight[0] else "х" weight: List[float] = [xweight.split(splitter)[0] for xweight in weight] approaches = [] if not weight: for rep_index in range(0, len(reps)): approach = Approach(weight=0, reps=reps[rep_index]) approaches.append(approach) else: weight_pointer = 0 for rep_index in range(0, len(reps)): approach = Approach(weight=weight[weight_pointer], reps=reps[rep_index]) if rep_index < len(weight) - 1: weight_pointer += 1 approaches.append(approach) exercise = Exercise( name=name, approaches=approaches, splitted_weight=weight_splitted ) return exercise def parse_training_exercises(exercise_line: str) -> Exercise: stripped: List[str] = [entry.strip() for entry in exercise_line.split("|")][1:-1] for entry in stripped: if entry in ["Упражнение", "Вес", "Подходы"]: raise ValueError if stripped: if "---" in stripped[0]: raise ValueError if len(stripped) != 3: raise ValueError return serialize_exercise( name=stripped[0], weight=stripped[1], reps=stripped[2] ) def parse_training_data(): training_data: str = filter_training_data(read_example_file("full.txt")) lines = training_data.splitlines() current_training = None trains = [] for index, line in enumerate(lines): header_parsed, date, trainer, year_count = parse_training_header(line) if index == len(lines) - 1: trains.append(current_training) if header_parsed: trains.append(current_training) try: current_training = Training( date=datetime.strptime(date, "%d.%m.%Y").date(), exercises=[] ) except ValueError: current_training = Training( date=datetime.strptime(date, "%d.%m.%y").date(), exercises=[] ) continue try: exr = parse_training_exercises(line) current_training.exercises.append(exr) except ValueError: pass return trains[1:] def remap_unique_exercises(apple_trainings: List[Training]) -> List[Training]: for apple_training in apple_trainings: if not apple_training: continue for apple_exercise in apple_training.exercises: if not apple_exercise: continue print(f"{apple_training.date} : {apple_exercise}") apple_exercise.name = unique_apple_exercises_mapper.get(apple_exercise.name) return apple_trainings