import copy import os import re from pprint import pprint from typing import Dict, List, Tuple 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 { # "name": stripped[0], # "weight": stripped[1], # "reps": stripped[2], # } 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, None, None, None 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("notes.txt")) training_template: Dict = { "date": None, "trainer": None, "year_count": None, "exercises": [], } parsed_trainings: List[List[str]] = [] current_training: Dict = {} lines = training_data.splitlines() for index, line in enumerate(lines): # Check for last line if index == len(lines) - 1: current_training["exercises"] = current_training["exercises"][1:] parsed_trainings.append(current_training) break header_parsed, date, trainer, year_count = parse_training_header(line) if header_parsed: if not current_training: pass else: current_training["exercises"] = current_training["exercises"][1:] parsed_trainings.append(current_training) current_training = copy.deepcopy(training_template) current_training["date"] = date current_training["trainer"] = trainer current_training["year_count"] = year_count try: exr = parse_training_exercises(line) current_training["exercises"].append(exr) except ValueError: pass trainings: List[Training] = [] for training in parsed_trainings: if not training: continue pprint(training) print("-" * 10) train = Training(date=training.get("date"), exercises=training.get("exercises")) return trainings pprint(parse_training_data()[1:])