from .base import BaseDownloader from bs4 import BeautifulSoup import re class UptoboxDownloader(BaseDownloader): """Downloader for uptobox.com""" BASE_DOMAINS = ["uptobox.com", "uptobox.fr"] def can_handle(self, url: str) -> bool: return any(domain in url.lower() for domain in self.BASE_DOMAINS) async def get_download_link(self, url: str) -> tuple[str, str]: """Extract direct download link from uptobox""" try: response = await self.client.get(url, follow_redirects=True) soup = BeautifulSoup(response.text, 'lxml') # Method 1: Look for direct download button/link download_btn = soup.find('a', {'id': 'directDownload'}) or soup.find('a', class_='download-btn') if download_btn and download_btn.get('href'): href = download_btn['href'] filename = self._extract_filename_from_url(url) or "uptobox_file" return href, filename # Method 2: Look for any download link in page links = soup.find_all('a', href=True) for link in links: href = link['href'] text = link.get_text().lower() if any(keyword in text for keyword in ['download', 'télécharger', 'ddl']): if href.startswith('http'): filename = self._extract_filename_from_url(url) or "uptobox_file" return href, filename # Method 3: Return the original URL (uptobox handles downloads directly) filename = self._extract_filename_from_url(url) or "uptobox_file" return url, filename except Exception as e: raise Exception(f"Error extracting Uptobox link: {str(e)}") def _extract_filename_from_url(self, url: str) -> str | None: """Try to extract filename from URL""" # Look for filename parameter in URL match = re.search(r'[&?]filename=([^&]+)', url) if match: from urllib.parse import unquote return unquote(match.group(1)) # Extract from path parts = url.split('/') if len(parts) > 0: last_part = parts[-1] if '.' in last_part: return last_part return None