import os import re from pprint import pprint from typing import List, Tuple from datetime import datetime from obsidian.py_models import Approach, Exercise, Training 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 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)): print(reps[rep_index]) 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 ) print(exercise) 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_header( training_data_line: str, ) -> Tuple[bool, str, str, str]: pattern: str = r"#\s(?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() year_count = match.group("year_counter").strip() return True, date, trainer, year_count return False, "", "", "" def filter_training_data(training_data: str): cleaned_text = re.sub(r"^\s*?\n", "", training_data, flags=re.MULTILINE) return cleaned_text 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) 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 for t in trains: pprint(t) print("\n") return trains pprint(parse_training_data()[1:])