Spaces:
Sleeping
Sleeping
| """Audio Upload Data Transfer Object""" | |
| from dataclasses import dataclass | |
| from typing import Optional | |
| import mimetypes | |
| import os | |
| class AudioUploadDto: | |
| """DTO for file upload data | |
| Handles audio file upload information including filename, | |
| content, and content type validation. | |
| """ | |
| filename: str | |
| content: bytes | |
| content_type: str | |
| size: Optional[int] = None | |
| def __post_init__(self): | |
| """Validate the DTO after initialization""" | |
| # Add logging for debugging mp3 validation issues | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| logger.info(f"Validating AudioUploadDto - Filename: {self.filename}") | |
| logger.info(f"Content-Type: {self.content_type}") | |
| logger.info(f"File size: {len(self.content)} bytes") | |
| # Check file extension and MIME type mapping | |
| _, ext = os.path.splitext(self.filename.lower()) | |
| logger.info(f"File extension: {ext}") | |
| content_type_map = { | |
| '.wav': 'audio/wav', | |
| '.mp3': 'audio/mpeg', | |
| '.m4a': 'audio/mp4', | |
| '.flac': 'audio/flac', | |
| '.ogg': 'audio/ogg' | |
| } | |
| expected_content_type = content_type_map.get(ext) | |
| logger.info(f"Expected content type for {ext}: {expected_content_type}") | |
| logger.info(f"Actual content type: {self.content_type}") | |
| # Check mimetypes.guess_type result | |
| guessed_type = mimetypes.guess_type(self.filename)[0] | |
| logger.info(f"mimetypes.guess_type result: {guessed_type}") | |
| self._validate() | |
| if self.size is None: | |
| self.size = len(self.content) | |
| def _validate(self): | |
| """Validate audio upload data""" | |
| if not self.filename: | |
| raise ValueError("Filename cannot be empty") | |
| if not self.content: | |
| raise ValueError("Audio content cannot be empty") | |
| if not self.content_type: | |
| raise ValueError("Content type cannot be empty") | |
| # Validate file extension | |
| _, ext = os.path.splitext(self.filename.lower()) | |
| supported_extensions = ['.wav', '.mp3', '.m4a', '.flac', '.ogg'] | |
| if ext not in supported_extensions: | |
| raise ValueError(f"Unsupported file extension: {ext}. Supported: {supported_extensions}") | |
| # Validate content type | |
| expected_content_type = mimetypes.guess_type(self.filename)[0] | |
| if expected_content_type and not self.content_type.startswith('audio/'): | |
| raise ValueError(f"Invalid content type: {self.content_type}. Expected audio/* type") | |
| # Validate file size (max 100MB) | |
| max_size = 100 * 1024 * 1024 # 100MB | |
| if len(self.content) > max_size: | |
| raise ValueError(f"File too large: {len(self.content)} bytes. Maximum: {max_size} bytes") | |
| # Validate minimum file size (at least 1KB) | |
| min_size = 1024 # 1KB | |
| if len(self.content) < min_size: | |
| raise ValueError(f"File too small: {len(self.content)} bytes. Minimum: {min_size} bytes") | |
| def file_extension(self) -> str: | |
| """Get the file extension""" | |
| return os.path.splitext(self.filename.lower())[1] | |
| def base_filename(self) -> str: | |
| """Get filename without extension""" | |
| return os.path.splitext(self.filename)[0] | |
| def to_dict(self) -> dict: | |
| """Convert to dictionary representation""" | |
| return { | |
| 'filename': self.filename, | |
| 'content_type': self.content_type, | |
| 'size': self.size, | |
| 'file_extension': self.file_extension | |
| } |