mirror of
https://github.com/pacnpal/Pac-cogs.git
synced 2025-12-20 19:01:06 -05:00
lol
This commit is contained in:
@@ -3,11 +3,20 @@
|
||||
import logging
|
||||
from typing import Dict, Any, Optional
|
||||
from datetime import datetime
|
||||
from enum import Enum, auto
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ProgressStatus(Enum):
|
||||
"""Status of a progress operation"""
|
||||
PENDING = auto()
|
||||
ACTIVE = auto()
|
||||
COMPLETED = auto()
|
||||
FAILED = auto()
|
||||
CANCELLED = auto()
|
||||
|
||||
class ProgressTracker:
|
||||
"""Progress tracker singleton."""
|
||||
"""Progress tracker for downloads and compressions."""
|
||||
_instance = None
|
||||
|
||||
def __new__(cls):
|
||||
@@ -18,296 +27,71 @@ class ProgressTracker:
|
||||
|
||||
def __init__(self):
|
||||
if not hasattr(self, '_initialized'):
|
||||
self._data: Dict[str, Dict[str, Any]] = {}
|
||||
self._download_progress: Dict[str, Dict[str, Any]] = {}
|
||||
self._compression_progress: Dict[str, Dict[str, Any]] = {}
|
||||
self._initialized = True
|
||||
|
||||
def update(self, key: str, data: Dict[str, Any]) -> None:
|
||||
"""Update progress for a key."""
|
||||
if key not in self._data:
|
||||
self._data[key] = {
|
||||
def update_download_progress(self, url: str, data: Dict[str, Any]) -> None:
|
||||
"""Update progress for a download."""
|
||||
if url not in self._download_progress:
|
||||
self._download_progress[url] = {
|
||||
'active': True,
|
||||
'start_time': datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
'percent': 0,
|
||||
'retries': 0
|
||||
}
|
||||
self._download_progress[url].update(data)
|
||||
self._download_progress[url]['last_update'] = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
|
||||
logger.debug(f"Download progress for {url}: {self._download_progress[url].get('percent', 0)}%")
|
||||
|
||||
def increment_download_retries(self, url: str) -> None:
|
||||
"""Increment retry count for a download."""
|
||||
if url in self._download_progress:
|
||||
self._download_progress[url]['retries'] = self._download_progress[url].get('retries', 0) + 1
|
||||
logger.debug(f"Incremented retries for {url} to {self._download_progress[url]['retries']}")
|
||||
|
||||
def get_download_progress(self, url: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""Get progress for a download."""
|
||||
if url is None:
|
||||
return self._download_progress
|
||||
return self._download_progress.get(url, {})
|
||||
|
||||
def update_compression_progress(self, file_path: str, data: Dict[str, Any]) -> None:
|
||||
"""Update progress for a compression."""
|
||||
if file_path not in self._compression_progress:
|
||||
self._compression_progress[file_path] = {
|
||||
'active': True,
|
||||
'start_time': datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
'percent': 0
|
||||
}
|
||||
self._data[key].update(data)
|
||||
self._data[key]['last_update'] = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
|
||||
logger.debug(f"Progress for {key}: {self._data[key].get('percent', 0)}%")
|
||||
self._compression_progress[file_path].update(data)
|
||||
self._compression_progress[file_path]['last_update'] = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
|
||||
logger.debug(f"Compression progress for {file_path}: {self._compression_progress[file_path].get('percent', 0)}%")
|
||||
|
||||
def get(self, key: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""Get progress for a key."""
|
||||
if key is None:
|
||||
return self._data
|
||||
return self._data.get(key, {})
|
||||
|
||||
def complete(self, key: str) -> None:
|
||||
"""Mark progress as complete."""
|
||||
if key in self._data:
|
||||
self._data[key]['active'] = False
|
||||
logger.info(f"Operation completed for {key}")
|
||||
|
||||
def clear(self) -> None:
|
||||
"""Clear all progress data."""
|
||||
self._data.clear()
|
||||
logger.info("Progress data cleared")
|
||||
|
||||
_tracker = ProgressTracker()
|
||||
|
||||
def get_compression(self, file_path: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""Get compression progress."""
|
||||
def get_compression_progress(self, file_path: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""Get progress for a compression."""
|
||||
if file_path is None:
|
||||
return self._compressions
|
||||
return self._compressions.get(file_path, {})
|
||||
return self._compression_progress
|
||||
return self._compression_progress.get(file_path, {})
|
||||
|
||||
def complete_download(self, url: str) -> None:
|
||||
"""Mark download as complete."""
|
||||
if url in self._downloads:
|
||||
self._downloads[url]['active'] = False
|
||||
if url in self._download_progress:
|
||||
self._download_progress[url]['active'] = False
|
||||
logger.info(f"Download completed for {url}")
|
||||
|
||||
def complete_compression(self, file_path: str) -> None:
|
||||
"""Mark compression as complete."""
|
||||
if file_path in self._compressions:
|
||||
self._compressions[file_path]['active'] = False
|
||||
logger.info(f"Compression completed for {file_path}")
|
||||
|
||||
def clear(self) -> None:
|
||||
"""Clear all progress data."""
|
||||
self._downloads.clear()
|
||||
self._compressions.clear()
|
||||
logger.info("Progress data cleared")
|
||||
|
||||
# Global instance
|
||||
_tracker = ProgressTrack
|
||||
|
||||
# Global instance
|
||||
_tracker = ProgressTracker()
|
||||
|
||||
def get_tracker() -> Progre
|
||||
"""Clear all progress tracking"""
|
||||
self._download_progress.clear()
|
||||
self._compression_progress.clear()
|
||||
logger.info("Cleared all progress tracking data")
|
||||
|
||||
# Create singleton instance
|
||||
progress_tracker = ProgressTracker()
|
||||
|
||||
def get_progress_tracker() -> ProgressTracker:
|
||||
|
||||
def mark_compression_complete(self, file_path: str) -> None:
|
||||
"""Mark a compression operation as complete"""
|
||||
if file_path in self._compression_progress:
|
||||
self._compression_progress[file_path]['active'] = False
|
||||
logger.info(f"Compression completed for {file_path}")
|
||||
|
||||
def clear_progress(self) -> None:
|
||||
"""Clear all progress tracking"""
|
||||
def clear(self) -> None:
|
||||
"""Clear all progress data."""
|
||||
self._download_progress.clear()
|
||||
self._compression_progress.clear()
|
||||
logger.info("Cleared all progress tracking data")
|
||||
logger.info("Progress data cleared")
|
||||
|
||||
# Create singleton instance
|
||||
progress_tracker = ProgressTracker()
|
||||
|
||||
# Export the singleton instance
|
||||
def get_progress_tracker() -> ProgressTracker:
|
||||
|
||||
|
||||
Args:
|
||||
data: Dictionary containing download progress data
|
||||
"""
|
||||
try:
|
||||
info_dict = data.get("info_dict", {})
|
||||
url = info_dict.get("webpage_url")
|
||||
if not url or url not in self._download_progress:
|
||||
return
|
||||
|
||||
if data.get("status") == "downloading":
|
||||
percent_str = data.get("_percent_str", "0").replace("%", "")
|
||||
try:
|
||||
percent = float(percent_str)
|
||||
except ValueError:
|
||||
percent = 0.0
|
||||
|
||||
total_bytes = (
|
||||
data.get("total_bytes", 0) or
|
||||
data.get("total_bytes_estimate", 0)
|
||||
)
|
||||
|
||||
self._download_progress[url].update({
|
||||
"active": True,
|
||||
"percent": percent,
|
||||
"speed": data.get("_speed_str", "N/A"),
|
||||
"eta": data.get("_eta_str", "N/A"),
|
||||
"downloaded_bytes": data.get("downloaded_bytes", 0),
|
||||
"total_bytes": total_bytes,
|
||||
"retries": data.get("retry_count", 0),
|
||||
"fragment_count": data.get("fragment_count", 0),
|
||||
"fragment_index": data.get("fragment_index", 0),
|
||||
"video_title": info_dict.get("title", "Unknown"),
|
||||
"extractor": info_dict.get("extractor", "Unknown"),
|
||||
"format": info_dict.get("format", "Unknown"),
|
||||
"resolution": info_dict.get("resolution", "Unknown"),
|
||||
"fps": info_dict.get("fps", "Unknown"),
|
||||
"last_update": datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
|
||||
})
|
||||
|
||||
logger.debug(
|
||||
f"Download progress for {url}: "
|
||||
f"{percent:.1f}% at {self._download_progress[url]['speed']}, "
|
||||
f"ETA: {self._download_progress[url]['eta']}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating download progress: {e}", exc_info=True)
|
||||
|
||||
def end_download(self, url: str, status: ProgressStatus = ProgressStatus.COMPLETED) -> None:
|
||||
"""
|
||||
Mark a download as completed.
|
||||
|
||||
Args:
|
||||
url: The URL being downloaded
|
||||
status: The final status of the download
|
||||
"""
|
||||
if url in self._download_progress:
|
||||
self._download_progress[url]["active"] = False
|
||||
logger.info(f"Download {status.value} for {url}")
|
||||
|
||||
def start_compression(self, params: CompressionParams) -> None:
|
||||
"""
|
||||
Initialize progress tracking for compression.
|
||||
|
||||
Args:
|
||||
params: Compression parameters
|
||||
"""
|
||||
current_time = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self._compression_progress[params.input_file] = CompressionProgress(
|
||||
active=True,
|
||||
filename=params.input_file,
|
||||
start_time=current_time,
|
||||
percent=0.0,
|
||||
elapsed_time="0:00",
|
||||
input_size=params.input_size,
|
||||
current_size=0,
|
||||
target_size=params.target_size,
|
||||
codec=params.codec_params.get("c:v", "unknown"),
|
||||
hardware_accel=params.use_hardware,
|
||||
preset=params.codec_params.get("preset", "unknown"),
|
||||
crf=params.codec_params.get("crf", "unknown"),
|
||||
duration=params.duration,
|
||||
bitrate=params.codec_params.get("b:v", "unknown"),
|
||||
audio_codec=params.codec_params.get("c:a", "unknown"),
|
||||
audio_bitrate=params.codec_params.get("b:a", "unknown"),
|
||||
last_update=current_time,
|
||||
current_time=None
|
||||
)
|
||||
|
||||
def update_compression_progress(
|
||||
self,
|
||||
input_file: str,
|
||||
progress: float,
|
||||
elapsed_time: str,
|
||||
current_size: int,
|
||||
current_time: float
|
||||
) -> None:
|
||||
"""
|
||||
Update compression progress information.
|
||||
|
||||
Args:
|
||||
input_file: The input file being compressed
|
||||
progress: Current progress percentage (0-100)
|
||||
elapsed_time: Time elapsed as string
|
||||
current_size: Current file size in bytes
|
||||
current_time: Current timestamp in seconds
|
||||
"""
|
||||
if input_file in self._compression_progress:
|
||||
self._compression_progress[input_file].update({
|
||||
"percent": max(0.0, min(100.0, progress)),
|
||||
"elapsed_time": elapsed_time,
|
||||
"current_size": current_size,
|
||||
"current_time": current_time,
|
||||
"last_update": datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
|
||||
})
|
||||
|
||||
logger.debug(
|
||||
f"Compression progress for {input_file}: "
|
||||
f"{progress:.1f}%, Size: {current_size}/{self._compression_progress[input_file]['target_size']} bytes"
|
||||
)
|
||||
|
||||
def end_compression(
|
||||
self,
|
||||
input_file: str,
|
||||
status: ProgressStatus = ProgressStatus.COMPLETED
|
||||
) -> None:
|
||||
"""
|
||||
Mark a compression operation as completed.
|
||||
|
||||
Args:
|
||||
input_file: The input file being compressed
|
||||
status: The final status of the compression
|
||||
"""
|
||||
if input_file in self._compression_progress:
|
||||
self._compression_progress[input_file]["active"] = False
|
||||
logger.info(f"Compression {status.value} for {input_file}")
|
||||
|
||||
def get_download_progress(self, url: Optional[str] = None) -> Optional[DownloadProgress]:
|
||||
"""
|
||||
Get progress information for a download.
|
||||
|
||||
Args:
|
||||
url: Optional URL to get progress for. If None, returns all progress.
|
||||
|
||||
Returns:
|
||||
Progress information for the specified download or None if not found
|
||||
"""
|
||||
if url is None:
|
||||
return self._download_progress
|
||||
return self._download_progress.get(url)
|
||||
|
||||
def get_compression_progress(
|
||||
self,
|
||||
input_file: Optional[str] = None
|
||||
) -> Optional[CompressionProgress]:
|
||||
"""
|
||||
Get progress information for a compression operation.
|
||||
|
||||
Args:
|
||||
input_file: Optional file to get progress for. If None, returns all progress.
|
||||
|
||||
Returns:
|
||||
Progress information for the specified compression or None if not found
|
||||
"""
|
||||
if input_file is None:
|
||||
return self._compression_progress
|
||||
return self._compression_progress.get(input_file)
|
||||
|
||||
def get_active_downloads(self) -> Dict[str, DownloadProgress]:
|
||||
"""
|
||||
Get all active downloads.
|
||||
|
||||
Returns:
|
||||
Dictionary of active downloads and their progress
|
||||
"""
|
||||
return {
|
||||
url: progress
|
||||
for url, progress in self._download_progress.items()
|
||||
if progress.get("active", False)
|
||||
}
|
||||
|
||||
def get_active_compressions(self) -> Dict[str, CompressionProgress]:
|
||||
"""
|
||||
Get all active compression operations.
|
||||
|
||||
Returns:
|
||||
Dictionary of active compressions and their progress
|
||||
"""
|
||||
return {
|
||||
input_file: progress
|
||||
for input_file, progress in self._compression_progress.items()
|
||||
if progress.get("active", False)
|
||||
}
|
||||
|
||||
def clear_progress(self) -> None:
|
||||
"""Clear all progress tracking"""
|
||||
self._download_progress.clear()
|
||||
self._compression_progress.clear()
|
||||
logger.info("Cleared
|
||||
def is_healthy(self) -> bool:
|
||||
"""Check if tracker is healthy."""
|
||||
return True # Basic health check, can be expanded if needed
|
||||
|
||||
Reference in New Issue
Block a user