Files

96 lines
4.0 KiB
Python

"""
Модуль validation.py содержит классы и функции для валидации входных данных.
"""
import os
import magic
from typing import Dict, List
import logging
# Получаем логгер из централизованной настройки
logger = logging.getLogger('app.validators')
class ValidationError(Exception):
"""Исключение для ошибок валидации."""
pass
class FileValidator:
"""
Класс для валидации файлов.
Проверяет тип файла, размер и другие параметры на основе конфигурации.
"""
def __init__(self, config: Dict):
"""
Инициализация валидатора файлов.
Args:
config: Словарь с параметрами конфигурации.
"""
self.validation_config = config.get("file_validation", {})
self.max_file_size_mb = self.validation_config.get("max_file_size_mb", 100)
self.allowed_extensions = self.validation_config.get("allowed_extensions",
[".wav", ".mp3", ".ogg", ".flac", ".m4a"])
self.allowed_mime_types = self.validation_config.get("allowed_mime_types",
["audio/wav", "audio/mpeg", "audio/ogg",
"audio/flac", "audio/mp4"])
def _validate_file_extension(self, filename: str) -> None:
"""
Валидирует расширение файла.
Args:
filename: Имя файла.
Raises:
ValidationError: Если расширение файла не входит в список разрешенных.
"""
if not any(filename.lower().endswith(ext.lower()) for ext in self.allowed_extensions):
# Логирование попытки загрузки файла с неразрешенным расширением
file_extension = os.path.splitext(filename)[1]
logger.warning("Attempt to upload a file with disallowed extension '%s'. "
"Filename: %s. Allowed extensions: %s", file_extension, filename, ", ".join(self.allowed_extensions))
raise ValidationError(f"File extension is not allowed. "
f"Allowed extensions: {', '.join(self.allowed_extensions)}")
def validate_file_by_path(self, file_path: str, filename: str) -> bool:
"""
Валидирует файл по пути на диске.
Args:
file_path: Путь к файлу.
filename: Имя файла (для проверки расширения).
Returns:
True, если файл прошел валидацию.
Raises:
ValidationError: Если файл не прошел валидацию.
"""
# Проверка расширения
self._validate_file_extension(filename)
# Проверка размера
file_size = os.path.getsize(file_path)
max_size_bytes = self.max_file_size_mb * 1024 * 1024
if file_size > max_size_bytes:
raise ValidationError(f"File size ({file_size / (1024*1024):.2f} MB) "
f"exceeds the maximum allowed size ({self.max_file_size_mb} MB)")
# Проверка MIME-типа
try:
mime_type = magic.from_file(file_path, mime=True)
if mime_type not in self.allowed_mime_types:
raise ValidationError(f"File MIME type ({mime_type}) is not allowed. "
f"Allowed MIME types: {', '.join(self.allowed_mime_types)}")
except ValidationError:
raise
except Exception as e:
logger.warning("Failed to determine file MIME type: %s", e)
return True