import re from typing import List, Tuple from datetime import datetime from app.core.models.training import Training from app.core.parsers.apple_mapper import unique_apple_exercises_mapper from app.core.parsers.base import BaseNotesParser class AppleNotesParser(BaseNotesParser): """Parser for Apple Notes format training data.""" def __init__(self): super().__init__("apple.md", unique_apple_exercises_mapper) def filter_training_data(self, training_data: str) -> str: """Filter Apple-specific training data format.""" 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(self, training_data_line: str) -> Tuple[bool, str, str, str]: """Parse Apple Notes training header format.""" 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 create_training_from_date(self, date_str: str) -> Training: """Create Training object from date string with fallback parsing.""" try: return Training( date=datetime.strptime(date_str, "%d.%m.%Y").date(), exercises=[] ) except ValueError: return Training( date=datetime.strptime(date_str, "%d.%m.%y").date(), exercises=[] ) def parse(self, data: str) -> List[Training]: """Parse Apple Notes 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 Apple Notes training data.""" parser = AppleNotesParser() return parser.parse_training_data() def remap_unique_exercises(apple_trainings: List[Training]) -> List[Training]: """Remap exercise names using Apple-specific mapping (deprecated - use parser.parse_and_map_training_data()).""" parser = AppleNotesParser() return parser.apply_exercise_mapping(apple_trainings)