""" Validation logic for Scenar Creator. Extracted from scenar/core.py — validate_inputs, validate_excel_template, overlap detection. """ import pandas as pd from datetime import datetime import logging logger = logging.getLogger(__name__) DEFAULT_COLOR = "#ffffff" MAX_FILE_SIZE_MB = 10 REQUIRED_COLUMNS = ["Datum", "Zacatek", "Konec", "Program", "Typ", "Garant", "Poznamka"] class ScenarsError(Exception): """Base exception for Scenar Creator.""" pass class ValidationError(ScenarsError): """Raised when input validation fails.""" pass class TemplateError(ScenarsError): """Raised when Excel template is invalid.""" pass def validate_inputs(title: str, detail: str, file_size: int) -> None: """Validate user inputs for security and sanity.""" if not title or not isinstance(title, str): raise ValidationError("Title is required and must be a string") if len(title.strip()) == 0: raise ValidationError("Title cannot be empty") if len(title) > 200: raise ValidationError("Title is too long (max 200 characters)") if not detail or not isinstance(detail, str): raise ValidationError("Detail is required and must be a string") if len(detail.strip()) == 0: raise ValidationError("Detail cannot be empty") if len(detail) > 500: raise ValidationError("Detail is too long (max 500 characters)") if file_size > MAX_FILE_SIZE_MB * 1024 * 1024: raise ValidationError(f"File size exceeds {MAX_FILE_SIZE_MB} MB limit") def normalize_time(time_str: str): """Parse time string in formats %H:%M or %H:%M:%S.""" for fmt in ('%H:%M', '%H:%M:%S'): try: return datetime.strptime(time_str, fmt).time() except ValueError: continue return None def validate_excel_template(df: pd.DataFrame) -> None: """Validate that Excel has required columns.""" missing_cols = set(REQUIRED_COLUMNS) - set(df.columns) if missing_cols: raise TemplateError( f"Excel template missing required columns: {', '.join(missing_cols)}. " f"Expected: {', '.join(REQUIRED_COLUMNS)}" )