""" File validation utilities for CAE Mesh Generator """ import os from pathlib import Path from typing import Tuple, Optional def validate_step_file(file_path: str) -> Tuple[bool, Optional[str]]: """ Validate if uploaded file is a valid STEP file Args: file_path: Path to the uploaded file Returns: Tuple of (is_valid, error_message) """ try: if not os.path.exists(file_path): return False, "File does not exist" # Check file size file_size = os.path.getsize(file_path) if file_size == 0: return False, "File is empty" if file_size > 100 * 1024 * 1024: # 100MB limit return False, "File too large (max 100MB)" # Check file extension file_ext = Path(file_path).suffix.lower() if file_ext not in ['.step', '.stp']: return False, f"Invalid file extension: {file_ext}" # Basic STEP file content validation try: with open(file_path, 'r', encoding='utf-8', errors='ignore') as f: first_line = f.readline().strip() if not first_line.startswith('ISO-10303'): return False, "Invalid STEP file format (missing ISO-10303 header)" # Check for basic STEP structure content = f.read(1000) # Read first 1000 chars if 'HEADER;' not in content and 'DATA;' not in content: return False, "Invalid STEP file structure" except UnicodeDecodeError: return False, "File encoding error - not a valid text-based STEP file" return True, None except Exception as e: return False, f"File validation error: {str(e)}" def get_file_info(file_path: str) -> dict: """ Get detailed file information Args: file_path: Path to the file Returns: Dictionary with file information """ try: stat = os.stat(file_path) return { 'size': stat.st_size, 'size_mb': round(stat.st_size / (1024 * 1024), 2), 'modified': stat.st_mtime, 'extension': Path(file_path).suffix.lower(), 'exists': True } except Exception as e: return { 'size': 0, 'size_mb': 0, 'modified': None, 'extension': '', 'exists': False, 'error': str(e) }