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
This commit is contained in:
pacnpal
2024-11-16 22:46:29 +00:00
parent dac21f2fcd
commit d2d07c6bf6
5 changed files with 98 additions and 69 deletions

View File

@@ -7,11 +7,11 @@ import subprocess
from datetime import datetime from datetime import datetime
from typing import Dict, Optional, Callable, Set, Tuple from typing import Dict, Optional, Callable, Set, Tuple
from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager from ..ffmpeg.ffmpeg_manager import FFmpegManager
from videoarchiver.ffmpeg.exceptions import CompressionError from ..ffmpeg.exceptions import CompressionError
from videoarchiver.utils.exceptions import VideoVerificationError from .exceptions import VideoVerificationError
from videoarchiver.utils.file_operations import FileOperations from .file_operations import FileOperations
from videoarchiver.utils.progress_handler import ProgressHandler from .progress_handler import ProgressHandler
logger = logging.getLogger("VideoArchiver") logger = logging.getLogger("VideoArchiver")
@@ -207,4 +207,5 @@ class CompressionHandler:
self._active_processes.discard(process) self._active_processes.discard(process)
except Exception as e: except Exception as e:
logger.error(f"Compression attempt failed: {str logger.error(f"Compression attempt failed: {str(e)}")
return False

View File

@@ -1,16 +1,19 @@
"""Module for managing video compression""" """Manages video compression operations"""
import os import os
import logging
import asyncio import asyncio
import json import logging
import subprocess import subprocess
from datetime import datetime 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 from .exceptions import CompressionError, VideoVerificationError
logger = logging.getLogger("CompressionManager") logger = logging.getLogger("VideoArchiver")
class CompressionManager: class CompressionManager:
"""Manages video compression operations""" """Manages video compression operations"""
@@ -26,7 +29,7 @@ class CompressionManager:
self, self,
input_file: str, input_file: str,
output_file: str, output_file: str,
progress_callback: Optional[Callable[[float], None]] = None progress_callback: Optional[Callable[[float], None]] = None,
) -> Tuple[bool, str]: ) -> Tuple[bool, str]:
"""Compress a video file """Compress a video file
@@ -44,8 +47,7 @@ class CompressionManager:
try: try:
# Get optimal compression parameters # Get optimal compression parameters
compression_params = self.ffmpeg_mgr.get_compression_params( compression_params = self.ffmpeg_mgr.get_compression_params(
input_file, input_file, self.max_file_size // (1024 * 1024) # Convert to MB
self.max_file_size // (1024 * 1024) # Convert to MB
) )
# Try hardware acceleration first # Try hardware acceleration first
@@ -54,18 +56,20 @@ class CompressionManager:
output_file, output_file,
compression_params, compression_params,
progress_callback, progress_callback,
use_hardware=True use_hardware=True,
) )
# Fall back to CPU if hardware acceleration fails # Fall back to CPU if hardware acceleration fails
if not success: 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( success, error = await self._try_compression(
input_file, input_file,
output_file, output_file,
compression_params, compression_params,
progress_callback, progress_callback,
use_hardware=False use_hardware=False,
) )
if not success: if not success:
@@ -87,7 +91,7 @@ class CompressionManager:
output_file: str, output_file: str,
params: Dict[str, str], params: Dict[str, str],
progress_callback: Optional[Callable[[float], None]], progress_callback: Optional[Callable[[float], None]],
use_hardware: bool use_hardware: bool,
) -> Tuple[bool, str]: ) -> Tuple[bool, str]:
"""Attempt video compression with given parameters""" """Attempt video compression with given parameters"""
if self._shutting_down: if self._shutting_down:
@@ -96,10 +100,7 @@ class CompressionManager:
try: try:
# Build FFmpeg command # Build FFmpeg command
cmd = await self._build_ffmpeg_command( cmd = await self._build_ffmpeg_command(
input_file, input_file, output_file, params, use_hardware
output_file,
params,
use_hardware
) )
# Get video duration for progress calculation # Get video duration for progress calculation
@@ -107,17 +108,12 @@ class CompressionManager:
# Initialize compression progress tracking # Initialize compression progress tracking
await self._init_compression_progress( await self._init_compression_progress(
input_file, input_file, params, use_hardware, duration
params,
use_hardware,
duration
) )
# Run compression # Run compression
process = await asyncio.create_subprocess_exec( process = await asyncio.create_subprocess_exec(
*cmd, *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
) )
# Track the process # Track the process
@@ -126,11 +122,7 @@ class CompressionManager:
try: try:
success = await self._monitor_compression( success = await self._monitor_compression(
process, process, input_file, output_file, duration, progress_callback
input_file,
output_file,
duration,
progress_callback
) )
return success, "" return success, ""
@@ -146,7 +138,7 @@ class CompressionManager:
input_file: str, input_file: str,
output_file: str, output_file: str,
params: Dict[str, str], params: Dict[str, str],
use_hardware: bool use_hardware: bool,
) -> List[str]: ) -> List[str]:
"""Build FFmpeg command with appropriate parameters""" """Build FFmpeg command with appropriate parameters"""
ffmpeg_path = str(self.ffmpeg_mgr.get_ffmpeg_path()) ffmpeg_path = str(self.ffmpeg_mgr.get_ffmpeg_path())
@@ -177,7 +169,7 @@ class CompressionManager:
input_file: str, input_file: str,
output_file: str, output_file: str,
duration: float, duration: float,
progress_callback: Optional[Callable[[float], None]] progress_callback: Optional[Callable[[float], None]],
) -> bool: ) -> bool:
"""Monitor compression progress""" """Monitor compression progress"""
start_time = datetime.utcnow() start_time = datetime.utcnow()
@@ -198,7 +190,7 @@ class CompressionManager:
output_file, output_file,
duration, duration,
start_time, start_time,
progress_callback progress_callback,
) )
except Exception as e: except Exception as e:
logger.error(f"Error updating progress: {e}") logger.error(f"Error updating progress: {e}")
@@ -206,11 +198,7 @@ class CompressionManager:
await process.wait() await process.wait()
return os.path.exists(output_file) return os.path.exists(output_file)
async def _verify_output( async def _verify_output(self, input_file: str, output_file: str) -> bool:
self,
input_file: str,
output_file: str
) -> bool:
"""Verify compressed output file""" """Verify compressed output file"""
try: try:
# Check file exists and is not empty # Check file exists and is not empty
@@ -274,11 +262,9 @@ class CompressionManager:
input_file: str, input_file: str,
params: Dict[str, str], params: Dict[str, str],
use_hardware: bool, use_hardware: bool,
duration: float duration: float,
) -> None: ) -> None:
"""Initialize compression progress tracking""" """Initialize compression progress tracking"""
from videoarchiver.processor import _compression_progress
_compression_progress[input_file] = { _compression_progress[input_file] = {
"active": True, "active": True,
"filename": os.path.basename(input_file), "filename": os.path.basename(input_file),
@@ -306,7 +292,7 @@ class CompressionManager:
output_file: str, output_file: str,
duration: float, duration: float,
start_time: datetime, start_time: datetime,
progress_callback: Optional[Callable[[float], None]] progress_callback: Optional[Callable[[float], None]],
) -> None: ) -> None:
"""Update compression progress""" """Update compression progress"""
if line.startswith("out_time_ms="): if line.startswith("out_time_ms="):
@@ -314,17 +300,23 @@ class CompressionManager:
if duration > 0: if duration > 0:
progress = min(100, (current_time / duration) * 100) progress = min(100, (current_time / duration) * 100)
# Update compression progress
from videoarchiver.processor import _compression_progress
if input_file in _compression_progress: if input_file in _compression_progress:
elapsed = datetime.utcnow() - start_time elapsed = datetime.utcnow() - start_time
_compression_progress[input_file].update({ _compression_progress[input_file].update(
"percent": progress, {
"elapsed_time": str(elapsed).split(".")[0], "percent": progress,
"current_size": os.path.getsize(output_file) if os.path.exists(output_file) else 0, "elapsed_time": str(elapsed).split(".")[0],
"current_time": current_time, "current_size": (
"last_update": datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"), 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: if progress_callback:
progress_callback(progress) progress_callback(progress)

View File

@@ -7,12 +7,12 @@ import yt_dlp
from typing import Dict, Optional, Callable, Tuple from typing import Dict, Optional, Callable, Tuple
from pathlib import Path from pathlib import Path
from videoarchiver.utils.url_validator import check_url_support from .url_validator import check_url_support
from videoarchiver.utils.progress_handler import ProgressHandler, CancellableYTDLLogger from .progress_handler import ProgressHandler, CancellableYTDLLogger
from videoarchiver.utils.file_operations import FileOperations from .file_operations import FileOperations
from videoarchiver.utils.compression_handler import CompressionHandler from .compression_handler import CompressionHandler
from videoarchiver.utils.process_manager import ProcessManager from .process_manager import ProcessManager
from videoarchiver.ffmpeg.ffmpeg_manager import FFmpegManager from ..ffmpeg.ffmpeg_manager import FFmpegManager
logger = logging.getLogger("VideoArchiver") logger = logging.getLogger("VideoArchiver")
@@ -265,7 +265,5 @@ class DownloadCore:
async def force_cleanup(self) -> None: async def force_cleanup(self) -> None:
"""Force cleanup of all resources""" """Force cleanup of all resources"""
self.ytdl_logger.cancelled = True self.ytdl_logger.cancelled = True
await self.process_m
self.ytdl_logger.cancelled = True
await self.process_manager.force_cleanup() await self.process_manager.force_cleanup()
await self.compress await self.compression_handler.force_cleanup()

View File

@@ -3,6 +3,40 @@
from typing import Optional, Dict, Any from typing import Optional, Dict, Any
from enum import Enum, auto 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): class ErrorSeverity(Enum):
"""Severity levels for errors""" """Severity levels for errors"""
LOW = auto() LOW = auto()

View File

@@ -9,8 +9,8 @@ import subprocess
from typing import Tuple from typing import Tuple
from pathlib import Path from pathlib import Path
from videoarchiver.utils.exceptions import VideoVerificationError from .exceptions import VideoVerificationError
from videoarchiver.utils.file_deletion import secure_delete_file from .file_deletion import secure_delete_file
logger = logging.getLogger("VideoArchiver") logger = logging.getLogger("VideoArchiver")
@@ -135,4 +135,8 @@ class FileOperations:
if os.path.exists(file_path): if os.path.exists(file_path):
size = os.path.getsize(file_path) size = os.path.getsize(file_path)
max_size = max_size_mb * 1024 * 1024 max_size = max_size_mb * 1024 * 1024
return size <= max_size, size
return False, 0
except Exception as e:
logger.error(f"Error checking file size: {e}")
return False, 0