📝 Gen patches json

This commit is contained in:
Nikhil Badyal
2024-12-23 12:27:43 +05:30
committed by Nikhil Badyal
parent e97ffbef67
commit 8f17bf9f2b
9 changed files with 123 additions and 86 deletions
-8
View File
@@ -3,7 +3,6 @@ EXTRA_FILES=https://github.com/inotia00/VancedMicroG/releases/latest@VancedMicro
PATCH_APPS=youtube,youtube_revancify_red,youtube_revancify_blue,youtube_mmt,youtube_music,reddit
GLOBAL_CLI_DL=https://github.com/revanced/revanced-cli
GLOBAL_PATCHES_DL=https://github.com/revanced/revanced-patches
GLOBAL_PATCHES_JSON_DL=https://api.revanced.app/v4/patches/list
#Example
EXISTING_DOWNLOADED_APKS=twitter
@@ -12,7 +11,6 @@ PERSONAL_ACCESS_TOKEN=ghp_asample_token
#YouTube:
YOUTUBE_CLI_DL=https://github.com/inotia00/revanced-cli
YOUTUBE_PATCHES_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_PATCHES_JSON_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_EXCLUDE_PATCH=custom-branding-icon-revancify-blue,custom-branding-icon-revancify-red,custom-branding-icon-mmt,custom-branding-youtube-name,enable-debug-logging
#Example
@@ -24,7 +22,6 @@ YOUTUBE_REVANCIFY_RED_PACKAGE_NAME=com.google.android.youtube
YOUTUBE_REVANCIFY_RED_DL_SOURCE=https://www.apkmirror.com/apk/google-inc/youtube/
YOUTUBE_REVANCIFY_RED_CLI_DL=https://github.com/inotia00/revanced-cli
YOUTUBE_REVANCIFY_RED_PATCHES_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_REVANCIFY_RED_PATCHES_JSON_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_REVANCIFY_RED_EXCLUDE_PATCH=custom-branding-icon-revancify-blue,custom-branding-icon-mmt,custom-branding-youtube-name,enable-debug-logging
#YouTube Revancify Blue:
@@ -32,7 +29,6 @@ YOUTUBE_REVANCIFY_BLUE_PACKAGE_NAME=com.google.android.youtube
YOUTUBE_REVANCIFY_BLUE_DL_SOURCE=https://www.apkmirror.com/apk/google-inc/youtube/
YOUTUBE_REVANCIFY_BLUE_CLI_DL=https://github.com/inotia00/revanced-cli
YOUTUBE_REVANCIFY_BLUE_PATCHES_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_REVANCIFY_BLUE_PATCHES_JSON_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_REVANCIFY_BLUE_EXCLUDE_PATCH=custom-branding-icon-revancify-red,custom-branding-icon-mmt,custom-branding-youtube-name,enable-debug-logging
#YouTube MMT:
@@ -40,13 +36,11 @@ YOUTUBE_MMT_PACKAGE_NAME=com.google.android.youtube
YOUTUBE_MMT_DL_SOURCE=https://www.apkmirror.com/apk/google-inc/youtube/
YOUTUBE_MMT_CLI_DL=https://github.com/inotia00/revanced-cli
YOUTUBE_MMT_PATCHES_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_MMT_PATCHES_JSON_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_MMT_EXCLUDE_PATCH=custom-branding-icon-revancify-blue,custom-branding-icon-revancify-red,custom-branding-youtube-name,enable-debug-logging
#YouTube Music:
YOUTUBE_MUSIC_CLI_DL=https://github.com/inotia00/revanced-cli
YOUTUBE_MUSIC_PATCHES_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_MUSIC_PATCHES_JSON_DL=https://github.com/YT-Advanced/ReX-patches
YOUTUBE_MUSIC_EXCLUDE_PATCH=custom-branding-icon-mmt,custom-branding-icon-revancify-blue,custom-branding-icon-revancify-red,custom-branding-music-name,enable-compact-dialog,enable-debug-logging
#Example
@@ -55,11 +49,9 @@ YOUTUBE_MUSIC_VERSION=6.15.52
#Reddit
REDDIT_CLI_DL=https://github.com/inotia00/revanced-cli
REDDIT_PATCHES_DL=https://github.com/YT-Advanced/ReX-patches
REDDIT_PATCHES_JSON_DL=https://github.com/YT-Advanced/ReX-patches
#Example
#Twitter
TWITTER_VERSION=latest
TWITTER_CLI_DL=local://cli.jar
TWITTER_PATCHES_DL=local://patches.jar
TWITTER_PATCHES_JSON_DL=local://patches.json
-27
View File
@@ -6,13 +6,10 @@ GLOBAL_PATCHES_DL=https://github.com/revanced/revanced-patches/releases/latest
#YouTube:
YOUTUBE_PATCHES_DL=https://github.com/inotia00/revanced-patches/latest-prerelease
YOUTUBE_PATCHES_JSON_DL=https://github.com/inotia00/revanced-patches/latest-prerelease
YOUTUBE_EXCLUDE_PATCH=custom-branding-icon-youtube,custom-branding-name-youtube,enable-debug-logging,hide-fullscreen-button
#YouTube Music:
YOUTUBE_MUSIC_PATCHES_DL=https://github.com/inotia00/revanced-patches/latest-prerelease
YOUTUBE_MUSIC_PATCHES_JSON_DL=https://github.com/inotia00/revanced-patches/latest-prerelease
YOUTUBE_MUSIC_EXCLUDE_PATCH=custom-branding-icon-youtube-music,custom-branding-name-youtube-music,enable-compact-dialog,enable-debug-logging,enable-old-player-layout
YOUTUBE_MUSIC_VERSION=latest
@@ -22,27 +19,3 @@ REDDIT_EXCLUDE_PATCH=change-package-name
#Twitter:
TWITTER_PATCHES_DL=https://github.com/crimera/piko/releases/latest
#Global:
#EXTRA_FILES=https://github.com/ReVanced/GmsCore/releases/latest@Revanced-Microg.apk
#PATCH_APPS=youtube,youtube_music,reddit,instagram
#
#YOUTUBE_EXCLUDE_PATCH=custom-branding
#
#FACEBOOK_VERSION=latest
#YOUTUBE_MUSIC_VERSION=latest
#REDDIT_VERSION=latest
#TWITTER_VERSION=latest
#INSTAGRAM_VERSION=latest
#
#
#SOUNDCLOUD_DL_SOURCE=https://apkpure.net/-/com.soundcloud.android
#SOUNDCLOUD_PACKAGE_NAME=com.soundcloud.android
#
#REDDIT_DL_SOURCE=https://apkpure.net/-/com.reddit.frontpage
#REDDIT_PACKAGE_NAME=com.reddit.frontpage
#
#
#TWITTER_DL_SOURCE=https://apkpure.net/-/com.twitter.android
#TWITTER_PACKAGE_NAME=com.twitter.android
-4
View File
@@ -117,7 +117,6 @@ You can use any of the following methods to build.
| [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_SPACE_FORMATTED_PATCHES*](#global-resources) | Whether patches are space formatted. | True |
| [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_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_OLD_KEY*](#global-keystore-file-name) | Whether key was generated with cli v4(new) or not | <br/>[Builder's v3(old) own key](https://github.com/nikhilbadyal/docker-py-revanced/blob/main/apks/revanced.keystore) |
| [GLOBAL_OPTIONS_FILE*](#global-options-file) | Options file to be used | [Builder's default file](https://github.com/nikhilbadyal/docker-py-revanced/blob/main/apks/options.json) |
@@ -140,7 +139,6 @@ 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*_SPACE_FORMATTED_PATCHES](#global-resources) | Whether patches are space formatted. **APP_NAME**. | GLOBAL_SPACE_FORMATTED_PATCHES |
| [*APP_NAME*_KEYSTORE_FILE_NAME](#global-keystore-file-name) | Key file to be used for signing **APP_NAME**. | GLOBAL_KEYSTORE_FILE_NAME |
| [*APP_NAME*_OLD_KEY](#global-keystore-file-name) | Whether key used was generated with cli > v4(new) <br/><br/>**APP_NAME**. <br/> <br/> | GLOBAL_OLK_KEY |
@@ -293,7 +291,6 @@ 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://api.revanced.app/v4/patches/list
```
Resources downloaded from envs and will be used for patching for any **APP_NAME**.
Unless provided different resource for the individual app.<br><br>
@@ -304,7 +301,6 @@ 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://api.revanced.app/v4/patches/list
```
With the config tool will try to patch YouTube with resources from inotia00 while other global resource will used
for patching other apps.<br>
+1 -2
View File
@@ -32,7 +32,6 @@ class APP(object):
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.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, dict[str, str]] = {}
@@ -45,6 +44,7 @@ class APP(object):
self.download_source = config.env.str(f"{app_name}_DL_SOURCE".upper(), "")
self.package_name = package_name
self.old_key = config.env.bool(f"{app_name}_OLD_KEY".upper(), config.global_old_key)
self.patches: list[dict[Any, Any]] = []
self.space_formatted = config.env.bool(
f"{app_name}_SPACE_FORMATTED_PATCHES".upper(),
config.global_space_formatted,
@@ -149,7 +149,6 @@ class APP(object):
download_tasks = [
("cli", self.cli_dl, config, ".*jar"),
("patches", self.patches_dl, config, ".*rvp"),
("patches_json", self.patches_json_dl, config, ".*"),
]
# Using a ThreadPoolExecutor for parallelism
+1 -2
View File
@@ -5,7 +5,7 @@ from typing import Self
from environs import Env
from src.utils import default_build, default_cli, default_patches, default_patches_json, resource_folder
from src.utils import default_build, default_cli, default_patches, resource_folder
class RevancedConfig(object):
@@ -22,7 +22,6 @@ 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_keystore_name = env.str("GLOBAL_KEYSTORE_FILE_NAME", "revanced.keystore")
self.global_options_file = env.str("GLOBAL_OPTIONS_FILE", "options.json")
self.global_archs_to_build = env.list("GLOBAL_ARCHS_TO_BUILD", [])
+6 -4
View File
@@ -84,11 +84,10 @@ class Parser(object):
"""
try:
name = name.lower().replace(" ", "-")
patch_index = self._PATCHES.index(name)
indices = [i for i in range(len(self._PATCHES)) if self._PATCHES[i] == name]
for patch_index in indices:
if self._PATCHES[patch_index - 1] == "-e":
self._PATCHES[patch_index - 1] = "-i"
self._PATCHES[patch_index - 1] = "-d"
else:
self._PATCHES[patch_index - 1] = "-e"
except ValueError:
@@ -99,8 +98,10 @@ class Parser(object):
def exclude_all_patches(self: Self) -> None:
"""The function `exclude_all_patches` exclude all the patches."""
for idx, item in enumerate(self._PATCHES):
if item == "-i":
self._PATCHES[idx] = "-e"
if idx == 0:
continue
if item == "-e":
self._PATCHES[idx] = "-d"
def include_exclude_patch(
self: Self,
@@ -193,6 +194,7 @@ class Parser(object):
excluded = set(possible_archs) - set(app.archs_to_build)
for arch in excluded:
args.extend(("--rip-lib", arch))
args.extend(("-f",))
start = perf_counter()
logger.debug(f"Sending request to revanced cli for building with args java {args}")
process = Popen(["java", *args], stdout=PIPE)
+11 -36
View File
@@ -1,15 +1,14 @@
"""Revanced Patches."""
import contextlib
import json
from pathlib import Path
from typing import Any, ClassVar, Self
from typing import ClassVar, Self
from loguru import logger
from src.app import APP
from src.config import RevancedConfig
from src.exceptions import AppNotFoundError, PatchesJsonLoadError
from src.exceptions import AppNotFoundError
from src.patches_gen import convert_command_output_to_json
class Patches(object):
@@ -125,22 +124,23 @@ class Patches(object):
The `app` parameter is of type `APP`. It represents an instance of the `APP` class.
"""
self.patches_dict[app.app_name] = []
patch_loader = PatchLoader()
patches_file = app.resource["patches_json"]["file_name"]
patches = patch_loader.load_patches(f"{config.temp_folder}/{patches_file}")
app.patches = convert_command_output_to_json(
f"{config.temp_folder}/{app.resource["cli"]["file_name"]}",
f"{config.temp_folder}/{app.resource["patches"]["file_name"]}",
)
for patch in patches:
for patch in app.patches:
if not patch["compatiblePackages"]:
p = {x: patch[x] for x in ["name", "description"]}
p["app"] = "universal"
p["version"] = "all"
self.patches_dict["universal_patch"].append(p)
else:
for compatible_package, versions in patch["compatiblePackages"].items():
for compatible_package, version in [(x["name"], x["versions"]) for x in patch["compatiblePackages"]]:
if app.package_name == compatible_package:
p = {x: patch[x] for x in ["name", "description", "use"]}
p = {x: patch[x] for x in ["name", "description"]}
p["app"] = compatible_package
p["version"] = versions[-1] if versions else "all"
p["version"] = version[-1] if version else "all"
self.patches_dict[app.app_name].append(p)
app.no_of_patches = len(self.patches_dict[app.app_name])
@@ -199,28 +199,3 @@ class Patches(object):
app.app_version = recommended_version
app.experiment = experiment
return total_patches
class PatchLoader(object):
"""Patch Loader."""
@staticmethod
def load_patches(file_name: str) -> Any:
"""The function `load_patches` loads patches from a file and returns them.
Parameters
----------
file_name : str
The `file_name` parameter is a string that represents the name or path of the file from which
the patches will be loaded.
Returns
-------
the patches loaded from the file.
"""
try:
with Path(file_name).open() as f:
return json.load(f)
except FileNotFoundError as e:
msg = "File not found"
raise PatchesJsonLoadError(msg, file_name=file_name) from e
+104
View File
@@ -0,0 +1,104 @@
"""Generate patches using cli."""
import re
import subprocess
from pathlib import Path
from typing import Any
def convert_command_output_to_json(
jar_file_name: str,
patches_file: str,
) -> list[dict[Any, Any]]:
"""
Runs the ReVanced CLI command, processes the output, and saves it as a sorted JSON file.
Args:
jar_file_name (str): Name or path of the JAR file to run.
patches_file (str): The patches file name or path to pass to the command.
"""
def run_command_and_capture_output(patches_command: list[str]) -> Any:
result = subprocess.run(patches_command, capture_output=True, text=True, check=True)
return result.stdout
def parse_text_to_json(text: str) -> list[dict[Any, Any]]:
# Split the data into individual sections based on "Name:"
sections = re.split(r"(?=Name:)", text)
result = []
for section in sections:
# Extract the name
name_match = re.search(r"Name: (.*?)\n", section)
name = name_match.group(1).strip() if name_match else None
# Extract the description
description_match = re.search(r"Description: (.*?)\n", section)
description = description_match.group(1).strip() if description_match else ""
# Extract the enabled state
enabled_match = re.search(r"Enabled: (true|false)", section, re.IGNORECASE)
enabled = enabled_match.group(1).lower() == "true" if enabled_match else False
# Extract compatible packages
compatible_packages = []
if "Compatible packages:" in section:
package_sections = re.split(r"\s*Package name: ", section.split("Compatible packages:")[1])
for package_section in package_sections[1:]: # Skip the initial split
package_name = package_section.split("\n")[0].strip()
versions_match = re.search(r"Compatible versions:\s*((?:\d+\.\d+\.\d+\s*)+)", package_section)
versions = versions_match.group(1).split() if versions_match else []
compatible_packages.append({"name": package_name, "versions": versions if versions else None})
# Extract options
options = []
if "Options:" in section:
options_section = section.split("Options:")[1]
option_matches = re.findall(
r"Title: (.*?)\n\s*Description: (.*?)\n\s*Required: (true|false)\n\s*Key: (.*?)\n\s*Default: (.*?)\n(?:\s*Possible values:\s*(.*?))?\s*Type: (.*?)\n", # noqa: E501
options_section,
re.DOTALL,
)
for match in option_matches:
option = {
"title": match[0].strip(),
"description": match[1].strip(),
"required": match[2].lower() == "true",
"key": match[3].strip(),
"default": match[4].strip(),
"possible_values": [v.strip() for v in match[5].split() if v.strip()] if match[5] else [],
"type": match[6].strip(),
}
options.append(option)
# Append the parsed data
result.append(
{
"name": name,
"description": description,
"compatiblePackages": compatible_packages if compatible_packages else None,
"use": enabled,
"options": options,
},
)
return result
# Run the command
command = ["java", "-jar", jar_file_name, "list-patches", "-ipuv", patches_file]
output = run_command_and_capture_output(command)
parsed_data = parse_text_to_json(output)
# Filter out invalid entries where "name" is None
parsed_data = [entry for entry in parsed_data if entry["name"] is not None]
# Sort the data by the "name" field
parsed_data.sort(key=lambda x: x["name"])
with Path("patches.json").open("w") as file:
import json
json.dump(parsed_data, file, indent=2)
return parsed_data
-3
View File
@@ -38,7 +38,6 @@ request_header = {
}
default_cli = "https://github.com/revanced/revanced-cli/releases/latest"
default_patches = "https://github.com/revanced/revanced-patches/releases/latest"
default_patches_json = "https://api.revanced.app/v4/patches/list"
bs4_parser = "html.parser"
changelog_file = "changelog.md"
changelog_json_file = "changelog.json"
@@ -52,7 +51,6 @@ time_zone = "Asia/Kolkata"
app_version_key = "app_version"
patches_version_key = "patches_version"
cli_version_key = "cli_version"
patches_json_version_key = "patches_json_version"
implement_method = "Please implement the method"
status_code_200 = 200
resource_folder = "apks"
@@ -267,7 +265,6 @@ def save_patch_info(app: "APP", updates_info: dict[str, Any]) -> dict[str, Any]:
app_version_key: app.app_version,
patches_version_key: app.resource["patches"]["version"],
cli_version_key: app.resource["cli"]["version"],
patches_json_version_key: app.resource["patches_json"]["version"],
"ms_epoch_since_patched": datetime_to_ms_epoch(datetime.now(timezone(time_zone))),
"date_patched": datetime.now(timezone(time_zone)),
"app_dump": app.for_dump(),