From d2d07c6bf6422398d5f10c56ee232af2ebe6d895 Mon Sep 17 00:00:00 2001 From: pacnpal <183241239+pacnpal@users.noreply.github.com> Date: Sat, 16 Nov 2024 22:46:29 +0000 Subject: [PATCH] Fix import issues: - Add __all__ list to exceptions.py - Fix absolute imports to use relative imports - Fix duplicate imports - Fix truncated code in download_core.py - Add missing imports and type hints - Fix indentation and formatting issues --- videoarchiver/utils/compression_handler.py | 13 +-- videoarchiver/utils/compression_manager.py | 94 ++++++++++------------ videoarchiver/utils/download_core.py | 16 ++-- videoarchiver/utils/exceptions.py | 34 ++++++++ videoarchiver/utils/file_operations.py | 10 ++- 5 files changed, 98 insertions(+), 69 deletions(-) diff --git a/videoarchiver/utils/compression_handler.py b/videoarchiver/utils/compression_handler.py index d82debf..ba6ed88 100644 --- a/videoarchiver/utils/compression_handler.py +++ b/videoarchiver/utils/compression_handler.py @@ -7,11 +7,11 @@ import subprocess from datetime import datetime from typing import Dict, Optional, Callable, Set, Tuple -from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager -from videoarchiver.ffmpeg.exceptions import CompressionError -from videoarchiver.utils.exceptions import VideoVerificationError -from videoarchiver.utils.file_operations import FileOperations -from videoarchiver.utils.progress_handler import ProgressHandler +from ..ffmpeg.ffmpeg_manager import FFmpegManager +from ..ffmpeg.exceptions import CompressionError +from .exceptions import VideoVerificationError +from .file_operations import FileOperations +from .progress_handler import ProgressHandler logger = logging.getLogger("VideoArchiver") @@ -207,4 +207,5 @@ class CompressionHandler: self._active_processes.discard(process) except Exception as e: - logger.error(f"Compression attempt failed: {str \ No newline at end of file + logger.error(f"Compression attempt failed: {str(e)}") + return False diff --git a/videoarchiver/utils/compression_manager.py b/videoarchiver/utils/compression_manager.py index ceccbb8..72435f0 100644 --- a/videoarchiver/utils/compression_manager.py +++ b/videoarchiver/utils/compression_manager.py @@ -1,16 +1,19 @@ -"""Module for managing video compression""" +"""Manages video compression operations""" import os -import logging import asyncio -import json +import logging import subprocess from datetime import datetime -from typing import Dict, Optional, Tuple, Callable, Set +from typing import Dict, Any, Optional, Callable, List, Set, Tuple +from ..processor import _compression_progress +from .compression_handler import CompressionHandler +from .progress_handler import ProgressHandler +from .file_operations import FileOperations from .exceptions import CompressionError, VideoVerificationError -logger = logging.getLogger("CompressionManager") +logger = logging.getLogger("VideoArchiver") class CompressionManager: """Manages video compression operations""" @@ -26,15 +29,15 @@ class CompressionManager: self, input_file: str, output_file: str, - progress_callback: Optional[Callable[[float], None]] = None + progress_callback: Optional[Callable[[float], None]] = None, ) -> Tuple[bool, str]: """Compress a video file - + Args: input_file: Path to input video file output_file: Path to output video file progress_callback: Optional callback for compression progress - + Returns: Tuple[bool, str]: (Success status, Error message if any) """ @@ -44,8 +47,7 @@ class CompressionManager: try: # Get optimal compression parameters compression_params = self.ffmpeg_mgr.get_compression_params( - input_file, - self.max_file_size // (1024 * 1024) # Convert to MB + input_file, self.max_file_size // (1024 * 1024) # Convert to MB ) # Try hardware acceleration first @@ -54,18 +56,20 @@ class CompressionManager: output_file, compression_params, progress_callback, - use_hardware=True + use_hardware=True, ) # Fall back to CPU if hardware acceleration fails if not success: - logger.warning(f"Hardware acceleration failed: {error}, falling back to CPU encoding") + logger.warning( + f"Hardware acceleration failed: {error}, falling back to CPU encoding" + ) success, error = await self._try_compression( input_file, output_file, compression_params, progress_callback, - use_hardware=False + use_hardware=False, ) if not success: @@ -87,7 +91,7 @@ class CompressionManager: output_file: str, params: Dict[str, str], progress_callback: Optional[Callable[[float], None]], - use_hardware: bool + use_hardware: bool, ) -> Tuple[bool, str]: """Attempt video compression with given parameters""" if self._shutting_down: @@ -96,10 +100,7 @@ class CompressionManager: try: # Build FFmpeg command cmd = await self._build_ffmpeg_command( - input_file, - output_file, - params, - use_hardware + input_file, output_file, params, use_hardware ) # Get video duration for progress calculation @@ -107,17 +108,12 @@ class CompressionManager: # Initialize compression progress tracking await self._init_compression_progress( - input_file, - params, - use_hardware, - duration + input_file, params, use_hardware, duration ) # Run compression process = await asyncio.create_subprocess_exec( - *cmd, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE + *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) # Track the process @@ -126,11 +122,7 @@ class CompressionManager: try: success = await self._monitor_compression( - process, - input_file, - output_file, - duration, - progress_callback + process, input_file, output_file, duration, progress_callback ) return success, "" @@ -146,7 +138,7 @@ class CompressionManager: input_file: str, output_file: str, params: Dict[str, str], - use_hardware: bool + use_hardware: bool, ) -> List[str]: """Build FFmpeg command with appropriate parameters""" ffmpeg_path = str(self.ffmpeg_mgr.get_ffmpeg_path()) @@ -177,7 +169,7 @@ class CompressionManager: input_file: str, output_file: str, duration: float, - progress_callback: Optional[Callable[[float], None]] + progress_callback: Optional[Callable[[float], None]], ) -> bool: """Monitor compression progress""" start_time = datetime.utcnow() @@ -198,7 +190,7 @@ class CompressionManager: output_file, duration, start_time, - progress_callback + progress_callback, ) except Exception as e: logger.error(f"Error updating progress: {e}") @@ -206,11 +198,7 @@ class CompressionManager: await process.wait() return os.path.exists(output_file) - async def _verify_output( - self, - input_file: str, - output_file: str - ) -> bool: + async def _verify_output(self, input_file: str, output_file: str) -> bool: """Verify compressed output file""" try: # Check file exists and is not empty @@ -274,11 +262,9 @@ class CompressionManager: input_file: str, params: Dict[str, str], use_hardware: bool, - duration: float + duration: float, ) -> None: """Initialize compression progress tracking""" - from videoarchiver.processor import _compression_progress - _compression_progress[input_file] = { "active": True, "filename": os.path.basename(input_file), @@ -306,7 +292,7 @@ class CompressionManager: output_file: str, duration: float, start_time: datetime, - progress_callback: Optional[Callable[[float], None]] + progress_callback: Optional[Callable[[float], None]], ) -> None: """Update compression progress""" if line.startswith("out_time_ms="): @@ -314,17 +300,23 @@ class CompressionManager: if duration > 0: progress = min(100, (current_time / duration) * 100) - # Update compression progress - from videoarchiver.processor import _compression_progress if input_file in _compression_progress: elapsed = datetime.utcnow() - start_time - _compression_progress[input_file].update({ - "percent": progress, - "elapsed_time": str(elapsed).split(".")[0], - "current_size": os.path.getsize(output_file) if os.path.exists(output_file) else 0, - "current_time": current_time, - "last_update": datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"), - }) + _compression_progress[input_file].update( + { + "percent": progress, + "elapsed_time": str(elapsed).split(".")[0], + "current_size": ( + os.path.getsize(output_file) + if os.path.exists(output_file) + else 0 + ), + "current_time": current_time, + "last_update": datetime.utcnow().strftime( + "%Y-%m-%d %H:%M:%S" + ), + } + ) if progress_callback: progress_callback(progress) diff --git a/videoarchiver/utils/download_core.py b/videoarchiver/utils/download_core.py index b001b57..8d169f6 100644 --- a/videoarchiver/utils/download_core.py +++ b/videoarchiver/utils/download_core.py @@ -7,12 +7,12 @@ import yt_dlp from typing import Dict, Optional, Callable, Tuple from pathlib import Path -from videoarchiver.utils.url_validator import check_url_support -from videoarchiver.utils.progress_handler import ProgressHandler, CancellableYTDLLogger -from videoarchiver.utils.file_operations import FileOperations -from videoarchiver.utils.compression_handler import CompressionHandler -from videoarchiver.utils.process_manager import ProcessManager -from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager +from .url_validator import check_url_support +from .progress_handler import ProgressHandler, CancellableYTDLLogger +from .file_operations import FileOperations +from .compression_handler import CompressionHandler +from .process_manager import ProcessManager +from ..ffmpeg.ffmpeg_manager import FFmpegManager logger = logging.getLogger("VideoArchiver") @@ -265,7 +265,5 @@ class DownloadCore: async def force_cleanup(self) -> None: """Force cleanup of all resources""" self.ytdl_logger.cancelled = True - await self.process_m - self.ytdl_logger.cancelled = True await self.process_manager.force_cleanup() - await self.compress \ No newline at end of file + await self.compression_handler.force_cleanup() diff --git a/videoarchiver/utils/exceptions.py b/videoarchiver/utils/exceptions.py index a370b43..7fdf92a 100644 --- a/videoarchiver/utils/exceptions.py +++ b/videoarchiver/utils/exceptions.py @@ -3,6 +3,40 @@ from typing import Optional, Dict, Any from enum import Enum, auto +__all__ = [ + 'ErrorSeverity', + 'ErrorContext', + 'VideoArchiverError', + 'VideoDownloadError', + 'VideoProcessingError', + 'VideoVerificationError', + 'VideoUploadError', + 'VideoCleanupError', + 'FileCleanupError', + 'ConfigurationError', + 'PermissionError', + 'NetworkError', + 'ResourceError', + 'QueueError', + 'ComponentError', + 'DiscordAPIError', + 'ResourceExhaustedError', + 'ProcessingError', + 'CleanupError', + 'FileOperationError', + 'ProcessorError', + 'ValidationError', + 'DisplayError', + 'URLExtractionError', + 'MessageHandlerError', + 'QueueHandlerError', + 'QueueProcessorError', + 'FFmpegError', + 'DatabaseError', + 'HealthCheckError', + 'TrackingError' +] + class ErrorSeverity(Enum): """Severity levels for errors""" LOW = auto() diff --git a/videoarchiver/utils/file_operations.py b/videoarchiver/utils/file_operations.py index 1aa8349..327ce9c 100644 --- a/videoarchiver/utils/file_operations.py +++ b/videoarchiver/utils/file_operations.py @@ -9,8 +9,8 @@ import subprocess from typing import Tuple from pathlib import Path -from videoarchiver.utils.exceptions import VideoVerificationError -from videoarchiver.utils.file_deletion import secure_delete_file +from .exceptions import VideoVerificationError +from .file_deletion import secure_delete_file logger = logging.getLogger("VideoArchiver") @@ -135,4 +135,8 @@ class FileOperations: if os.path.exists(file_path): size = os.path.getsize(file_path) max_size = max_size_mb * 1024 * 1024 - \ No newline at end of file + return size <= max_size, size + return False, 0 + except Exception as e: + logger.error(f"Error checking file size: {e}") + return False, 0