Squashed commit of the following:

commit 8724c545a8af8f34565aa71620e66cbd71547f37
Author: DLmaster <DLmaster_361@163.com>
Date:   Fri Apr 11 18:08:28 2025 +0800

    feat(core): 预接入mirrorc

commit d57ebaa281ff7c418aa8f11fe8e8ba260d8dbeca
Author: DLmaster <DLmaster_361@163.com>
Date:   Thu Apr 10 12:37:26 2025 +0800

    chore(core): 基础配置相关内容重构

    - 添加理智药设置选项 #34
    - 输入对话框添加回车键确认能力 #35
    - 用户列表UI改版升级
    - 配置类取消单例限制
    - 配置读取方式与界面渲染方法优化

commit 710542287d04719c8443b91acb227de1dccc20d0
Author: DLmaster <DLmaster_361@163.com>
Date:   Fri Mar 28 23:32:17 2025 +0800

    chore(core): search相关结构重整

commit 8009c69236655e29119ce62ff53a0360abaed2af
Merge: 648f42b 9f88f92
Author: DLmaster <DLmaster_361@163.com>
Date:   Mon Mar 24 15:31:40 2025 +0800

    Merge branch 'dev' into user_list_dev
This commit is contained in:
DLmaster
2025-04-11 18:57:10 +08:00
parent bded794647
commit 38a04fc4b2
21 changed files with 3759 additions and 3018 deletions

View File

@@ -46,12 +46,13 @@ from qfluentwidgets import (
FluentIconBase,
Signal,
ComboBox,
EditableComboBox,
CheckBox,
IconWidget,
FluentIcon,
CardWidget,
BodyLabel,
qconfig,
QConfig,
ConfigItem,
TimeEdit,
OptionsConfigItem,
@@ -65,22 +66,27 @@ from qfluentwidgets import (
ProgressRing,
TextBrowser,
HeaderCardWidget,
SwitchButton,
IndicatorPosition,
Slider,
)
from qfluentwidgets.common.overload import singledispatchmethod
import os
import re
import markdown
from datetime import datetime
from urllib.parse import urlparse
from functools import partial
from typing import Optional, Union, List, Dict
from app.core import Config
from app.services import Crypto
class LineEditMessageBox(MessageBoxBase):
"""输入对话框"""
def __init__(self, parent, title: str, content: str, mode: str):
def __init__(self, parent, title: str, content: Union[str, None], mode: str):
super().__init__(parent)
self.title = SubtitleLabel(title)
@@ -90,6 +96,7 @@ class LineEditMessageBox(MessageBoxBase):
elif mode == "密码":
self.input = PasswordLineEdit()
self.input.returnPressed.connect(self.yesButton.click)
self.input.setPlaceholderText(content)
# 将组件添加到布局中
@@ -248,6 +255,143 @@ class NoticeMessageBox(MessageBoxBase):
self.Layout.addStretch(1)
class SwitchSettingCard(SettingCard):
"""Setting card with switch button"""
checkedChanged = Signal(bool)
def __init__(
self,
icon: Union[str, QIcon, FluentIconBase],
title: str,
content: Union[str, None],
qconfig: QConfig,
configItem: ConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem = configItem
self.switchButton = SwitchButton(self.tr("Off"), self, IndicatorPosition.RIGHT)
if configItem:
self.setValue(self.qconfig.get(configItem))
configItem.valueChanged.connect(self.setValue)
# add switch button to layout
self.hBoxLayout.addWidget(self.switchButton, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.switchButton.checkedChanged.connect(self.__onCheckedChanged)
def __onCheckedChanged(self, isChecked: bool):
"""switch button checked state changed slot"""
self.setValue(isChecked)
self.checkedChanged.emit(isChecked)
def setValue(self, isChecked: bool):
if self.configItem:
self.qconfig.set(self.configItem, isChecked)
self.switchButton.setChecked(isChecked)
self.switchButton.setText(self.tr("On") if isChecked else self.tr("Off"))
def setChecked(self, isChecked: bool):
self.setValue(isChecked)
def isChecked(self):
return self.switchButton.isChecked()
class RangeSettingCard(SettingCard):
"""Setting card with a slider"""
valueChanged = Signal(int)
def __init__(
self,
icon: Union[str, QIcon, FluentIconBase],
title: str,
content: Union[str, None],
qconfig: QConfig,
configItem: ConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem = configItem
self.slider = Slider(Qt.Horizontal, self)
self.valueLabel = QLabel(self)
self.slider.setMinimumWidth(268)
self.slider.setSingleStep(1)
self.slider.setRange(*configItem.range)
self.slider.setValue(configItem.value)
self.valueLabel.setNum(configItem.value)
self.hBoxLayout.addStretch(1)
self.hBoxLayout.addWidget(self.valueLabel, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(6)
self.hBoxLayout.addWidget(self.slider, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.valueLabel.setObjectName("valueLabel")
configItem.valueChanged.connect(self.setValue)
self.slider.valueChanged.connect(self.__onValueChanged)
def __onValueChanged(self, value: int):
"""slider value changed slot"""
self.setValue(value)
self.valueChanged.emit(value)
def setValue(self, value):
self.qconfig.set(self.configItem, value)
self.valueLabel.setNum(value)
self.valueLabel.adjustSize()
self.slider.setValue(value)
class ComboBoxSettingCard(SettingCard):
"""Setting card with a combo box"""
def __init__(
self,
icon: Union[str, QIcon, FluentIconBase],
title: str,
content: Union[str, None],
texts: List[str],
qconfig: QConfig,
configItem: OptionsConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem = configItem
self.comboBox = ComboBox(self)
self.hBoxLayout.addWidget(self.comboBox, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.optionToText = {o: t for o, t in zip(configItem.options, texts)}
for text, option in zip(texts, configItem.options):
self.comboBox.addItem(text, userData=option)
self.comboBox.setCurrentText(self.optionToText[self.qconfig.get(configItem)])
self.comboBox.currentIndexChanged.connect(self._onCurrentIndexChanged)
configItem.valueChanged.connect(self.setValue)
def _onCurrentIndexChanged(self, index: int):
self.qconfig.set(self.configItem, self.comboBox.itemData(index))
def setValue(self, value):
if value not in self.optionToText:
return
self.comboBox.setCurrentText(self.optionToText[value])
self.qconfig.set(self.configItem, value)
class LineEditSettingCard(SettingCard):
"""Setting card with LineEdit"""
@@ -255,22 +399,24 @@ class LineEditSettingCard(SettingCard):
def __init__(
self,
text,
icon: Union[str, QIcon, FluentIconBase],
title,
content=None,
configItem: ConfigItem = None,
title: str,
content: Union[str, None],
text: str,
qconfig: QConfig,
configItem: ConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem = configItem
self.LineEdit = LineEdit(self)
self.LineEdit.setMinimumWidth(250)
self.LineEdit.setPlaceholderText(text)
if configItem:
self.setValue(qconfig.get(configItem))
self.setValue(self.qconfig.get(configItem))
configItem.valueChanged.connect(self.setValue)
self.hBoxLayout.addWidget(self.LineEdit, 0, Qt.AlignRight)
@@ -279,39 +425,46 @@ class LineEditSettingCard(SettingCard):
self.LineEdit.textChanged.connect(self.__textChanged)
def __textChanged(self, content: str):
self.setValue(content)
self.textChanged.emit(content)
self.setValue(content.strip())
self.textChanged.emit(content.strip())
def setValue(self, content: str):
if self.configItem:
qconfig.set(self.configItem, content)
self.qconfig.set(self.configItem, content.strip())
self.LineEdit.setText(content)
self.LineEdit.setText(content.strip())
class PasswordLineEditSettingCard(SettingCard):
"""Setting card with PasswordLineEdit"""
textChanged = Signal(str)
textChanged = Signal()
def __init__(
self,
text,
icon: Union[str, QIcon, FluentIconBase],
title,
content=None,
configItem: ConfigItem = None,
title: str,
content: Union[str, None],
text: str,
algorithm: str,
qconfig: QConfig,
configItem: ConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.algorithm = algorithm
self.qconfig = qconfig
self.configItem = configItem
self.LineEdit = PasswordLineEdit(self)
self.LineEdit.setMinimumWidth(250)
self.LineEdit.setMinimumWidth(200)
self.LineEdit.setPlaceholderText(text)
if algorithm == "AUTO":
self.LineEdit.setViewPasswordButtonVisible(False)
self.if_setValue = False
if configItem:
self.setValue(qconfig.get(configItem))
self.setValue(self.qconfig.get(configItem))
configItem.valueChanged.connect(self.setValue)
self.hBoxLayout.addWidget(self.LineEdit, 0, Qt.AlignRight)
@@ -320,14 +473,141 @@ class PasswordLineEditSettingCard(SettingCard):
self.LineEdit.textChanged.connect(self.__textChanged)
def __textChanged(self, content: str):
self.setValue(Crypto.win_encryptor(content))
self.textChanged.emit(content)
if self.if_setValue:
return None
if self.algorithm == "DPAPI":
self.setValue(Crypto.win_encryptor(content))
elif self.algorithm == "AUTO":
self.setValue(Crypto.AUTO_encryptor(content))
self.textChanged.emit()
def setValue(self, content: str):
if self.configItem:
qconfig.set(self.configItem, content)
self.LineEdit.setText(Crypto.win_decryptor(content))
self.if_setValue = True
if self.configItem:
self.qconfig.set(self.configItem, content)
if self.algorithm == "DPAPI":
self.LineEdit.setText(Crypto.win_decryptor(content))
elif self.algorithm == "AUTO":
if Crypto.check_PASSWORD(Config.PASSWORD):
self.LineEdit.setText(Crypto.AUTO_decryptor(content, Config.PASSWORD))
self.LineEdit.setPasswordVisible(True)
self.LineEdit.setReadOnly(False)
elif Config.PASSWORD:
self.LineEdit.setText("管理密钥错误")
self.LineEdit.setPasswordVisible(True)
self.LineEdit.setReadOnly(True)
else:
self.LineEdit.setText("************")
self.LineEdit.setPasswordVisible(False)
self.LineEdit.setReadOnly(True)
self.if_setValue = False
class UserLableSettingCard(SettingCard):
"""Setting card with User's Lable"""
textChanged = Signal(str)
def __init__(
self,
icon: Union[str, QIcon, FluentIconBase],
title: str,
content: Union[str, None],
qconfig: QConfig,
configItems: Dict[str, ConfigItem],
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItems = configItems
self.Lable = SubtitleLabel(self)
if configItems:
for configItem in configItems.values():
configItem.valueChanged.connect(self.setValue)
self.setValue()
self.hBoxLayout.addWidget(self.Lable, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
def setValue(self):
if self.configItems:
text_list = []
if not self.qconfig.get(self.configItems["IfPassCheck"]):
text_list.append("未通过人工排查")
text_list.append(
f"今日已代理{self.qconfig.get(self.configItems["ProxyTimes"])}"
if Config.server_date()
== self.qconfig.get(self.configItems["LastProxyDate"])
else "今日未进行代理"
)
text_list.append(
"本周剿灭已完成"
if datetime.strptime(
self.qconfig.get(self.configItems["LastAnnihilationDate"]),
"%Y-%m-%d",
).isocalendar()[:2]
== datetime.strptime(Config.server_date(), "%Y-%m-%d").isocalendar()[:2]
else "本周剿灭未完成"
)
self.Lable.setText(" | ".join(text_list))
class PushAndSwitchButtonSettingCard(SettingCard):
"""Setting card with push & switch button"""
checkedChanged = Signal(bool)
clicked = Signal()
def __init__(
self,
icon: Union[str, QIcon, FluentIconBase],
title: str,
content: Union[str, None],
text: str,
qconfig: QConfig,
configItem: ConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem = configItem
self.switchButton = SwitchButton("", self, IndicatorPosition.RIGHT)
self.button = PushButton(text, self)
self.hBoxLayout.addWidget(self.button, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.button.clicked.connect(self.clicked)
if configItem:
self.setValue(self.qconfig.get(configItem))
configItem.valueChanged.connect(self.setValue)
# add switch button to layout
self.hBoxLayout.addWidget(self.switchButton, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.switchButton.checkedChanged.connect(self.__onCheckedChanged)
def __onCheckedChanged(self, isChecked: bool):
"""switch button checked state changed slot"""
self.setValue(isChecked)
self.checkedChanged.emit(isChecked)
def setValue(self, isChecked: bool):
if self.configItem:
self.qconfig.set(self.configItem, isChecked)
self.switchButton.setChecked(isChecked)
self.switchButton.setText("" if isChecked else "")
class SpinBoxSettingCard(SettingCard):
@@ -337,15 +617,17 @@ class SpinBoxSettingCard(SettingCard):
def __init__(
self,
range: tuple[int, int],
icon: Union[str, QIcon, FluentIconBase],
title,
content=None,
configItem: ConfigItem = None,
title: str,
content: Union[str, None],
range: tuple[int, int],
qconfig: QConfig,
configItem: ConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem = configItem
self.SpinBox = SpinBox(self)
self.SpinBox.setRange(range[0], range[1])
@@ -366,7 +648,7 @@ class SpinBoxSettingCard(SettingCard):
def setValue(self, value: int):
if self.configItem:
qconfig.set(self.configItem, value)
self.qconfig.set(self.configItem, value)
self.SpinBox.setValue(value)
@@ -375,16 +657,18 @@ class NoOptionComboBoxSettingCard(SettingCard):
def __init__(
self,
configItem: OptionsConfigItem,
icon: Union[str, QIcon, FluentIconBase],
title,
content=None,
value=None,
texts=None,
title: str,
content: Union[str, None],
value: List[str],
texts: List[str],
qconfig: QConfig,
configItem: OptionsConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem = configItem
self.comboBox = ComboBox(self)
self.comboBox.setMinimumWidth(250)
@@ -395,20 +679,131 @@ class NoOptionComboBoxSettingCard(SettingCard):
for text, option in zip(texts, value):
self.comboBox.addItem(text, userData=option)
self.comboBox.setCurrentText(self.optionToText[qconfig.get(configItem)])
self.comboBox.setCurrentText(self.optionToText[self.qconfig.get(configItem)])
self.comboBox.currentIndexChanged.connect(self._onCurrentIndexChanged)
configItem.valueChanged.connect(self.setValue)
def _onCurrentIndexChanged(self, index: int):
qconfig.set(self.configItem, self.comboBox.itemData(index))
self.qconfig.set(self.configItem, self.comboBox.itemData(index))
def setValue(self, value):
if value not in self.optionToText:
return
self.comboBox.setCurrentText(self.optionToText[value])
qconfig.set(self.configItem, value)
self.qconfig.set(self.configItem, value)
def reLoadOptions(self, value: List[str], texts: List[str]):
self.comboBox.currentIndexChanged.disconnect()
self.comboBox.clear()
self.optionToText = {o: t for o, t in zip(value, texts)}
for text, option in zip(texts, value):
self.comboBox.addItem(text, userData=option)
self.comboBox.setCurrentText(
self.optionToText[self.qconfig.get(self.configItem)]
)
self.comboBox.currentIndexChanged.connect(self._onCurrentIndexChanged)
class EditableComboBoxSettingCard(SettingCard):
"""Setting card with EditableComboBox"""
def __init__(
self,
icon: Union[str, QIcon, FluentIconBase],
title: str,
content: Union[str, None],
value: List[str],
texts: List[str],
qconfig: QConfig,
configItem: OptionsConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem = configItem
self.comboBox = self._EditableComboBox(self)
self.comboBox.setMinimumWidth(100)
self.hBoxLayout.addWidget(self.comboBox, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.optionToText = {o: t for o, t in zip(value, texts)}
for text, option in zip(texts, value):
self.comboBox.addItem(text, userData=option)
if qconfig.get(configItem) not in self.optionToText:
self.optionToText[qconfig.get(configItem)] = qconfig.get(configItem)
self.comboBox.addItem(
qconfig.get(configItem), userData=qconfig.get(configItem)
)
self.comboBox.setCurrentText(self.optionToText[qconfig.get(configItem)])
self.comboBox.currentIndexChanged.connect(self._onCurrentIndexChanged)
configItem.valueChanged.connect(self.setValue)
def _onCurrentIndexChanged(self, index: int):
self.qconfig.set(
self.configItem,
(
self.comboBox.itemData(index)
if self.comboBox.itemData(index)
else self.comboBox.itemText(index)
),
)
def setValue(self, value):
if value not in self.optionToText:
self.optionToText[value] = value
if self.comboBox.findText(value) == -1:
self.comboBox.addItem(value, userData=value)
else:
self.comboBox.setItemData(self.comboBox.findText(value), value)
self.comboBox.setCurrentText(self.optionToText[value])
self.qconfig.set(self.configItem, value)
def reLoadOptions(self, value: List[str], texts: List[str]):
self.comboBox.currentIndexChanged.disconnect()
self.comboBox.clear()
self.optionToText = {o: t for o, t in zip(value, texts)}
for text, option in zip(texts, value):
self.comboBox.addItem(text, userData=option)
if self.qconfig.get(self.configItem) not in self.optionToText:
self.optionToText[self.qconfig.get(self.configItem)] = self.qconfig.get(
self.configItem
)
self.comboBox.addItem(
self.qconfig.get(self.configItem),
userData=self.qconfig.get(self.configItem),
)
self.comboBox.setCurrentText(
self.optionToText[self.qconfig.get(self.configItem)]
)
self.comboBox.currentIndexChanged.connect(self._onCurrentIndexChanged)
class _EditableComboBox(EditableComboBox):
"""EditableComboBox"""
def __init__(self, parent=None):
super().__init__(parent)
def _onReturnPressed(self):
if not self.text():
return
index = self.findText(self.text())
if index >= 0 and index != self.currentIndex():
self._currentIndex = index
self.currentIndexChanged.emit(index)
elif index == -1:
self.addItem(self.text())
self.setCurrentIndex(self.count() - 1)
self.currentIndexChanged.emit(self.count() - 1)
class TimeEditSettingCard(SettingCard):
@@ -419,14 +814,16 @@ class TimeEditSettingCard(SettingCard):
def __init__(
self,
icon: Union[str, QIcon, FluentIconBase],
title,
content=None,
configItem_bool: ConfigItem = None,
configItem_time: ConfigItem = None,
title: str,
content: Union[str, None],
qconfig: QConfig,
configItem_bool: ConfigItem,
configItem_time: ConfigItem,
parent=None,
):
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem_bool = configItem_bool
self.configItem_time = configItem_time
self.CheckBox = CheckBox(self)
@@ -464,13 +861,13 @@ class TimeEditSettingCard(SettingCard):
def setValue_bool(self, value: bool):
if self.configItem_bool:
qconfig.set(self.configItem_bool, value)
self.qconfig.set(self.configItem_bool, value)
self.CheckBox.setChecked(value)
def setValue_time(self, value: str):
if self.configItem_time:
qconfig.set(self.configItem_time, value)
self.qconfig.set(self.configItem_time, value)
self.TimeEdit.setTime(QTime.fromString(value, "HH:mm"))
@@ -510,31 +907,18 @@ class UrlListSettingCard(ExpandSettingCard):
def __init__(
self,
icon: Union[str, QIcon, FluentIconBase],
configItem: ConfigItem,
title: str,
content: str = None,
content: Union[str, None],
qconfig: QConfig,
configItem: ConfigItem,
parent=None,
):
"""
Parameters
----------
configItem: RangeConfigItem
configuration item operated by the card
title: str
the title of card
content: str
the content of card
parent: QWidget
parent widget
"""
super().__init__(icon, title, content, parent)
self.qconfig = qconfig
self.configItem = configItem
self.addUrlButton = PushButton("添加代理网址", self)
self.urls: List[str] = qconfig.get(configItem).copy()
self.urls: List[str] = self.qconfig.get(configItem).copy()
self.__initWidget()
def __initWidget(self):
@@ -567,7 +951,7 @@ class UrlListSettingCard(ExpandSettingCard):
self.__addUrlItem(url)
self.urls.append(url)
qconfig.set(self.configItem, self.urls)
self.qconfig.set(self.configItem, self.urls)
self.urlChanged.emit(self.urls)
def __addUrlItem(self, url: str):
@@ -600,7 +984,7 @@ class UrlListSettingCard(ExpandSettingCard):
self._adjustViewSize()
self.urlChanged.emit(self.urls)
qconfig.set(self.configItem, self.urls)
self.qconfig.set(self.configItem, self.urls)
def __validate(self, value):
@@ -681,7 +1065,7 @@ class IconButton(TransparentToolButton):
icon: Union[str, QIcon, FluentIconBase],
isTooltip: bool,
tip_title: str,
tip_content: str,
tip_content: Union[str, None],
parent: QWidget = None,
):
self.__init__(parent)

View File

@@ -47,7 +47,6 @@ from qfluentwidgets import (
from PySide6.QtCore import Qt
from PySide6.QtGui import QTextCursor
from typing import List, Dict
import json
from app.core import Config, TaskManager, Task, MainInfoBar
@@ -164,31 +163,39 @@ class DispatchCenter(QWidget):
def update_top_bar(self):
"""更新顶栏"""
list = []
queue_numb, member_numb = 0, 0
if (Config.app_path / "config/QueueConfig").exists():
for json_file in (Config.app_path / "config/QueueConfig").glob("*.json"):
list.append(f"队列 - {json_file.stem}")
queue_numb += 1
if (Config.app_path / "config/MaaConfig").exists():
for subdir in (Config.app_path / "config/MaaConfig").iterdir():
if subdir.is_dir():
list.append(f"实例 - Maa - {subdir.name}")
member_numb += 1
self.script_list["主调度台"].top_bar.object.clear()
self.script_list["主调度台"].top_bar.object.addItems(list)
self.script_list["主调度台"].top_bar.mode.clear()
self.script_list["主调度台"].top_bar.mode.addItems(["自动代理", "人工排查"])
if queue_numb == 1:
for name, info in Config.queue_dict.items():
self.script_list["主调度台"].top_bar.object.addItem(
(
"队列"
if info["Config"].get(info["Config"].queueSet_Name) == ""
else f"队列 - {info["Config"].get(info["Config"].queueSet_Name)}"
),
userData=name,
)
for name, info in Config.member_dict.items():
self.script_list["主调度台"].top_bar.object.addItem(
(
f"实例 - {info['Type']}"
if info["Config"].get(info["Config"].MaaSet_Name) == ""
else f"实例 - {info['Type']} - {info["Config"].get(info["Config"].MaaSet_Name)}"
),
userData=name,
)
if len(Config.queue_dict) == 1:
self.script_list["主调度台"].top_bar.object.setCurrentIndex(0)
elif member_numb == 1:
self.script_list["主调度台"].top_bar.object.setCurrentIndex(queue_numb)
elif len(Config.member_dict) == 1:
self.script_list["主调度台"].top_bar.object.setCurrentIndex(
len(Config.queue_dict)
)
else:
self.script_list["主调度台"].top_bar.object.setCurrentIndex(-1)
self.script_list["主调度台"].top_bar.mode.clear()
self.script_list["主调度台"].top_bar.mode.addItems(["自动代理", "人工排查"])
self.script_list["主调度台"].top_bar.mode.setCurrentIndex(0)
@@ -270,32 +277,31 @@ class DispatchBox(QWidget):
)
return None
name = self.object.currentText().split(" - ")[-1]
if name in Config.running_list:
logger.warning(f"任务已存在:{name}")
MainInfoBar.push_info_bar("warning", "任务已存在", name, 5000)
if self.object.currentData() in Config.running_list:
logger.warning(f"任务已存在:{self.object.currentData()}")
MainInfoBar.push_info_bar(
"warning", "任务已存在", self.object.currentData(), 5000
)
return None
if self.object.currentText().split(" - ")[0] == "队列":
if "调度队列" in self.object.currentData():
with (Config.app_path / f"config/QueueConfig/{name}.json").open(
mode="r", encoding="utf-8"
) as f:
info = json.load(f)
logger.info(f"用户添加任务:{self.object.currentData()}")
TaskManager.add_task(
f"{self.mode.currentText()}_主调度台",
self.object.currentData(),
Config.queue_dict[self.object.currentData()]["Config"].toDict(),
)
logger.info(f"用户添加任务:{name}")
TaskManager.add_task(f"{self.mode.currentText()}_主调度台", name, info)
elif "脚本" in self.object.currentData():
elif self.object.currentText().split(" - ")[0] == "实例":
if Config.member_dict[self.object.currentData()]["Type"] == "Maa":
if self.object.currentText().split(" - ")[1] == "Maa":
info = {"Queue": {"Member_1": name}}
logger.info(f"用户添加任务:{name}")
logger.info(f"用户添加任务:{self.object.currentData()}")
TaskManager.add_task(
f"{self.mode.currentText()}_主调度台", "自定义队列", info
f"{self.mode.currentText()}_主调度台",
"自定义队列",
{"Queue": {"Member_1": self.object.currentData()}},
)
class DispatchInfoCard(HeaderCardWidget):

View File

@@ -160,15 +160,9 @@ class Home(QWidget):
def get_home_image(self) -> None:
"""获取主页图片"""
if (
Config.global_config.get(Config.global_config.function_HomeImageMode)
== "默认"
):
if Config.get(Config.function_HomeImageMode) == "默认":
pass
elif (
Config.global_config.get(Config.global_config.function_HomeImageMode)
== "自定义"
):
elif Config.get(Config.function_HomeImageMode) == "自定义":
file_path, _ = QFileDialog.getOpenFileName(
self, "打开自定义主页图片", "", "图片文件 (*.png *.jpg *.bmp)"
@@ -202,10 +196,7 @@ class Home(QWidget):
"未选择图片文件!",
5000,
)
elif (
Config.global_config.get(Config.global_config.function_HomeImageMode)
== "主题图像"
):
elif Config.get(Config.function_HomeImageMode) == "主题图像":
# 从远程服务器获取最新主题图像
for _ in range(3):
@@ -244,7 +235,6 @@ class Home(QWidget):
).exists() or (
datetime.now()
> datetime.strptime(theme_image["time"], "%Y-%m-%d %H:%M")
and datetime.strptime(theme_image["time"], "%Y-%m-%d %H:%M")
> time_local
):
@@ -293,28 +283,19 @@ class Home(QWidget):
def set_banner(self):
"""设置主页图像"""
if (
Config.global_config.get(Config.global_config.function_HomeImageMode)
== "默认"
):
if Config.get(Config.function_HomeImageMode) == "默认":
self.banner.set_banner_image(
str(Config.app_path / "resources/images/Home/BannerDefault.png")
)
self.imageButton.hide()
self.banner_text.setVisible(False)
elif (
Config.global_config.get(Config.global_config.function_HomeImageMode)
== "自定义"
):
elif Config.get(Config.function_HomeImageMode) == "自定义":
for file in Config.app_path.glob("resources/images/Home/BannerCustomize.*"):
self.banner.set_banner_image(str(file))
break
self.imageButton.show()
self.banner_text.setVisible(False)
elif (
Config.global_config.get(Config.global_config.function_HomeImageMode)
== "主题图像"
):
elif Config.get(Config.function_HomeImageMode) == "主题图像":
self.banner.set_banner_image(
str(Config.app_path / "resources/images/Home/BannerTheme.jpg")
)

View File

@@ -28,28 +28,23 @@ v4.2
from loguru import logger
from PySide6.QtWidgets import QSystemTrayIcon
from qfluentwidgets import (
qconfig,
Action,
PushButton,
SystemTrayMenu,
SplashScreen,
FluentIcon,
InfoBar,
InfoBarPosition,
setTheme,
isDarkTheme,
SystemThemeListener,
Theme,
MSFluentWindow,
NavigationItemPosition,
qconfig,
FluentBackgroundTheme,
)
from PySide6.QtGui import QIcon, QCloseEvent
from PySide6.QtCore import Qt, QTimer
import json
from PySide6.QtCore import QTimer
from datetime import datetime, timedelta
import shutil
import sys
import darkdetect
from app.core import Config, TaskManager, MainTimer, MainInfoBar
from app.services import Notify, Crypto, System
@@ -69,7 +64,6 @@ class AUTO_MAA(MSFluentWindow):
self.setWindowIcon(QIcon(str(Config.app_path / "resources/icons/AUTO_MAA.ico")))
self.setWindowTitle("AUTO_MAA")
setTheme(Theme.AUTO, lazy=True)
self.switch_theme()
self.splashScreen = SplashScreen(self.windowIcon(), self)
@@ -130,10 +124,9 @@ class AUTO_MAA(MSFluentWindow):
NavigationItemPosition.BOTTOM,
)
self.stackedWidget.currentChanged.connect(
lambda index: (self.member_manager.refresh() if index == 1 else None)
)
self.stackedWidget.currentChanged.connect(
lambda index: self.queue_manager.refresh() if index == 2 else None
lambda index: (
self.queue_manager.reload_member_name() if index == 2 else None
)
)
self.stackedWidget.currentChanged.connect(
lambda index: (
@@ -190,6 +183,7 @@ class AUTO_MAA(MSFluentWindow):
self.tray.setContextMenu(self.tray_menu)
self.tray.activated.connect(self.on_tray_activated)
Config.gameid_refreshed.connect(self.member_manager.refresh_gameid)
TaskManager.create_gui.connect(self.dispatch_center.add_board)
TaskManager.connect_gui.connect(self.dispatch_center.connect_main_board)
Notify.push_info_bar.connect(MainInfoBar.push_info_bar)
@@ -211,7 +205,10 @@ class AUTO_MAA(MSFluentWindow):
def switch_theme(self) -> None:
"""切换主题"""
setTheme(Theme.AUTO, lazy=True)
setTheme(
Theme(darkdetect.theme()) if darkdetect.theme() else Theme.LIGHT, lazy=True
)
QTimer.singleShot(300, lambda: setTheme(Theme.AUTO, lazy=True))
# 云母特效启用时需要增加重试机制
@@ -238,25 +235,22 @@ class AUTO_MAA(MSFluentWindow):
def start_up_task(self) -> None:
"""启动时任务"""
# 加载配置
qconfig.load(Config.config_path, Config.global_config)
Config.global_config.save()
# 清理旧日志
self.clean_old_logs()
# 清理临时更新器
if (Config.app_path / "AUTO_Updater.active.exe").exists():
(Config.app_path / "AUTO_Updater.active.exe").unlink()
# 检查密码
self.setting.check_PASSWORD()
# 获取主题图像
if (
Config.global_config.get(Config.global_config.function_HomeImageMode)
== "主题图像"
):
if Config.get(Config.function_HomeImageMode) == "主题图像":
self.home.get_home_image()
# 直接运行主任务
if Config.global_config.get(Config.global_config.start_IfRunDirectly):
if Config.get(Config.start_IfRunDirectly):
self.start_main_task()
@@ -264,18 +258,18 @@ class AUTO_MAA(MSFluentWindow):
self.setting.show_notice(if_show=False)
# 检查更新
if Config.global_config.get(Config.global_config.update_IfAutoUpdate):
if Config.get(Config.update_IfAutoUpdate):
self.setting.check_update()
# 直接最小化
if Config.global_config.get(Config.global_config.start_IfMinimizeDirectly):
if Config.get(Config.start_IfMinimizeDirectly):
self.titleBar.minBtn.click()
def set_min_method(self) -> None:
"""设置最小化方法"""
if Config.global_config.get(Config.global_config.ui_IfToTray):
if Config.get(Config.ui_IfToTray):
self.titleBar.minBtn.clicked.disconnect()
self.titleBar.minBtn.clicked.connect(lambda: self.show_ui("隐藏到托盘"))
@@ -295,10 +289,7 @@ class AUTO_MAA(MSFluentWindow):
删除超过用户设定天数的日志文件(基于目录日期)
"""
if (
Config.global_config.get(Config.global_config.function_HistoryRetentionTime)
== 0
):
if Config.get(Config.function_HistoryRetentionTime) == 0:
logger.info("由于用户设置日志永久保留,跳过日志清理")
return
@@ -312,9 +303,7 @@ class AUTO_MAA(MSFluentWindow):
# 只检查 `YYYY-MM-DD` 格式的文件夹
folder_date = datetime.strptime(date_folder.name, "%Y-%m-%d")
if datetime.now() - folder_date > timedelta(
days=Config.global_config.get(
Config.global_config.function_HistoryRetentionTime
)
days=Config.get(Config.function_HistoryRetentionTime)
):
shutil.rmtree(date_folder, ignore_errors=True)
deleted_count += 1
@@ -327,26 +316,25 @@ class AUTO_MAA(MSFluentWindow):
def start_main_task(self) -> None:
"""启动主任务"""
if (Config.app_path / "config/QueueConfig/调度队列_1.json").exists():
with (Config.app_path / "config/QueueConfig/调度队列_1.json").open(
mode="r", encoding="utf-8"
) as f:
info = json.load(f)
if "调度队列_1" in Config.queue_dict:
logger.info("自动添加任务调度队列_1")
TaskManager.add_task("自动代理_主调度台", "主任务队列", info)
TaskManager.add_task(
"自动代理_主调度台",
"主任务队列",
Config.queue_dict["调度队列_1"]["Config"].toDict(),
)
elif (Config.app_path / "config/MaaConfig/脚本_1").exists():
info = {"Queue": {"Member_1": "脚本_1"}}
elif "脚本_1" in Config.member_dict:
logger.info("自动添加任务脚本_1")
TaskManager.add_task("自动代理_主调度台", "主任务队列", info)
TaskManager.add_task(
"自动代理_主调度台", "主任务队列", {"Queue": {"Member_1": "脚本_1"}}
)
else:
logger.worning("启动主任务失败:未找到有效的主任务配置文件")
logger.warning("启动主任务失败:未找到有效的主任务配置文件")
MainInfoBar.push_info_bar(
"warning", "启动主任务失败", "“调度队列_1”与“脚本_1”均不存在", -1
)
@@ -354,21 +342,21 @@ class AUTO_MAA(MSFluentWindow):
def show_ui(self, mode: str, if_quick: bool = False) -> None:
"""配置窗口状态"""
self.switch_theme()
if mode == "显示主窗口":
# 配置主窗口
size = list(
map(
int,
Config.global_config.get(Config.global_config.ui_size).split("x"),
Config.get(Config.ui_size).split("x"),
)
)
location = list(
map(
int,
Config.global_config.get(Config.global_config.ui_location).split(
"x"
),
Config.get(Config.ui_location).split("x"),
)
)
self.window().setGeometry(location[0], location[1], size[0], size[1])
@@ -376,14 +364,14 @@ class AUTO_MAA(MSFluentWindow):
self.window().raise_()
self.window().activateWindow()
if not if_quick:
if Config.global_config.get(Config.global_config.ui_maximized):
if Config.get(Config.ui_maximized):
self.window().showMaximized()
self.set_min_method()
self.show_ui("配置托盘")
elif mode == "配置托盘":
if Config.global_config.get(Config.global_config.ui_IfShowTray):
if Config.get(Config.ui_IfShowTray):
self.tray.show()
else:
self.tray.hide()
@@ -393,18 +381,16 @@ class AUTO_MAA(MSFluentWindow):
# 保存窗口相关属性
if not self.window().isMaximized():
Config.global_config.set(
Config.global_config.ui_size,
Config.set(
Config.ui_size,
f"{self.geometry().width()}x{self.geometry().height()}",
)
Config.global_config.set(
Config.global_config.ui_location,
Config.set(
Config.ui_location,
f"{self.geometry().x()}x{self.geometry().y()}",
)
Config.global_config.set(
Config.global_config.ui_maximized, self.window().isMaximized()
)
Config.global_config.save()
Config.set(Config.ui_maximized, self.window().isMaximized())
Config.save()
# 隐藏主窗口
if not if_quick:
@@ -420,11 +406,10 @@ class AUTO_MAA(MSFluentWindow):
# 清理各功能线程
MainTimer.Timer.stop()
MainTimer.Timer.deleteLater()
MainTimer.LongTimer.stop()
MainTimer.LongTimer.deleteLater()
TaskManager.stop_task("ALL")
# 关闭数据库连接
Config.close_database()
# 关闭主题监听
self.themeListener.terminate()
self.themeListener.deleteLater()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,7 @@ from PySide6.QtWidgets import (
QApplication,
QVBoxLayout,
)
from PySide6.QtCore import Qt
from qfluentwidgets import (
ScrollArea,
FluentIcon,
@@ -38,13 +39,12 @@ from qfluentwidgets import (
Dialog,
HyperlinkCard,
HeaderCardWidget,
SwitchSettingCard,
RangeSettingCard,
ExpandGroupSettingCard,
PushSettingCard,
ComboBoxSettingCard,
HyperlinkButton,
)
import os
import re
import json
import time
import shutil
@@ -56,8 +56,10 @@ from typing import Dict, List, Union
from app.core import Config, MainInfoBar
from app.services import Crypto, System, Notify
from app.utils import DownloadManager
from .Widget import (
SwitchSettingCard,
RangeSettingCard,
ComboBoxSettingCard,
LineEditMessageBox,
LineEditSettingCard,
PasswordLineEditSettingCard,
@@ -111,7 +113,7 @@ class Setting(QWidget):
def agree_bilibili(self) -> None:
"""授权bilibili游戏隐私政策"""
if Config.global_config.get(Config.global_config.function_IfAgreeBilibili):
if Config.get(Config.function_IfAgreeBilibili):
choice = MessageBox(
"授权声明",
@@ -124,9 +126,7 @@ class Setting(QWidget):
"success", "操作成功", "已确认授权bilibili游戏隐私政策", 3000
)
else:
Config.global_config.set(
Config.global_config.function_IfAgreeBilibili, False
)
Config.set(Config.function_IfAgreeBilibili, False)
else:
logger.info("取消授权bilibili游戏隐私政策")
@@ -141,7 +141,7 @@ class Setting(QWidget):
Path(os.getenv("APPDATA")) / "Netease/MuMuPlayer-12.0/data/startupImage"
)
if Config.global_config.get(Config.global_config.function_IfSkipMumuSplashAds):
if Config.get(Config.function_IfSkipMumuSplashAds):
choice = MessageBox(
"风险声明",
@@ -160,9 +160,7 @@ class Setting(QWidget):
"success", "操作成功", "已开启跳过MuMu启动广告功能", 3000
)
else:
Config.global_config.set(
Config.global_config.function_IfSkipMumuSplashAds, False
)
Config.set(Config.function_IfSkipMumuSplashAds, False)
else:
@@ -267,28 +265,17 @@ class Setting(QWidget):
def check_update(self) -> None:
"""检查版本更新,调起文件下载进程"""
# 从本地版本信息文件获取当前版本信息
with Config.version_path.open(mode="r", encoding="utf-8") as f:
version_current: Dict[
str, Union[str, Dict[str, Union[str, Dict[str, List[str]]]]]
] = json.load(f)
main_version_current = list(map(int, Config.VERSION.split(".")))
updater_version_current = list(
map(int, version_current["updater_version"].split("."))
)
# 检查更新器是否存在
if not (Config.app_path / "Updater.exe").exists():
updater_version_current = [0, 0, 0, 0]
current_version = list(map(int, Config.VERSION.split(".")))
# 从远程服务器获取最新版本信息
for _ in range(3):
try:
response = requests.get(
f"https://gitee.com/DLmaster_361/AUTO_MAA/raw/{Config.global_config.get(Config.global_config.update_UpdateType)}/resources/version.json"
f"https://mirrorchyan.com/api/resources/AUTO_MAA/latest?current_version={version_text(current_version)}&cdk={Crypto.win_decryptor(Config.get(Config.update_MirrorChyanCDK))}&channel={Config.get(Config.update_UpdateType)}"
)
version_info: Dict[str, Union[int, str, Dict[str, str]]] = (
response.json()
)
version_remote: Dict[
str, Union[str, Dict[str, Union[str, Dict[str, List[str]]]]]
] = response.json()
break
except Exception as e:
err = e
@@ -304,52 +291,77 @@ class Setting(QWidget):
if choice.exec():
return None
main_version_remote = list(map(int, version_remote["main_version"].split(".")))
updater_version_remote = list(
map(int, version_remote["updater_version"].split("."))
)
remote_proxy_list = version_remote["proxy_list"]
Config.global_config.set(
Config.global_config.update_ProxyUrlList,
list(
set(
Config.global_config.get(Config.global_config.update_ProxyUrlList)
+ remote_proxy_list
if version_info["code"] != 0:
logger.error(f"获取版本信息时出错:{version_info["msg"]}")
error_remark_dict = {
1001: "获取版本信息的URL参数不正确",
7001: "填入的 CDK 已过期",
7002: "填入的 CDK 错误",
7003: "填入的 CDK 今日下载次数已达上限",
7004: "填入的 CDK 类型和待下载的资源不匹配",
7005: "填入的 CDK 不合法",
8001: "对应架构和系统下的资源不存在",
8002: "错误的系统参数",
8003: "错误的架构参数",
8004: "错误的更新通道参数",
1: version_info["msg"],
}
if version_info["code"] in error_remark_dict:
MainInfoBar.push_info_bar(
"error",
"获取版本信息时出错",
error_remark_dict[version_info["code"]],
-1,
)
),
else:
MainInfoBar.push_info_bar(
"error",
"获取版本信息时出错",
"意料之外的错误,请及时联系项目组以获取来自 Mirror 酱的技术支持",
-1,
)
return None
remote_version = list(
map(
int,
version_info["data"]["version_name"][1:]
.replace("-beta", "")
.split("."),
)
)
version_info_json: Dict[str, Dict[str, str]] = json.loads(
re.sub(
r"^<!--\s*(.*?)\s*-->$",
r"\1",
version_info["data"]["release_note"].splitlines()[0],
)
)
# 有版本更新
if (main_version_remote > main_version_current) or (
updater_version_remote > updater_version_current
):
if remote_version > current_version:
# 生成版本更新信息
if main_version_remote > main_version_current:
main_version_info = f"## 主程序:{version_text(main_version_current)} --> {version_text(main_version_remote)}\n\n"
else:
main_version_info = (
f"## 主程序:{version_text(main_version_current)}\n\n"
)
if updater_version_remote > updater_version_current:
updater_version_info = f"## 更新器:{version_text(updater_version_current)} --> {version_text(updater_version_remote)}\n\n"
else:
updater_version_info = (
f"## 更新器:{version_text(updater_version_current)}\n\n"
)
main_version_info = f"## 主程序:{version_text(current_version)} --> {version_text(remote_version)}"
update_version_info = {}
all_version_info = {}
for v_i in [
info
for version, info in version_remote["version_info"].items()
if list(map(int, version.split("."))) > main_version_current
for version, info in version_info_json.items()
if list(map(int, version.split("."))) > current_version
]:
for key, value in v_i.items():
if key in update_version_info:
update_version_info[key] += value.copy()
else:
update_version_info[key] = value.copy()
for v_i in version_remote["version_info"].values():
for v_i in update_version_info.values():
for key, value in v_i.items():
if key in all_version_info:
all_version_info[key] += value.copy()
@@ -357,69 +369,48 @@ class Setting(QWidget):
all_version_info[key] = value.copy()
version_info = {
"更新总览": f"{main_version_info}{updater_version_info}{version_info_markdown(update_version_info)}",
"更新总览": f"{main_version_info}\n\n{version_info_markdown(update_version_info)}",
"ALL~版本信息": version_info_markdown(all_version_info),
**{
version_text(list(map(int, k.split(".")))): version_info_markdown(v)
for k, v in version_remote["version_info"].items()
for k, v in update_version_info.items()
},
}
# 询问是否开始版本更新
choice = NoticeMessageBox(self.window(), "版本更新", version_info)
if not choice.exec():
return None
if choice.exec():
# 更新更新器
if updater_version_remote > updater_version_current:
# 创建更新进程
self.updater = DownloadManager(
Config.app_path,
"AUTO_MAA更新器",
main_version_remote,
updater_version_remote,
{
"proxy_list": Config.global_config.get(
Config.global_config.update_ProxyUrlList
),
"download_dict": version_remote["download_dict"],
"thread_numb": Config.global_config.get(
Config.global_config.update_ThreadNumb
),
},
with Config.version_path.open(mode="r", encoding="utf-8") as f:
version_info = json.load(f)
version_info["main_version"] = Config.VERSION
with Config.version_path.open(mode="w", encoding="utf-8") as f:
json.dump(version_info, f, ensure_ascii=False, indent=4)
if (Config.app_path / "AUTO_Updater.exe").exists():
shutil.copy(
Config.app_path / "AUTO_Updater.exe",
Config.app_path / "AUTO_Updater.active.exe",
)
else:
logger.error("更新器文件不存在")
MainInfoBar.push_info_bar(
"error", "更新器不存在", "请手动前往 GitHub 获取最新版本", -1
)
return None
subprocess.Popen(
str(Config.app_path / "AUTO_Updater.active.exe"),
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
# 完成更新器的更新后更新主程序
if main_version_remote > main_version_current:
self.updater.download_accomplish.connect(self.update_main)
# 显示更新页面
self.updater.show()
self.updater.run()
# 更新主程序
elif main_version_remote > main_version_current:
self.update_main()
self.close()
QApplication.quit()
# 无版本更新
else:
MainInfoBar.push_info_bar("success", "更新检查", "已是最新版本~", 3000)
def update_main(self) -> None:
"""更新主程序"""
with Config.version_path.open(mode="r", encoding="utf-8") as f:
version_info = json.load(f)
version_info["main_version"] = Config.VERSION
with Config.version_path.open(mode="w", encoding="utf-8") as f:
json.dump(version_info, f, ensure_ascii=False, indent=4)
subprocess.Popen(
str(Config.app_path / "Updater.exe"),
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
self.close()
QApplication.quit()
def show_notice(self, if_show: bool = True):
"""显示公告"""
@@ -464,8 +455,9 @@ class Setting(QWidget):
}
if if_show or (
datetime.now() > datetime.strptime(notice["time"], "%Y-%m-%d %H:%M")
and datetime.strptime(notice["time"], "%Y-%m-%d %H:%M") > time_local
datetime.now()
> datetime.strptime(notice["time"], "%Y-%m-%d %H:%M")
> time_local
):
choice = NoticeMessageBox(self.window(), "公告", notice["notice_dict"])
@@ -485,37 +477,47 @@ class FunctionSettingCard(HeaderCardWidget):
self.setTitle("功能")
self.card_HomeImageMode = ComboBoxSettingCard(
configItem=Config.global_config.function_HomeImageMode,
icon=FluentIcon.PAGE_RIGHT,
title="主页背景图模式",
content="选择主页背景图的来源",
texts=["默认", "自定义", "主题图像"],
qconfig=Config,
configItem=Config.function_HomeImageMode,
parent=self,
)
self.card_HistoryRetentionTime = ComboBoxSettingCard(
configItem=Config.global_config.function_HistoryRetentionTime,
icon=FluentIcon.PAGE_RIGHT,
title="历史记录保留时间",
content="选择历史记录的保留时间,超期自动清理",
texts=["7 天", "15 天", "30 天", "60 天", "永久"],
qconfig=Config,
configItem=Config.function_HistoryRetentionTime,
parent=self,
)
self.card_IfAllowSleep = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="启动时阻止系统休眠",
content="仅阻止电脑自动休眠,不会影响屏幕是否熄灭",
configItem=Config.global_config.function_IfAllowSleep,
qconfig=Config,
configItem=Config.function_IfAllowSleep,
parent=self,
)
self.card_IfSilence = self.SilenceSettingCard(self)
self.card_IfAgreeBilibili = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="托管bilibili游戏隐私政策",
content="授权AUTO_MAA同意bilibili游戏隐私政策",
configItem=Config.global_config.function_IfAgreeBilibili,
qconfig=Config,
configItem=Config.function_IfAgreeBilibili,
parent=self,
)
self.card_IfSkipMumuSplashAds = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="跳过MuMu启动广告",
content="启动MuMu模拟器时屏蔽启动广告",
configItem=Config.global_config.function_IfSkipMumuSplashAds,
qconfig=Config,
configItem=Config.function_IfSkipMumuSplashAds,
parent=self,
)
Layout = QVBoxLayout()
@@ -541,14 +543,18 @@ class FunctionSettingCard(HeaderCardWidget):
icon=FluentIcon.PAGE_RIGHT,
title="静默模式",
content="是否启用静默模式",
configItem=Config.global_config.function_IfSilence,
qconfig=Config,
configItem=Config.function_IfSilence,
parent=self,
)
self.card_BossKey = LineEditSettingCard(
text="请输入安卓模拟器老板键",
icon=FluentIcon.PAGE_RIGHT,
title="模拟器老板键",
content="输入模拟器老板快捷键,以“+”分隔",
configItem=Config.global_config.function_BossKey,
text="请输入安卓模拟器老板键",
qconfig=Config,
configItem=Config.function_BossKey,
parent=self,
)
widget = QWidget()
@@ -570,19 +576,25 @@ class StartSettingCard(HeaderCardWidget):
icon=FluentIcon.PAGE_RIGHT,
title="开机时自动启动",
content="将AUTO_MAA添加到开机启动项",
configItem=Config.global_config.start_IfSelfStart,
qconfig=Config,
configItem=Config.start_IfSelfStart,
parent=self,
)
self.card_IfRunDirectly = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="启动后直接运行主任务",
content="启动AUTO_MAA后自动运行自动代理任务优先级调度队列 1 > 脚本 1",
configItem=Config.global_config.start_IfRunDirectly,
qconfig=Config,
configItem=Config.start_IfRunDirectly,
parent=self,
)
self.card_IfMinimizeDirectly = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="启动后直接最小化",
content="启动AUTO_MAA后直接最小化",
configItem=Config.global_config.start_IfMinimizeDirectly,
qconfig=Config,
configItem=Config.start_IfMinimizeDirectly,
parent=self,
)
Layout = QVBoxLayout()
@@ -602,13 +614,17 @@ class UiSettingCard(HeaderCardWidget):
icon=FluentIcon.PAGE_RIGHT,
title="显示托盘图标",
content="常态显示托盘图标",
configItem=Config.global_config.ui_IfShowTray,
qconfig=Config,
configItem=Config.ui_IfShowTray,
parent=self,
)
self.card_IfToTray = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="最小化到托盘",
content="最小化时隐藏到托盘",
configItem=Config.global_config.ui_IfToTray,
qconfig=Config,
configItem=Config.ui_IfToTray,
parent=self,
)
Layout = QVBoxLayout()
@@ -634,6 +650,7 @@ class NotifySettingCard(HeaderCardWidget):
icon=FluentIcon.SEND,
title="测试通知",
content="发送测试通知到所有已启用的通知渠道",
parent=self,
)
self.card_TestNotification.clicked.connect(self.send_test_notification)
@@ -652,8 +669,8 @@ class NotifySettingCard(HeaderCardWidget):
MainInfoBar.push_info_bar(
"success",
"测试通知已发送",
"请检查已配置的通知渠道是否可以收到消息",
3000
"请检查已配置的通知渠道是否正常收到消息",
3000,
)
class NotifyContentSettingCard(ExpandGroupSettingCard):
@@ -664,23 +681,29 @@ class NotifySettingCard(HeaderCardWidget):
)
self.card_SendTaskResultTime = ComboBoxSettingCard(
configItem=Config.global_config.notify_SendTaskResultTime,
icon=FluentIcon.PAGE_RIGHT,
title="推送任务结果选项",
content="选择推送自动代理与人工排查任务结果的时机",
texts=["不推送", "任何时刻", "仅失败时"],
qconfig=Config,
configItem=Config.notify_SendTaskResultTime,
parent=self,
)
self.card_IfSendStatistic = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="推送统计信息",
content="推送自动代理统计信息的通知",
configItem=Config.global_config.notify_IfSendStatistic,
qconfig=Config,
configItem=Config.notify_IfSendStatistic,
parent=self,
)
self.card_IfSendSixStar = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="推送公招高资喜报",
content="公招出现六星词条时推送喜报",
configItem=Config.global_config.notify_IfSendSixStar,
qconfig=Config,
configItem=Config.notify_IfSendSixStar,
parent=self,
)
widget = QWidget()
@@ -703,7 +726,9 @@ class NotifySettingCard(HeaderCardWidget):
icon=FluentIcon.PAGE_RIGHT,
title="推送系统通知",
content="使用Plyer推送系统级通知不会在通知中心停留",
configItem=Config.global_config.notify_IfPushPlyer,
qconfig=Config,
configItem=Config.notify_IfPushPlyer,
parent=self,
)
widget = QWidget()
@@ -724,35 +749,46 @@ class NotifySettingCard(HeaderCardWidget):
icon=FluentIcon.PAGE_RIGHT,
title="推送邮件通知",
content="是否启用邮件通知功能",
configItem=Config.global_config.notify_IfSendMail,
qconfig=Config,
configItem=Config.notify_IfSendMail,
parent=self,
)
self.card_SMTPServerAddress = LineEditSettingCard(
text="请输入SMTP服务器地址",
icon=FluentIcon.PAGE_RIGHT,
title="SMTP服务器地址",
content="发信邮箱的SMTP服务器地址",
configItem=Config.global_config.notify_SMTPServerAddress,
text="请输入SMTP服务器地址",
qconfig=Config,
configItem=Config.notify_SMTPServerAddress,
parent=self,
)
self.card_FromAddress = LineEditSettingCard(
text="请输入发信邮箱地址",
icon=FluentIcon.PAGE_RIGHT,
title="发信邮箱地址",
content="发送通知的邮箱地址",
configItem=Config.global_config.notify_FromAddress,
text="请输入发信邮箱地址",
qconfig=Config,
configItem=Config.notify_FromAddress,
parent=self,
)
self.card_AuthorizationCode = PasswordLineEditSettingCard(
text="请输入发信邮箱授权码",
icon=FluentIcon.PAGE_RIGHT,
title="发信邮箱授权码",
content="发送通知的邮箱授权码",
configItem=Config.global_config.notify_AuthorizationCode,
text="请输入发信邮箱授权码",
algorithm="DPAPI",
qconfig=Config,
configItem=Config.notify_AuthorizationCode,
parent=self,
)
self.card_ToAddress = LineEditSettingCard(
text="请输入收信邮箱地址",
icon=FluentIcon.PAGE_RIGHT,
title="收信邮箱地址",
content="接收通知的邮箱地址",
configItem=Config.global_config.notify_ToAddress,
text="请输入收信邮箱地址",
qconfig=Config,
configItem=Config.notify_ToAddress,
parent=self,
)
widget = QWidget()
@@ -779,28 +815,36 @@ class NotifySettingCard(HeaderCardWidget):
icon=FluentIcon.PAGE_RIGHT,
title="推送SeverChan通知",
content="是否启用SeverChan通知功能",
configItem=Config.global_config.notify_IfServerChan,
qconfig=Config,
configItem=Config.notify_IfServerChan,
parent=self,
)
self.card_ServerChanKey = LineEditSettingCard(
text="请输入SendKey",
icon=FluentIcon.PAGE_RIGHT,
title="SendKey",
content="Server酱的SendKeySC3与SCT都可以",
configItem=Config.global_config.notify_ServerChanKey,
text="请输入SendKey",
qconfig=Config,
configItem=Config.notify_ServerChanKey,
parent=self,
)
self.card_ServerChanChannel = LineEditSettingCard(
text="请输入需要推送的Channel代码SCT生效",
icon=FluentIcon.PAGE_RIGHT,
title="ServerChanChannel代码",
content="可以留空,留空则默认。可以多个,请使用“|”隔开",
configItem=Config.global_config.notify_ServerChanChannel,
text="请输入需要推送的Channel代码SCT生效",
qconfig=Config,
configItem=Config.notify_ServerChanChannel,
parent=self,
)
self.card_ServerChanTag = LineEditSettingCard(
text="请输入加入推送的TagSC3生效",
icon=FluentIcon.PAGE_RIGHT,
title="Tag内容",
content="可以留空,留空则默认。可以多个,请使用“|”隔开",
configItem=Config.global_config.notify_ServerChanTag,
text="请输入加入推送的TagSC3生效",
qconfig=Config,
configItem=Config.notify_ServerChanTag,
parent=self,
)
widget = QWidget()
@@ -826,14 +870,18 @@ class NotifySettingCard(HeaderCardWidget):
icon=FluentIcon.PAGE_RIGHT,
title="推送企业微信机器人通知",
content="是否启用企业微信机器人通知功能",
configItem=Config.global_config.notify_IfCompanyWebHookBot,
qconfig=Config,
configItem=Config.notify_IfCompanyWebHookBot,
parent=self,
)
self.card_CompanyWebHookBotUrl = LineEditSettingCard(
text="请输入Webhook的Url",
icon=FluentIcon.PAGE_RIGHT,
title="WebhookUrl",
content="企业微信群机器人的Webhook地址",
configItem=Config.global_config.notify_CompanyWebHookBotUrl,
text="请输入Webhook的Url",
qconfig=Config,
configItem=Config.notify_CompanyWebHookBotUrl,
parent=self,
)
widget = QWidget()
@@ -856,6 +904,7 @@ class SecuritySettingCard(HeaderCardWidget):
icon=FluentIcon.VPN,
title="修改管理密钥",
content="修改用于解密用户密码的管理密钥",
parent=self,
)
Layout = QVBoxLayout()
@@ -869,45 +918,70 @@ class UpdaterSettingCard(HeaderCardWidget):
super().__init__(parent)
self.setTitle("更新")
self.card_IfAutoUpdate = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="自动检查更新",
content="将在启动时自动检查AUTO_MAA是否有新版本",
configItem=Config.global_config.update_IfAutoUpdate,
)
self.card_UpdateType = ComboBoxSettingCard(
configItem=Config.global_config.update_UpdateType,
icon=FluentIcon.PAGE_RIGHT,
title="版本更新类别",
content="选择AUTO_MAA的更新类别",
texts=["稳定版", "公测版"],
)
self.card_ThreadNumb = RangeSettingCard(
configItem=Config.global_config.update_ThreadNumb,
icon=FluentIcon.PAGE_RIGHT,
title="下载器线程数",
content="更新器的下载线程数,建议仅在下载速度较慢时适量拉高",
)
self.card_ProxyUrlList = UrlListSettingCard(
icon=FluentIcon.SETTING,
configItem=Config.global_config.update_ProxyUrlList,
title="代理地址列表",
content="更新器代理地址列表",
parent=self,
)
self.card_CheckUpdate = PushSettingCard(
text="检查更新",
icon=FluentIcon.UPDATE,
title="获取最新版本",
content="检查AUTO_MAA是否有新版本",
parent=self,
)
self.card_IfAutoUpdate = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="自动检查更新",
content="将在启动时自动检查AUTO_MAA是否有新版本",
qconfig=Config,
configItem=Config.update_IfAutoUpdate,
parent=self,
)
self.card_UpdateType = ComboBoxSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="版本更新类别",
content="选择AUTO_MAA的更新类别",
texts=["稳定版", "公测版"],
qconfig=Config,
configItem=Config.update_UpdateType,
parent=self,
)
self.card_ThreadNumb = RangeSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="下载器线程数",
content="更新器的下载线程数,建议仅在下载速度较慢时适量拉高",
qconfig=Config,
configItem=Config.update_ThreadNumb,
parent=self,
)
self.card_ProxyUrlList = UrlListSettingCard(
icon=FluentIcon.SETTING,
title="代理地址列表",
content="更新器代理地址列表",
qconfig=Config,
configItem=Config.update_ProxyUrlList,
parent=self,
)
self.card_MirrorChyanCDK = PasswordLineEditSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="Mirror酱CDK",
content="填写后改为使用由Mirror酱提供的下载服务",
text="请输入Mirror酱CDK",
algorithm="DPAPI",
qconfig=Config,
configItem=Config.update_MirrorChyanCDK,
parent=self,
)
mirrorchyan_url = HyperlinkButton(
"https://mirrorchyan.com/", "购买Mirror酱CDK", self
)
self.card_MirrorChyanCDK.hBoxLayout.insertWidget(
5, mirrorchyan_url, 0, Qt.AlignRight
)
Layout = QVBoxLayout()
Layout.addWidget(self.card_CheckUpdate)
Layout.addWidget(self.card_IfAutoUpdate)
Layout.addWidget(self.card_UpdateType)
Layout.addWidget(self.card_ThreadNumb)
Layout.addWidget(self.card_ProxyUrlList)
Layout.addWidget(self.card_CheckUpdate)
Layout.addWidget(self.card_MirrorChyanCDK)
self.viewLayout.addLayout(Layout)
@@ -922,6 +996,7 @@ class OtherSettingCard(HeaderCardWidget):
icon=FluentIcon.PAGE_RIGHT,
title="公告",
content="查看AUTO_MAA的最新公告",
parent=self,
)
self.card_UserDocs = HyperlinkCard(
url="https://clozya.github.io/AUTOMAA_docs",
@@ -929,8 +1004,9 @@ class OtherSettingCard(HeaderCardWidget):
icon=FluentIcon.PAGE_RIGHT,
title="AUTO_MAA官方文档站",
content="访问AUTO_MAA的官方文档站获取使用指南和项目相关信息",
parent=self,
)
self.card_Association = self.AssociationSettingCard()
self.card_Association = self.AssociationSettingCard(self)
Layout = QVBoxLayout()
Layout.addWidget(self.card_Notice)
@@ -954,6 +1030,7 @@ class OtherSettingCard(HeaderCardWidget):
icon=FluentIcon.GITHUB,
title="GitHub",
content="查看AUTO_MAA的源代码提交问题和建议欢迎参与开发",
parent=self,
)
self.card_QQGroup = HyperlinkCard(
url="https://qm.qq.com/q/bd9fISNoME",
@@ -961,6 +1038,7 @@ class OtherSettingCard(HeaderCardWidget):
icon=FluentIcon.CHAT,
title="QQ群",
content="与AUTO_MAA开发者和用户交流",
parent=self,
)
widget = QWidget()