From bd5224c1a1b9f73caf2bd91dc5a8b3044277de2d Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 17:21:16 +0530 Subject: [PATCH 01/14] =?UTF-8?q?=E2=9C=A8=20Per=20app=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- main.py | 77 ++++-------------- src/app.py | 94 ++++++++++++++++++++++ src/config.py | 35 +++----- src/downloader/apkmirror.py | 4 - src/downloader/download.py | 23 ++++-- src/downloader/github.py | 11 ++- src/downloader/utils.py | 59 -------------- src/parser.py | 42 +++------- src/patches.py | 156 ++++++++---------------------------- src/utils.py | 26 ++++++ 11 files changed, 222 insertions(+), 307 deletions(-) create mode 100644 src/app.py diff --git a/.gitignore b/.gitignore index 5ef80a1..aba434d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ venv /revanced-cache/ changelog.md .idea -*patches.json +*.json diff --git a/main.py b/main.py index b1b4869..071edac 100644 --- a/main.py +++ b/main.py @@ -6,86 +6,39 @@ from loguru import logger from src.config import RevancedConfig from src.downloader.factory import DownloaderFactory -from src.downloader.utils import download_revanced from src.parser import Parser from src.patches import Patches -from src.utils import AppNotFound, PatcherDownloadFailed +from src.utils import AppNotFound, PatchesJsonFailed, check_java def main() -> None: """Entry point.""" + from src.app import APP + env = Env() config = RevancedConfig(env) + check_java(config.dry_run) - patcher = Patches(config) - try: - download_revanced(config, patcher) - except PatcherDownloadFailed as e: - logger.error(f"Failed to download {e}") - sys.exit(1) - - logger.info(f"Will Patch only {patcher.config.apps}") - for app in patcher.config.apps: + logger.info(f"Will Patch only {config.apps}") + for app in config.apps: + logger.info("Trying to build %s" % app) try: - logger.info("Trying to build %s" % app) + app = APP(app_name=app, config=config) + patcher = Patches(config, app) parser = Parser(patcher, config) - app_all_patches, version, is_experimental = patcher.get_app_configs(app) + app_all_patches = patcher.get_app_configs(app) patcher.include_exclude_patch(app, parser, app_all_patches) downloader = DownloaderFactory.create_downloader( - app=app, patcher=patcher, config=config + app=app.app_name, patcher=patcher, config=config ) - downloader.download(version, app) - config.app_versions[app] = version - logger.info(f"Downloaded {app}, version {version}") - parser.patch_app(app=app, version=version, is_experimental=is_experimental) + downloader.download(app.app_version, app.app_name) + parser.patch_app(app) except AppNotFound as e: logger.info(f"Invalid app requested to build {e}") + except PatchesJsonFailed: + logger.exception("Patches.json not found") except Exception as e: logger.exception(f"Failed to build {app} because of {e}") - if len(config.alternative_youtube_patches) and "youtube" in config.apps: - for alternative_patch in config.alternative_youtube_patches: - parser = Parser(patcher, config) - app_all_patches, version, is_experimental = patcher.get_app_configs( - "youtube" - ) - patcher.include_exclude_patch("youtube", parser, app_all_patches) - was_inverted = parser.invert_patch(alternative_patch) - if was_inverted: - logger.info( - f"Rebuilding youtube with inverted {alternative_patch} patch." - ) - parser.patch_app( - app="youtube", - version=config.app_versions.get("youtube", "latest"), - is_experimental=is_experimental, - output_prefix="-" + alternative_patch + "-", - ) - else: - logger.info( - f"Skipping Rebuilding youtube as {alternative_patch} patch was not found." - ) - if len(config.alternative_youtube_music_patches) and "youtube_music" in config.apps: - for alternative_patch in config.alternative_youtube_music_patches: - parser = Parser(patcher, config) - app_all_patches, version, is_experimental = patcher.get_app_configs( - "youtube_music" - ) - patcher.include_exclude_patch("youtube_music", parser, app_all_patches) - was_inverted = parser.invert_patch(alternative_patch) - if was_inverted: - logger.info( - f"Rebuilding youtube music with inverted {alternative_patch} patch." - ) - parser.patch_app( - app="youtube_music", - version=config.app_versions.get("youtube_music", "latest"), - is_experimental=is_experimental, - output_prefix="-" + alternative_patch + "-", - ) - else: - logger.info( - f"Skipping Rebuilding youtube music as {alternative_patch} patch was not found." - ) if __name__ == "__main__": diff --git a/src/app.py b/src/app.py new file mode 100644 index 0000000..00337cb --- /dev/null +++ b/src/app.py @@ -0,0 +1,94 @@ +"""Class to represent apk to be patched.""" +import concurrent +import hashlib +import pathlib +from concurrent.futures import ThreadPoolExecutor +from typing import Dict + +from loguru import logger + +from src.config import RevancedConfig +from src.utils import PatcherDownloadFailed, slugify + + +class APP(object): + """Patched APK.""" + + def __init__(self, app_name: str, config: RevancedConfig): + self.app_name = app_name + self.app_version = config.env.str(f"{app_name}_VERSION".upper(), None) + self.experiment = False + self.cli_dl = config.env.str(f"{app_name}_CLI_DL".upper(), config.global_cli_dl) + 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}_INTEGRATION_DL".upper(), config.global_integrations_dl + ) + self.exclude_request = config.env.list(f"EXCLUDE_PATCH_{app_name}".upper(), []) + self.include_request = config.env.list(f"INCLUDE_PATCH_{app_name}".upper(), []) + self.resource: Dict[str, str] = {} + self.no_of_patches = 0 + self.download_patch_resources(config) + + def get_output_file_name(self) -> str: + """Get output file appended with version.""" + return f"Re-{self.app_name}-{slugify(self.app_version)}.apk" + + def set_recommended_version(self, version: str, exp: bool = False) -> None: + """Update if cooking non-recommended.""" + self.app_version = version + self.experiment = exp + + def __str__(self: "APP") -> str: + attrs = vars(self) + return ", ".join("%s: %s" % item for item in attrs.items()) + + @staticmethod + def download(url: str, config: RevancedConfig, assets_filter: str = None) -> str: # type: ignore + """Downloader.""" + from src.downloader.download import Downloader + + url = url.strip() + if url.startswith("https://github"): + from src.downloader.github import Github + + url = Github.patch_resource(url, assets_filter)[0] + extension = pathlib.Path(url).suffix + file_name = APP.generate_filename(url) + extension + Downloader(None, config).direct_download(url, file_name) # type: ignore + return file_name + + def download_patch_resources(self, config: RevancedConfig) -> None: + """Download resource for patching.""" + logger.info("Downloading resources for patching.") + # Create a list of resource download tasks + download_tasks = [ + ("cli", self.cli_dl, config), + ("integrations", self.integrations_dl, config), + ("patches", self.patches_dl, config, ".*jar"), + ("patches_json", self.patches_dl, config, ".*json"), + ] + + # Using a ThreadPoolExecutor for parallelism + with ThreadPoolExecutor() as executor: + futures = { + resource_name: executor.submit(self.download, *args) + for resource_name, *args in download_tasks + } + + # Wait for all tasks to complete + concurrent.futures.wait(futures.values()) + + # Retrieve results from completed tasks + for resource_name, future in futures.items(): + try: + self.resource[resource_name] = future.result() + except Exception as e: + raise PatcherDownloadFailed(f"An exception occurred: {e}") + + @staticmethod + def generate_filename(url: str) -> str: + """Get file name from url.""" + encoded_url: str = hashlib.sha256(url.encode()).hexdigest() + return encoded_url diff --git a/src/config.py b/src/config.py index d7b3471..39f657b 100644 --- a/src/config.py +++ b/src/config.py @@ -1,23 +1,27 @@ """Revanced Configurations.""" from pathlib import Path -from typing import Dict, List +from typing import List from environs import Env from requests import Session from src.utils import default_build +default_cli = "https://github.com/revanced/revanced-cli/releases/latest" +default_patches = "https://github.com/revanced/revanced-patches/releases/latest" +default_integrations = ( + "https://github.com/revanced/revanced-integrations/releases/latest" +) + class RevancedConfig(object): """Revanced Configurations.""" def __init__(self, env: Env) -> None: - self.app_versions: Dict[str, str] = {} self.env = env self.temp_folder = Path("apks") self.session = Session() self.session.headers["User-Agent"] = "anything" - self.build_extended = env.bool("BUILD_EXTENDED", False) self.apk_mirror = "https://www.apkmirror.com" self.upto_down = [ "spotify", @@ -34,27 +38,7 @@ class RevancedConfig(object): self.keystore_name = env.str("KEYSTORE_FILE_NAME", "revanced.keystore") self.ci_test = env.bool("CI_TEST", False) self.apps = env.list("PATCH_APPS", default_build) - self.extended_apps: List[str] = ["youtube", "youtube_music", "microg", "reddit"] - self.rip_libs_apps: List[str] = ["youtube"] - self.normal_cli_jar = "revanced-cli.jar" - self.normal_patches_jar = "revanced-patches.jar" - self.normal_integrations_apk = "revanced-integrations.apk" - self.normal_options_json = "options.json" - self.cli_jar = ( - f"inotia00-{self.normal_cli_jar}" - if self.build_extended - else self.normal_cli_jar - ) - self.patches_jar = ( - f"inotia00-{self.normal_patches_jar}" - if self.build_extended - else self.normal_patches_jar - ) - self.integrations_apk = ( - f"inotia00-{self.normal_integrations_apk}" - if self.build_extended - else self.normal_integrations_apk - ) + self.rip_libs_apps: List[str] = [] self.apk_mirror_urls = { "reddit": f"{self.apk_mirror}/apk/redditinc/reddit/", "twitter": f"{self.apk_mirror}/apk/x-corp/twitter/", @@ -97,3 +81,6 @@ class RevancedConfig(object): 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) + self.global_cli_dl = env.str("GLOBAL_CLI_DL", default_cli) + self.global_patches_dl = env.str("GLOBAL_CLI_DL", default_patches) + self.global_integrations_dl = env.str("GLOBAL_CLI_DL", default_integrations) diff --git a/src/downloader/apkmirror.py b/src/downloader/apkmirror.py index 4a80527..d0975af 100644 --- a/src/downloader/apkmirror.py +++ b/src/downloader/apkmirror.py @@ -30,7 +30,6 @@ class ApkMirror(Downloader): "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") - logger.debug("Finished Extracting link and downloading") def get_download_page(self, parser: LexborHTMLParser, main_page: str) -> str: """Function to get the download page in apk_mirror. @@ -67,7 +66,6 @@ class ApkMirror(Downloader): :param version: Version of the application to download :return: Version of downloaded apk """ - logger.debug(f"Trying to download {app},specific version {version}") version = version.replace(".", "-") main_page = f"{self.config.apk_mirror_version_urls.get(app)}-{version}-release/" parser = LexborHTMLParser( @@ -75,7 +73,6 @@ class ApkMirror(Downloader): ) download_page = self.get_download_page(parser, main_page) self.extract_download_link(download_page, app) - logger.debug(f"Downloaded {app} apk from apkmirror_specific_version") def latest_version(self, app: str, **kwargs: Any) -> None: """Function to download whatever the latest version of app from @@ -105,4 +102,3 @@ class ApkMirror(Downloader): 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) - logger.debug(f"Downloaded {app} apk from apkmirror_specific_version in rt") diff --git a/src/downloader/download.py b/src/downloader/download.py index 0dbe4e3..6960048 100644 --- a/src/downloader/download.py +++ b/src/downloader/download.py @@ -1,5 +1,6 @@ """Downloader Class.""" import os +from pathlib import Path from queue import PriorityQueue from time import perf_counter from typing import Any, Tuple @@ -23,14 +24,20 @@ class Downloader(object): self.config = config self.patcher = patcher - def _download(self, url: str, file_name: str) -> None: - if ( - os.path.exists(self.config.temp_folder.joinpath(file_name)) - or self.config.dry_run - ): + @staticmethod + def file_status_check(file_name: Path, dry_run: bool, url: str) -> bool: + """Check if file already exists.""" + if os.path.exists(file_name) or dry_run: logger.debug( - f"Skipping download of {file_name}. File already exists or dry running." + f"Skipping download of {file_name} from {url}. File already exists or dry running." ) + return True + return False + + def _download(self, url: str, file_name: str) -> None: + if self.file_status_check( + self.config.temp_folder.joinpath(file_name), self.config.dry_run, url + ): return logger.info(f"Trying to download {file_name} from {url}") self._QUEUE_LENGTH += 1 @@ -99,3 +106,7 @@ class Downloader(object): self.specific_version(app, version) else: self.latest_version(app, **kwargs) + + def direct_download(self, dl: str, file_name: str) -> None: + """Download from DL.""" + self._download(dl, file_name) diff --git a/src/downloader/github.py b/src/downloader/github.py index 91046c2..8121959 100644 --- a/src/downloader/github.py +++ b/src/downloader/github.py @@ -1,7 +1,8 @@ """Github Downloader.""" -from typing import Dict +from typing import Dict, List import requests +from lastversion import latest from loguru import logger from src.downloader.download import Downloader @@ -41,3 +42,11 @@ class Github(Downloader): download_url = response.json()["assets"][0]["browser_download_url"] update_changelog(f"{owner}/{repo_name}", response.json()) self._download(download_url, file_name=app) + + @staticmethod + def patch_resource(repo_url: str, assets_filter: str) -> list[str]: + """Fetch patch resource from repo url.""" + latest_resource_version: List[str] = latest( + repo_url, assets_filter=assets_filter, output_format="assets" + ) + return latest_resource_version diff --git a/src/downloader/utils.py b/src/downloader/utils.py index 6a62436..667199b 100644 --- a/src/downloader/utils.py +++ b/src/downloader/utils.py @@ -1,63 +1,4 @@ """Utility class.""" -import os -from concurrent.futures import ThreadPoolExecutor, as_completed -from loguru import logger - -from src.config import RevancedConfig -from src.patches import Patches -from src.utils import PatcherDownloadFailed implement_method = "Please implement the method" - - -def download_revanced(config: RevancedConfig, patcher: Patches) -> None: - """Download Revanced and Extended Patches, Integration and CLI.""" - from src.downloader.factory import DownloaderFactory - - if os.path.exists("changelog.md") and not config.dry_run: - logger.debug("Deleting old changelog.md") - os.remove("changelog.md") - assets = [ - ["revanced", "revanced-cli", config.normal_cli_jar], - ["revanced", "revanced-integrations", config.normal_integrations_apk], - ["revanced", "revanced-patches", config.normal_patches_jar], - ] - if config.build_extended: - assets += [ - ["inotia00", "revanced-cli", config.cli_jar], - ["inotia00", "revanced-integrations", config.integrations_apk], - ["inotia00", "revanced-patches", config.patches_jar], - ] - if ( - "youtube" in config.apps - or "youtube_music" in config.apps - or "microg" in config.apps - ): - if config.build_extended and "microg" in config.apps: - assets += [ - ["inotia00", "mMicroG", "microg.apk"], - ] - else: - assets += [ - ["inotia00", "mMicroG", "microg-output.apk"], - ] - downloader = DownloaderFactory.create_downloader( - app="patches", patcher=patcher, config=config - ) - with ThreadPoolExecutor(7) as executor: - futures = [ - executor.submit( - downloader.download, - version="latest", - app=repo[2], - **{"owner": repo[0], "name": repo[1]}, - ) - for repo in assets - ] - for future in as_completed(futures): - try: - future.result() - except Exception as e: - raise PatcherDownloadFailed(f"An exception occurred: {e}") - logger.info("Downloaded revanced microG ,cli, integrations and patches.") diff --git a/src/parser.py b/src/parser.py index e5694c4..8180847 100644 --- a/src/parser.py +++ b/src/parser.py @@ -6,9 +6,10 @@ from typing import List from loguru import logger +from src.app import APP from src.config import RevancedConfig from src.patches import Patches -from src.utils import possible_archs, slugify +from src.utils import possible_archs class Parser(object): @@ -70,43 +71,29 @@ class Parser(object): # noinspection IncorrectFormatting def patch_app( self, - app: str, - version: str, - is_experimental: bool = False, - output_prefix: str = "-", + app: APP, ) -> None: """Revanced APP Patcher. :param app: Name of the app - :param version: Version of the application - :param is_experimental: Whether to enable experimental support - :param output_prefix: Prefix to add to the output apks file name """ - cli = self.config.normal_cli_jar - patches = self.config.normal_patches_jar - integrations = self.config.normal_integrations_apk - options = self.config.normal_options_json - if self.config.build_extended and app in self.config.extended_apps: - cli = self.config.cli_jar - patches = self.config.patches_jar - integrations = self.config.integrations_apk args = [ "-jar", - cli, + app.resource["cli"], "-a", - app + ".apk", + app.app_name + ".apk", "-b", - patches, + app.resource["patches"], "-m", - integrations, + app.resource["integrations"], "-o", - f"Re-{app}-{slugify(version)}{output_prefix}output.apk", + app.get_output_file_name(), "--keystore", self.config.keystore_name, "--options", - options, + "options.json", ] - if is_experimental: + if app.experiment: logger.debug("Using experimental features") args.append("--experimental") args[1::2] = map(lambda i: self.config.temp_folder.joinpath(i), args[1::2]) @@ -114,11 +101,7 @@ class Parser(object): self.exclude_all_patches() if self._PATCHES: args.extend(self._PATCHES) - if ( - self.config.build_extended - and len(self.config.archs_to_build) > 0 - and app in self.config.rip_libs_apps - ): + if app.app_name in self.config.rip_libs_apps: excluded = set(possible_archs) - set(self.config.archs_to_build) for arch in excluded: args.append("--rip-lib") @@ -126,8 +109,9 @@ class Parser(object): start = perf_counter() logger.debug( - f"Sending request to revanced cli for building {app} revanced with args java {args}" + f"Sending request to revanced cli for building with args java {args}" ) + return process = Popen(["java", *args], stdout=PIPE) output = process.stdout if not output: diff --git a/src/patches.py b/src/patches.py index e168b81..48717ab 100644 --- a/src/patches.py +++ b/src/patches.py @@ -1,13 +1,13 @@ """Revanced Patches.""" import json -import subprocess +import os from typing import Any, Dict, List, Tuple from loguru import logger -from requests import Session +from src.app import APP from src.config import RevancedConfig -from src.utils import AppNotFound, handle_response +from src.utils import AppNotFound, PatchesJsonFailed class Patches(object): @@ -50,59 +50,28 @@ class Patches(object): "ml.docilealligator.infinityforreddit": "infinity", "me.ccrama.redditslide": "slide", "com.onelouder.baconreader": "bacon", + "com.google.android.youtube": "youtube", + "com.google.android.apps.youtube.music": "youtube_music", + "com.mgoogle.android.gms": "microg", } revanced_app_ids = { key: (value, "_" + value) for key, value in _revanced_app_ids.items() } - _revanced_extended_app_ids = { - "com.google.android.youtube": "youtube", - "com.google.android.apps.youtube.music": "youtube_music", - "com.mgoogle.android.gms": "microg", - "com.reddit.frontpage": "reddit", - } - revanced_extended_app_ids = { - key: (value, "_" + value) for key, value in _revanced_extended_app_ids.items() - } - @staticmethod - def support_app() -> Dict[str, str]: - """Return supported apps.""" - return Patches._revanced_app_ids - - @staticmethod - def check_java(dry_run: bool) -> None: - """Check if Java17 is installed.""" - try: - if dry_run: - return - jd = subprocess.check_output( - ["java", "-version"], stderr=subprocess.STDOUT - ).decode("utf-8") - jd = jd[1:-1] - if "Runtime Environment" not in jd: - raise subprocess.CalledProcessError(-1, "java -version") - if "17" not in jd and "20" not in jd: - raise subprocess.CalledProcessError(-1, "java -version") - logger.debug("Cool!! Java is available") - except subprocess.CalledProcessError: - logger.debug("Java>= 17 Must be installed") - exit(-1) + def scrap_patches(self, file_name: str) -> Any: + """Scrap Patches.""" + if os.path.exists(file_name): + with open(file_name) as f: + patches = json.load(f) + return patches + raise PatchesJsonFailed() # noinspection DuplicatedCode - def fetch_patches(self) -> None: + def fetch_patches(self, config: RevancedConfig, app: APP) -> None: """Function to fetch all patches.""" - session = Session() - if self.config.dry_run: - logger.debug("fetching all patches from local file") - with open("patches.json") as f: - patches = json.load(f) - else: - url = "https://raw.githubusercontent.com/revanced/revanced-patches/main/patches.json" - logger.debug(f"fetching all patches from {url}") - response = session.get(url) - handle_response(response) - patches = response.json() - + patches = self.scrap_patches( + f'{config.temp_folder}/{app.resource["patches_json"]}' + ) for app_name in (self.revanced_app_ids[x][1] for x in self.revanced_app_ids): setattr(self, app_name, []) setattr(self, "universal_patch", []) @@ -122,47 +91,11 @@ class Patches(object): p["app"] = compatible_package p["version"] = version[-1] if version else "all" getattr(self, app_name).append(p) - if self.config.dry_run: - extended_patches = patches - else: - if self.config.build_extended: - url = "https://raw.githubusercontent.com/inotia00/revanced-patches/revanced-extended/patches.json" - else: - url = "https://raw.githubusercontent.com/revanced/revanced-patches/main/patches.json" - response = session.get(url) - handle_response(response) - extended_patches = response.json() - for app_name in ( - self.revanced_extended_app_ids[x][1] for x in self.revanced_extended_app_ids - ): - setattr(self, app_name, []) + n_patches = len(getattr(self, f"_{app.app_name}")) + app.no_of_patches = n_patches - for patch in extended_patches: - for compatible_package, version in [ - (x["name"], x["versions"]) for x in patch["compatiblePackages"] - ]: - if compatible_package in self.revanced_extended_app_ids: - app_name = self.revanced_extended_app_ids[compatible_package][1] - p = {x: patch[x] for x in ["name", "description"]} - p["app"] = compatible_package - p["version"] = version[-1] if version else "all" - getattr(self, app_name).append(p) - - for app_name, app_id in self.revanced_extended_app_ids.values(): - n_patches = len(getattr(self, app_id)) - logger.debug(f"Total patches in {app_name} are {n_patches}") - for app_name, app_id in self.revanced_app_ids.values(): - n_patches = len(getattr(self, app_id)) - logger.debug(f"Total patches in {app_name} are {n_patches}") - n_patches = len(getattr(self, "universal_patch")) - logger.debug(f"Total universal patches are {n_patches}") - - def __init__(self, config: RevancedConfig) -> None: - self.config = config - self.check_java(self.config.dry_run) - self.fetch_patches() - if self.config.dry_run: - self.config.apps = list(self._revanced_app_ids.values()) + def __init__(self, config: RevancedConfig, app: APP) -> None: + self.fetch_patches(config, app) def get(self, app: str) -> Tuple[List[Dict[str, str]], str]: """Get all patches for the given app. @@ -170,11 +103,7 @@ class Patches(object): :param app: Name of the application :return: Patches """ - logger.debug("Getting patches for %s" % app) app_names = {value[0]: value[1] for value in self.revanced_app_ids.values()} - app_names.update( - {value[0]: value[1] for value in self.revanced_extended_app_ids.values()} - ) if not (app_name := app_names.get(app)): raise AppNotFound(app) @@ -182,14 +111,13 @@ class Patches(object): version = "latest" try: version = next(i["version"] for i in patches if i["version"] != "all") - logger.debug(f"Recommended Version for patching {app} is {version}") except StopIteration: pass return patches, version # noinspection IncorrectFormatting def include_exclude_patch( - self, app: str, parser: Any, patches: List[Dict[str, str]] + self, app: APP, parser: Any, patches: List[Dict[str, str]] ) -> None: """Include and exclude patches for a given app. @@ -197,34 +125,20 @@ class Patches(object): :param parser: Parser Obj :param patches: All the patches of a given app """ - if self.config.build_extended and app in self.config.extended_apps: - excluded_patches = self.config.env.list( - f"EXCLUDE_PATCH_{app}_EXTENDED".upper(), [] - ) - included_patches = self.config.env.list( - f"INCLUDE_PATCH_{app}_EXTENDED".upper(), [] - ) - else: - excluded_patches = self.config.env.list(f"EXCLUDE_PATCH_{app}".upper(), []) - included_patches = self.config.env.list(f"INCLUDE_PATCH_{app}".upper(), []) for patch in patches: normalized_patch = patch["name"].lower().replace(" ", "-") parser.include( normalized_patch - ) if normalized_patch not in excluded_patches else parser.exclude( + ) if normalized_patch not in app.exclude_request else parser.exclude( normalized_patch ) - for normalized_patch in included_patches: + for normalized_patch in app.include_request: parser.include(normalized_patch) if normalized_patch not in getattr( self, "universal_patch", [] ) else () - excluded = parser.get_excluded_patches() - if excluded: - logger.debug(f"Excluded patches {excluded} for {app}") - else: - logger.debug(f"No excluded patches for {app}") + logger.info(app) - def get_app_configs(self, app: str) -> Tuple[List[Dict[str, str]], str, bool]: + def get_app_configs(self, app: "APP") -> List[Dict[str, str]]: """Get Configurations for a given app. :param app: Name of the application @@ -232,15 +146,15 @@ class Patches(object): experimental """ experiment = False - total_patches, recommended_version = self.get(app=app) - env_version = self.config.env.str(f"{app}_VERSION".upper(), None) - if env_version: - logger.debug(f"Picked {app} version {env_version} from env.") + total_patches, recommended_version = self.get(app=app.app_name) + if app.app_version: + logger.debug(f"Picked {app} version {app.app_version:} from env.") if ( - env_version == "latest" - or env_version > recommended_version - or env_version < recommended_version + app.app_version == "latest" + or app.app_version > recommended_version + or app.app_version < recommended_version ): experiment = True - recommended_version = env_version - return total_patches, recommended_version, experiment + recommended_version = app.app_version + app.set_recommended_version(recommended_version, experiment) + return total_patches diff --git a/src/utils.py b/src/utils.py index 1cb7ad0..950bd6d 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,5 +1,6 @@ """Utilities.""" import re +import subprocess from typing import Dict from loguru import logger @@ -50,6 +51,12 @@ class PatcherDownloadFailed(Exception): pass +class PatchesJsonFailed(ValueError): + """Patches failed.""" + + pass + + def handle_response(response: Response) -> None: """Handle Get Request Response.""" response_code = response.status_code @@ -76,3 +83,22 @@ def slugify(string: str) -> str: string = string.strip("-") return string + + +def check_java(dry_run: bool) -> None: + """Check if Java17 is installed.""" + try: + if dry_run: + return + jd = subprocess.check_output( + ["java", "-version"], stderr=subprocess.STDOUT + ).decode("utf-8") + jd = jd[1:-1] + if "Runtime Environment" not in jd: + raise subprocess.CalledProcessError(-1, "java -version") + if "17" not in jd and "20" not in jd: + raise subprocess.CalledProcessError(-1, "java -version") + logger.debug("Cool!! Java is available") + except subprocess.CalledProcessError: + logger.debug("Java>= 17 Must be installed") + exit(-1) From c2c7e519560dc19e67a00c61cdb8da06664371ed Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 17:31:38 +0530 Subject: [PATCH 02/14] =?UTF-8?q?=F0=9F=93=9D=20Updated=20Docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 97 +++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 3a5b90d..6b86464 100644 --- a/README.md +++ b/README.md @@ -189,16 +189,10 @@ By default, script build the version as recommended by Revanced team. EXCLUDE_PATCH_YOUTUBE=custom-branding,hide-get-premium EXCLUDE_PATCH_YOUTUBE_MUSIC=yt-music-is-shit ``` - If you are using `Revanced Extended.` Add `_EXTENDED` in exclude options. - Example: - ```dotenv - EXCLUDE_PATCH_YOUTUBE_EXTENDED=custom-branding-red,custom-branding-blue,materialyou - EXCLUDE_PATCH_YOUTUBE_MUSIC_EXTENDED=custom-branding-music - ``` **_All the patches for an app are included by default._**.

