import re from typing import List, Optional from app.core.dto.training import TrainingDTO from app.core.parsers.apple_mapper import unique_apple_exercises_mapper from app.core.parsers.base import BaseNotesParser, TrainingHeader class AppleNotesParser(BaseNotesParser): """Parser for Apple Notes format training data.""" HEADER_PATTERN = re.compile( r"^\*\*(?P\d+.\d+.\d+)\s\((?P.+?)(?:-(?P[^)]+))?\)\*\*" ) REDUNDANT_LINES = [ "| | | |", "|---|---|---|", "|**Упражнение**|**Вес**|**Подходы**|", ] def __init__(self): super().__init__("complete_data/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() filtered_lines = [line for line in lines if line not in self.REDUNDANT_LINES] return "\n".join(filtered_lines) def parse_training_header(self, training_data_line: str) -> Optional[TrainingHeader]: """Parse Apple Notes training header format.""" match = self.HEADER_PATTERN.search(training_data_line) if not match: return None year_counter = match.group("year_counter") return TrainingHeader( date=match.group("date").strip(), trainer=match.group("trainer").strip(), year_counter=year_counter.strip() if year_counter else None, ) def parse_training_data() -> List[TrainingDTO]: """Parse Apple Notes training data.""" return AppleNotesParser().parse_file()