mirror of
https://github.com/sotam0316/docker-py-revanced.git
synced 2026-04-25 03:48:37 +09:00
156 lines
5.2 KiB
Python
156 lines
5.2 KiB
Python
"""Revanced Parser."""
|
|
from subprocess import PIPE, Popen
|
|
from time import perf_counter
|
|
from typing import List, Self
|
|
|
|
from loguru import logger
|
|
|
|
from src.app import APP
|
|
from src.config import RevancedConfig
|
|
from src.exceptions import PatchingFailedError
|
|
from src.patches import Patches
|
|
from src.utils import possible_archs
|
|
|
|
|
|
class Parser(object):
|
|
"""Revanced Parser."""
|
|
|
|
CLI_JAR = "-jar"
|
|
APK_ARG = "-a"
|
|
PATCHES_ARG = "-b"
|
|
INTEGRATIONS_ARG = "-m"
|
|
OUTPUT_ARG = "-o"
|
|
KEYSTORE_ARG = "--keystore"
|
|
OPTIONS_ARG = "--options"
|
|
|
|
def __init__(self: Self, patcher: Patches, config: RevancedConfig) -> None:
|
|
self._PATCHES: List[str] = []
|
|
self._EXCLUDED: List[str] = []
|
|
self.patcher = patcher
|
|
self.config = config
|
|
|
|
def include(self: Self, name: str) -> None:
|
|
"""The function `include` adds a given patch to a list of patches.
|
|
|
|
Parameters
|
|
----------
|
|
name : str
|
|
The `name` parameter is a string that represents the name of the patch to be included.
|
|
"""
|
|
self._PATCHES.extend(["-i", name])
|
|
|
|
def exclude(self: Self, name: str) -> None:
|
|
"""The `exclude` function adds a given patch to the list of excluded patches.
|
|
|
|
Parameters
|
|
----------
|
|
name : str
|
|
The `name` parameter is a string that represents the name of the patch to be excluded.
|
|
"""
|
|
self._PATCHES.extend(["-e", name])
|
|
self._EXCLUDED.append(name)
|
|
|
|
def get_excluded_patches(self: Self) -> List[str]:
|
|
"""The function `get_excluded_patches` is a getter method that returns a list of excluded patches.
|
|
|
|
Returns
|
|
-------
|
|
The method is returning a list of excluded patches.
|
|
"""
|
|
return self._EXCLUDED
|
|
|
|
def get_all_patches(self: Self) -> List[str]:
|
|
"""The function "get_all_patches" is a getter method that returns a ist of all patches.
|
|
|
|
Returns
|
|
-------
|
|
The method is returning a list of all patches.
|
|
"""
|
|
return self._PATCHES
|
|
|
|
def invert_patch(self: Self, name: str) -> bool:
|
|
"""The function `invert_patch` takes a name as input, it toggles the status of the patch.
|
|
|
|
Parameters
|
|
----------
|
|
name : str
|
|
The `name` parameter is a string that represents the name of a patch.
|
|
|
|
Returns
|
|
-------
|
|
a boolean value. It returns True if the patch name is found in the list of patches and
|
|
successfully inverted, and False if the patch name is not found in the list.
|
|
"""
|
|
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"
|
|
else:
|
|
self._PATCHES[patch_index - 1] = "-e"
|
|
except ValueError:
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
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"
|
|
|
|
# noinspection IncorrectFormatting
|
|
def patch_app(
|
|
self: Self,
|
|
app: APP,
|
|
) -> None:
|
|
"""The function `patch_app` is used to patch an app using the Revanced CLI tool.
|
|
|
|
Parameters
|
|
----------
|
|
app : APP
|
|
The `app` parameter is an instance of the `APP` class. It represents an application that needs
|
|
to be patched.
|
|
"""
|
|
args = [
|
|
self.CLI_JAR,
|
|
app.resource["cli"],
|
|
self.APK_ARG,
|
|
app.download_file_name,
|
|
self.PATCHES_ARG,
|
|
app.resource["patches"],
|
|
self.INTEGRATIONS_ARG,
|
|
app.resource["integrations"],
|
|
self.OUTPUT_ARG,
|
|
app.get_output_file_name(),
|
|
self.KEYSTORE_ARG,
|
|
app.keystore_name,
|
|
self.OPTIONS_ARG,
|
|
"options.json",
|
|
]
|
|
if app.experiment:
|
|
logger.debug("Using experimental features")
|
|
args.append("--experimental")
|
|
args[1::2] = map(self.config.temp_folder.joinpath, args[1::2])
|
|
if self.config.ci_test:
|
|
self.exclude_all_patches()
|
|
if self._PATCHES:
|
|
args.extend(self._PATCHES)
|
|
if app.app_name in self.config.rip_libs_apps:
|
|
excluded = set(possible_archs) - set(app.archs_to_build)
|
|
for arch in excluded:
|
|
args.extend(("--rip-lib", arch))
|
|
start = perf_counter()
|
|
logger.debug(f"Sending request to revanced cli for building with args java {args}")
|
|
process = Popen(["java", *args], stdout=PIPE)
|
|
output = process.stdout
|
|
if not output:
|
|
msg = "Failed to send request for patching."
|
|
raise PatchingFailedError(msg)
|
|
for line in output:
|
|
logger.debug(line.decode(), flush=True, end="")
|
|
process.wait()
|
|
logger.info(f"Patching completed for app {app} in {perf_counter() - start:.2f} seconds.")
|