If you want to apply a universal patch. You can include it manually. See below for more information.
- If you want to include any universal patch. Set comma separated patch in `.env` file or in `ENVS` in `GitHub +5. If you want to include any universal patch. Set comma separated patch in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format ```ini @@ -213,9 +207,23 @@ By default, script build the version as recommended by Revanced team. ```dotenv INCLUDE_PATCH_YOUTUBE_EXTENDED=remove-screenshot-restriction ``` - **_Remember_** - Revanced patches are provided space separated, make sure you type those **-** separated here. It means a - patch named _**Hey There**_ will be entered as **_hey-there_** in the above example. -5. If you want to build a specific version . Add `version` in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) + **_Remember_** - Revanced patches are provided space separated, make sure you type those **-** separated here. + It means a patch named _**Hey There**_ will be entered as **_hey-there_** in the above example. +6. If you want to use custom Patching resource. You can do so by providing respective DLs. Per app support is there too. + ```ini + YOUTUBE_MUSIC_INTEGRATION_DL=https://github.com/inotia00/revanced-integrations/releases/latest + YOUTUBE_MUSIC_PATCHES_DL=https://github.com/inotia00/revanced-patches/releases/latest + YOUTUBE_MUSIC_CLI_DL=https://github.com/inotia00/revanced-cli/releases/latest + ``` + These link if not from GitHub must be direct download links. +7. You can also provide a default resources which will be used when per app config is missing. + ```ini + GLOBAL_INTEGRATION_DL=https://github.com/inotia00/revanced-integrations/releases/latest + GLOBAL_PATCHES_DL=https://github.com/inotia00/revanced-patches/releases/latest + GLOBAL_CLI_DL=https://github.com/inotia00/revanced-cli/releases/latest + ``` + These link if not from GitHub must be direct download links. +8. If you want to build a specific version . Add `version` in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format ```ini _VERSION= @@ -229,7 +237,7 @@ By default, script build the version as recommended by Revanced team. TIKTOK_VERSION=X.X.X WARNWETTER_VERSION=X.X.X ``` -6. If you want to build `latest` version, whatever latest is available(including +9. If you want to build `latest` version, whatever latest is available(including beta) . Add `latest` in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format @@ -248,48 +256,39 @@ By default, script build the version as recommended by Revanced team. WARNWETTER_VERSION=latest ``` -7. If you don't want to use default keystore. You can provide your own by placing it - inside `apks` folder. And adding the name of `keystore-file` in `.env` file or in `ENVS` in `GitHub secrets` - (Recommended) in the format - ```dotenv - KEYSTORE_FILE_NAME=revanced.keystore - ``` -8. If you want to use Revanced-Extended for YouTube and YouTube Music. Add the following adding - in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format - ```dotenv - BUILD_EXTENDED=True - ``` - or disable it with (default) - ```dotenv - BUILD_EXTENDED=False - ``` -9. For Telegram Upload. - 1. Set up a telegram channel, send a message to it and forward the message to - this telegram [bot](https://t.me/username_to_id_bot) - 2. Copy `id` and save it to `TELEGRAM_CHAT_ID`
-
- 3. `TELEGRAM_BOT_TOKEN` - Telegram provides BOT_TOKEN. It works as sender. Open [bot](https://t.me/BotFather) and - create one copy api key
-
- 4. `TELEGRAM_API_ID` - Telegram API_ID is provided by telegram [here](https://my.telegram.org/apps)
-
- 5. `TELEGRAM_API_HASH` - Telegram API_HASH is provided by telegram [here](https://my.telegram.org/apps)
-
- 6. After Everything done successfully the actions secrets of the repository will look something like
- -10. You can build only for a particular arch in order to get smaller apk files.This can be done with by adding comma +10. If you don't want to use default keystore. You can provide your own by placing it + inside `apks` folder. And adding the name of `keystore-file` in `.env` file or in `ENVS` in `GitHub secrets` + (Recommended) in the format + ```dotenv + KEYSTORE_FILE_NAME=revanced.keystore + ``` +11. For Telegram Upload. + 1. Set up a telegram channel, send a message to it and forward the message to + this telegram [bot](https://t.me/username_to_id_bot) + 2. Copy `id` and save it to `TELEGRAM_CHAT_ID`
+
+ 3. `TELEGRAM_BOT_TOKEN` - Telegram provides BOT_TOKEN. It works as sender. Open [bot](https://t.me/BotFather) and + create one copy api key
+
+ 4. `TELEGRAM_API_ID` - Telegram API_ID is provided by telegram [here](https://my.telegram.org/apps)
+
+ 5. `TELEGRAM_API_HASH` - Telegram API_HASH is provided by telegram [here](https://my.telegram.org/apps)
+
+ 6. After Everything done successfully the actions secrets of the repository will look something like
+ +12. You can build only for a particular arch in order to get smaller apk files.This can be done with by adding comma separated `ARCHS_TO_BUILD` in `ENVS` in `GitHub secrets` (Recommended) in the format. ```dotenv ARCHS_TO_BUILD=arm64-v8a,armeabi-v7a ``` Possible values for `ARCHS_TO_BUILD` are: `armeabi-v7a`,`x86`,`x86_64`,`arm64-v8a` Make sure you are using `revanced-extended` as `revanced` doesn't support this. -11. You can scan your built apks files with VirusTotal. For that, Add `VT_API_KEY` in `GitHub secrets`. -12. Configuration defined in `ENVS` in `GitHub secrets` will override the configuration in `.env` file. You can use this +13. You can scan your built apks files with VirusTotal. For that, Add `VT_API_KEY` in `GitHub secrets`. +14. Configuration defined in `ENVS` in `GitHub secrets` will override the configuration in `.env` file. You can use this fact to define your normal configurations in `.env` file and sometimes if you want to build something different just once. Add it in `GitHub secrets`.
Or you can ignore what I said above and always use `GitHub secrets`. -13. If APKMirror or other apk source is blocked in your region or script somehow is unable to download from apkmirror. +15. If APKMirror or other apk source is blocked in your region or script somehow is unable to download from apkmirror. You can download apk manually from any source. Place them in `/apks` directory and provide environment variable in `.env` file or in `ENVS` in `GitHub secrets`(Recommended) in the format. ```dotenv @@ -303,18 +302,16 @@ By default, script build the version as recommended by Revanced team. `/apks` folder. Name of the downloaded apk must match with the available app choices found [here.](#note) -14. If you run script again & again. You might hit GitHub API limit. In that case you can provide your Personal +16. If you run script again & again. You might hit GitHub API limit. In that case you can provide your Personal GitHub Access Token in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format - ```dotenv PERSONAL_ACCESS_TOKEN= ``` -15. Sample Envs
+17. Sample Envs
-16. Make your Action has write access. If not click +18. Make your Action has write access. If not click [here](https://github.com/nikhilbadyal/docker-py-revanced/settings/actions). In the bottom give read and write access to Actions. -17. If you want to patch reddit apps using your own Client ID. You can provide your Client ID +19. If you want to patch reddit apps using your own Client ID. You can provide your Client ID as secret `REDDIT_CLIENT_ID` in `GitHub secrets`. - -Thanks to [@aliharslan0](https://github.com/aliharslan0/pyrevanced) for his work. From f419e0e36fdd21281a08912c82821ff7ac1cc67e Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 17:41:08 +0530 Subject: [PATCH 03/14] =?UTF-8?q?=F0=9F=8E=A8=20Per=20app=20key=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- src/app.py | 3 +++ src/config.py | 4 +++- src/parser.py | 3 +-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6b86464..b6bf901 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,7 @@ By default, script build the version as recommended by Revanced team. YOUTUBE_MUSIC_INTEGRATION_DL=https://github.com/inotia00/revanced-integrations/releases/latest YOUTUBE_MUSIC_PATCHES_DL=https://github.com/inotia00/revanced-patches/releases/latest YOUTUBE_MUSIC_CLI_DL=https://github.com/inotia00/revanced-cli/releases/latest + YOUTUBE_MUSIC_KEYSTORE_FILE_NAME=key.store ``` These link if not from GitHub must be direct download links. 7. You can also provide a default resources which will be used when per app config is missing. @@ -260,7 +261,7 @@ By default, script build the version as recommended by Revanced team. inside `apks` folder. And adding the name of `keystore-file` in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format ```dotenv - KEYSTORE_FILE_NAME=revanced.keystore + GLOBAL_KEYSTORE_FILE_NAME=revanced.keystore ``` 11. For Telegram Upload. 1. Set up a telegram channel, send a message to it and forward the message to diff --git a/src/app.py b/src/app.py index 00337cb..5a1ac5f 100644 --- a/src/app.py +++ b/src/app.py @@ -29,6 +29,9 @@ class APP(object): self.include_request = config.env.list(f"INCLUDE_PATCH_{app_name}".upper(), []) self.resource: Dict[str, str] = {} self.no_of_patches = 0 + self.keystore_name = config.env.str( + f"{app_name}_KEYSTORE_FILE_NAME".upper(), config.global_keystore_name + ) self.download_patch_resources(config) def get_output_file_name(self) -> str: diff --git a/src/config.py b/src/config.py index 39f657b..acd272a 100644 --- a/src/config.py +++ b/src/config.py @@ -35,7 +35,9 @@ class RevancedConfig(object): ] self.apk_pure = ["hex-editor", "androidtwelvewidgets"] self.apk_sos = ["expensemanager", "candyvpn"] - self.keystore_name = env.str("KEYSTORE_FILE_NAME", "revanced.keystore") + self.global_keystore_name = env.str( + "GLOBAL_KEYSTORE_FILE_NAME", "revanced.keystore" + ) self.ci_test = env.bool("CI_TEST", False) self.apps = env.list("PATCH_APPS", default_build) self.rip_libs_apps: List[str] = [] diff --git a/src/parser.py b/src/parser.py index 8180847..2a62080 100644 --- a/src/parser.py +++ b/src/parser.py @@ -89,7 +89,7 @@ class Parser(object): "-o", app.get_output_file_name(), "--keystore", - self.config.keystore_name, + app.keystore_name, "--options", "options.json", ] @@ -111,7 +111,6 @@ class Parser(object): logger.debug( f"Sending request to revanced cli for building with args java {args}" ) - return process = Popen(["java", *args], stdout=PIPE) output = process.stdout if not output: From b93b8a915d8b678c748d227fab2047e96b43150a Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 17:49:40 +0530 Subject: [PATCH 04/14] =?UTF-8?q?=F0=9F=8E=A8=20Per=20app=20arch=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++-- src/app.py | 3 +++ src/config.py | 2 +- src/parser.py | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b6bf901..e6ab75f 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,7 @@ By default, script build the version as recommended by Revanced team. YOUTUBE_MUSIC_PATCHES_DL=https://github.com/inotia00/revanced-patches/releases/latest YOUTUBE_MUSIC_CLI_DL=https://github.com/inotia00/revanced-cli/releases/latest YOUTUBE_MUSIC_KEYSTORE_FILE_NAME=key.store + YOUTUBE_MUSIC_ARCHS_TO_BUILD=arm64-v8a,armeabi-v7a ``` These link if not from GitHub must be direct download links. 7. You can also provide a default resources which will be used when per app config is missing. @@ -280,10 +281,10 @@ By default, script build the version as recommended by Revanced team. 12. You can build only for a particular arch in order to get smaller apk files.This can be done with by adding comma separated `ARCHS_TO_BUILD` in `ENVS` in `GitHub secrets` (Recommended) in the format. ```dotenv - ARCHS_TO_BUILD=arm64-v8a,armeabi-v7a + GLOABAL_ARCHS_TO_BUILD=arm64-v8a,armeabi-v7a ``` Possible values for `ARCHS_TO_BUILD` are: `armeabi-v7a`,`x86`,`x86_64`,`arm64-v8a` - Make sure you are using `revanced-extended` as `revanced` doesn't support this. + Make sure the patching resource support this. 13. You can scan your built apks files with VirusTotal. For that, Add `VT_API_KEY` in `GitHub secrets`. 14. Configuration defined in `ENVS` in `GitHub secrets` will override the configuration in `.env` file. You can use this fact to define your normal configurations in `.env` file and sometimes if you want to build something different just diff --git a/src/app.py b/src/app.py index 5a1ac5f..9572cb7 100644 --- a/src/app.py +++ b/src/app.py @@ -32,6 +32,9 @@ class APP(object): 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 + ) self.download_patch_resources(config) def get_output_file_name(self) -> str: diff --git a/src/config.py b/src/config.py index acd272a..f61521e 100644 --- a/src/config.py +++ b/src/config.py @@ -75,7 +75,7 @@ class RevancedConfig(object): key: value + value.split("/")[-2] for key, value in self.apk_mirror_urls.items() } - self.archs_to_build = env.list("ARCHS_TO_BUILD", []) + self.global_archs_to_build = env.list("GLOBAL_ARCHS_TO_BUILD", []) self.alternative_youtube_patches = env.list("ALTERNATIVE_YOUTUBE_PATCHES", []) self.alternative_youtube_music_patches = env.list( "ALTERNATIVE_YOUTUBE_MUSIC_PATCHES", [] diff --git a/src/parser.py b/src/parser.py index 2a62080..2e1d647 100644 --- a/src/parser.py +++ b/src/parser.py @@ -102,7 +102,7 @@ class Parser(object): if self._PATCHES: args.extend(self._PATCHES) if app.app_name in self.config.rip_libs_apps: - excluded = set(possible_archs) - set(self.config.archs_to_build) + excluded = set(possible_archs) - set(app.archs_to_build) for arch in excluded: args.append("--rip-lib") args.append(arch) From 2680881e202c0a9358bd403c776418fb455a2ad0 Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 17:53:09 +0530 Subject: [PATCH 05/14] =?UTF-8?q?=F0=9F=90=9B=20Fix=20variable=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/config.py b/src/config.py index f61521e..5d03de9 100644 --- a/src/config.py +++ b/src/config.py @@ -35,9 +35,6 @@ class RevancedConfig(object): ] self.apk_pure = ["hex-editor", "androidtwelvewidgets"] self.apk_sos = ["expensemanager", "candyvpn"] - self.global_keystore_name = env.str( - "GLOBAL_KEYSTORE_FILE_NAME", "revanced.keystore" - ) self.ci_test = env.bool("CI_TEST", False) self.apps = env.list("PATCH_APPS", default_build) self.rip_libs_apps: List[str] = [] @@ -75,7 +72,6 @@ class RevancedConfig(object): key: value + value.split("/")[-2] for key, value in self.apk_mirror_urls.items() } - self.global_archs_to_build = env.list("GLOBAL_ARCHS_TO_BUILD", []) self.alternative_youtube_patches = env.list("ALTERNATIVE_YOUTUBE_PATCHES", []) self.alternative_youtube_music_patches = env.list( "ALTERNATIVE_YOUTUBE_MUSIC_PATCHES", [] @@ -84,5 +80,11 @@ class RevancedConfig(object): self.personal_access_token = env.str("PERSONAL_ACCESS_TOKEN", None) self.dry_run = env.bool("DRY_RUN", False) self.global_cli_dl = env.str("GLOBAL_CLI_DL", default_cli) - self.global_patches_dl = env.str("GLOBAL_CLI_DL", default_patches) - self.global_integrations_dl = env.str("GLOBAL_CLI_DL", default_integrations) + self.global_patches_dl = env.str("GLOBAL_PATCHES_DL", default_patches) + 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", []) From f37815fdf90e6181f6bb82a199b403dbdde0be04 Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 21:46:19 +0530 Subject: [PATCH 06/14] =?UTF-8?q?=F0=9F=90=9B=20Failing=20to=20fetch=20lat?= =?UTF-8?q?est=20release?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.py | 8 ++++---- src/patches.py | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/app.py b/src/app.py index 9572cb7..21521ce 100644 --- a/src/app.py +++ b/src/app.py @@ -51,7 +51,7 @@ class APP(object): return ", ".join("%s: %s" % item for item in attrs.items()) @staticmethod - def download(url: str, config: RevancedConfig, assets_filter: str = None) -> str: # type: ignore + def download(url: str, config: RevancedConfig, assets_filter: str) -> str: """Downloader.""" from src.downloader.download import Downloader @@ -70,14 +70,14 @@ class APP(object): logger.info("Downloading resources for patching.") # Create a list of resource download tasks download_tasks = [ - ("cli", self.cli_dl, config), - ("integrations", self.integrations_dl, config), + ("cli", self.cli_dl, config, ".*jar"), + ("integrations", self.integrations_dl, config, ".*apk"), ("patches", self.patches_dl, config, ".*jar"), ("patches_json", self.patches_dl, config, ".*json"), ] # Using a ThreadPoolExecutor for parallelism - with ThreadPoolExecutor() as executor: + with ThreadPoolExecutor(4) as executor: futures = { resource_name: executor.submit(self.download, *args) for resource_name, *args in download_tasks diff --git a/src/patches.py b/src/patches.py index 48717ab..35217bb 100644 --- a/src/patches.py +++ b/src/patches.py @@ -58,6 +58,11 @@ class Patches(object): key: (value, "_" + value) for key, value in _revanced_app_ids.items() } + @staticmethod + def support_app() -> Dict[str, str]: + """Return supported apps.""" + return Patches._revanced_app_ids + def scrap_patches(self, file_name: str) -> Any: """Scrap Patches.""" if os.path.exists(file_name): From d3877ca27b45339c95d217c0dda98ff621b848e8 Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 21:53:41 +0530 Subject: [PATCH 07/14] =?UTF-8?q?=F0=9F=93=9D=20Updated=20doc=20string=20f?= =?UTF-8?q?or=20java=20check=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.py b/src/utils.py index 950bd6d..9e0ed76 100644 --- a/src/utils.py +++ b/src/utils.py @@ -86,7 +86,7 @@ def slugify(string: str) -> str: def check_java(dry_run: bool) -> None: - """Check if Java17 is installed.""" + """Check if Java>=17 is installed.""" try: if dry_run: return From c94a20d5e2862f0e003f7f5c3a9a5e43fbd310e2 Mon Sep 17 00:00:00 2001 From: Nikhil Badyal <59223300+nikhilbadyal@users.noreply.github.com> Date: Sat, 5 Aug 2023 09:25:39 -0700 Subject: [PATCH 08/14] =?UTF-8?q?=E2=99=BB=20Updated=20sting=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: code-review-doctor[bot] <72320148+code-review-doctor[bot]@users.noreply.github.com> --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 071edac..dfe9594 100644 --- a/main.py +++ b/main.py @@ -21,7 +21,7 @@ def main() -> None: logger.info(f"Will Patch only {config.apps}") for app in config.apps: - logger.info("Trying to build %s" % app) + logger.info(f"Trying to build {app}") try: app = APP(app_name=app, config=config) patcher = Patches(config, app) From 710e867c85b5f958922aba279091c365ee0b2701 Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 21:59:03 +0530 Subject: [PATCH 09/14] =?UTF-8?q?=F0=9F=94=A5=20use=20f=20strings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.py b/src/app.py index 21521ce..b56c96e 100644 --- a/src/app.py +++ b/src/app.py @@ -48,7 +48,7 @@ class APP(object): def __str__(self: "APP") -> str: attrs = vars(self) - return ", ".join("%s: %s" % item for item in attrs.items()) + return ", ".join([f"{key}: {value}" for key, value in attrs.items()]) @staticmethod def download(url: str, config: RevancedConfig, assets_filter: str) -> str: From d3888f3fad13d0ac9be587ced932564a9c506287 Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 22:00:23 +0530 Subject: [PATCH 10/14] =?UTF-8?q?=F0=9F=92=9A=20Fixed=20file=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.py b/src/app.py index b56c96e..2c35ed3 100644 --- a/src/app.py +++ b/src/app.py @@ -39,7 +39,7 @@ class APP(object): def get_output_file_name(self) -> str: """Get output file appended with version.""" - return f"Re-{self.app_name}-{slugify(self.app_version)}.apk" + return f"Re-{self.app_name}-{slugify(self.app_version)}-output.apk" def set_recommended_version(self, version: str, exp: bool = False) -> None: """Update if cooking non-recommended.""" From 2897a8f6c377543c797dddb6e4b7d202fc5ae203 Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sat, 5 Aug 2023 22:04:43 +0530 Subject: [PATCH 11/14] =?UTF-8?q?=F0=9F=8E=A8=20Use=20un=20necessary=20lam?= =?UTF-8?q?bda?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser.py b/src/parser.py index 2e1d647..473edd8 100644 --- a/src/parser.py +++ b/src/parser.py @@ -96,7 +96,7 @@ class Parser(object): if app.experiment: logger.debug("Using experimental features") args.append("--experimental") - args[1::2] = map(lambda i: self.config.temp_folder.joinpath(i), args[1::2]) + args[1::2] = map(self.config.temp_folder.joinpath, args[1::2]) if self.config.ci_test: self.exclude_all_patches() if self._PATCHES: From 2197c30f334fa8c2e9c5c9aa6321cb15820dfe27 Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sun, 6 Aug 2023 12:00:38 +0530 Subject: [PATCH 12/14] =?UTF-8?q?=F0=9F=93=9D=20Consistent=20env=20convent?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 279 +++++++++++++++++++++++++++----------------------- src/app.py | 4 +- src/config.py | 4 - 3 files changed, 151 insertions(+), 136 deletions(-) diff --git a/README.md b/README.md index e6ab75f..6529ab3 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,11 @@ # 🤓Docker-Py-ReVanced -A little python script that will help you in building Revanced and Revanced-Extended [apps](#note). +A little python script that will help you in building Revanced [apps](#note). **`Note`** - If you are a root user and want magisk module (Extended). Get them [here](https://github.com/nikhilbadyal/revanced-magisk-module) This is just a builder for revanced and not a revanced support. Please be understanding and refrain from asking -about revanced features/bugs. Discuss those on proper relevant forums(on Revanced GitHub , Discord) - -**`Note`** - I prefer [Revanced Extended](https://github.com/inotia00/revanced-patches/tree/revanced-extended) more -(for YouTube & YouTube Music) hence the YouTube and YouTube Music builds in this repo are from -Revanced Extended. +about revanced features/bugs. Discuss those on proper relevant forums. ## Pre-Built APKs @@ -19,7 +15,7 @@ You can get pre-built apks [here](https://revanced_apkss.t.me/) You can use any of the following methods to build. -- 🚀In GitHub (**_`Recommended`_**) +- 🚀 **_GitHub**_ (**_`Recommended`_**) 1. Click Star to support the project.

@@ -51,8 +47,8 @@ You can use any of the following methods to build. 5. If the building process is successful, you’ll get your APKs in the
-- 🐳With Docker Compose - Windows/Mac users simply install Docker Desktop. If using Linux see below +- 🐳 **_Docker Compose_**
+ Windows/Mac users simply install Docker Desktop. If using Linux see below 1. Install Docker(Skip if already installed) ```bash @@ -80,7 +76,7 @@ You can use any of the following methods to build. 6. Update `.env` file if you want some customization(See notes) 7. Run script with ```shell - docker-compose up + docker-compose up --build ``` - 🐳With Docker @@ -99,7 +95,7 @@ You can use any of the following methods to build. - 🫠Without Docker - 1. Install Java17 (zulu preferred) + 1. Install Java >= 17 2. Install Python 3. Create virtual environment ``` @@ -115,15 +111,51 @@ You can use any of the following methods to build. ``` 6. Run the script with ``` - python python main.py + python main.py ``` +## Configurations + +### Global Config + +| Env Name | Description | Default | +|:---------------------------|:-------------------------------------------------:|:---------------------------------------------------------------------------------------------------------| +| PATCH_APPS | Apps to patch/build | youtube | +| EXISTING_DOWNLOADED_APKS | Already downloaded clean apks | [] | +| PERSONAL_ACCESS_TOKEN | Github Token to be used | None | +| DRY_RUN | Do a dry run | False | +| GLOBAL_CLI_DL* | DL for CLI to be used for patching apps. | [Revanced CLI](https://github.com/revanced/revanced-cli) | +| GLOBAL_PATCHES_DL* | DL for Patches to be used for patching apps. | [Revanced Patches](https://github.com/revanced/revanced-patches) | +| GLOBAL_INTEGRATIONS_DL* | DL for Integrations to be used for patching apps. | [Revanced CLI](https://github.com/revanced/revanced-integrations) | +| GLOBAL_KEYSTORE_FILE_NAME* | Key file to be used for signing apps | [Builder's own key](https://github.com/nikhilbadyal/docker-py-revanced/blob/main/apks/revanced.keystore) | +| GLOBAL_ARCHS_TO_BUILD* | Arch to keep in the patched apk. | All | +| REDDIT_CLIENT_ID | Reddit Client ID to patch reddit apps | None | +| VT_API_KEY | Virus Total Key to scan APKs | None | +| TELEGRAM_CHAT_ID | Receiver in Telegram upload | None | +| TELEGRAM_BOT_TOKEN | APKs Sender for Telegram upload | None | +| TELEGRAM_API_ID | Used for telegram Authentication | None | +| TELEGRAM_API_HASH | Used for telegram Authentication | None | + +`*` - Can be overridden for individual app. +### App Level Config + +| Env Name | Description | Default | +|:------------------------------|:---------------------------------------------------------:|:-------------------------------| +| *APP_NAME*_CLI_DL | DL for CLI to be used for patching **APP_NAME**. | GLOBAL_CLI_DL | +| *APP_NAME*_PATCHES_DL | DL for Patches to be used for patching **APP_NAME**. | GLOBAL_PATCHES_DL | +| *APP_NAME*_INTEGRATIONS_DL | DL for Integrations to be used for patching **APP_NAME**. | GLOBAL_INTEGRATIONS_DL | +| *APP_NAME*_KEYSTORE_FILE_NAME | Key file to be used for signing **APP_NAME**. | GLOBAL_KEYSTORE_FILE_NAME | +| *APP_NAME*_ARCHS_TO_BUILD | Arch to keep in the patched **APP_NAME**. | GLOBAL_ARCHS_TO_BUILD | +| *APP_NAME*_EXCLUDE_PATCH** | Patches to exclude while patching **APP_NAME**. | [] | +| *APP_NAME*_INCLUDE_PATCH** | Patches to include while patching **APP_NAME**. | [] | +| *APP_NAME*_VERSION** | Version to use for download for patching. | Recommended by patch resources | + +`**` - By default all patches for a given app are included.
+`**` - Can be used to included universal patch. + ## Note -(Pay attention to 3,4)
-By default, script build the version as recommended by Revanced team. - -1. Supported values for **REVANCED_APPS_NAME** are : +1. Supported values for **APP_NAME** are : 1. [youtube](https://www.apkmirror.com/apk/google-inc/youtube/) 2. [youtube_music](https://www.apkmirror.com/apk/google-inc/youtube-music/) @@ -165,106 +197,123 @@ By default, script build the version as recommended by Revanced team. 38. [bacon](https://www.apkmirror.com/apk/onelouder-apps/baconreader-for-reddit/) 39. [microg](https://github.com/inotia00/mMicroG/releases) -
Please verify the source of original APKs yourself with links provided. I'm not responsible for any damaged caused. - If you know any better/safe source to download clean. Please raise a PR. - -2. Remember to download the **_Microg_**. Otherwise, you will not be able to open YouTube. -3. By default, it will build only `youtube`. To build other apps supported by revanced team. - Add the apps you want to build in `.env` file or in `ENVS` in - `GitHub secrets` in the format +
Please verify the source of original APKs yourself with links provided. I'm not responsible for any damage + caused.If you know any better/safe source to download clean. Open a discussion. +2. By default, script build the latest version as recommended by `patches.json` team. +3. Remember to download the **_Microg_**. Otherwise, you may not be able to open YouTube/YouTube Music. +4. By default, tool will build only `youtube`. To build other apps supported by patching resources. + Add the apps you want to build in `.env` file or in `ENVS` in `GitHub secrets` in the format ```ini - PATCH_APPS= + PATCH_APPS= ``` Example: ```ini PATCH_APPS=youtube,twitter,reddit ``` -4. If you want to exclude any patch. Set comma separated patch in `.env` file or in `ENVS` in `GitHub secrets` - (Recommended) in the format - ```ini - EXCLUDE_PATCH_= +5. If APKMirror or other apk sources are blocked in your region or script somehow is unable to download from apkmirror. + You can download apk manually from any source. Place them in `/apks` directory and provide environment variable + in `.env` file or in `ENVS` in `GitHub secrets`(Recommended) in the format. + ```dotenv + EXISTING_DOWNLOADED_APKS= ``` Example: ```dotenv - EXCLUDE_PATCH_YOUTUBE=custom-branding,hide-get-premium - EXCLUDE_PATCH_YOUTUBE_MUSIC=yt-music-is-shit + EXISTING_DOWNLOADED_APKS=youtube,youtube_music ``` - **_All the patches for an app are included by default._**.

If you want to apply a universal patch. You can - include it - manually. See below for more information.
-5. If you want to include any universal patch. Set comma separated patch in `.env` file or in `ENVS` in `GitHub + If you add above. Script will not download the `youtube` & `youtube_music`apk from internet and expects an apk in + `/apks` folder with **same** name. +6. If you run script again & again. You might hit GitHub API limit. In that case you can provide your Personal + GitHub Access Token in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format - + ```dotenv + PERSONAL_ACCESS_TOKEN= + ``` +7. You can provide Direct download to the resource to used for patching apps `.env` file or in `ENVS` in `GitHub secrets` + (Recommended) in the format - + ```dotenv + GLOBAL_CLI_DL=https://github.com/revanced/revanced-cli + GLOBAL_PATCHES_DL=https://github.com/revanced/revanced-patches + GLOBAL_INTEGRATIONS_DL=https://github.com/revanced/revanced-integrations + ``` + Resources downloaded from envs and will be used for patching for any **APP_NAME**. + Unless provided different resource for the individual app.

+ Tool also support resource config at app level. You can patch A app with X resources while patching B with Y + resources. + This can be done by providing Direct download link for resources for app.
+ Example: + ```dotenv + YOUTUBE_CLI_DL=https://github.com/inotia00/revanced-cli + YOUTUBE_PATCHES_DL=https://github.com/inotia00/revanced-patches + YOUTUBE_INTEGRATIONS_DL=https://github.com/inotia00/revanced-integrations + ``` + With the config tool will try to patch youtube with resources from inotia00 while other global resource will used + for patching other apps. + *Note* - The link provided must be DLs. Unless they are from GitHub. +8. If you don't want to use default keystore. You can provide your own by placing it + inside `apks` folder. And adding the name of `keystore-file` in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format - ```ini - INCLUDE_PATCH_= + ```dotenv + GLOBAL_KEYSTORE_FILE_NAME=revanced.keystore ``` + Tool also support providing secret key at app level. You can sign A app with X key while signing B with Y + key.
+ Example: + ```dotenv + YOUTUBE_KEYSTORE_FILE_NAME=youtube.keystore + ``` +9. You can build only for a particular arch in order to get smaller apk files.This can be done with by adding comma + separated `ARCHS_TO_BUILD` in `ENVS` in `GitHub secrets` (Recommended) in the format. + ```dotenv + GLOABAL_ARCHS_TO_BUILD=arm64-v8a,armeabi-v7a + ``` + Tool also support configuring at app level.
+ Example: ```dotenv - INCLUDE_PATCH_YOUTUBE=remove-screenshot-restriction + YOUTUBE_ARCHS_TO_BUILD=arm64-v8a,armeabi-v7a ``` - If you are using `Revanced Extended.` Add `_EXTENDED` in exclude options. - Example: - ```dotenv - INCLUDE_PATCH_YOUTUBE_EXTENDED=remove-screenshot-restriction - ``` - **_Remember_** - Revanced patches are provided space separated, make sure you type those **-** separated here. - It means a patch named _**Hey There**_ will be entered as **_hey-there_** in the above example. -6. If you want to use custom Patching resource. You can do so by providing respective DLs. Per app support is there too. - ```ini - YOUTUBE_MUSIC_INTEGRATION_DL=https://github.com/inotia00/revanced-integrations/releases/latest - YOUTUBE_MUSIC_PATCHES_DL=https://github.com/inotia00/revanced-patches/releases/latest - YOUTUBE_MUSIC_CLI_DL=https://github.com/inotia00/revanced-cli/releases/latest - YOUTUBE_MUSIC_KEYSTORE_FILE_NAME=key.store - YOUTUBE_MUSIC_ARCHS_TO_BUILD=arm64-v8a,armeabi-v7a - ``` - These link if not from GitHub must be direct download links. -7. You can also provide a default resources which will be used when per app config is missing. - ```ini - GLOBAL_INTEGRATION_DL=https://github.com/inotia00/revanced-integrations/releases/latest - GLOBAL_PATCHES_DL=https://github.com/inotia00/revanced-patches/releases/latest - GLOBAL_CLI_DL=https://github.com/inotia00/revanced-cli/releases/latest - ``` - These link if not from GitHub must be direct download links. -8. If you want to build a specific version . Add `version` in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) - in the format - ```ini - _VERSION= - ``` - Example: - ```ini - YOUTUBE_VERSION=17.31.36 - YOUTUBE_MUSIC_VERSION=X.X.X - TWITTER_VERSION=X.X.X - REDDIT_VERSION=X.X.X - TIKTOK_VERSION=X.X.X - WARNWETTER_VERSION=X.X.X - ``` -9. If you want to build `latest` version, whatever latest is available(including - beta) . - Add `latest` in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format - - ```ini - _VERSION=latest - ``` - - Example: - - ```ini - YOUTUBE_VERSION=latest - YOUTUBE_MUSIC_VERSION=latest - TWITTER_VERSION=latest - REDDIT_VERSION=latest - TIKTOK_VERSION=latest - WARNWETTER_VERSION=latest - ``` - -10. If you don't want to use default keystore. You can provide your own by placing it - inside `apks` folder. And adding the name of `keystore-file` in `.env` file or in `ENVS` in `GitHub secrets` + *Note* - + 1. Possible values are: `armeabi-v7a`,`x86`,`x86_64`,`arm64-v8a` + 2. Make sure the patching resource(CLI) support this feature. +10. If you want to exclude any patch. Set comma separated patch in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format - ```dotenv - GLOBAL_KEYSTORE_FILE_NAME=revanced.keystore + ```ini + _EXCLUDE_PATCH= ``` -11. For Telegram Upload. + Example: + ```dotenv + YOUTUBE_EXCLUDE_PATCH=custom-branding,hide-get-premium + YOUTUBE_MUSIC_EXCLUDE_PATCH=yt-music-is-shit + ``` + Note - + 1. **All** the patches for an app are **included** by default.
+ 2. Revanced patches are provided as space separated, make sure you type those **-** separated here. + It means a patch named _**Hey There**_ must be entered as **_hey-there_** in the above example. +11. If you want to include any universal patch. Set comma separated patch in `.env` file or in `ENVS` in `GitHub + secrets` + (Recommended) in the format + ```ini + _INCLUDE_PATCH= + ``` + Example: + ```dotenv + YOUTUBE_INCLUDE_PATCH=remove-screenshot-restriction + ``` + Note - + 1. Revanced patches are provided as space separated, make sure you type those **-** separated here. + It means a patch named _**Hey There**_ must be entered as **_hey-there_** in the above example. +12. If you want to build a specific version or latest version. Add `version` in `.env` file or in `ENVS` in `GitHub + secrets` (Recommended) in the format + ```ini + _VERSION= + ``` + Example: + ```ini + YOUTUBE_VERSION=17.31.36 + YOUTUBE_MUSIC_VERSION=X.X.X + TWITTER_VERSION=latest + ``` +13. For Telegram Upload. 1. Set up a telegram channel, send a message to it and forward the message to this telegram [bot](https://t.me/username_to_id_bot) 2. Copy `id` and save it to `TELEGRAM_CHAT_ID`
@@ -278,42 +327,12 @@ By default, script build the version as recommended by Revanced team.
6. After Everything done successfully the actions secrets of the repository will look something like
-12. You can build only for a particular arch in order to get smaller apk files.This can be done with by adding comma - separated `ARCHS_TO_BUILD` in `ENVS` in `GitHub secrets` (Recommended) in the format. - ```dotenv - GLOABAL_ARCHS_TO_BUILD=arm64-v8a,armeabi-v7a - ``` - Possible values for `ARCHS_TO_BUILD` are: `armeabi-v7a`,`x86`,`x86_64`,`arm64-v8a` - Make sure the patching resource support this. -13. You can scan your built apks files with VirusTotal. For that, Add `VT_API_KEY` in `GitHub secrets`. 14. Configuration defined in `ENVS` in `GitHub secrets` will override the configuration in `.env` file. You can use this fact to define your normal configurations in `.env` file and sometimes if you want to build something different just once. Add it in `GitHub secrets`.
- Or you can ignore what I said above and always use `GitHub secrets`. -15. If APKMirror or other apk source is blocked in your region or script somehow is unable to download from apkmirror. - You can download apk manually from any source. Place them in `/apks` directory and provide environment variable - in `.env` file or in `ENVS` in `GitHub secrets`(Recommended) in the format. - ```dotenv - EXISTING_DOWNLOADED_APKS= - ``` - Example: - ```dotenv - EXISTING_DOWNLOADED_APKS=youtube,youtube_music - ``` - If you add above. Script will not download the `Youtube` & `youtube music`apk from internet and expects an apk in - `/apks` folder. - - Name of the downloaded apk must match with the available app choices found [here.](#note) -16. If you run script again & again. You might hit GitHub API limit. In that case you can provide your Personal - GitHub Access Token in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format - - ```dotenv - PERSONAL_ACCESS_TOKEN= - ``` -17. Sample Envs
+15. Sample Envs
-18. Make your Action has write access. If not click +16. Make your Action has write access. If not click [here](https://github.com/nikhilbadyal/docker-py-revanced/settings/actions). In the bottom give read and write access to Actions. -19. If you want to patch reddit apps using your own Client ID. You can provide your Client ID - as secret `REDDIT_CLIENT_ID` in `GitHub secrets`. diff --git a/src/app.py b/src/app.py index 2c35ed3..1947be5 100644 --- a/src/app.py +++ b/src/app.py @@ -25,8 +25,8 @@ class APP(object): self.integrations_dl = config.env.str( f"{app_name}_INTEGRATION_DL".upper(), config.global_integrations_dl ) - self.exclude_request = config.env.list(f"EXCLUDE_PATCH_{app_name}".upper(), []) - self.include_request = config.env.list(f"INCLUDE_PATCH_{app_name}".upper(), []) + self.exclude_request = config.env.list(f"{app_name}_EXCLUDE_PATCH".upper(), []) + self.include_request = config.env.list(f"{app_name}_INCLUDE_PATCH".upper(), []) self.resource: Dict[str, str] = {} self.no_of_patches = 0 self.keystore_name = config.env.str( diff --git a/src/config.py b/src/config.py index 5d03de9..3b44f77 100644 --- a/src/config.py +++ b/src/config.py @@ -72,10 +72,6 @@ class RevancedConfig(object): key: value + value.split("/")[-2] for key, value in self.apk_mirror_urls.items() } - self.alternative_youtube_patches = env.list("ALTERNATIVE_YOUTUBE_PATCHES", []) - self.alternative_youtube_music_patches = env.list( - "ALTERNATIVE_YOUTUBE_MUSIC_PATCHES", [] - ) 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) From 03da0d218e6c0ad726bf97cabf595ae65ee10961 Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sun, 6 Aug 2023 13:32:22 +0530 Subject: [PATCH 13/14] =?UTF-8?q?=F0=9F=93=9D=20Doc=20linking?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 111 +++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 6529ab3..b375d84 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🤓Docker-Py-ReVanced -A little python script that will help you in building Revanced [apps](#note). +A little python script that will help you in building Revanced [apps](#patch-apps). **`Note`** - If you are a root user and want magisk module (Extended). Get them [here](https://github.com/nikhilbadyal/revanced-magisk-module) @@ -118,37 +118,37 @@ You can use any of the following methods to build. ### Global Config -| Env Name | Description | Default | -|:---------------------------|:-------------------------------------------------:|:---------------------------------------------------------------------------------------------------------| -| PATCH_APPS | Apps to patch/build | youtube | -| EXISTING_DOWNLOADED_APKS | Already downloaded clean apks | [] | -| PERSONAL_ACCESS_TOKEN | Github Token to be used | None | -| DRY_RUN | Do a dry run | False | -| GLOBAL_CLI_DL* | DL for CLI to be used for patching apps. | [Revanced CLI](https://github.com/revanced/revanced-cli) | -| GLOBAL_PATCHES_DL* | DL for Patches to be used for patching apps. | [Revanced Patches](https://github.com/revanced/revanced-patches) | -| GLOBAL_INTEGRATIONS_DL* | DL for Integrations to be used for patching apps. | [Revanced CLI](https://github.com/revanced/revanced-integrations) | -| GLOBAL_KEYSTORE_FILE_NAME* | Key file to be used for signing apps | [Builder's own key](https://github.com/nikhilbadyal/docker-py-revanced/blob/main/apks/revanced.keystore) | -| GLOBAL_ARCHS_TO_BUILD* | Arch to keep in the patched apk. | All | -| REDDIT_CLIENT_ID | Reddit Client ID to patch reddit apps | None | -| VT_API_KEY | Virus Total Key to scan APKs | None | -| TELEGRAM_CHAT_ID | Receiver in Telegram upload | None | -| TELEGRAM_BOT_TOKEN | APKs Sender for Telegram upload | None | -| TELEGRAM_API_ID | Used for telegram Authentication | None | -| TELEGRAM_API_HASH | Used for telegram Authentication | None | +| Env Name | Description | Default | +|:---------------------------------------------------------|:-------------------------------------------------:|:---------------------------------------------------------------------------------------------------------| +| [PATCH_APPS](#patch-apps) | Apps to patch/build | youtube | +| [EXISTING_DOWNLOADED_APKS ](#existing-downloaded-apks) | Already downloaded clean apks | [] | +| [PERSONAL_ACCESS_TOKEN](#personal-access-token) | Github Token to be used | None | +| DRY_RUN | Do a dry run | False | +| [GLOBAL_CLI_DL*](#global-resources) | DL for CLI to be used for patching apps. | [Revanced CLI](https://github.com/revanced/revanced-cli) | +| [GLOBAL_PATCHES_DL*](#global-resources) | DL for Patches to be used for patching apps. | [Revanced Patches](https://github.com/revanced/revanced-patches) | +| [GLOBAL_INTEGRATIONS_DL*](#global-resources) | DL for Integrations to be used for patching apps. | [Revanced CLI](https://github.com/revanced/revanced-integrations) | +| [GLOBAL_KEYSTORE_FILE_NAME*](#global-keystore-file-name) | Key file to be used for signing apps | [Builder's own key](https://github.com/nikhilbadyal/docker-py-revanced/blob/main/apks/revanced.keystore) | +| [GLOBAL_ARCHS_TO_BUILD*](#global-archs-to-build) | Arch to keep in the patched apk. | All | +| REDDIT_CLIENT_ID | Reddit Client ID to patch reddit apps | None | +| VT_API_KEY | Virus Total Key to scan APKs | None | +| [TELEGRAM_CHAT_ID](#telegram-support) | Receiver in Telegram upload | None | +| [TELEGRAM_BOT_TOKEN](#telegram-support) | APKs Sender for Telegram upload | None | +| [TELEGRAM_API_ID](#telegram-support) | Used for telegram Authentication | None | +| [TELEGRAM_API_HASH](#telegram-support) | Used for telegram Authentication | None | `*` - Can be overridden for individual app. ### App Level Config -| Env Name | Description | Default | -|:------------------------------|:---------------------------------------------------------:|:-------------------------------| -| *APP_NAME*_CLI_DL | DL for CLI to be used for patching **APP_NAME**. | GLOBAL_CLI_DL | -| *APP_NAME*_PATCHES_DL | DL for Patches to be used for patching **APP_NAME**. | GLOBAL_PATCHES_DL | -| *APP_NAME*_INTEGRATIONS_DL | DL for Integrations to be used for patching **APP_NAME**. | GLOBAL_INTEGRATIONS_DL | -| *APP_NAME*_KEYSTORE_FILE_NAME | Key file to be used for signing **APP_NAME**. | GLOBAL_KEYSTORE_FILE_NAME | -| *APP_NAME*_ARCHS_TO_BUILD | Arch to keep in the patched **APP_NAME**. | GLOBAL_ARCHS_TO_BUILD | -| *APP_NAME*_EXCLUDE_PATCH** | Patches to exclude while patching **APP_NAME**. | [] | -| *APP_NAME*_INCLUDE_PATCH** | Patches to include while patching **APP_NAME**. | [] | -| *APP_NAME*_VERSION** | Version to use for download for patching. | Recommended by patch resources | +| Env Name | Description | Default | +|:------------------------------------------------------------|:---------------------------------------------------------:|:-------------------------------| +| [*APP_NAME*_CLI_DL](#global-resources) | DL for CLI to be used for patching **APP_NAME**. | GLOBAL_CLI_DL | +| [*APP_NAME*_PATCHES_DL](#global-resources) | DL for Patches to be used for patching **APP_NAME**. | GLOBAL_PATCHES_DL | +| [*APP_NAME*_INTEGRATIONS_DL](#global-resources) | DL for Integrations to be used for patching **APP_NAME**. | GLOBAL_INTEGRATIONS_DL | +| [*APP_NAME*_KEYSTORE_FILE_NAME](#global-keystore-file-name) | Key file to be used for signing **APP_NAME**. | GLOBAL_KEYSTORE_FILE_NAME | +| [*APP_NAME*_ARCHS_TO_BUILD](#global-archs-to-build) | Arch to keep in the patched **APP_NAME**. | GLOBAL_ARCHS_TO_BUILD | +| [*APP_NAME*_EXCLUDE_PATCH**](#custom-exclude-patching) | Patches to exclude while patching **APP_NAME**. | [] | +| [*APP_NAME*_INCLUDE_PATCH**](#custom-include-patching) | Patches to include while patching **APP_NAME**. | [] | +| [*APP_NAME*_VERSION**](#app-version) | Version to use for download for patching. | Recommended by patch resources | `**` - By default all patches for a given app are included.
`**` - Can be used to included universal patch. @@ -201,8 +201,8 @@ You can use any of the following methods to build. caused.If you know any better/safe source to download clean. Open a discussion. 2. By default, script build the latest version as recommended by `patches.json` team. 3. Remember to download the **_Microg_**. Otherwise, you may not be able to open YouTube/YouTube Music. -4. By default, tool will build only `youtube`. To build other apps supported by patching resources. - Add the apps you want to build in `.env` file or in `ENVS` in `GitHub secrets` in the format +4. By default, tool will build only `youtube`. To build other apps supported by patching + resources.Add the apps you want to build in `.env` file or in `ENVS` in `GitHub secrets` in the format ```ini PATCH_APPS= ``` @@ -210,9 +210,10 @@ You can use any of the following methods to build. ```ini PATCH_APPS=youtube,twitter,reddit ``` -5. If APKMirror or other apk sources are blocked in your region or script somehow is unable to download from apkmirror. - You can download apk manually from any source. Place them in `/apks` directory and provide environment variable - in `.env` file or in `ENVS` in `GitHub secrets`(Recommended) in the format. +5. If APKMirror or other apk sources are blocked in your region or script + somehow is unable to download from apkmirror. You can download apk manually from any source. Place them in + `/apks` directory and provide environment variable in `.env` file or in `ENVS` in `GitHub secrets`(Recommended) + in the format. ```dotenv EXISTING_DOWNLOADED_APKS= ``` @@ -222,14 +223,14 @@ You can use any of the following methods to build. ``` If you add above. Script will not download the `youtube` & `youtube_music`apk from internet and expects an apk in `/apks` folder with **same** name. -6. If you run script again & again. You might hit GitHub API limit. In that case you can provide your Personal - GitHub Access Token in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) in the format - +6. If you run script again & again. You might hit GitHub API limit. In that case + you can provide your Personal GitHub Access Token in `.env` file or in `ENVS` in `GitHub secrets` (Recommended) + in the format - ```dotenv PERSONAL_ACCESS_TOKEN= ``` -7. You can provide Direct download to the resource to used for patching apps `.env` file or in `ENVS` in `GitHub - secrets` - (Recommended) in the format - +7. You can provide Direct download to the resource to used for patching apps `.env` file + or in `ENVS` in `GitHub secrets` (Recommended) in the format - ```dotenv GLOBAL_CLI_DL=https://github.com/revanced/revanced-cli GLOBAL_PATCHES_DL=https://github.com/revanced/revanced-patches @@ -249,9 +250,9 @@ You can use any of the following methods to build. With the config tool will try to patch youtube with resources from inotia00 while other global resource will used for patching other apps. *Note* - The link provided must be DLs. Unless they are from GitHub. -8. If you don't want to use default keystore. You can provide your own by placing it - inside `apks` folder. And adding the name of `keystore-file` in `.env` file or in `ENVS` in `GitHub secrets` - (Recommended) in the format +8. If you don't want to use default keystore. You can provide your own by + placing it inside `apks` folder. And adding the name of `keystore-file` in `.env` file or in `ENVS` in `GitHub + secrets` (Recommended) in the format ```dotenv GLOBAL_KEYSTORE_FILE_NAME=revanced.keystore ``` @@ -261,8 +262,9 @@ You can use any of the following methods to build. ```dotenv YOUTUBE_KEYSTORE_FILE_NAME=youtube.keystore ``` -9. You can build only for a particular arch in order to get smaller apk files.This can be done with by adding comma - separated `ARCHS_TO_BUILD` in `ENVS` in `GitHub secrets` (Recommended) in the format. +9. You can build only for a particular arch in order to get smaller apk files.This + can be done with by adding comma separated `ARCHS_TO_BUILD` in `ENVS` in `GitHub secrets` (Recommended) in the + format. ```dotenv GLOABAL_ARCHS_TO_BUILD=arm64-v8a,armeabi-v7a ``` @@ -275,8 +277,8 @@ You can use any of the following methods to build. *Note* - 1. Possible values are: `armeabi-v7a`,`x86`,`x86_64`,`arm64-v8a` 2. Make sure the patching resource(CLI) support this feature. -10. If you want to exclude any patch. Set comma separated patch in `.env` file or in `ENVS` in `GitHub secrets` - (Recommended) in the format +10. If you want to exclude any patch. Set comma separated patch in `.env` file + or in `ENVS` in `GitHub secrets` (Recommended) in the format ```ini _EXCLUDE_PATCH= ``` @@ -289,9 +291,8 @@ You can use any of the following methods to build. 1. **All** the patches for an app are **included** by default.
2. Revanced patches are provided as space separated, make sure you type those **-** separated here. It means a patch named _**Hey There**_ must be entered as **_hey-there_** in the above example. -11. If you want to include any universal patch. Set comma separated patch in `.env` file or in `ENVS` in `GitHub - secrets` - (Recommended) in the format +11. If you want to include any universal patch. Set comma separated patch in `.env` + file or in `ENVS` in `GitHub secrets` (Recommended) in the format ```ini _INCLUDE_PATCH= ``` @@ -302,8 +303,8 @@ You can use any of the following methods to build. Note - 1. Revanced patches are provided as space separated, make sure you type those **-** separated here. It means a patch named _**Hey There**_ must be entered as **_hey-there_** in the above example. -12. If you want to build a specific version or latest version. Add `version` in `.env` file or in `ENVS` in `GitHub - secrets` (Recommended) in the format +12. If you want to build a specific version or latest version. Add `version` in `.env` file + or in `ENVS` in `GitHub secrets` (Recommended) in the format ```ini _VERSION= ``` @@ -313,7 +314,7 @@ You can use any of the following methods to build. YOUTUBE_MUSIC_VERSION=X.X.X TWITTER_VERSION=latest ``` -13. For Telegram Upload. +13. For Telegram Upload. 1. Set up a telegram channel, send a message to it and forward the message to this telegram [bot](https://t.me/username_to_id_bot) 2. Copy `id` and save it to `TELEGRAM_CHAT_ID`
@@ -325,14 +326,14 @@ You can use any of the following methods to build.
5. `TELEGRAM_API_HASH` - Telegram API_HASH is provided by telegram [here](https://my.telegram.org/apps)

- 6. After Everything done successfully the actions secrets of the repository will look something like
- + 6. After Everything done successfully a part of the actions secrets of the repository may look like
+ 14. Configuration defined in `ENVS` in `GitHub secrets` will override the configuration in `.env` file. You can use this fact to define your normal configurations in `.env` file and sometimes if you want to build something different just once. Add it in `GitHub secrets`.
15. Sample Envs
- -16. Make your Action has write access. If not click + +16. Make sure your Action has write access. If not click [here](https://github.com/nikhilbadyal/docker-py-revanced/settings/actions). In the bottom give read and write access to Actions. From d2f0a7baeea894042659c53a8c87a0ed2d5cf27b Mon Sep 17 00:00:00 2001 From: Nikhil Badyal Date: Sun, 6 Aug 2023 20:24:16 +0530 Subject: [PATCH 14/14] =?UTF-8?q?=E2=9C=A8=20Custom=20Patches=20json=20dl?= =?UTF-8?q?=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++++- src/app.py | 5 ++++- src/config.py | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b375d84..7d135f1 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ You can use any of the following methods to build. ### Global Config -| Env Name | Description | Default | +| **Env Name** | **Description** | **Default** | |:---------------------------------------------------------|:-------------------------------------------------:|:---------------------------------------------------------------------------------------------------------| | [PATCH_APPS](#patch-apps) | Apps to patch/build | youtube | | [EXISTING_DOWNLOADED_APKS ](#existing-downloaded-apks) | Already downloaded clean apks | [] | @@ -126,6 +126,7 @@ You can use any of the following methods to build. | DRY_RUN | Do a dry run | False | | [GLOBAL_CLI_DL*](#global-resources) | DL for CLI to be used for patching apps. | [Revanced CLI](https://github.com/revanced/revanced-cli) | | [GLOBAL_PATCHES_DL*](#global-resources) | DL for Patches to be used for patching apps. | [Revanced Patches](https://github.com/revanced/revanced-patches) | +| [GLOBAL_PATCHES_JSON_DL*](#global-resources) | DL for Patches Json to be used for patching apps. | [Revanced Patches](https://github.com/revanced/revanced-patches) | | [GLOBAL_INTEGRATIONS_DL*](#global-resources) | DL for Integrations to be used for patching apps. | [Revanced CLI](https://github.com/revanced/revanced-integrations) | | [GLOBAL_KEYSTORE_FILE_NAME*](#global-keystore-file-name) | Key file to be used for signing apps | [Builder's own key](https://github.com/nikhilbadyal/docker-py-revanced/blob/main/apks/revanced.keystore) | | [GLOBAL_ARCHS_TO_BUILD*](#global-archs-to-build) | Arch to keep in the patched apk. | All | @@ -143,6 +144,7 @@ You can use any of the following methods to build. |:------------------------------------------------------------|:---------------------------------------------------------:|:-------------------------------| | [*APP_NAME*_CLI_DL](#global-resources) | DL for CLI to be used for patching **APP_NAME**. | GLOBAL_CLI_DL | | [*APP_NAME*_PATCHES_DL](#global-resources) | DL for Patches to be used for patching **APP_NAME**. | GLOBAL_PATCHES_DL | +| [*APP_NAME*_PATCHES_JSON_DL](#global-resources) | DL for Patches Json to be used for patching **APP_NAME**. | GLOBAL_PATCHES_JSON_DL | | [*APP_NAME*_INTEGRATIONS_DL](#global-resources) | DL for Integrations to be used for patching **APP_NAME**. | GLOBAL_INTEGRATIONS_DL | | [*APP_NAME*_KEYSTORE_FILE_NAME](#global-keystore-file-name) | Key file to be used for signing **APP_NAME**. | GLOBAL_KEYSTORE_FILE_NAME | | [*APP_NAME*_ARCHS_TO_BUILD](#global-archs-to-build) | Arch to keep in the patched **APP_NAME**. | GLOBAL_ARCHS_TO_BUILD | @@ -234,6 +236,7 @@ You can use any of the following methods to build. ```dotenv GLOBAL_CLI_DL=https://github.com/revanced/revanced-cli GLOBAL_PATCHES_DL=https://github.com/revanced/revanced-patches + GLOBAL_PATCHES_JSON_DL=https://github.com/revanced/revanced-patches GLOBAL_INTEGRATIONS_DL=https://github.com/revanced/revanced-integrations ``` Resources downloaded from envs and will be used for patching for any **APP_NAME**. @@ -245,6 +248,7 @@ You can use any of the following methods to build. ```dotenv YOUTUBE_CLI_DL=https://github.com/inotia00/revanced-cli YOUTUBE_PATCHES_DL=https://github.com/inotia00/revanced-patches + YOUTUBE_PATCHES_JSON_DL=https://github.com/inotia00/revanced-patches YOUTUBE_INTEGRATIONS_DL=https://github.com/inotia00/revanced-integrations ``` With the config tool will try to patch youtube with resources from inotia00 while other global resource will used diff --git a/src/app.py b/src/app.py index 1947be5..9ae881c 100644 --- a/src/app.py +++ b/src/app.py @@ -25,6 +25,9 @@ class APP(object): self.integrations_dl = config.env.str( f"{app_name}_INTEGRATION_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 = config.env.list(f"{app_name}_EXCLUDE_PATCH".upper(), []) self.include_request = config.env.list(f"{app_name}_INCLUDE_PATCH".upper(), []) self.resource: Dict[str, str] = {} @@ -73,7 +76,7 @@ class APP(object): ("cli", self.cli_dl, config, ".*jar"), ("integrations", self.integrations_dl, config, ".*apk"), ("patches", self.patches_dl, config, ".*jar"), - ("patches_json", self.patches_dl, config, ".*json"), + ("patches_json", self.patches_json_dl, config, ".*json"), ] # Using a ThreadPoolExecutor for parallelism diff --git a/src/config.py b/src/config.py index 3b44f77..c3baf9a 100644 --- a/src/config.py +++ b/src/config.py @@ -9,6 +9,7 @@ from src.utils import default_build default_cli = "https://github.com/revanced/revanced-cli/releases/latest" default_patches = "https://github.com/revanced/revanced-patches/releases/latest" +default_patches_json = default_patches default_integrations = ( "https://github.com/revanced/revanced-integrations/releases/latest" ) @@ -77,6 +78,9 @@ class RevancedConfig(object): self.dry_run = env.bool("DRY_RUN", False) self.global_cli_dl = env.str("GLOBAL_CLI_DL", default_cli) self.global_patches_dl = env.str("GLOBAL_PATCHES_DL", default_patches) + self.global_patches_json_dl = env.str( + "GLOBAL_PATCHES_JSON_DL", default_patches_json + ) self.global_integrations_dl = env.str( "GLOBAL_INTEGRATIONS_DL", default_integrations )