Files
docker-py-revanced/src/downloader/apkmirror.py
T
Nikhil Badyal bd5224c1a1 Per app config
2023-08-06 21:04:30 +05:30

105 lines
4.0 KiB
Python

"""Downloader Class."""
import re
from typing import Any
from loguru import logger
from selectolax.lexbor import LexborHTMLParser
from src.downloader.download import Downloader
from src.utils import AppNotFound
class ApkMirror(Downloader):
"""Files downloader."""
def extract_download_link(self, page: str, app: str) -> None:
"""Function to extract the download link from apkmirror html page.
:param page: Url of the page
:param app: Name of the app
"""
logger.debug(f"Extracting download link from\n{page}")
parser = LexborHTMLParser(self.config.session.get(page).text)
resp = self.config.session.get(
self.config.apk_mirror + parser.css_first("a.accent_bg").attributes["href"]
)
parser = LexborHTMLParser(resp.text)
href = parser.css_first(
"p.notes:nth-child(3) > span:nth-child(1) > a:nth-child(1)"
).attributes["href"]
self._download(self.config.apk_mirror + href, f"{app}.apk")
def get_download_page(self, parser: LexborHTMLParser, main_page: str) -> str:
"""Function to get the download page in apk_mirror.
:param parser: Parser
:param main_page: Main Download Page in APK mirror(Index)
:return:
"""
logger.debug(f"Getting download page from {main_page}")
apm = parser.css(".apkm-badge")
sub_url = ""
for is_apm in apm:
parent_text = is_apm.parent.parent.text()
if "APK" in is_apm.text() and (
"arm64-v8a" in parent_text
or "universal" in parent_text
or "noarch" in parent_text
):
parser = is_apm.parent
sub_url = parser.css_first(".accent_color").attributes["href"]
break
if sub_url == "":
logger.exception(
f"Unable to find any apk on apkmirror_specific_version on {main_page}"
)
raise AppNotFound("Unable to find apk on apkmirror site.")
download_url = self.config.apk_mirror + sub_url
return download_url
def specific_version(self, app: str, version: str) -> None:
"""Function to download the specified version of app from apkmirror.
:param app: Name of the application
:param version: Version of the application to download
:return: Version of downloaded apk
"""
version = version.replace(".", "-")
main_page = f"{self.config.apk_mirror_version_urls.get(app)}-{version}-release/"
parser = LexborHTMLParser(
self.config.session.get(main_page, allow_redirects=True).text
)
download_page = self.get_download_page(parser, main_page)
self.extract_download_link(download_page, app)
def latest_version(self, app: str, **kwargs: Any) -> None:
"""Function to download whatever the latest version of app from
apkmirror.
:param app: Name of the application
:return: Version of downloaded apk
"""
logger.debug(f"Trying to download {app}'s latest version from apkmirror")
page = self.config.apk_mirror_urls.get(app)
if not page:
logger.debug("Invalid app")
raise AppNotFound("Invalid app")
parser = LexborHTMLParser(self.config.session.get(page).text)
try:
main_page = parser.css_first(".appRowVariantTag>.accent_color").attributes[
"href"
]
except AttributeError:
# Handles a case when variants are not available
main_page = parser.css_first(".downloadLink").attributes["href"]
match = re.search(r"\d", main_page)
if not match:
logger.error("Cannot find app main page")
raise AppNotFound()
main_page = f"{self.config.apk_mirror}{main_page}"
parser = LexborHTMLParser(self.config.session.get(main_page).text)
download_page = self.get_download_page(parser, main_page)
self.extract_download_link(download_page, app)