🐛 Fix Uptodown downloader (#415)

This commit is contained in:
Việt Huỳnh
2023-12-11 19:37:35 +07:00
committed by GitHub
parent 910be73d8c
commit 9ee7adef52
+43 -21
View File
@@ -2,13 +2,13 @@
from typing import Any, Self from typing import Any, Self
import requests import requests
from bs4 import BeautifulSoup from bs4 import BeautifulSoup, Tag
from loguru import logger from loguru import logger
from src.app import APP from src.app import APP
from src.downloader.download import Downloader from src.downloader.download import Downloader
from src.exceptions import UptoDownAPKDownloadError from src.exceptions import UptoDownAPKDownloadError
from src.utils import bs4_parser, handle_request_response, request_header, request_timeout, session from src.utils import bs4_parser, handle_request_response, request_header, request_timeout
class UptoDown(Downloader): class UptoDown(Downloader):
@@ -18,24 +18,24 @@ class UptoDown(Downloader):
"""Extract download link from uptodown url.""" """Extract download link from uptodown url."""
r = requests.get(page, headers=request_header, allow_redirects=True, timeout=request_timeout) r = requests.get(page, headers=request_header, allow_redirects=True, timeout=request_timeout)
handle_request_response(r, page) handle_request_response(r, page)
soup = BeautifulSoup(r.text, bs4_parser) download_page_url = page.replace("/download", "/post-download")
download_button = soup.find(id="detail-download-button") download_page_html = requests.get(download_page_url, headers=request_header, timeout=request_timeout).text
if not download_button: soup = BeautifulSoup(download_page_html, bs4_parser)
msg = f"Unable to download {app} from uptodown." post_download = soup.find("div", class_="post-download")
raise UptoDownAPKDownloadError(msg, url=page)
download_url = download_button.get("data-url") # type: ignore[union-attr] if not isinstance(post_download, Tag):
if not download_url:
msg = f"Unable to download {app} from uptodown." msg = f"Unable to download {app} from uptodown."
raise UptoDownAPKDownloadError(msg, url=page) raise UptoDownAPKDownloadError(msg, url=page)
data_url = post_download.get("data-url")
download_url = f"https://dw.uptodown.com/dwn/{data_url}"
file_name = f"{app}.apk" file_name = f"{app}.apk"
if isinstance(download_url, str): self._download(download_url, file_name)
self._download(download_url, file_name)
return file_name, download_url return file_name, download_url
msg = f"Unable to download {app} from uptodown."
raise UptoDownAPKDownloadError(msg, url=page)
def specific_version(self: Self, app: APP, version: str) -> tuple[str, str]: def specific_version(self: Self, app: APP, version: str) -> tuple[str, str]:
"""Function to download the specified version of app from apkmirror. """Function to download the specified version of app from uptodown.
:param app: Name of the application :param app: Name of the application
:param version: Version of the application to download :param version: Version of the application to download
@@ -43,18 +43,40 @@ class UptoDown(Downloader):
""" """
logger.debug("downloading specified version of app from uptodown.") logger.debug("downloading specified version of app from uptodown.")
url = f"{app.download_source}/versions" url = f"{app.download_source}/versions"
html = session.get(url).text html = requests.get(url, headers=request_header, timeout=request_timeout).text
soup = BeautifulSoup(html, bs4_parser) soup = BeautifulSoup(html, bs4_parser)
versions_list = soup.find("section", {"id": "versions"}) detail_app_name = soup.find("h1", id="detail-app-name")
if not isinstance(detail_app_name, Tag):
msg = f"Unable to download {app} from uptodown."
raise UptoDownAPKDownloadError(msg, url=url)
app_code = detail_app_name.get("code")
version_page = 1
download_url = None download_url = None
for version_item in versions_list.find_all("div", {"data-url": True}): # type: ignore[union-attr] version_found = False
extracted_version = version_item.find("span", {"class": "version"}).text
if extracted_version == version: while not version_found:
download_url = version_item["data-url"] version_url = f"{app.download_source}/apps/{app_code}/versions/{version_page}"
r = requests.get(version_url, timeout=request_timeout)
handle_request_response(r, version_url)
json = r.json()
if "data" not in json:
break break
for item in json["data"]:
if item["version"] == version:
download_url = item["versionURL"]
version_found = True
break
version_page += 1
if download_url is None: if download_url is None:
msg = f"Unable to download {app.app_name} from uptodown." msg = f"Unable to download {app.app_name} from uptodown."
raise UptoDownAPKDownloadError(msg, url=url) raise UptoDownAPKDownloadError(msg, url=url)
return self.extract_download_link(download_url, app.app_name) return self.extract_download_link(download_url, app.app_name)
def latest_version(self: Self, app: APP, **kwargs: Any) -> tuple[str, str]: def latest_version(self: Self, app: APP, **kwargs: Any) -> tuple[str, str]: