"""Изменяет цветовую тему приложения и иконку "color_theme": { "enabled": true, "logo": { "gradient": { "angle": 0.0, "start_color": "#ffccff00", "end_color": "#ffcccc00" }, "ears_color": "#ffffd0d0" }, "colors": { "primary": "#ccff00", "secondary": "#ffcccc00", "background": "#ffffff", "text": "#000000" } } """ priority = 0 # imports from lxml import etree from typing import Dict, Any from pydantic import Field, BaseModel from utils.config import PatchConfig from utils.public import ( insert_after_public, insert_after_color, change_color, ) #Config class Gradient(BaseModel): angle: float = Field(0.0, description="Угол градиента") start_color: str = Field("#ffccff00", description="Начальный цвет градиента") end_color: str = Field("#ffcccc00", description="Конечный цвет градиента") class Logo(BaseModel): gradient: Gradient = Field(Gradient(), description="Настройки градиента") # type: ignore [reportCallIssue] ears_color: str = Field("#ffd0d0d0", description="Цвет ушей логотипа") class Colors(BaseModel): primary: str = Field("#ccff00", description="Основной цвет") secondary: str = Field("#ffcccc00", description="Вторичный цвет") background: str = Field("#ffffff", description="Фоновый цвет") text: str = Field("#000000", description="Цвет текста") class Config(PatchConfig): logo: Logo = Field(Logo(), description="Настройки цветов логотипа") # type: ignore [reportCallIssue] colors: Colors = Field(Colors(), description="Настройки цветов") # type: ignore [reportCallIssue] # Patch def apply(config: Config, base: Dict[str, Any]) -> bool: main_color = config.colors.primary splash_color = config.colors.secondary # Обновление сообщения об отсутствии подключения with open("./decompiled/assets/no_connection.html", "r", encoding="utf-8") as file: file_contents = file.read() new_contents = file_contents.replace("#f04e4e", main_color) with open("./decompiled/assets/no_connection.html", "w", encoding="utf-8") as file: file.write(new_contents) # Суффиксы лого drawable_types = ["", "-night"] for drawable_type in drawable_types: # Градиент лого приложения file_path = f"./decompiled/res/drawable{drawable_type}/$logo__0.xml" parser = etree.XMLParser(remove_blank_text=True) tree = etree.parse(file_path, parser) root = tree.getroot() # Замена атрибутов значениями из конфигурации root.set(f"{{{base['xml_ns']['android']}}}angle", str(config.logo.gradient.angle)) root.set(f"{{{base['xml_ns']['android']}}}startColor", config.logo.gradient.start_color) root.set(f"{{{base['xml_ns']['android']}}}endColor", config.logo.gradient.end_color) # Сохранение tree.write(file_path, pretty_print=True, xml_declaration=True, encoding="utf-8") # Замена анимации лого file_path = f"./decompiled/res/drawable{drawable_type}/$logo_splash_anim__0.xml" parser = etree.XMLParser(remove_blank_text=True) tree = etree.parse(file_path, parser) root = tree.getroot() for el in root.findall("path", namespaces=base["xml_ns"]): name = el.get(f"{{{base['xml_ns']['android']}}}name") if name == "path": el.set(f"{{{base['xml_ns']['android']}}}fillColor", config.colors.secondary) elif name in ["path_1", "path_2"]: el.set(f"{{{base['xml_ns']['android']}}}fillColor", config.logo.ears_color) # Сохранение tree.write(file_path, pretty_print=True, xml_declaration=True, encoding="utf-8") for filename in ["$ic_launcher_foreground__0", "$ic_banner_foreground__0"]: file_path = f"./decompiled/res/drawable-v24/{filename}.xml" parser = etree.XMLParser(remove_blank_text=True) tree = etree.parse(file_path, parser) root = tree.getroot() # Замена атрибутов значениями из конфигурации root.set(f"{{{base['xml_ns']['android']}}}angle", str(config.logo.gradient.angle)) items = root.findall("item", namespaces=base['xml_ns']) assert len(items) == 2 items[0].set(f"{{{base['xml_ns']['android']}}}color", config.logo.gradient.start_color) items[1].set(f"{{{base['xml_ns']['android']}}}color", config.logo.gradient.end_color) # Сохранение tree.write(file_path, pretty_print=True, xml_declaration=True, encoding="utf-8") # Добаление новых цветов для темы insert_after_public("carmine", "custom_color") insert_after_public("carmine_alpha_10", "custom_color_alpha_10") insert_after_color("carmine", "custom_color", main_color[0]+'ff'+main_color[1:]) insert_after_color("carmine_alpha_10", "custom_color_alpha_10", main_color[0]+'1a'+main_color[1:]) # Замена цветов change_color("accent_alpha_10", main_color[0]+'1a'+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_70", main_color[0]+'b3'+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_alpha_70", main_color[0]+'b3'+main_color[1:]) change_color("refresh_progress", main_color[0]+'ff'+main_color[1:]) change_color("ic_launcher_background", "#ff000000") change_color("bottom_nav_indicator_active", "#ffffffff") change_color("bottom_nav_indicator_icon_checked", main_color[0]+'ff'+main_color[1:]) change_color("bottom_nav_indicator_label_checked", main_color[0]+'ff'+main_color[1:]) return True