diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cadb014..31d9c3d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.0.288' + rev: 'v0.0.289' hooks: - id: ruff args: diff --git a/pyproject.toml b/pyproject.toml index 9cdf4b6..4cce331 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,48 +1,6 @@ [tool.ruff] line-length = 120 -select = [ - "F", # pyflakes - "E", # pycodestyle Error - "W", # pycodestyle Warning - "C90", #mccabe - "I", #isort - "N", #isort - "D", #isort - "UP", # pyupgrade - "ANN", # flake8-annotations - "ASYNC", # flake8-async - "S", # flake8-bandit - "BLE", # flake8-blind-except - "FBT", #flake8-boolean-trap - "B", #flake8-bugbear - "A" , #flake8-builtins - "C4" , #flake8-comprehensions - "DTZ" , #flake8-datetimez - "T10" , #flake8-debugger - "EM" , #flake8-errmsg - "EXE" , #flake8-executable - "ISC" , #flake8-implicit-str-concat - "ICN" , #flake8-import-conventions - "G" , #flake8-logging-format - "INP" , #flake8-no-pep420 - "PIE" , #flake8-pie - "PYI" , #flake8-pyi - "RSE" , #flake8-raise - "RET" , #flake8-return - "SLF" , #flake8-self - "SIM" , #flake8-simplify - "TCH" , #flake8-type-checking - "INT" , #flake8-gettext - "ARG" , #flake8-unused-arguments - "PTH" , #flake8-use-pathlib - "ERA" , #eradicate - "PGH" , #pygrep-hooks - "PL" , #Pylint - "TRY" , #tryceratops - "FLY" , #flynt - "PERF" , #flynt - "RUF" , #Ruff-specific rules -] +select = [ "ALL"] ignore = [ "D401", "ANN401", @@ -55,6 +13,7 @@ ignore = [ "UP004", #useless-object-inheritance "PLR0911" #too many returns ] +target-version = "py311" fix = true show-fixes = true [tool.ruff.pydocstyle] diff --git a/scripts/status_check.py b/scripts/status_check.py index 64c1959..5bdd57e 100644 --- a/scripts/status_check.py +++ b/scripts/status_check.py @@ -1,7 +1,6 @@ """Status check.""" import re from pathlib import Path -from typing import List import requests from bs4 import BeautifulSoup, Tag @@ -53,7 +52,7 @@ def apkcombo_scrapper(package_name: str) -> str: raise APKComboIconScrapError(url=apkcombo_url) from e -def bigger_image(possible_links: List[str]) -> str: +def bigger_image(possible_links: list[str]) -> str: """Select image with higher dimension.""" higher_dimension_url = "" max_dimension = 0 @@ -125,7 +124,7 @@ def gplay_icon_scrapper(package_name: str) -> str: return str( gplay_app( package_name, - )["icon"] + )["icon"], ) except BuilderError as e: raise GooglePlayScraperException from e @@ -168,7 +167,7 @@ def icon_scrapper(package_name: str) -> str: return not_found_icon -def generate_markdown_table(data: List[List[str]]) -> str: +def generate_markdown_table(data: list[list[str]]) -> str: """Generate markdown table.""" if not data: return "No data to generate for the table." @@ -219,7 +218,7 @@ def main() -> None: output += table with Path("status.md").open("w", encoding="utf_8") as status: status.write(output) - print(output) + print(output) # noqa: T201 if __name__ == "__main__": diff --git a/src/app.py b/src/app.py index 6a86415..ae9fbd6 100644 --- a/src/app.py +++ b/src/app.py @@ -3,7 +3,7 @@ import concurrent import hashlib import pathlib from concurrent.futures import ThreadPoolExecutor -from typing import Dict, List, Self +from typing import Self from loguru import logger @@ -31,9 +31,9 @@ class APP(object): self.patches_dl = config.env.str(f"{app_name}_PATCHES_DL".upper(), config.global_patches_dl) self.integrations_dl = config.env.str(f"{app_name}_INTEGRATIONS_DL".upper(), config.global_integrations_dl) self.patches_json_dl = config.env.str(f"{app_name}_PATCHES_JSON_DL".upper(), config.global_patches_json_dl) - self.exclude_request: List[str] = config.env.list(f"{app_name}_EXCLUDE_PATCH".upper(), []) - self.include_request: List[str] = config.env.list(f"{app_name}_INCLUDE_PATCH".upper(), []) - self.resource: Dict[str, str] = {} + self.exclude_request: list[str] = config.env.list(f"{app_name}_EXCLUDE_PATCH".upper(), []) + self.include_request: list[str] = config.env.list(f"{app_name}_INCLUDE_PATCH".upper(), []) + self.resource: dict[str, str] = {} self.no_of_patches: int = 0 self.keystore_name = config.env.str(f"{app_name}_KEYSTORE_FILE_NAME".upper(), config.global_keystore_name) self.archs_to_build = config.env.list(f"{app_name}_ARCHS_TO_BUILD".upper(), config.global_archs_to_build) diff --git a/src/config.py b/src/config.py index f09f68c..c1fcfe0 100644 --- a/src/config.py +++ b/src/config.py @@ -1,6 +1,6 @@ """Revanced Configurations.""" from pathlib import Path -from typing import List, Self +from typing import Self from environs import Env @@ -20,7 +20,7 @@ class RevancedConfig(object): self.temp_folder_name = "apks" self.temp_folder = Path(self.temp_folder_name) self.ci_test = env.bool("CI_TEST", False) - self.rip_libs_apps: List[str] = [] + self.rip_libs_apps: list[str] = [] self.existing_downloaded_apks = env.list("EXISTING_DOWNLOADED_APKS", []) self.personal_access_token = env.str("PERSONAL_ACCESS_TOKEN", None) self.dry_run = env.bool("DRY_RUN", False) @@ -30,7 +30,7 @@ class RevancedConfig(object): self.global_integrations_dl = env.str("GLOBAL_INTEGRATIONS_DL", default_integrations) self.global_keystore_name = env.str("GLOBAL_KEYSTORE_FILE_NAME", "revanced.keystore") self.global_archs_to_build = env.list("GLOBAL_ARCHS_TO_BUILD", []) - self.extra_download_files: List[str] = env.list("EXTRA_FILES", []) + self.extra_download_files: list[str] = env.list("EXTRA_FILES", []) self.apk_editor = "apkeditor-output.jar" self.extra_download_files.append("https://github.com/REAndroid/APKEditor@apkeditor.jar") self.apps = env.list("PATCH_APPS", default_build) diff --git a/src/downloader/apkmirror.py b/src/downloader/apkmirror.py index 013f226..9e215f1 100644 --- a/src/downloader/apkmirror.py +++ b/src/downloader/apkmirror.py @@ -1,5 +1,5 @@ """Downloader Class.""" -from typing import Any, Dict, Self, Tuple +from typing import Any, Self import requests from bs4 import BeautifulSoup, Tag @@ -15,7 +15,7 @@ from src.utils import bs4_parser, contains_any_word, handle_request_response, re class ApkMirror(Downloader): """Files downloader.""" - def _extract_force_download_link(self: Self, link: str, app: str) -> Tuple[str, str]: + def _extract_force_download_link(self: Self, link: str, app: str) -> tuple[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() @@ -29,7 +29,7 @@ class ApkMirror(Downloader): msg = f"Unable to extract force download for {app}" raise APKMirrorAPKDownloadError(msg, url=link) - def extract_download_link(self: Self, page: str, app: str) -> Tuple[str, str]: + def extract_download_link(self: Self, page: str, app: str) -> tuple[str, str]: """Function to extract the download link from apkmirror html page. :param page: Url of the page @@ -58,7 +58,7 @@ class ApkMirror(Downloader): """ list_widget = self._extracted_search_div(main_page, "listWidget") table_rows = list_widget.find_all(class_="table-row") - links: Dict[str, str] = {} + links: dict[str, str] = {} apk_archs = ["arm64-v8a", "universal", "noarch"] for row in table_rows: if row.find(class_="accent_color"): @@ -81,7 +81,7 @@ class ApkMirror(Downloader): soup = BeautifulSoup(r.text, bs4_parser) return soup.find(class_=search_class) # type: ignore[return-value] - def specific_version(self: Self, app: APP, version: str, main_page: str = "") -> Tuple[str, str]: + def specific_version(self: Self, app: APP, version: str, main_page: str = "") -> tuple[str, str]: """Function to download the specified version of app from apkmirror. :param app: Name of the application @@ -97,7 +97,7 @@ class ApkMirror(Downloader): download_page = self.get_download_page(main_page) return self.extract_download_link(download_page, 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]: """Function to download whatever the latest version of app from apkmirror. :param app: Name of the application diff --git a/src/downloader/apkmonk.py b/src/downloader/apkmonk.py index c2bf5b8..49c5187 100644 --- a/src/downloader/apkmonk.py +++ b/src/downloader/apkmonk.py @@ -1,6 +1,6 @@ """APK Monk Downloader Class.""" import re -from typing import Any, Self, Tuple +from typing import Any, Self import requests from bs4 import BeautifulSoup @@ -16,7 +16,7 @@ from src.utils import bs4_parser, handle_request_response, request_header, reque class ApkMonk(Downloader): """Files downloader.""" - def extract_download_link(self: Self, page: str, app: str) -> Tuple[str, str]: + def extract_download_link(self: Self, page: str, app: str) -> tuple[str, str]: """Function to extract the download link from apkmonk html page. :param page: Url of the page @@ -48,7 +48,7 @@ class ApkMonk(Downloader): self._download(final_download_url, file_name) return file_name, final_download_url - def specific_version(self: Self, app: APP, version: str, main_page: str = "") -> Tuple[str, str]: + def specific_version(self: Self, app: APP, version: str, main_page: str = "") -> tuple[str, str]: """Function to download the specified version of app from apkmirror. :param app: Name of the application @@ -73,7 +73,7 @@ class ApkMonk(Downloader): url=app.download_source, ) - def latest_version(self: Self, app: APP, **kwargs: Any) -> Tuple[str, str]: + def latest_version(self: Self, app: APP, **kwargs: Any) -> tuple[str, str]: """Function to download whatever the latest version of app from apkmonkP. :param app: Name of the application diff --git a/src/downloader/apkpure.py b/src/downloader/apkpure.py index fd150e7..68d36d8 100644 --- a/src/downloader/apkpure.py +++ b/src/downloader/apkpure.py @@ -1,5 +1,5 @@ """APK Pure Downloader Class.""" -from typing import Any, Self, Tuple +from typing import Any, Self from src.app import APP from src.downloader.download import Downloader @@ -8,7 +8,7 @@ from src.downloader.download import Downloader class ApkPure(Downloader): """Files downloader.""" - def latest_version(self: Self, app: APP, **kwargs: Any) -> Tuple[str, str]: + def latest_version(self: Self, app: APP, **kwargs: Any) -> tuple[str, str]: """Function to download whatever the latest version of app from apkmirror. :param app: Name of the application diff --git a/src/downloader/apksos.py b/src/downloader/apksos.py index 3e46fb1..2272bae 100644 --- a/src/downloader/apksos.py +++ b/src/downloader/apksos.py @@ -1,5 +1,5 @@ """APK SOS Downloader Class.""" -from typing import Any, Self, Tuple +from typing import Any, Self import requests from bs4 import BeautifulSoup @@ -13,7 +13,7 @@ from src.utils import bs4_parser, handle_request_response, request_header, reque class ApkSos(Downloader): """Files downloader.""" - def extract_download_link(self: Self, page: str, app: str) -> Tuple[str, str]: + def extract_download_link(self: Self, page: str, app: str) -> tuple[str, str]: """Function to extract the download link from apkmirror html page. :param page: Url of the page @@ -32,7 +32,7 @@ class ApkSos(Downloader): msg = f"Unable to download {app}" raise APKSosAPKDownloadError(msg, url=page) - def latest_version(self: Self, app: APP, **kwargs: Any) -> Tuple[str, str]: + def latest_version(self: Self, app: APP, **kwargs: Any) -> tuple[str, str]: """Function to download whatever the latest version of app from apkmirror. :param app: Name of the application diff --git a/src/downloader/download.py b/src/downloader/download.py index 4c2eecc..44cf5b1 100644 --- a/src/downloader/download.py +++ b/src/downloader/download.py @@ -4,7 +4,7 @@ import subprocess from pathlib import Path from queue import PriorityQueue from time import perf_counter -from typing import Any, Self, Tuple +from typing import Any, Self from loguru import logger from tqdm import tqdm @@ -21,7 +21,7 @@ class Downloader(object): def __init__(self: Self, config: RevancedConfig) -> None: self._CHUNK_SIZE = 10485760 - self._QUEUE: PriorityQueue[Tuple[float, str]] = PriorityQueue() + self._QUEUE: PriorityQueue[tuple[float, str]] = PriorityQueue() self._QUEUE_LENGTH = 0 self.config = config @@ -61,11 +61,11 @@ class Downloader(object): self._QUEUE.put((perf_counter() - start, file_name)) logger.debug(f"Downloaded {file_name}") - def extract_download_link(self: Self, page: str, app: str) -> Tuple[str, str]: + def extract_download_link(self: Self, page: str, app: str) -> tuple[str, str]: """Extract download link from web page.""" raise NotImplementedError(implement_method) - 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. :param app: Name of the application @@ -74,7 +74,7 @@ class Downloader(object): """ raise NotImplementedError(implement_method) - def latest_version(self: Self, app: APP, **kwargs: Any) -> Tuple[str, str]: + def latest_version(self: Self, app: APP, **kwargs: Any) -> tuple[str, str]: """Function to download the latest version of app. :param app: Name of the application @@ -112,7 +112,7 @@ class Downloader(object): base_name, _ = os.path.splitext(filename) return base_name + new_extension - def download(self: Self, version: str, app: APP, **kwargs: Any) -> Tuple[str, str]: + def download(self: Self, version: str, app: APP, **kwargs: Any) -> tuple[str, str]: """Public function to download apk to patch. :param version: version to download diff --git a/src/downloader/github.py b/src/downloader/github.py index 72b3699..3bea84f 100644 --- a/src/downloader/github.py +++ b/src/downloader/github.py @@ -1,6 +1,6 @@ """Github Downloader.""" import re -from typing import Dict, Self, Tuple +from typing import Self from urllib.parse import urlparse import requests @@ -16,7 +16,7 @@ from src.utils import handle_request_response, request_timeout, update_changelog class Github(Downloader): """Files downloader.""" - def latest_version(self: Self, app: APP, **kwargs: Dict[str, str]) -> Tuple[str, str]: + def latest_version(self: Self, app: APP, **kwargs: dict[str, str]) -> tuple[str, str]: """Function to download files from GitHub repositories. :param app: App to download @@ -45,7 +45,7 @@ class Github(Downloader): return app.app_name, download_url @staticmethod - def _extract_repo_owner_and_tag(url: str) -> Tuple[str, str, str]: + def _extract_repo_owner_and_tag(url: str) -> tuple[str, str, str]: """Extract repo owner and url from github url.""" parsed_url = urlparse(url) path_segments = parsed_url.path.strip("/").split("/") diff --git a/src/downloader/google_drive.py b/src/downloader/google_drive.py index 37ff4f6..cf5d5d4 100644 --- a/src/downloader/google_drive.py +++ b/src/downloader/google_drive.py @@ -1,5 +1,5 @@ """Google Drive downloader Class.""" -from typing import Any, Self, Tuple +from typing import Any, Self import gdown @@ -10,7 +10,7 @@ from src.downloader.download import Downloader class GoogleDrive(Downloader): """Google Driver downloader.""" - 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. :param app: Name of the application @@ -19,7 +19,7 @@ class GoogleDrive(Downloader): """ return self.latest_version(app) - def latest_version(self: Self, app: APP, **kwargs: Any) -> Tuple[str, str]: + def latest_version(self: Self, app: APP, **kwargs: Any) -> tuple[str, str]: """Function to download whatever the latest version of app from Google Driver. :param app: Name of the application diff --git a/src/downloader/uptodown.py b/src/downloader/uptodown.py index e091380..89944dd 100644 --- a/src/downloader/uptodown.py +++ b/src/downloader/uptodown.py @@ -1,5 +1,5 @@ """Upto Down Downloader.""" -from typing import Any, Self, Tuple +from typing import Any, Self import requests from bs4 import BeautifulSoup @@ -14,7 +14,7 @@ from src.utils import bs4_parser, handle_request_response, request_header, reque class UptoDown(Downloader): """Files downloader.""" - def extract_download_link(self: Self, page: str, app: str) -> Tuple[str, str]: + def extract_download_link(self: Self, page: str, app: str) -> tuple[str, str]: """Extract download link from uptodown url.""" r = requests.get(page, headers=request_header, allow_redirects=True, timeout=request_timeout) handle_request_response(r, page) @@ -34,7 +34,7 @@ class UptoDown(Downloader): 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. :param app: Name of the application @@ -57,7 +57,7 @@ class UptoDown(Downloader): raise UptoDownAPKDownloadError(msg, url=url) 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]: """Function to download the latest version of app from uptodown.""" logger.debug("downloading latest version of app from uptodown.") page = f"{app.download_source}/download" diff --git a/src/parser.py b/src/parser.py index 5ab5171..13d0a16 100644 --- a/src/parser.py +++ b/src/parser.py @@ -2,7 +2,7 @@ from pathlib import Path from subprocess import PIPE, Popen from time import perf_counter -from typing import Dict, List, Self +from typing import Self from loguru import logger @@ -26,8 +26,8 @@ class Parser(object): OPTIONS_ARG = "--options" def __init__(self: Self, patcher: Patches, config: RevancedConfig) -> None: - self._PATCHES: List[str] = [] - self._EXCLUDED: List[str] = [] + self._PATCHES: list[str] = [] + self._EXCLUDED: list[str] = [] self.patcher = patcher self.config = config @@ -52,7 +52,7 @@ class Parser(object): self._PATCHES.extend(["-e", name]) self._EXCLUDED.append(name) - def get_excluded_patches(self: Self) -> List[str]: + def get_excluded_patches(self: Self) -> list[str]: """The function `get_excluded_patches` is a getter method that returns a list of excluded patches. Returns @@ -61,7 +61,7 @@ class Parser(object): """ return self._EXCLUDED - def get_all_patches(self: Self) -> List[str]: + def get_all_patches(self: Self) -> list[str]: """The function "get_all_patches" is a getter method that returns a ist of all patches. Returns @@ -104,13 +104,16 @@ class Parser(object): self._PATCHES[idx] = "-e" def include_exclude_patch( - self: Self, app: APP, patches: List[Dict[str, str]], patches_dict: Dict[str, str] + self: Self, + app: APP, + patches: list[dict[str, str]], + patches_dict: dict[str, str], ) -> None: """The function `include_exclude_patch` includes and excludes patches for a given app.""" for patch in patches: normalized_patch = patch["name"].lower().replace(" ", "-") self.include(normalized_patch) if normalized_patch not in app.exclude_request else self.exclude( - normalized_patch + normalized_patch, ) for normalized_patch in app.include_request: self.include(normalized_patch) if normalized_patch not in patches_dict["universal_patch"] else () diff --git a/src/patches.py b/src/patches.py index c2d1090..ab3a189 100644 --- a/src/patches.py +++ b/src/patches.py @@ -3,7 +3,7 @@ import contextlib import json from pathlib import Path -from typing import Any, ClassVar, Dict, List, Self, Tuple +from typing import Any, ClassVar, Self from loguru import logger @@ -15,7 +15,7 @@ from src.exceptions import AppNotFoundError, PatchesJsonLoadError class Patches(object): """Revanced Patches.""" - revanced_package_names: ClassVar[Dict[str, str]] = { + revanced_package_names: ClassVar[dict[str, str]] = { "com.reddit.frontpage": "reddit", "com.duolingo": "duolingo", "com.ss.android.ugc.trill": "tiktok", @@ -91,7 +91,7 @@ class Patches(object): raise AppNotFoundError(msg) @staticmethod - def support_app() -> Dict[str, str]: + def support_app() -> dict[str, str]: """The function returns a dictionary of supported app IDs. Returns @@ -132,10 +132,10 @@ class Patches(object): app.no_of_patches = len(self.patches_dict[app.app_name]) def __init__(self: Self, config: RevancedConfig, app: APP) -> None: - self.patches_dict: Dict[str, Any] = {"universal_patch": []} + self.patches_dict: dict[str, Any] = {"universal_patch": []} self.fetch_patches(config, app) - def get(self: Self, app: str) -> Tuple[List[Dict[str, str]], str]: + def get(self: Self, app: str) -> tuple[list[dict[str, str]], str]: """The function `get` returns all patches and version for a given application. Parameters @@ -156,7 +156,7 @@ class Patches(object): version = next(i["version"] for i in patches if i["version"] != "all") return patches, version - def get_app_configs(self: Self, app: "APP") -> List[Dict[str, str]]: + def get_app_configs(self: Self, app: "APP") -> list[dict[str, str]]: """The function `get_app_configs` returns configurations for a given app. Parameters diff --git a/src/utils.py b/src/utils.py index caef0db..a7e8953 100644 --- a/src/utils.py +++ b/src/utils.py @@ -3,7 +3,7 @@ import re import subprocess import sys from pathlib import Path -from typing import Any, Dict, List +from typing import Any import requests from loguru import logger @@ -32,7 +32,7 @@ session = Session() session.headers["User-Agent"] = request_header["User-Agent"] -def update_changelog(name: str, response: Dict[str, str]) -> None: +def update_changelog(name: str, response: dict[str, str]) -> None: """The function `update_changelog` updates the changelog file. Parameters @@ -49,7 +49,7 @@ def update_changelog(name: str, response: Dict[str, str]) -> None: write_to_file(change_log) -def format_changelog(name: str, response: Dict[str, str], parent_repo: str) -> str: +def format_changelog(name: str, response: dict[str, str], parent_repo: str) -> str: """The `format_changelog` returns formatted changelog string. Parameters @@ -194,6 +194,6 @@ def apkmirror_status_check(package_name: str) -> Any: return response.json() -def contains_any_word(string: str, words: List[str]) -> bool: +def contains_any_word(string: str, words: list[str]) -> bool: """Checks if a string contains any word.""" return any(word in string for word in words)