mirror of
https://github.com/Radiquum/anixart-patcher.git
synced 2025-09-06 03:03:50 +05:00
refactor: tqdm -> rich.progress
This commit is contained in:
parent
43b1406b4a
commit
7b5ba163bd
10 changed files with 260 additions and 141 deletions
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
"log_level": "INFO",
|
||||||
"tools": [
|
"tools": [
|
||||||
{
|
{
|
||||||
"tool": "apktool.jar",
|
"tool": "apktool.jar",
|
||||||
|
@ -11,5 +12,9 @@
|
||||||
"decompiled": "./decompiled",
|
"decompiled": "./decompiled",
|
||||||
"patches": "./patches",
|
"patches": "./patches",
|
||||||
"dist": "./dist"
|
"dist": "./dist"
|
||||||
|
},
|
||||||
|
"xml_ns": {
|
||||||
|
"android": "http://schemas.android.com/apk/res/android",
|
||||||
|
"app": "http://schemas.android.com/apk/res-auto"
|
||||||
}
|
}
|
||||||
}
|
}
|
15
config.py
15
config.py
|
@ -30,18 +30,31 @@ class ConfigFolders(TypedDict):
|
||||||
dist: str
|
dist: str
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigXmlNS(TypedDict):
|
||||||
|
android: str
|
||||||
|
app: str
|
||||||
|
|
||||||
|
|
||||||
class Config(TypedDict):
|
class Config(TypedDict):
|
||||||
|
log_level: str
|
||||||
tools: list[ConfigTools]
|
tools: list[ConfigTools]
|
||||||
folders: ConfigFolders
|
folders: ConfigFolders
|
||||||
|
xml_ns: ConfigXmlNS
|
||||||
|
|
||||||
|
|
||||||
def load_config() -> Config:
|
def load_config() -> Config:
|
||||||
|
config = None
|
||||||
|
|
||||||
if not os.path.exists("config.json"):
|
if not os.path.exists("config.json"):
|
||||||
log.exception("file `config.json` is not found!")
|
log.exception("file `config.json` is not found!")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
with open("./config.json", "r", encoding="utf-8") as file:
|
with open("./config.json", "r", encoding="utf-8") as file:
|
||||||
return json.loads(file.read())
|
config = json.loads(file.read())
|
||||||
|
|
||||||
|
log.setLevel(config.get("log_level", "NOTSET").upper())
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
config = load_config()
|
config = load_config()
|
||||||
|
|
|
@ -1,73 +1,88 @@
|
||||||
"""Change app color theme"""
|
"""Change app color theme"""
|
||||||
|
|
||||||
|
# patch settings
|
||||||
|
# priority, default: -99 (run before last)
|
||||||
priority = -99
|
priority = -99
|
||||||
|
|
||||||
import os
|
# imports
|
||||||
|
## bundled
|
||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
from beaupy import select
|
from beaupy import select
|
||||||
from tqdm import tqdm
|
|
||||||
|
## installed
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
|
## custom
|
||||||
|
from config import config, log, console
|
||||||
|
|
||||||
|
|
||||||
|
class PatchConfig_ChangeColorThemeValue(TypedDict):
|
||||||
|
attributes: list[dict[str, str]]
|
||||||
|
text: list[dict[str, str]]
|
||||||
|
files: list[dict[str, str]]
|
||||||
|
|
||||||
|
|
||||||
class PatchConfig_ChangeColorTheme(TypedDict):
|
class PatchConfig_ChangeColorTheme(TypedDict):
|
||||||
src: str
|
themes: list[str]
|
||||||
themes: str
|
key: PatchConfig_ChangeColorThemeValue
|
||||||
|
|
||||||
def apply(config: PatchConfig_ChangeColorTheme) -> bool:
|
|
||||||
print("select color theme to apply")
|
|
||||||
|
|
||||||
theme = select(config["themes"], cursor="->", cursor_style="cyan")
|
def apply(patch_config: PatchConfig_ChangeColorTheme) -> bool:
|
||||||
theme_attr = config[theme]['attributes']
|
|
||||||
theme_text = config[theme]['text']
|
|
||||||
theme_files = config[theme]['files']
|
|
||||||
|
|
||||||
with tqdm(
|
console.print("select color theme to apply (press [bold]enter[/bold] to confirm)")
|
||||||
total=len(theme_attr),
|
theme = select(patch_config["themes"], cursor="->", cursor_style="cyan")
|
||||||
unit="attr",
|
if not theme:
|
||||||
unit_divisor=1,
|
console.print(f"theme: default")
|
||||||
desc="color attributes"
|
return False
|
||||||
) as bar:
|
console.print(f"theme: {theme}")
|
||||||
for attr in theme_attr:
|
|
||||||
|
theme_attr = patch_config[theme]["attributes"]
|
||||||
|
theme_text = patch_config[theme]["text"]
|
||||||
|
theme_files = patch_config[theme]["files"]
|
||||||
|
|
||||||
|
for item in theme_attr:
|
||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
tree = etree.parse(f"{config['src']}/{attr['file_path']}", parser)
|
tree = etree.parse(
|
||||||
|
f"{config['folders']['decompiled']}/{item['file_path']}", parser
|
||||||
|
)
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
root.find(attr['tag_path']).set(attr['attr_name'], attr['attr_value']['to'])
|
root.find(item["tag_path"]).set(item["attr_name"], item["attr_value"]["to"])
|
||||||
tree.write(
|
tree.write(
|
||||||
f"{config['src']}/{attr['file_path']}",
|
f"{config['folders']['decompiled']}/{item['file_path']}",
|
||||||
pretty_print=True,
|
pretty_print=True,
|
||||||
xml_declaration=True,
|
xml_declaration=True,
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
bar.update()
|
log.debug(
|
||||||
|
f"[CHANGE_COLOR_THEME/ATTRIBUTES] set attribute `{item['attr_name']}` from `{item['attr_value']['from']}` to `{item['attr_value']['to']}`"
|
||||||
|
)
|
||||||
|
|
||||||
with tqdm(
|
for item in theme_text:
|
||||||
total=len(theme_text),
|
|
||||||
unit="attr",
|
|
||||||
unit_divisor=1,
|
|
||||||
desc="color values"
|
|
||||||
) as bar:
|
|
||||||
for text in theme_text:
|
|
||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
tree = etree.parse(f"{config['src']}/{text['file_path']}", parser)
|
tree = etree.parse(
|
||||||
|
f"{config['folders']['decompiled']}/{item['file_path']}", parser
|
||||||
|
)
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
root.find(text['tag_path']).text = text['text']['to']
|
root.find(item["tag_path"]).text = item["text"]["to"]
|
||||||
tree.write(
|
tree.write(
|
||||||
f"{config['src']}/{text['file_path']}",
|
f"{config['folders']['decompiled']}/{item['file_path']}",
|
||||||
pretty_print=True,
|
pretty_print=True,
|
||||||
xml_declaration=True,
|
xml_declaration=True,
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
bar.update()
|
log.debug(
|
||||||
|
f"[CHANGE_COLOR_THEME/VALUES] set text from `{item['text']['from']}` to `{item['text']['to']}`"
|
||||||
|
)
|
||||||
|
|
||||||
if len(theme_files) > 0:
|
if len(theme_files) > 0:
|
||||||
with tqdm(
|
for item in theme_files:
|
||||||
total=len(theme_files),
|
with open(
|
||||||
unit="files",
|
f"{config['folders']['decompiled']}/{item['file_path']}",
|
||||||
unit_divisor=1,
|
"w",
|
||||||
desc="color files"
|
encoding="utf-8",
|
||||||
) as bar:
|
) as f:
|
||||||
for file in theme_files:
|
f.write("\n".join(item["file_content"]))
|
||||||
with open(f"{config['src']}/{file['file_path']}", "w", encoding="utf-8") as f:
|
log.debug(f"[CHANGE_COLOR_THEME/FILES] replaced file {item['file_path']}")
|
||||||
f.write("\n".join(file['file_content']))
|
|
||||||
bar.update()
|
|
||||||
|
|
||||||
|
log.debug(f"[CHANGE_COLOR_THEME] color theme `{theme}` has been applied")
|
||||||
return True
|
return True
|
|
@ -1,36 +1,51 @@
|
||||||
"""Change package name"""
|
"""Change package name"""
|
||||||
|
|
||||||
|
# patch settings
|
||||||
|
# priority, default: -100 (run last)
|
||||||
priority = -100
|
priority = -100
|
||||||
|
|
||||||
|
# imports
|
||||||
|
## bundled
|
||||||
import os
|
import os
|
||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
|
|
||||||
|
## custom
|
||||||
|
from config import config, log
|
||||||
|
|
||||||
|
|
||||||
class PatchConfig_ChangePackageName(TypedDict):
|
class PatchConfig_ChangePackageName(TypedDict):
|
||||||
src: str
|
|
||||||
new_package_name: str
|
new_package_name: str
|
||||||
|
|
||||||
|
|
||||||
def rename_dir(src, dst):
|
def rename_dir(src, dst):
|
||||||
os.makedirs(dst, exist_ok=True)
|
os.makedirs(dst, exist_ok=True)
|
||||||
os.rename(src, dst)
|
os.rename(src, dst)
|
||||||
|
|
||||||
def apply(config: dict) -> bool:
|
|
||||||
assert config["new_package_name"] is not None, "new_package_name is not configured"
|
|
||||||
|
|
||||||
for root, dirs, files in os.walk(f"{config['src']}"):
|
def apply(patch_config: PatchConfig_ChangePackageName) -> bool:
|
||||||
|
assert (
|
||||||
|
patch_config["new_package_name"] is not None
|
||||||
|
), "new_package_name is not configured"
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(f"{config['folders']['decompiled']}"):
|
||||||
|
if len(files) < 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
dir_name = root.removeprefix(f"{config['folders']['decompiled']}/")
|
||||||
|
|
||||||
for filename in files:
|
for filename in files:
|
||||||
file_path = os.path.join(root, filename)
|
file_path = os.path.join(root, filename)
|
||||||
|
|
||||||
if os.path.isfile(file_path):
|
if os.path.isfile(file_path):
|
||||||
try:
|
try:
|
||||||
with open(file_path, "r", encoding="utf-8") as file:
|
with open(file_path, "r", encoding="utf-8") as file:
|
||||||
file_contents = file.read()
|
file_contents = file.read()
|
||||||
|
|
||||||
new_contents = file_contents.replace(
|
new_contents = file_contents.replace(
|
||||||
"com.swiftsoft.anixartd", config["new_package_name"]
|
"com.swiftsoft.anixartd", patch_config["new_package_name"]
|
||||||
)
|
)
|
||||||
new_contents = new_contents.replace(
|
new_contents = new_contents.replace(
|
||||||
"com/swiftsoft/anixartd",
|
"com/swiftsoft/anixartd",
|
||||||
config["new_package_name"].replace(".", "/"),
|
patch_config["new_package_name"].replace(".", "/"),
|
||||||
)
|
)
|
||||||
|
|
||||||
with open(file_path, "w", encoding="utf-8") as file:
|
with open(file_path, "w", encoding="utf-8") as file:
|
||||||
|
@ -38,22 +53,31 @@ def apply(config: dict) -> bool:
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if os.path.exists(f"{config['src']}/smali/com/swiftsoft/anixartd"):
|
if os.path.exists(
|
||||||
|
f"{config['folders']['decompiled']}/smali/com/swiftsoft/anixartd"
|
||||||
|
):
|
||||||
rename_dir(
|
rename_dir(
|
||||||
f"{config['src']}/smali/com/swiftsoft/anixartd",
|
f"{config['folders']['decompiled']}/smali/com/swiftsoft/anixartd",
|
||||||
os.path.join(
|
os.path.join(
|
||||||
f"{config['src']}", "smali", config["new_package_name"].replace(".", "/")
|
f"{config['folders']['decompiled']}",
|
||||||
|
"smali",
|
||||||
|
patch_config["new_package_name"].replace(".", "/"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
if os.path.exists(f"{config['src']}/smali_classes2/com/swiftsoft/anixartd"):
|
if os.path.exists(
|
||||||
|
f"{config['folders']['decompiled']}/smali_classes2/com/swiftsoft/anixartd"
|
||||||
|
):
|
||||||
rename_dir(
|
rename_dir(
|
||||||
f"{config['src']}/smali_classes2/com/swiftsoft/anixartd",
|
f"{config['folders']['decompiled']}/smali_classes2/com/swiftsoft/anixartd",
|
||||||
os.path.join(
|
os.path.join(
|
||||||
f"{config['src']}",
|
f"{config['folders']['decompiled']}",
|
||||||
"smali_classes2",
|
"smali_classes2",
|
||||||
config["new_package_name"].replace(".", "/"),
|
patch_config["new_package_name"].replace(".", "/"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
log.debug(
|
||||||
|
f"[CHANGE_PACKAGE_NAME] package name has been changed to {patch_config['new_package_name']}"
|
||||||
|
)
|
||||||
return True
|
return True
|
|
@ -1,25 +1,45 @@
|
||||||
"""Remove unnecessary resources"""
|
"""Remove unnecessary resources"""
|
||||||
|
|
||||||
|
# patch settings
|
||||||
|
# priority, default: 0
|
||||||
priority = 0
|
priority = 0
|
||||||
from tqdm import tqdm
|
|
||||||
|
|
||||||
|
# imports
|
||||||
|
## bundled
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
|
|
||||||
|
## installed
|
||||||
|
from rich.progress import track
|
||||||
|
|
||||||
|
## custom
|
||||||
|
from config import config, log, console
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
|
|
||||||
class PatchConfig_Compress(TypedDict):
|
class PatchConfig_Compress(TypedDict):
|
||||||
src: str
|
|
||||||
keep_dirs: list[str]
|
keep_dirs: list[str]
|
||||||
|
|
||||||
def apply(config: PatchConfig_Compress) -> bool:
|
def apply(patch_config: PatchConfig_Compress) -> bool:
|
||||||
for item in os.listdir(f"{config['src']}/unknown/"):
|
path = f"{config['folders']['decompiled']}/unknown"
|
||||||
item_path = os.path.join(f"{config['src']}/unknown/", item)
|
items = os.listdir(path)
|
||||||
|
|
||||||
|
for item in track(
|
||||||
|
items,
|
||||||
|
console=console,
|
||||||
|
description="[COMPRESS]",
|
||||||
|
total=len(items),
|
||||||
|
):
|
||||||
|
item_path = f"{path}/{item}"
|
||||||
if os.path.isfile(item_path):
|
if os.path.isfile(item_path):
|
||||||
os.remove(item_path)
|
os.remove(item_path)
|
||||||
tqdm.write(f"removed file: {item_path}")
|
log.debug(f"[COMPRESS] removed file: {item_path}")
|
||||||
elif os.path.isdir(item_path):
|
elif os.path.isdir(item_path):
|
||||||
if item not in config["keep_dirs"]:
|
if item not in patch_config["keep_dirs"]:
|
||||||
shutil.rmtree(item_path)
|
shutil.rmtree(item_path)
|
||||||
tqdm.write(f"removed directory: {item_path}")
|
log.debug(f"[COMPRESS] removed directory: {item_path}")
|
||||||
|
|
||||||
|
log.debug(f"[COMPRESS] resources have been removed")
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
"""Disable ad banners"""
|
"""Disable ad banners"""
|
||||||
|
|
||||||
|
# patch settings
|
||||||
|
# priority, default: 0
|
||||||
priority = 0
|
priority = 0
|
||||||
from typing import TypedDict
|
|
||||||
|
|
||||||
|
# imports
|
||||||
|
## custom
|
||||||
|
from config import config, log
|
||||||
from scripts.smali_parser import (
|
from scripts.smali_parser import (
|
||||||
find_smali_method_end,
|
find_smali_method_end,
|
||||||
find_smali_method_start,
|
find_smali_method_start,
|
||||||
|
@ -11,10 +15,7 @@ from scripts.smali_parser import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PatchConfig_DisableAdBanner(TypedDict):
|
# Patch
|
||||||
src: str
|
|
||||||
|
|
||||||
|
|
||||||
replace = """ .locals 0
|
replace = """ .locals 0
|
||||||
|
|
||||||
const/4 p0, 0x1
|
const/4 p0, 0x1
|
||||||
|
@ -23,9 +24,10 @@ replace = """ .locals 0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def apply(config: PatchConfig_DisableAdBanner) -> bool:
|
def apply(__no_config__) -> bool:
|
||||||
path = f"{config['src']}/smali_classes2/com/swiftsoft/anixartd/Prefs.smali"
|
path = f"{config['folders']['decompiled']}/smali_classes2/com/swiftsoft/anixartd/Prefs.smali"
|
||||||
lines = get_smali_lines(path)
|
lines = get_smali_lines(path)
|
||||||
|
|
||||||
for index, line in enumerate(lines):
|
for index, line in enumerate(lines):
|
||||||
if line.find("IS_SPONSOR") >= 0:
|
if line.find("IS_SPONSOR") >= 0:
|
||||||
method_start = find_smali_method_start(lines, index)
|
method_start = find_smali_method_start(lines, index)
|
||||||
|
@ -33,7 +35,8 @@ def apply(config: PatchConfig_DisableAdBanner) -> bool:
|
||||||
new_content = replace_smali_method_body(
|
new_content = replace_smali_method_body(
|
||||||
lines, method_start, method_end, replace
|
lines, method_start, method_end, replace
|
||||||
)
|
)
|
||||||
|
|
||||||
with open(path, "w", encoding="utf-8") as file:
|
with open(path, "w", encoding="utf-8") as file:
|
||||||
file.writelines(new_content)
|
file.writelines(new_content)
|
||||||
|
|
||||||
|
log.debug(f"[DISABLE_AD] file {path} has been modified")
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
"""Remove beta banner"""
|
"""Remove beta banner"""
|
||||||
|
|
||||||
|
# patch settings
|
||||||
|
# priority, default: 0
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
|
# imports
|
||||||
|
## bundled
|
||||||
import os
|
import os
|
||||||
from tqdm import tqdm
|
|
||||||
|
## installed
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from typing import TypedDict
|
## custom
|
||||||
|
from config import config, log
|
||||||
|
|
||||||
|
|
||||||
class PatchConfig_DisableBetaBanner(TypedDict):
|
def apply(__no_config__) -> bool:
|
||||||
src: str
|
beta_banner_xml = f"{config['folders']['decompiled']}/res/layout/item_beta.xml"
|
||||||
|
|
||||||
|
|
||||||
def apply(config: PatchConfig_DisableBetaBanner) -> bool:
|
|
||||||
xml_ns = {
|
|
||||||
"android": "http://schemas.android.com/apk/res/android",
|
|
||||||
"app": "http://schemas.android.com/apk/res-auto",
|
|
||||||
}
|
|
||||||
attributes = [
|
attributes = [
|
||||||
"paddingTop",
|
"paddingTop",
|
||||||
"paddingBottom",
|
"paddingBottom",
|
||||||
|
@ -27,19 +27,23 @@ def apply(config: PatchConfig_DisableBetaBanner) -> bool:
|
||||||
"layout_marginTop",
|
"layout_marginTop",
|
||||||
"layout_marginBottom",
|
"layout_marginBottom",
|
||||||
"layout_marginStart",
|
"layout_marginStart",
|
||||||
"layout_marginEnd"
|
"layout_marginEnd",
|
||||||
]
|
]
|
||||||
|
|
||||||
beta_banner_xml = f"{config['src']}/res/layout/item_beta.xml"
|
|
||||||
if os.path.exists(beta_banner_xml):
|
if os.path.exists(beta_banner_xml):
|
||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
tree = etree.parse(beta_banner_xml, parser)
|
tree = etree.parse(beta_banner_xml, parser)
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
|
|
||||||
for attr in attributes:
|
for attr in attributes:
|
||||||
tqdm.write(f"set {attr} = 0.0dip")
|
log.debug(
|
||||||
root.set(f"{{{xml_ns['android']}}}{attr}", "0.0dip")
|
f"[DISABLE_BETA_BANNER] set attribute `{attr}` from `{root.get(attr)}` to `0.0dip`"
|
||||||
|
)
|
||||||
|
root.set(f"{{{config['xml_ns']['android']}}}{attr}", "0.0dip")
|
||||||
|
|
||||||
tree.write(beta_banner_xml, pretty_print=True, xml_declaration=True, encoding="utf-8")
|
tree.write(
|
||||||
|
beta_banner_xml, pretty_print=True, xml_declaration=True, encoding="utf-8"
|
||||||
|
)
|
||||||
|
|
||||||
|
log.debug(f"[DISABLE_BETA_BANNER] file {beta_banner_xml} has been modified")
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
requests
|
requests
|
||||||
tqdm
|
|
||||||
lxml
|
lxml
|
||||||
rich
|
rich
|
||||||
beaupy
|
beaupy
|
|
@ -1,7 +1,28 @@
|
||||||
import requests
|
|
||||||
import os
|
import os
|
||||||
from tqdm import tqdm
|
import requests
|
||||||
from config import config, log
|
import logging
|
||||||
|
from config import config, log, console
|
||||||
|
from rich.progress import (
|
||||||
|
BarColumn,
|
||||||
|
DownloadColumn,
|
||||||
|
Progress,
|
||||||
|
TextColumn,
|
||||||
|
TimeRemainingColumn,
|
||||||
|
TransferSpeedColumn,
|
||||||
|
)
|
||||||
|
|
||||||
|
progress = Progress(
|
||||||
|
TextColumn("[bold blue]{task.fields[filename]}", justify="right"),
|
||||||
|
BarColumn(bar_width=None),
|
||||||
|
"[progress.percentage]{task.percentage:>3.1f}%",
|
||||||
|
"•",
|
||||||
|
DownloadColumn(),
|
||||||
|
"•",
|
||||||
|
TransferSpeedColumn(),
|
||||||
|
"•",
|
||||||
|
TimeRemainingColumn(),
|
||||||
|
console=console
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def check_if_tool_exists(tool: str) -> bool:
|
def check_if_tool_exists(tool: str) -> bool:
|
||||||
|
@ -19,27 +40,30 @@ def check_if_tool_exists(tool: str) -> bool:
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
requests_log = logging.getLogger("urllib3.connectionpool")
|
||||||
|
requests_log.setLevel(logging.WARNING)
|
||||||
|
|
||||||
def download_tool(url: str, tool: str):
|
def download_tool(url: str, tool: str):
|
||||||
if not check_if_tool_exists(tool):
|
if not check_if_tool_exists(tool):
|
||||||
log.info(f"downloading a tool: `{tool}`")
|
progress.start()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
log.info(f"Requesting {url}")
|
||||||
response = requests.get(url, stream=True)
|
response = requests.get(url, stream=True)
|
||||||
total = int(response.headers.get("content-length", 0))
|
total = int(response.headers.get("content-length", None))
|
||||||
with open(f"{config['folders']['tools']}/{tool}", "wb") as file, tqdm(
|
task_id = progress.add_task("download", start=False, total=total, filename=tool)
|
||||||
desc=tool,
|
|
||||||
total=total,
|
with open(f"{config['folders']['tools']}/{tool}", "wb") as file:
|
||||||
unit="iB",
|
progress.start_task(task_id)
|
||||||
unit_scale=True,
|
for bytes in response.iter_content(chunk_size=32768):
|
||||||
unit_divisor=1024,
|
|
||||||
) as bar:
|
|
||||||
for bytes in response.iter_content(chunk_size=8192):
|
|
||||||
size = file.write(bytes)
|
size = file.write(bytes)
|
||||||
bar.update(size)
|
progress.update(task_id, advance=size)
|
||||||
|
|
||||||
log.info(f"`{tool}` downloaded")
|
log.info(f"`{tool}` downloaded")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(f"error while downloading `{tool}`: {e}")
|
log.error(f"error while downloading `{tool}`: {e}")
|
||||||
|
|
||||||
|
progress.stop()
|
||||||
|
|
||||||
def check_and_download_all_tools():
|
def check_and_download_all_tools():
|
||||||
for tool in config["tools"]:
|
for tool in config["tools"]:
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import os, json
|
import os, json
|
||||||
import importlib
|
import importlib
|
||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
|
|
||||||
from beaupy import select_multiple
|
from beaupy import select_multiple
|
||||||
from tqdm import tqdm
|
from rich.progress import BarColumn, Progress, TextColumn
|
||||||
|
|
||||||
from config import config, log, console
|
from config import config, log, console
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +61,14 @@ class PatchStatus(TypedDict):
|
||||||
status: bool
|
status: bool
|
||||||
|
|
||||||
|
|
||||||
|
progress = Progress(
|
||||||
|
"[progress.description]{task.description}",
|
||||||
|
TextColumn(text_format="{task.fields[patch]}"),
|
||||||
|
BarColumn(bar_width=None),
|
||||||
|
"[blue]{task.completed}/{task.total}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def apply_patches(patches: list[str]) -> list[PatchStatus]:
|
def apply_patches(patches: list[str]) -> list[PatchStatus]:
|
||||||
modules = []
|
modules = []
|
||||||
statuses = []
|
statuses = []
|
||||||
|
@ -70,24 +80,26 @@ def apply_patches(patches: list[str]) -> list[PatchStatus]:
|
||||||
modules.append(Patch(name, module))
|
modules.append(Patch(name, module))
|
||||||
modules.sort(key=lambda x: x.package.priority, reverse=True)
|
modules.sort(key=lambda x: x.package.priority, reverse=True)
|
||||||
|
|
||||||
with tqdm(
|
with progress:
|
||||||
total=len(modules),
|
task = progress.add_task("applying patch:", total=len(modules), patch="")
|
||||||
unit="patch",
|
for module in modules:
|
||||||
unit_divisor=1,
|
progress.update(task, patch=module.name)
|
||||||
) as bar:
|
|
||||||
for patch in modules:
|
patch_conf = {}
|
||||||
bar.set_description(f"{patch.name}")
|
if os.path.exists(
|
||||||
conf = {}
|
f"{config['folders']['patches']}/{module.name}.config.json"
|
||||||
if os.path.exists(f"{config['folders']['patches']}/{patch.name}.config.json"):
|
):
|
||||||
with open(
|
with open(
|
||||||
f"{config['folders']['patches']}/{patch.name}.config.json",
|
f"{config['folders']['patches']}/{module.name}.config.json",
|
||||||
"r",
|
"r",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
) as conf:
|
) as f:
|
||||||
conf = json.loads(conf.read())
|
patch_conf = json.loads(f.read())
|
||||||
conf["src"] = config["folders"]["decompiled"]
|
|
||||||
status = patch.apply(conf)
|
status = module.apply(patch_conf)
|
||||||
statuses.append({"name": patch.name, "status": status})
|
statuses.append({"name": module.name, "status": status})
|
||||||
bar.update()
|
progress.update(task, advance=1)
|
||||||
|
|
||||||
|
progress.update(task, description="patches applied", patch="")
|
||||||
|
|
||||||
return statuses
|
return statuses
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue