diff --git a/core/download_orchestrator.py b/core/download_orchestrator.py index 5dff8143..4b2d8299 100644 --- a/core/download_orchestrator.py +++ b/core/download_orchestrator.py @@ -244,7 +244,8 @@ class DownloadOrchestrator: True if successful """ soulseek_cleared = await self.soulseek.clear_all_completed_downloads() - youtube_cleared = True # YouTube auto-removes completed downloads + # YouTube downloads must also be cleared from memory + youtube_cleared = await self.youtube.clear_all_completed_downloads() return soulseek_cleared and youtube_cleared diff --git a/core/youtube_client.py b/core/youtube_client.py index d05a04ff..4a1aa553 100644 --- a/core/youtube_client.py +++ b/core/youtube_client.py @@ -1029,6 +1029,33 @@ class YouTubeClient: file_path=download_info.get('file_path') ) + + async def clear_all_completed_downloads(self) -> bool: + """ + Clear all terminal (completed, cancelled, errored) downloads from the list. + Matches Soulseek interface. + """ + try: + with self._download_lock: + # Identify IDs to remove + ids_to_remove = [] + for download_id, info in self.active_downloads.items(): + state = info.get('state', '') + # Check for terminal states + # Note: We check exact strings used in _download_thread_worker and cancel_download + if state in ['Completed, Succeeded', 'Cancelled', 'Errored', 'Aborted']: + ids_to_remove.append(download_id) + + # Remove them + for download_id in ids_to_remove: + del self.active_downloads[download_id] + logger.debug(f"🗑️ Cleared finished download {download_id}") + + return True + except Exception as e: + logger.error(f"Error clearing downloads: {e}") + return False + async def cancel_download(self, download_id: str, username: str = None, remove: bool = False) -> bool: """ Cancel an active download (matches Soulseek interface).