Рефакторинг патчей, реализация Список патчей:
settings_urls: ✔ enabled disable_ad: ✔ enabled disable_beta_banner: ✔ enabled insert_new: ✔ enabled color_theme: ✔ enabled change_server: ✘ disabled package_name: ✔ enabled replace_navbar: ✔ enabled compress: ✔ enabled, обновление описаний
This commit is contained in:
@@ -118,7 +118,7 @@ def info(patch_name: str = ""):
|
|||||||
"""Вывод информации о патче"""
|
"""Вывод информации о патче"""
|
||||||
conf = load_config().model_dump()
|
conf = load_config().model_dump()
|
||||||
if patch_name:
|
if patch_name:
|
||||||
patch = Patch(patch_name, __import__(f"patcher.patches.{patch_name}"))
|
patch = Patch(patch_name, __import__(f"patches.{patch_name}", fromlist=['']))
|
||||||
console.print(f"[green]Информация о патче {patch.name}:")
|
console.print(f"[green]Информация о патче {patch.name}:")
|
||||||
console.print(f" [yellow]Приоритет: {patch.priority}")
|
console.print(f" [yellow]Приоритет: {patch.priority}")
|
||||||
console.print(f" [yellow]Описание: {patch.module.__doc__}")
|
console.print(f" [yellow]Описание: {patch.module.__doc__}")
|
||||||
|
|||||||
@@ -1,26 +1,33 @@
|
|||||||
"""
|
"""
|
||||||
Заменяет сервер api
|
Заменяет сервер api
|
||||||
|
|
||||||
"change_server": {
|
"change_server": {
|
||||||
|
"enabled": true,
|
||||||
"server": "https://anixarty.wowlikon.tech/modding"
|
"server": "https://anixarty.wowlikon.tech/modding"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
|
# imports
|
||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
def apply(config: dict) -> bool:
|
def apply(config: dict) -> bool:
|
||||||
response = requests.get(config['server'])
|
response = requests.get(config['server'])
|
||||||
assert response.status_code == 200, f"Failed to fetch data {response.status_code} {response.text}"
|
assert response.status_code == 200, f"Failed to fetch data {response.status_code} {response.text}"
|
||||||
|
|
||||||
new_api = json.loads(response.text)
|
new_api = json.loads(response.text)
|
||||||
for item in new_api['modifications']:
|
for item in new_api['modifications']:
|
||||||
tqdm.write(f"Изменение {item['file']}")
|
tqdm.write(f"Изменение {item['file']}")
|
||||||
filepath = './decompiled/smali_classes2/com/swiftsoft/anixartd/network/api/'+item['file']
|
filepath = './decompiled/smali_classes2/com/swiftsoft/anixartd/network/api/'+item['file']
|
||||||
|
|
||||||
with open(filepath, 'r') as f:
|
with open(filepath, 'r') as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
|
|
||||||
with open(filepath, 'w') as f:
|
with open(filepath, 'w') as f:
|
||||||
if content.count(item['src']) == 0:
|
if content.count(item['src']) == 0:
|
||||||
tqdm.write(f"⚠ Не найдено {item['src']}")
|
tqdm.write(f"⚠ Не найдено {item['src']}")
|
||||||
@@ -28,18 +35,22 @@ def apply(config: dict) -> bool:
|
|||||||
|
|
||||||
tqdm.write(f"Изменение Github ссылки")
|
tqdm.write(f"Изменение Github ссылки")
|
||||||
filepath = './decompiled/smali_classes2/com/swiftsoft/anixartd/utils/anixnet/GithubPagesNetFetcher.smali'
|
filepath = './decompiled/smali_classes2/com/swiftsoft/anixartd/utils/anixnet/GithubPagesNetFetcher.smali'
|
||||||
|
|
||||||
with open(filepath, 'r') as f:
|
with open(filepath, 'r') as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
|
|
||||||
with open(filepath, 'w') as f:
|
with open(filepath, 'w') as f:
|
||||||
f.write(content.replace('const-string v1, "https://anixhelper.github.io/pages/urls.json"', f'const-string v1, "{new_api["gh"]}"'))
|
f.write(content.replace('const-string v1, "https://anixhelper.github.io/pages/urls.json"', f'const-string v1, "{new_api["gh"]}"'))
|
||||||
|
|
||||||
content = ""
|
content = ""
|
||||||
tqdm.write("Удаление динамического выбора сервера")
|
tqdm.write("Удаление динамического выбора сервера")
|
||||||
filepath = './decompiled/smali_classes2/com/swiftsoft/anixartd/DaggerApp_HiltComponents_SingletonC$SingletonCImpl$SwitchingProvider.smali'
|
filepath = './decompiled/smali_classes2/com/swiftsoft/anixartd/DaggerApp_HiltComponents_SingletonC$SingletonCImpl$SwitchingProvider.smali'
|
||||||
|
|
||||||
with open(filepath, 'r') as f:
|
with open(filepath, 'r') as f:
|
||||||
for line in f.readlines():
|
for line in f.readlines():
|
||||||
if "addInterceptor" in line: continue
|
if "addInterceptor" in line: continue
|
||||||
content += line
|
content += line
|
||||||
|
|
||||||
with open(filepath, 'w') as f:
|
with open(filepath, 'w') as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Изменяет цветовую тему приложения и иконку
|
Изменяет цветовую тему приложения и иконку
|
||||||
|
|
||||||
"color_theme": {
|
"color_theme": {
|
||||||
|
"enabled": true,
|
||||||
"colors": {
|
"colors": {
|
||||||
"primary": "#ccff00",
|
"primary": "#ccff00",
|
||||||
"secondary": "#ffffd700",
|
"secondary": "#ffffd700",
|
||||||
@@ -15,10 +16,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
|
# imports
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from utils.public import (
|
from utils.public import (
|
||||||
insert_after_public,
|
insert_after_public,
|
||||||
insert_after_color,
|
insert_after_color,
|
||||||
@@ -26,6 +28,7 @@ from utils.public import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
def apply(config: dict) -> bool:
|
def apply(config: dict) -> bool:
|
||||||
main_color = config["colors"]["primary"]
|
main_color = config["colors"]["primary"]
|
||||||
splash_color = config["colors"]["secondary"]
|
splash_color = config["colors"]["secondary"]
|
||||||
@@ -103,6 +106,7 @@ def apply(config: dict) -> bool:
|
|||||||
change_color("accent_alpha_20", main_color[0]+'33'+main_color[1:])
|
change_color("accent_alpha_20", main_color[0]+'33'+main_color[1:])
|
||||||
change_color("accent_alpha_50", main_color[0]+'80'+main_color[1:])
|
change_color("accent_alpha_50", main_color[0]+'80'+main_color[1:])
|
||||||
change_color("accent_alpha_70", main_color[0]+'b3'+main_color[1:])
|
change_color("accent_alpha_70", main_color[0]+'b3'+main_color[1:])
|
||||||
|
|
||||||
change_color("colorAccent", main_color[0]+'ff'+main_color[1:])
|
change_color("colorAccent", main_color[0]+'ff'+main_color[1:])
|
||||||
change_color("link_color", main_color[0]+'ff'+main_color[1:])
|
change_color("link_color", main_color[0]+'ff'+main_color[1:])
|
||||||
change_color("link_color_alpha_70", main_color[0]+'b3'+main_color[1:])
|
change_color("link_color_alpha_70", main_color[0]+'b3'+main_color[1:])
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
# Compress
|
|
||||||
|
|
||||||
Патч удаляет ненужные ресурсы что-бы уменьшить размер АПК
|
|
||||||
|
|
||||||
## настройки (compress в config.json)
|
|
||||||
|
|
||||||
- remove_unknown_files: true/false - удаляет файлы из директории decompiled/unknown
|
|
||||||
- remove_unknown_files_keep_dirs: list[str] - оставляет указанные директории в decompiled/unknown
|
|
||||||
- remove_debug_lines: true/false - удаляет строки `.line n` из декомпилированных smali файлов использованные для дебага
|
|
||||||
- remove_AI_voiceover: true/false - заменяет ИИ озвучку маскота аниксы пустыми mp3 файлами
|
|
||||||
- compress_png_files: true/false - сжимает PNG в директории decompiled/res
|
|
||||||
- remove_drawable_files: true/false - удаляет неиспользованные drawable-* из директории decompiled/res
|
|
||||||
- remove_language_files: true/false - удаляет все языки кроме русского и английского
|
|
||||||
|
|
||||||
## efficiency
|
|
||||||
|
|
||||||
Проверено с версией 9.0 Beta 7
|
|
||||||
|
|
||||||
разница = оригинальный размер апк - патченный размер апк, не учитывая другие патчи
|
|
||||||
|
|
||||||
| Настройка | Размер файла | Разница | % |
|
|
||||||
| :----------- | :-------------------: | :-----------------: | :-: |
|
|
||||||
| None | 17092 bytes - 17.1 MB | - | - |
|
|
||||||
| Compress PNG | 17072 bytes - 17.1 MB | 20 bytes - 0.0 MB | 0.11% |
|
|
||||||
| Remove files | 17020 bytes - 17.0 MB | 72 bytes - 0.1 MB | 0.42% |
|
|
||||||
| Remove draws | 16940 bytes - 16.9 MB | 152 bytes - 0.2 MB | 0.89% |
|
|
||||||
| Remove lines | 16444 bytes - 16.4 MB | 648 bytes - 0.7 MB | 3.79% |
|
|
||||||
| Remove ai vo | 15812 bytes - 15.8 MB | 1280 bytes - 1.3 MB | 7.49% |
|
|
||||||
| Remove langs | 15764 bytes - 15.7 MB | 1328 bytes - 1.3 MB | 7.76% |
|
|
||||||
| Все включены | 13592 bytes - 13.6 MB | 3500 bytes - 4.8 MB | 20.5% |
|
|
||||||
+28
-1
@@ -1,4 +1,31 @@
|
|||||||
"""Remove and compress resources"""
|
"""
|
||||||
|
Удаляет ненужное и сжимает ресурсы что-бы уменьшить размер АПК
|
||||||
|
|
||||||
|
Эффективность на проверена на версии 9.0 Beta 7
|
||||||
|
разница = оригинальный размер апк - патченный размер апк, не учитывая другие патчи
|
||||||
|
|
||||||
|
| Настройка | Размер файла | Разница | % |
|
||||||
|
| :----------- | :-------------------: | :-----------------: | :-: |
|
||||||
|
| None | 17092 bytes - 17.1 MB | - | - |
|
||||||
|
| Compress PNG | 17072 bytes - 17.1 MB | 20 bytes - 0.0 MB | 0.11% |
|
||||||
|
| Remove files | 17020 bytes - 17.0 MB | 72 bytes - 0.1 MB | 0.42% |
|
||||||
|
| Remove draws | 16940 bytes - 16.9 MB | 152 bytes - 0.2 MB | 0.89% |
|
||||||
|
| Remove lines | 16444 bytes - 16.4 MB | 648 bytes - 0.7 MB | 3.79% |
|
||||||
|
| Remove ai vo | 15812 bytes - 15.8 MB | 1280 bytes - 1.3 MB | 7.49% |
|
||||||
|
| Remove langs | 15764 bytes - 15.7 MB | 1328 bytes - 1.3 MB | 7.76% |
|
||||||
|
| Все включены | 13592 bytes - 13.6 MB | 3500 bytes - 4.8 MB | 20.5% |
|
||||||
|
|
||||||
|
"compress": {
|
||||||
|
"enabled": true,
|
||||||
|
"remove_language_files": true, // удаляет все языки кроме русского и английского
|
||||||
|
"remove_AI_voiceover": true, // заменяет ИИ озвучку маскота аниксы пустыми mp3 файлами
|
||||||
|
"remove_debug_lines": false, // удаляет строки `.line n` из smali файлов использованные для дебага
|
||||||
|
"remove_drawable_files": false, // удаляет неиспользованные drawable-* из директории decompiled/res
|
||||||
|
"remove_unknown_files": true, // удаляет файлы из директории decompiled/unknown
|
||||||
|
"remove_unknown_files_keep_dirs": ["META-INF", "kotlin"], // оставляет указанные директории в decompiled/unknown
|
||||||
|
"compress_png_files": true // сжимает PNG в директории decompiled/res
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
priority = -1
|
priority = -1
|
||||||
|
|
||||||
|
|||||||
+16
-10
@@ -1,8 +1,15 @@
|
|||||||
"""
|
"""
|
||||||
Удаляет баннеры рекламы
|
Удаляет баннеры рекламы
|
||||||
|
|
||||||
|
"disable_ad": {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
|
# imports
|
||||||
|
import textwrap
|
||||||
from utils.smali_parser import (
|
from utils.smali_parser import (
|
||||||
find_smali_method_end,
|
find_smali_method_end,
|
||||||
find_smali_method_start,
|
find_smali_method_start,
|
||||||
@@ -11,15 +18,14 @@ from utils.smali_parser import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
replace = """ .locals 0
|
# Patch
|
||||||
|
|
||||||
const/4 p0, 0x1
|
|
||||||
|
|
||||||
return p0
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def apply(config) -> bool:
|
def apply(config) -> bool:
|
||||||
|
replacement = textwrap.dedent("""\
|
||||||
|
.locals 0
|
||||||
|
const/4 p0, 0x1
|
||||||
|
return p0
|
||||||
|
""").splitlines()
|
||||||
|
|
||||||
path = "./decompiled/smali_classes2/com/swiftsoft/anixartd/Prefs.smali"
|
path = "./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):
|
||||||
@@ -27,7 +33,7 @@ def apply(config) -> bool:
|
|||||||
method_start = find_smali_method_start(lines, index)
|
method_start = find_smali_method_start(lines, index)
|
||||||
method_end = find_smali_method_end(lines, index)
|
method_end = find_smali_method_end(lines, index)
|
||||||
new_content = replace_smali_method_body(
|
new_content = replace_smali_method_body(
|
||||||
lines, method_start, method_end, replace
|
lines, method_start, method_end, replacement
|
||||||
)
|
)
|
||||||
|
|
||||||
with open(path, "w", encoding="utf-8") as file:
|
with open(path, "w", encoding="utf-8") as file:
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
"""
|
"""
|
||||||
Удаляет баннеры бета-версии
|
Удаляет баннеры бета-версии
|
||||||
|
|
||||||
|
"disable_beta_banner": {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
|
# imports
|
||||||
import os
|
import os
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
def apply(config) -> bool:
|
def apply(config) -> bool:
|
||||||
attributes = [
|
attributes = [
|
||||||
"paddingTop",
|
"paddingTop",
|
||||||
@@ -29,7 +36,8 @@ def apply(config) -> bool:
|
|||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
|
|
||||||
for attr in attributes:
|
for attr in attributes:
|
||||||
# tqdm.write(f"set {attr} = 0.0dip")
|
if config["verbose"]:
|
||||||
|
tqdm.write(f"set {attr} = 0.0dip")
|
||||||
root.set(f"{{{config["xml_ns"]['android']}}}{attr}", "0.0dip")
|
root.set(f"{{{config["xml_ns"]['android']}}}{attr}", "0.0dip")
|
||||||
|
|
||||||
tree.write(
|
tree.write(
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
"""
|
"""
|
||||||
Вставляет новые файлы в проект
|
Вставляет новые файлы в проект
|
||||||
|
|
||||||
|
"insert_new": {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
import shutil
|
# imports
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
from utils.public import insert_after_public
|
from utils.public import insert_after_public
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
def apply(config: dict) -> bool:
|
def apply(config: dict) -> bool:
|
||||||
# Mod first launch window
|
# Mod first launch window
|
||||||
shutil.copytree(
|
shutil.copytree(
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
"""
|
"""
|
||||||
Изменяет имя пакета в apk, удаляет вход по google и vk
|
Изменяет имя пакета в apk, удаляет вход по google и vk
|
||||||
|
|
||||||
"package_name": {
|
"package_name": {
|
||||||
|
"enabled": true,
|
||||||
"new_package_name": "com.wowlikon.anixart"
|
"new_package_name": "com.wowlikon.anixart"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = -1
|
priority = -1
|
||||||
|
|
||||||
|
# imports
|
||||||
import os
|
import os
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
def rename_dir(src, dst):
|
def rename_dir(src, dst):
|
||||||
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
||||||
os.rename(src, dst)
|
os.rename(src, dst)
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
"""
|
"""
|
||||||
Меняет порядок вкладок в панели навигации
|
Меняет порядок вкладок в панели навигации
|
||||||
|
|
||||||
"replace_navbar": {
|
"replace_navbar": {
|
||||||
|
"enabled": true,
|
||||||
"items": ["home", "discover", "feed", "bookmarks", "profile"]
|
"items": ["home", "discover", "feed", "bookmarks", "profile"]
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
|
# imports
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
def apply(config: dict) -> bool:
|
def apply(config: dict) -> bool:
|
||||||
file_path = "./decompiled/res/menu/bottom.xml"
|
file_path = "./decompiled/res/menu/bottom.xml"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Добавляет в настройки ссылки и доавляет текст к версии приложения
|
Добавляет в настройки ссылки и добвляет текст к версии приложения
|
||||||
|
|
||||||
"settings_urls": {
|
"settings_urls": {
|
||||||
|
"enabled": true,
|
||||||
"menu": {
|
"menu": {
|
||||||
"Раздел": [
|
"Раздел": [
|
||||||
{
|
{
|
||||||
@@ -19,11 +20,14 @@
|
|||||||
"version": " by wowlikon"
|
"version": " by wowlikon"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
|
# imports
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
def make_category(ns, name, items):
|
def make_category(ns, name, items):
|
||||||
cat = etree.Element("PreferenceCategory", nsmap=ns)
|
cat = etree.Element("PreferenceCategory", nsmap=ns)
|
||||||
cat.set(f"{{{ns['android']}}}title", name)
|
cat.set(f"{{{ns['android']}}}title", name)
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
"""Change application icon"""
|
|
||||||
priority = 0
|
|
||||||
|
|
||||||
|
|
||||||
def apply(config: dict) -> bool:
|
|
||||||
return False
|
|
||||||
@@ -1,18 +1,23 @@
|
|||||||
"""
|
"""
|
||||||
Добавляет пользовательские скорости воспроизведения видео
|
Добавляет пользовательские скорости воспроизведения видео
|
||||||
|
|
||||||
"custom_speed": {
|
"custom_speed": {
|
||||||
|
"enabled": true,
|
||||||
"speeds": [9.0]
|
"speeds": [9.0]
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
|
# imports
|
||||||
from utils.smali_parser import float_to_hex
|
from utils.smali_parser import float_to_hex
|
||||||
from utils.public import (
|
from utils.public import (
|
||||||
insert_after_public,
|
insert_after_public,
|
||||||
insert_after_id,
|
insert_after_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
def apply(config: dict) -> bool:
|
def apply(config: dict) -> bool:
|
||||||
assert float_to_hex(1.5) == "0x3fc00000"
|
assert float_to_hex(1.5) == "0x3fc00000"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
"""
|
||||||
|
Шаблон патча
|
||||||
|
|
||||||
|
Здесь вы можете добавить описание патча, его назначение и другие детали.
|
||||||
|
|
||||||
|
Каждый патч должен независеть от других патчей и проверять себя при применении. Он не должен вернуть True, если есть проблемы.
|
||||||
|
На данный момент каждый патч должен иметь функцию `apply`, которая принимает на вход конфигурацию и возвращает True или False.
|
||||||
|
При успешном применении патча, функция apply должна вернуть True, иначе False.
|
||||||
|
Ошибка будет интерпретирована как False. С выводом ошибки в консоль.
|
||||||
|
Ещё патч должен иметь переменную `priority`, которая указывает приоритет патча, чем выше, тем раньше он будет применен.
|
||||||
|
|
||||||
|
Коротко о конфигурации. Она получается из `config.json` из config["patches"][patch_name].
|
||||||
|
Дополнительно в основном методе `apply` кроме этого есть "verbose" и содержимое "base".
|
||||||
|
Эти поля передаются всем патчам. `verbose` может быть указан так-же как флаг запуска:
|
||||||
|
```
|
||||||
|
python ./main.py build --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
В конце файла должно быть описание конфигурации патча.
|
||||||
|
Это может быть как короткий фрагмент из названия патча и одной опции "enabled", которая обрабатывается в коде патчера.
|
||||||
|
|
||||||
|
"todo_template": {
|
||||||
|
"enabled": true // Пример описания тк этот текст просто пример
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
priority = 0 # Приоритет патча, чем выше, тем раньше он будет применен
|
||||||
|
|
||||||
|
# imports
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
|
def apply(config: dict) -> bool: # Анотации типов для удобства, читаемости и поддержки IDE
|
||||||
|
tqdm.write("Вывод информации через tqdm, чтобы не мешать прогресс-бару")
|
||||||
|
if config["verbose"]:
|
||||||
|
tqdm.write("Для вывода подробной и отладочной информации используйте флаг --verbose")
|
||||||
|
return True
|
||||||
Reference in New Issue
Block a user