import re from typing import List, Tuple from app.core.models.training import Training from app.core.parsers.obsidian_mapper import obsidian_unique_exercies_mapping from app.core.parsers.base import BaseNotesParser class ObsidianNotesParser(BaseNotesParser): """Parser for Obsidian Notes format training data.""" def __init__(self): super().__init__("obsidian.md", obsidian_unique_exercies_mapping) def filter_training_data(self, training_data: str) -> str: """Filter Obsidian-specific training data format.""" cleaned_text = re.sub(r"^\s*?\n", "", training_data, flags=re.MULTILINE) return cleaned_text def parse_training_header(self, training_data_line: str) -> Tuple[bool, str, str, str]: """Parse Obsidian Notes training header format.""" 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 parse(self, data: str) -> List[Training]: """Parse Obsidian training data from string input.""" # Override the data file reading with direct string input original_method = self.read_data_file self.read_data_file = lambda _: data try: trainings = self.parse_and_map_training_data() return trainings finally: # Restore original method self.read_data_file = original_method def parse_training_data() -> List[Training]: """Parse Obsidian Notes training data.""" parser = ObsidianNotesParser() return parser.parse_training_data() def remap_unique_exercises(obsidian_trainings: List[Training]) -> List[Training]: """Remap exercise names using Obsidian-specific mapping (deprecated - use parser.parse_and_map_training_data()).""" parser = ObsidianNotesParser() return parser.apply_exercise_mapping(obsidian_trainings)