🎨 Merge APKM bundles to get apk for patching (#297)

This commit is contained in:
Nikhil Badyal
2023-08-22 11:05:01 +00:00
committed by GitHub
parent 4e22efda31
commit 70dbea76c9
15 changed files with 148 additions and 108 deletions
+32 -32
View File
@@ -1,5 +1,5 @@
"""Downloader Class."""
from typing import Any
from typing import Any, Dict
import requests
from bs4 import BeautifulSoup, Tag
@@ -9,35 +9,37 @@ from scripts.status_check import headers
from src.downloader.download import Downloader
from src.downloader.sources import APK_MIRROR_BASE_URL, apk_sources
from src.exceptions import APKMirrorAPKDownloadFailure
from src.utils import bs4_parser
from src.utils import bs4_parser, contains_any_word
class ApkMirror(Downloader):
"""Files downloader."""
def _extract_force_download_link(self, link: str, app: str) -> None:
def _extract_force_download_link(self, link: str, app: str) -> str:
"""Extract force download link."""
notes_divs = self._extracted_search_div(link, "tab-pane")
apk_type = self._extracted_search_div(link, "apkm-badge").get_text()
extension = "zip" if apk_type == "BUNDLE" else "apk"
possible_links = notes_divs.find_all("a")
for possible_link in possible_links:
if possible_link.get("href") and "download.php?id=" in possible_link.get(
"href"
):
return self._download(
APK_MIRROR_BASE_URL + possible_link["href"], f"{app}.apk"
)
file_name = f"{app}.{extension}"
self._download(APK_MIRROR_BASE_URL + possible_link["href"], file_name)
return file_name
raise APKMirrorAPKDownloadFailure(
f"Unable to extract force download for {app}", url=link
)
def extract_download_link(self, main_page: str, app: str) -> None:
def extract_download_link(self, page: str, app: str) -> str:
"""Function to extract the download link from apkmirror html page.
:param main_page: Url of the page
:param page: Url of the page
:param app: Name of the app
"""
logger.debug(f"Extracting download link from\n{main_page}")
download_button = self._extracted_search_div(main_page, "center")
logger.debug(f"Extracting download link from\n{page}")
download_button = self._extracted_search_div(page, "center")
download_links = download_button.find_all("a")
if final_download_link := next(
(
@@ -48,13 +50,12 @@ class ApkMirror(Downloader):
),
None,
):
self._extract_force_download_link(
return self._extract_force_download_link(
APK_MIRROR_BASE_URL + final_download_link, app
)
else:
raise APKMirrorAPKDownloadFailure(
f"Unable to extract link from {app} version list", url=main_page
)
raise APKMirrorAPKDownloadFailure(
f"Unable to extract link from {app} version list", url=page
)
def get_download_page(self, main_page: str) -> str:
"""Function to get the download page in apk_mirror.
@@ -64,27 +65,26 @@ class ApkMirror(Downloader):
"""
list_widget = self._extracted_search_div(main_page, "listWidget")
table_rows = list_widget.find_all(class_="table-row")
sub_url = None
links: Dict[str, str] = {}
apk_archs = ["arm64-v8a", "universal", "noarch"]
for row in table_rows:
if row.find(class_="accent_color"):
apk_type = row.find(class_="apkm-badge").get_text()
if apk_type == "APK" and (
"arm64-v8a" in row.text.strip()
or "universal" in row.text.strip()
or "noarch" in row.text.strip()
):
sub_url = row.find(class_="accent_color")["href"]
break
if not sub_url:
raise APKMirrorAPKDownloadFailure(
"Unable to extract download page", url=main_page
)
return f"{APK_MIRROR_BASE_URL}{sub_url}"
sub_url = row.find(class_="accent_color")["href"]
text = row.text.strip()
if apk_type == "APK" and (not contains_any_word(text, apk_archs)):
continue
links[apk_type] = f"{APK_MIRROR_BASE_URL}{sub_url}"
if preferred_link := links.get("APK", links.get("BUNDLE")):
return preferred_link
raise APKMirrorAPKDownloadFailure(
"Unable to extract download page", url=main_page
)
@staticmethod
def _extracted_search_div(url: str, search_class: str) -> Tag:
"""Extract search div."""
r = requests.get(url, headers=headers, timeout=10)
r = requests.get(url, headers=headers, timeout=60)
if r.status_code != 200:
raise APKMirrorAPKDownloadFailure(
f"Unable to connect with {url} on ApkMirror. Are you blocked by APKMirror or abused apkmirror "
@@ -94,7 +94,7 @@ class ApkMirror(Downloader):
soup = BeautifulSoup(r.text, bs4_parser)
return soup.find(class_=search_class)
def specific_version(self, app: str, version: str, main_page: str = "") -> None:
def specific_version(self, app: str, version: str, main_page: str = "") -> str:
"""Function to download the specified version of app from apkmirror.
:param app: Name of the application
@@ -108,9 +108,9 @@ class ApkMirror(Downloader):
version_page = apk_main_page + apk_main_page.split("/")[-2]
main_page = f"{version_page}-{version}-release/"
download_page = self.get_download_page(main_page)
self.extract_download_link(download_page, app)
return self.extract_download_link(download_page, app)
def latest_version(self, app: str, **kwargs: Any) -> None:
def latest_version(self, app: str, **kwargs: Any) -> str:
"""Function to download whatever the latest version of app from
apkmirror.