初步完成调度队列开发

This commit is contained in:
DLmaster
2025-01-05 19:24:01 +08:00
parent f94e129cba
commit 684211c129
14 changed files with 2527 additions and 957 deletions

View File

@@ -25,8 +25,9 @@ v4.2
作者DLmaster_361
"""
from PySide6.QtCore import Qt
from PySide6.QtCore import Qt, QTime
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QWidget, QHBoxLayout
from qfluentwidgets import (
LineEdit,
PasswordLineEdit,
@@ -37,11 +38,14 @@ from qfluentwidgets import (
FluentIconBase,
Signal,
ComboBox,
CheckBox,
qconfig,
ConfigItem,
TimeEdit,
OptionsConfigItem,
)
from typing import Union
from typing import Union, List
class InputMessageBox(MessageBoxBase):
@@ -68,6 +72,31 @@ class InputMessageBox(MessageBoxBase):
self.viewLayout.addWidget(self.input)
class SetMessageBox(MessageBoxBase):
"""输入对话框"""
def __init__(self, parent, title: str, content: List[str], list: List[List[str]]):
super().__init__(parent)
self.title = SubtitleLabel(title)
Widget = QWidget()
Layout = QHBoxLayout(Widget)
self.input: List[ComboBox] = []
for i in range(len(content)):
self.input.append(ComboBox())
self.input[i].addItems(list[i])
self.input[i].setCurrentIndex(-1)
self.input[i].setPlaceholderText(content[i])
Layout.addWidget(self.input[i])
# 将组件添加到布局中
self.viewLayout.addWidget(self.title)
self.viewLayout.addWidget(Widget)
class LineEditSettingCard(SettingCard):
"""Setting card with switch button"""
@@ -147,3 +176,107 @@ class SpinBoxSettingCard(SettingCard):
qconfig.set(self.configItem, value)
self.SpinBox.setValue(value)
class NoOptionComboBoxSettingCard(SettingCard):
def __init__(
self,
configItem: OptionsConfigItem,
icon: Union[str, QIcon, FluentIconBase],
title,
content=None,
value=None,
texts=None,
parent=None,
):
super().__init__(icon, title, content, parent)
self.configItem = configItem
self.comboBox = ComboBox(self)
self.comboBox.setMinimumWidth(250)
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)
self.comboBox.setCurrentText(self.optionToText[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))
def setValue(self, value):
if value not in self.optionToText:
return
self.comboBox.setCurrentText(self.optionToText[value])
qconfig.set(self.configItem, value)
class TimeEditSettingCard(SettingCard):
enabledChanged = Signal(bool)
timeChanged = Signal(str)
def __init__(
self,
icon: Union[str, QIcon, FluentIconBase],
title,
content=None,
configItem_bool: ConfigItem = None,
configItem_time: ConfigItem = None,
parent=None,
):
super().__init__(icon, title, content, parent)
self.configItem_bool = configItem_bool
self.configItem_time = configItem_time
self.CheckBox = CheckBox(self)
self.CheckBox.setTristate(False)
self.TimeEdit = TimeEdit(self)
self.TimeEdit.setDisplayFormat("HH:mm")
self.TimeEdit.setMinimumWidth(150)
if configItem_bool:
self.setValue_bool(qconfig.get(configItem_bool))
configItem_bool.valueChanged.connect(self.setValue_bool)
if configItem_time:
self.setValue_time(qconfig.get(configItem_time))
configItem_time.valueChanged.connect(self.setValue_time)
self.hBoxLayout.addWidget(self.CheckBox, 0, Qt.AlignRight)
self.hBoxLayout.addWidget(self.TimeEdit, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.CheckBox.stateChanged.connect(self.__enableChanged)
self.TimeEdit.timeChanged.connect(self.__timeChanged)
def __timeChanged(self, value: QTime):
self.setValue_time(value.toString("HH:mm"))
self.timeChanged.emit(value.toString("HH:mm"))
def __enableChanged(self, value: int):
if value == 0:
self.setValue_bool(False)
self.enabledChanged.emit(False)
else:
self.setValue_bool(True)
self.enabledChanged.emit(True)
def setValue_bool(self, value: bool):
if self.configItem_bool:
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.TimeEdit.setTime(QTime.fromString(value, "HH:mm"))

View File

@@ -10,68 +10,7 @@ class Main(QWidget):
self.notify = notify
self.crypto = crypto
self.PASSWORD = ""
self.if_user_list_editable = True
self.if_update_database = True
self.if_update_config = True
self.user_mode_list = ["simple", "beta"]
self.user_column = [
"admin",
"id",
"server",
"day",
"status",
"last",
"game",
"game_1",
"game_2",
"routine",
"annihilation",
"infrastructure",
"password",
"notes",
"numb",
"mode",
"uid",
]
self.userlist_simple_index = [
0,
1,
2,
3,
4,
5,
6,
7,
8,
"-",
9,
10,
11,
12,
"-",
"-",
"-",
]
self.userlist_beta_index = [
0,
"-",
"-",
1,
2,
3,
"-",
"-",
"-",
4,
5,
"-",
6,
7,
"-",
"-",
"-",
]
# uiLoader.registerCustomWidget(PushButton)
# uiLoader.registerCustomWidget(LineEdit)
@@ -172,7 +111,7 @@ class Main(QWidget):
# )
# self.if_self_start.stateChanged.connect(self.change_config)
# self.if_sleep: CheckBox = self.ui.findChild(CheckBox, "checkBox_ifsleep")
# self.if_sleep: CheckBox = self.ui.findChild(CheckBox, "checkBox_IfAllowSleep")
# self.if_sleep.stateChanged.connect(self.change_config)
# self.if_proxy_directly: CheckBox = self.ui.findChild(
@@ -262,279 +201,79 @@ class Main(QWidget):
if self.config.content["Default"]["SelfSet.IfProxyDirectly"] == "True":
self.maa_starter("日常代理")
def check_PASSWORD(self) -> None:
"""检查并配置管理密钥"""
if self.config.key_path.exists():
return None
while True:
# def update_config(self):
# """将self.config中的程序配置同步至GUI界面"""
if self.read("setkey"):
self.crypto.get_PASSWORD(self.PASSWORD)
break
else:
choice = MessageBox(
"确认", "您没有输入管理密钥,确定要暂时跳过这一步吗?", self.ui
)
if choice.exec():
break
# # 阻止GUI程序配置被立即读入程序形成死循环
# self.if_update_config = False
def update_user_info(self, operation: str) -> None:
"""将本地数据库中的用户配置同步至GUI的用户管理界面"""
# self.main_tab.setCurrentIndex(
# self.config.content["Default"]["SelfSet.MainIndex"]
# )
# 读入本地数据库
self.config.cur.execute("SELECT * FROM adminx WHERE True")
data = self.config.cur.fetchall()
# self.maa_path.setText(str(Path(self.config.content["Default"]["MaaSet.path"])))
# self.routine.setValue(self.config.content["Default"]["TimeLimit.routine"])
# self.annihilation.setValue(
# self.config.content["Default"]["TimeLimit.annihilation"]
# )
# self.num.setValue(self.config.content["Default"]["TimesLimit.run"])
# self.mail_address.setText(self.config.content["Default"]["SelfSet.MailAddress"])
# self.boss_key.setText(self.config.content["Default"]["SelfSet.BossKey"])
# 处理部分模式调整
if operation == "clear":
self.PASSWORD = ""
elif operation == "read_only":
self.if_user_list_editable = False
elif operation == "editable":
self.if_user_list_editable = True
# self.if_self_start.setChecked(
# bool(self.config.content["Default"]["SelfSet.IfSelfStart"] == "True")
# )
# 阻止GUI用户数据被立即写入数据库形成死循环
self.if_update_database = False
# self.if_sleep.setChecked(
# bool(self.config.content["Default"]["SelfSet.IfAllowSleep"] == "True")
# )
user_switch_list = ["转为高级", "转为简洁"]
self.user_switch.setText(user_switch_list[self.user_set.currentIndex()])
# self.if_proxy_directly.setChecked(
# bool(self.config.content["Default"]["SelfSet.IfProxyDirectly"] == "True")
# )
# 同步简洁用户配置列表
data_simple = [_ for _ in data if _[15] == "simple"]
self.user_list_simple.setRowCount(len(data_simple))
# self.if_send_mail.setChecked(
# bool(self.config.content["Default"]["SelfSet.IfSendMail"] == "True")
# )
for i, row in enumerate(data_simple):
# self.mail_address.setVisible(
# bool(self.config.content["Default"]["SelfSet.IfSendMail"] == "True")
# )
for j, value in enumerate(row):
# self.if_send_error_only.setChecked(
# bool(
# self.config.content["Default"]["SelfSet.IfSendMail.OnlyError"] == "True"
# )
# )
if self.userlist_simple_index[j] == "-":
continue
# self.if_send_error_only.setVisible(
# bool(self.config.content["Default"]["SelfSet.IfSendMail"] == "True")
# )
# 生成表格组件
if j == 2:
item = ComboBox()
item.addItems(["官服", "B服"])
if value == "Official":
item.setCurrentIndex(0)
elif value == "Bilibili":
item.setCurrentIndex(1)
item.currentIndexChanged.connect(
partial(
self.change_user_CellWidget,
data_simple[i][16],
self.user_column[j],
)
)
elif j in [4, 10, 11]:
item = QComboBox()
if j in [4, 10]:
item.addItems(["启用", "禁用"])
elif j == 11:
item.addItems(["启用", "禁用", "更改配置文件"])
if value == "y":
item.setCurrentIndex(0)
elif value == "n":
item.setCurrentIndex(1)
item.currentIndexChanged.connect(
partial(
self.change_user_CellWidget,
data_simple[i][16],
self.user_column[j],
)
)
elif j == 3 and value == -1:
item = QTableWidgetItem("无限")
elif j == 5:
curdate = self.server_date()
if curdate != value:
item = QTableWidgetItem("今日未代理")
else:
item = QTableWidgetItem(f"今日已代理{data_simple[i][14]}")
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
elif j == 12:
if self.PASSWORD == "":
item = QTableWidgetItem("******")
item.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
)
else:
result = self.crypto.decryptx(value, self.PASSWORD)
item = QTableWidgetItem(result)
if result == "管理密钥错误":
item.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
)
else:
item = QTableWidgetItem(str(value))
# self.if_silence.setChecked(
# bool(self.config.content["Default"]["SelfSet.IfSilence"] == "True")
# )
# 组件录入表格
if j in [2, 4, 10, 11]:
if not self.if_user_list_editable:
item.setEnabled(False)
self.user_list_simple.setCellWidget(
data_simple[i][16], self.userlist_simple_index[j], item
)
else:
self.user_list_simple.setItem(
data_simple[i][16], self.userlist_simple_index[j], item
)
# self.boss_key.setVisible(
# bool(self.config.content["Default"]["SelfSet.IfSilence"] == "True")
# )
# 同步高级用户配置列表
data_beta = [_ for _ in data if _[15] == "beta"]
self.user_list_beta.setRowCount(len(data_beta))
# self.if_to_tray.setChecked(
# bool(self.config.content["Default"]["SelfSet.IfToTray"] == "True")
# )
for i, row in enumerate(data_beta):
for j, value in enumerate(row):
if self.userlist_beta_index[j] == "-":
continue
# 生成表格组件
if j in [4, 9, 10]:
item = ComboBox()
if j == 4:
item.addItems(["启用", "禁用"])
elif j in [9, 10]:
item.addItems(["启用", "禁用", "修改MAA配置"])
if value == "y":
item.setCurrentIndex(0)
elif value == "n":
item.setCurrentIndex(1)
item.currentIndexChanged.connect(
partial(
self.change_user_CellWidget,
data_beta[i][16],
self.user_column[j],
)
)
elif j == 3 and value == -1:
item = QTableWidgetItem("无限")
elif j == 5:
curdate = self.server_date()
if curdate != value:
item = QTableWidgetItem("今日未代理")
else:
item = QTableWidgetItem(f"今日已代理{data_beta[i][14]}")
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
elif j == 12:
if self.PASSWORD == "":
item = QTableWidgetItem("******")
item.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
)
else:
result = self.crypto.decryptx(value, self.PASSWORD)
item = QTableWidgetItem(result)
if result == "管理密钥错误":
item.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
)
else:
item = QTableWidgetItem(str(value))
# 组件录入表格
if j in [4, 9, 10]:
if not self.if_user_list_editable:
item.setEnabled(False)
self.user_list_beta.setCellWidget(
data_beta[i][16], self.userlist_beta_index[j], item
)
else:
self.user_list_beta.setItem(
data_beta[i][16], self.userlist_beta_index[j], item
)
# 设置列表可编辑状态
if self.if_user_list_editable:
self.user_list_simple.setEditTriggers(TableWidget.AllEditTriggers)
self.user_list_beta.setEditTriggers(TableWidget.AllEditTriggers)
else:
self.user_list_simple.setEditTriggers(TableWidget.NoEditTriggers)
self.user_list_beta.setEditTriggers(TableWidget.NoEditTriggers)
# 允许GUI改变被同步到本地数据库
self.if_update_database = True
# 设置用户配置列表的标题栏宽度
self.user_list_simple.horizontalHeader().setSectionResizeMode(
QHeaderView.Stretch
)
self.user_list_beta.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
def update_config(self):
"""将self.config中的程序配置同步至GUI界面"""
# 阻止GUI程序配置被立即读入程序形成死循环
self.if_update_config = False
self.main_tab.setCurrentIndex(
self.config.content["Default"]["SelfSet.MainIndex"]
)
self.maa_path.setText(str(Path(self.config.content["Default"]["MaaSet.path"])))
self.routine.setValue(self.config.content["Default"]["TimeLimit.routine"])
self.annihilation.setValue(
self.config.content["Default"]["TimeLimit.annihilation"]
)
self.num.setValue(self.config.content["Default"]["TimesLimit.run"])
self.mail_address.setText(self.config.content["Default"]["SelfSet.MailAddress"])
self.boss_key.setText(self.config.content["Default"]["SelfSet.BossKey"])
self.if_self_start.setChecked(
bool(self.config.content["Default"]["SelfSet.IfSelfStart"] == "True")
)
self.if_sleep.setChecked(
bool(self.config.content["Default"]["SelfSet.IfSleep"] == "True")
)
self.if_proxy_directly.setChecked(
bool(self.config.content["Default"]["SelfSet.IfProxyDirectly"] == "True")
)
self.if_send_mail.setChecked(
bool(self.config.content["Default"]["SelfSet.IfSendMail"] == "True")
)
self.mail_address.setVisible(
bool(self.config.content["Default"]["SelfSet.IfSendMail"] == "True")
)
self.if_send_error_only.setChecked(
bool(
self.config.content["Default"]["SelfSet.IfSendMail.OnlyError"] == "True"
)
)
self.if_send_error_only.setVisible(
bool(self.config.content["Default"]["SelfSet.IfSendMail"] == "True")
)
self.if_silence.setChecked(
bool(self.config.content["Default"]["SelfSet.IfSilence"] == "True")
)
self.boss_key.setVisible(
bool(self.config.content["Default"]["SelfSet.IfSilence"] == "True")
)
self.if_to_tray.setChecked(
bool(self.config.content["Default"]["SelfSet.IfToTray"] == "True")
)
for i in range(10):
self.start_time[i][0].setChecked(
bool(self.config.content["Default"][f"TimeSet.set{i + 1}"] == "True")
)
time = QtCore.QTime(
int(self.config.content["Default"][f"TimeSet.run{i + 1}"][:2]),
int(self.config.content["Default"][f"TimeSet.run{i + 1}"][3:]),
)
self.start_time[i][1].setTime(time)
self.if_update_config = True
# for i in range(10):
# self.start_time[i][0].setChecked(
# bool(self.config.content["Default"][f"TimeSet.set{i + 1}"] == "True")
# )
# time = QtCore.QTime(
# int(self.config.content["Default"][f"TimeSet.run{i + 1}"][:2]),
# int(self.config.content["Default"][f"TimeSet.run{i + 1}"][3:]),
# )
# self.start_time[i][1].setTime(time)
# self.if_update_config = True
def update_board(self, run_text, wait_text, over_text, error_text, log_text):
"""写入数据至GUI执行界面的调度台面板"""
@@ -548,372 +287,6 @@ class Main(QWidget):
self.log_text.verticalScrollBar().maximum()
)
def add_user(self):
"""添加一位新用户"""
# 判断是否已设置管理密钥
if not self.config.key_path.exists():
choice = MessageBox(
"错误",
"请先设置管理密钥再执行添加用户操作",
self.ui,
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
return None
# 插入预设用户数据
set_book = [
["simple", self.user_list_simple.rowCount()],
["beta", self.user_list_beta.rowCount()],
]
self.config.cur.execute(
"INSERT INTO adminx VALUES('新用户','手机号码(官服)/B站IDB服','Official',-1,'y','2000-01-01','1-7','-','-','n','n','n',?,'',0,?,?)",
(
self.crypto.encryptx("未设置"),
set_book[self.user_set.currentIndex()][0],
set_book[self.user_set.currentIndex()][1],
),
)
self.config.db.commit(),
# 同步新用户至GUI
self.update_user_info("normal")
def del_user(self):
"""删除选中的首位用户"""
# 获取对应的行索引
if self.user_set.currentIndex() == 0:
row = self.user_list_simple.currentRow()
elif self.user_set.currentIndex() == 1:
row = self.user_list_beta.currentRow()
# 判断选择合理性
if row == -1:
choice = MessageBox("错误", "请选中一个用户后再执行删除操作", self.ui)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
return None
# 确认待删除用户信息
self.config.cur.execute(
"SELECT * FROM adminx WHERE mode = ? AND uid = ?",
(
self.user_mode_list[self.user_set.currentIndex()],
row,
),
)
data = self.config.cur.fetchall()
choice = MessageBox("确认", f"确定要删除用户 {data[0][0]} 吗?", self.ui)
# 删除用户
if choice.exec():
# 删除所选用户
self.config.cur.execute(
"DELETE FROM adminx WHERE mode = ? AND uid = ?",
(
self.user_mode_list[self.user_set.currentIndex()],
row,
),
)
self.config.db.commit()
if (
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}"
).exists():
shutil.rmtree(
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}"
)
# 后续用户补位
if self.user_set.currentIndex() == 0:
current_numb = self.user_list_simple.rowCount()
elif self.user_set.currentIndex() == 1:
current_numb = self.user_list_beta.rowCount()
for i in range(row + 1, current_numb):
self.config.cur.execute(
"UPDATE adminx SET uid = ? WHERE mode = ? AND uid = ?",
(i - 1, self.user_mode_list[self.user_set.currentIndex()], i),
)
self.config.db.commit()
if (
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}"
).exists():
(
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}"
).rename(
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i - 1}",
)
# 同步最终结果至GUI
self.update_user_info("normal")
def switch_user(self):
"""切换用户配置模式"""
# 获取当前用户配置模式信息
if self.user_set.currentIndex() == 0:
row = self.user_list_simple.currentRow()
elif self.user_set.currentIndex() == 1:
row = self.user_list_beta.currentRow()
# 判断选择合理性
if row == -1:
choice = MessageBox("错误", "请选中一个用户后再执行切换操作", self.ui)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
return None
# 确认待切换用户信息
self.config.cur.execute(
"SELECT * FROM adminx WHERE mode = ? AND uid = ?",
(
self.user_mode_list[self.user_set.currentIndex()],
row,
),
)
data = self.config.cur.fetchall()
mode_list = ["简洁", "高级"]
choice = MessageBox(
"确认",
f"确定要将用户 {data[0][0]} 转为{mode_list[1 - self.user_set.currentIndex()]}配置模式吗?",
self.ui,
)
# 切换用户
if choice.exec():
self.config.cur.execute("SELECT * FROM adminx WHERE True")
data = self.config.cur.fetchall()
if self.user_set.currentIndex() == 0:
current_numb = self.user_list_simple.rowCount()
elif self.user_set.currentIndex() == 1:
current_numb = self.user_list_beta.rowCount()
# 切换所选用户
other_numb = len(data) - current_numb
self.config.cur.execute(
"UPDATE adminx SET mode = ?, uid = ? WHERE mode = ? AND uid = ?",
(
self.user_mode_list[1 - self.user_set.currentIndex()],
other_numb,
self.user_mode_list[self.user_set.currentIndex()],
row,
),
)
self.config.db.commit()
if (
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}"
).exists():
shutil.move(
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}",
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[1 - self.user_set.currentIndex()]}/{other_numb}",
)
# 后续用户补位
for i in range(row + 1, current_numb):
self.config.cur.execute(
"UPDATE adminx SET uid = ? WHERE mode = ? AND uid = ?",
(i - 1, self.user_mode_list[self.user_set.currentIndex()], i),
)
self.config.db.commit(),
if (
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}"
).exists():
(
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}"
).rename(
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i - 1}"
)
self.update_user_info("normal")
def get_maa_config(self, info):
"""获取MAA配置文件"""
# 获取全局MAA配置文件
if info == ["Default"]:
shutil.copy(
Path(self.config.content["Default"]["MaaSet.path"]) / "config/gui.json",
self.config.app_path / "data/MAAconfig/Default",
)
# 获取基建配置文件
elif info[2] == "infrastructure":
infrastructure_path = self.read("file_path_infrastructure")
if infrastructure_path:
(
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/infrastructure"
).mkdir(parents=True, exist_ok=True)
shutil.copy(
infrastructure_path,
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/infrastructure/infrastructure.json",
)
return True
else:
choice = MessageBox(
"错误",
"未选择自定义基建文件",
self.ui,
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
return False
# 获取高级用户MAA配置文件
elif info[2] in ["routine", "annihilation"]:
(
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/{info[2]}"
).mkdir(parents=True, exist_ok=True)
shutil.copy(
Path(self.config.content["Default"]["MaaSet.path"]) / "config/gui.json",
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/{info[2]}",
)
def change_user_Item(self, item: TableWidget, mode):
"""将GUI中发生修改的用户配置表中的一般信息同步至本地数据库"""
# 验证能否写入本地数据库
if not self.if_update_database:
return None
text = item.text()
# 简洁用户配置列表
if mode == "simple":
# 待写入信息预处理
if item.column() == 3: # 代理天数
try:
text = max(int(text), -1)
except ValueError:
self.update_user_info("normal")
return None
if item.column() in [6, 7, 8]: # 关卡号
# 导入与应用特殊关卡规则
games = {}
with self.config.gameid_path.open(mode="r", encoding="utf-8") as f:
gameids = f.readlines()
for line in gameids:
if "" in line:
game_in, game_out = line.split("", 1)
games[game_in.strip()] = game_out.strip()
text = games.get(text, text)
if item.column() == 11: # 密码
text = self.crypto.encryptx(text)
# 保存至本地数据库
if text != "":
self.config.cur.execute(
f"UPDATE adminx SET {self.user_column[self.userlist_simple_index.index(item.column())]} = ? WHERE mode = 'simple' AND uid = ?",
(text, item.row()),
)
# 高级用户配置列表
elif mode == "beta":
# 待写入信息预处理
if item.column() == 1: # 代理天数
try:
text = max(int(text), -1)
except ValueError:
self.update_user_info("normal")
return None
if item.column() == 6: # 密码
text = self.crypto.encryptx(text)
# 保存至本地数据库
if text != "":
self.config.cur.execute(
f"UPDATE adminx SET {self.user_column[self.userlist_beta_index.index(item.column())]} = ? WHERE mode = 'beta' AND uid = ?",
(text, item.row()),
)
self.config.db.commit()
# 同步一般用户信息更改到GUI
self.update_user_info("normal")
def change_user_CellWidget(self, row, column, index):
"""将GUI中发生修改的用户配置表中的CellWidget类信息同步至本地数据库"""
# 验证能否写入本地数据库
if not self.if_update_database:
return None
# 初次开启自定义基建或选择修改配置文件时选择配置文件
if (
self.user_set.currentIndex() == 0
and column == "infrastructure"
and (
index == 2
or (
index == 0
and not (
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}/infrastructure/infrastructure.json"
).exists()
)
)
):
result = self.get_maa_config([0, row, "infrastructure"])
if index == 0 and not result:
index = 1
# 初次开启自定义MAA配置或选择修改MAA配置时调起MAA配置任务
if (
self.user_set.currentIndex() == 1
and column in ["routine", "annihilation"]
and (
index == 2
or (
index == 0
and not (
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}/{column}/gui.json"
).exists()
)
)
):
self.MaaManager.get_json_path = [
self.user_set.currentIndex(),
row,
column,
]
self.maa_starter("设置MAA_用户")
# 服务器
if self.user_set.currentIndex() == 0 and column == "server":
server_list = ["Official", "Bilibili"]
self.config.cur.execute(
f"UPDATE adminx SET server = ? WHERE mode = 'simple' AND uid = ?",
(server_list[index], row),
)
# 其它(启用/禁用)
elif index in [0, 1]:
index_list = ["y", "n"]
self.config.cur.execute(
f"UPDATE adminx SET {column} = ? WHERE mode = ? AND uid = ?",
(
index_list[index],
self.user_mode_list[self.user_set.currentIndex()],
row,
),
)
self.config.db.commit()
# 同步用户组件信息修改到GUI
self.update_user_info("normal")
def change_user_info(self, modes, uids, days, lasts, notes, numbs):
"""将代理完成后发生改动的用户信息同步至本地数据库"""
@@ -978,9 +351,9 @@ class Main(QWidget):
self.config.content["Default"]["SelfSet.BossKey"] = self.boss_key.text()
if self.if_sleep.isChecked():
self.config.content["Default"]["SelfSet.IfSleep"] = "True"
self.config.content["Default"]["SelfSet.IfAllowSleep"] = "True"
else:
self.config.content["Default"]["SelfSet.IfSleep"] = "False"
self.config.content["Default"]["SelfSet.IfAllowSleep"] = "False"
if self.if_self_start.isChecked():
self.config.content["Default"]["SelfSet.IfSelfStart"] = "True"
@@ -1026,6 +399,32 @@ class Main(QWidget):
# 同步程序配置至GUI
self.update_config()
def get_maa_config(self, info):
"""获取MAA配置文件"""
# 获取全局MAA配置文件
if info == ["Default"]:
shutil.copy(
Path(self.config.content["Default"]["MaaSet.path"])
/ "config/gui.json",
self.config.app_path / "data/MAAconfig/Default",
)
# 获取基建配置文件
# 获取高级用户MAA配置文件
elif info[2] in ["routine", "annihilation"]:
(
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/{info[2]}"
).mkdir(parents=True, exist_ok=True)
shutil.copy(
Path(self.config.content["Default"]["MaaSet.path"])
/ "config/gui.json",
self.config.app_path
/ f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/{info[2]}",
)
def set_theme(self):
"""手动更新主题色到组件"""
@@ -1122,65 +521,6 @@ class Main(QWidget):
)
return file_path
def set_system(self):
"""设置系统相关配置"""
# 同步系统休眠状态
if self.config.content["Default"]["SelfSet.IfSleep"] == "True":
# 设置系统电源状态
ctypes.windll.kernel32.SetThreadExecutionState(
self.ES_CONTINUOUS | self.ES_SYSTEM_REQUIRED
)
elif self.config.content["Default"]["SelfSet.IfSleep"] == "False":
# 恢复系统电源状态
ctypes.windll.kernel32.SetThreadExecutionState(self.ES_CONTINUOUS)
# 同步开机自启
if (
self.config.content["Default"]["SelfSet.IfSelfStart"] == "True"
and not self.is_startup()
):
key = winreg.OpenKey(
winreg.HKEY_CURRENT_USER,
r"Software\Microsoft\Windows\CurrentVersion\Run",
winreg.KEY_SET_VALUE,
winreg.KEY_ALL_ACCESS | winreg.KEY_WRITE | winreg.KEY_CREATE_SUB_KEY,
)
winreg.SetValueEx(
key, self.config.app_name, 0, winreg.REG_SZ, self.config.app_path_sys
)
winreg.CloseKey(key)
elif (
self.config.content["Default"]["SelfSet.IfSelfStart"] == "False"
and self.is_startup()
):
key = winreg.OpenKey(
winreg.HKEY_CURRENT_USER,
r"Software\Microsoft\Windows\CurrentVersion\Run",
winreg.KEY_SET_VALUE,
winreg.KEY_ALL_ACCESS | winreg.KEY_WRITE | winreg.KEY_CREATE_SUB_KEY,
)
winreg.DeleteValue(key, self.config.app_name)
winreg.CloseKey(key)
def is_startup(self):
"""判断程序是否已经开机自启"""
key = winreg.OpenKey(
winreg.HKEY_CURRENT_USER,
r"Software\Microsoft\Windows\CurrentVersion\Run",
0,
winreg.KEY_READ,
)
try:
value, _ = winreg.QueryValueEx(key, self.config.app_name)
winreg.CloseKey(key)
return True
except FileNotFoundError:
winreg.CloseKey(key)
return False
def timed_start(self):
"""定时启动代理任务"""
@@ -1228,20 +568,6 @@ class Main(QWidget):
# 执行日志记录,暂时缺省
pass
def get_window_info(self):
"""获取当前窗口信息"""
def callback(hwnd, window_info):
if win32gui.IsWindowVisible(hwnd) and win32gui.GetWindowText(hwnd):
_, pid = win32process.GetWindowThreadProcessId(hwnd)
process = psutil.Process(pid)
window_info.append((win32gui.GetWindowText(hwnd), process.exe()))
return True
window_info = []
win32gui.EnumWindows(callback, window_info)
return window_info
def maa_starter(self, mode):
"""启动MaaManager线程运行任务"""

View File

@@ -33,7 +33,6 @@ from PySide6.QtWidgets import (
QFileDialog, #
QTabWidget, #
QToolBox, #
QComboBox, #
QTableWidgetItem, #
QHeaderView, #
QVBoxLayout,
@@ -55,11 +54,14 @@ from qfluentwidgets import (
RoundMenu,
MessageBox,
MessageBoxBase,
HeaderCardWidget,
InfoBar,
InfoBarPosition,
BodyLabel,
Dialog,
SingleDirectionScrollArea,
SubtitleLabel,
setTheme,
Theme,
SystemThemeListener,
qconfig,
MSFluentWindow,
NavigationItemPosition,
)
@@ -85,36 +87,46 @@ import requests
uiLoader = QUiLoader()
from app import AppConfig, MaaConfig
from app.services import Notification, CryptoHandler
from app.services import Notification, CryptoHandler, SystemHandler
from app.utils import Updater, version_text
from .Widget import InputMessageBox, LineEditSettingCard, SpinBoxSettingCard
from .setting import Setting
from .member_manager import MemberManager
from .queue_manager import QueueManager
class AUTO_MAA(MSFluentWindow):
if_save = True
def __init__(self, config: AppConfig, notify: Notification, crypto: CryptoHandler):
super(AUTO_MAA, self).__init__()
def __init__(
self,
config: AppConfig,
notify: Notification,
crypto: CryptoHandler,
system: SystemHandler,
):
super().__init__()
self.config = config
self.notify = notify
self.config.open_database()
self.crypto = crypto
self.system = system
self.setWindowIcon(
QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico"))
)
self.setWindowTitle("AUTO_MAA")
setTheme(Theme.AUTO)
self.splashScreen = SplashScreen(self.windowIcon(), self)
self.show()
# 创建主窗口
self.setting = Setting(config=config, notify=notify, crypto=crypto)
self.member_manager = MemberManager(config=config, notify=notify, crypto=crypto)
self.setting = Setting(self.config, self.notify, self.crypto, self.system, self)
self.member_manager = MemberManager(self.config, self.notify, self.crypto, self)
self.queue_manager = QueueManager(self.config, self.notify, self)
self.addSubInterface(
self.setting,
@@ -130,6 +142,13 @@ class AUTO_MAA(MSFluentWindow):
FluentIcon.ROBOT,
NavigationItemPosition.TOP,
)
self.addSubInterface(
self.queue_manager,
FluentIcon.BOOK_SHELF,
"调度队列",
FluentIcon.BOOK_SHELF,
NavigationItemPosition.TOP,
)
# 创建系统托盘及其菜单
self.tray = QSystemTrayIcon(
@@ -137,7 +156,7 @@ class AUTO_MAA(MSFluentWindow):
self,
)
self.tray.setToolTip("AUTO_MAA")
self.tray_menu = SystemTrayMenu()
self.tray_menu = SystemTrayMenu("AUTO_MAA", self)
# 显示主界面菜单项
self.tray_menu.addAction(
@@ -171,10 +190,43 @@ class AUTO_MAA(MSFluentWindow):
# 设置托盘菜单
self.tray.setContextMenu(self.tray_menu)
self.tray.activated.connect(self.on_tray_activated)
self.setting.ui.card_IfShowTray.checkedChanged.connect(
lambda x: self.tray.show() if x else self.tray.hide()
)
self.splashScreen.finish()
self.show_main()
if self.config.global_config.get(self.config.global_config.update_IfAutoUpdate):
result = self.setting.check_update()
if result == "已是最新版本~":
InfoBar.success(
title="更新检查",
content=result,
orient=QtCore.Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP_RIGHT,
duration=3000,
parent=self,
)
else:
info = InfoBar.info(
title="更新检查",
content=result,
orient=QtCore.Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.BOTTOM_LEFT,
duration=-1,
parent=self,
)
Up = PushButton("更新")
Up.clicked.connect(
lambda: self.setting.check_version(if_question=False)
)
Up.clicked.connect(info.close)
info.addWidget(Up)
info.show()
def show_tray(self):
"""最小化到托盘"""
if self.if_save:
@@ -185,7 +237,10 @@ class AUTO_MAA(MSFluentWindow):
def show_main(self):
"""显示主界面"""
self.set_ui("配置")
self.tray.hide()
if self.config.global_config.get(self.config.global_config.ui_IfShowTray):
self.tray.show()
else:
self.tray.hide()
def on_tray_activated(self, reason):
"""双击返回主界面"""

File diff suppressed because it is too large Load Diff

714
app/ui/queue_manager.py Normal file
View File

@@ -0,0 +1,714 @@
# <AUTO_MAA:A MAA Multi Account Management and Automation Tool>
# Copyright © <2024> <DLmaster361>
# This file is part of AUTO_MAA.
# AUTO_MAA is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation, either version 3 of the License,
# or (at your option) any later version.
# AUTO_MAA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with AUTO_MAA. If not, see <https://www.gnu.org/licenses/>.
# DLmaster_361@163.com
"""
AUTO_MAA
AUTO_MAA调度队列界面
v4.2
作者DLmaster_361
"""
from PySide6.QtWidgets import (
QWidget, #
QMainWindow, #
QApplication, #
QSystemTrayIcon, #
QFileDialog, #
QTabWidget, #
QToolBox, #
QComboBox, #
QTableWidgetItem, #
QHeaderView, #
QVBoxLayout,
QStackedWidget,
QHBoxLayout,
)
from qfluentwidgets import (
Action,
PushButton,
LineEdit,
PasswordLineEdit,
qconfig,
TableWidget,
Pivot,
TimePicker,
ComboBox,
CheckBox,
ScrollArea,
SpinBox,
FluentIcon,
SwitchButton,
RoundMenu,
MessageBox,
MessageBoxBase,
HeaderCardWidget,
BodyLabel,
CommandBar,
setTheme,
Theme,
SwitchSettingCard,
ExpandGroupSettingCard,
SingleDirectionScrollArea,
)
from PySide6.QtUiTools import QUiLoader
from PySide6.QtGui import QIcon, QCloseEvent
from PySide6 import QtCore
from functools import partial
from typing import List, Tuple
from pathlib import Path
import os
import datetime
import json
import subprocess
import shutil
import win32gui
import win32process
import psutil
import pyautogui
import time
import winreg
import requests
uiLoader = QUiLoader()
from app import AppConfig, QueueConfig, MaaConfig
from app.services import Notification, CryptoHandler
from app.utils import Updater, version_text
from .Widget import (
InputMessageBox,
LineEditSettingCard,
SpinBoxSettingCard,
TimeEditSettingCard,
NoOptionComboBoxSettingCard,
)
class QueueManager(QWidget):
def __init__(
self,
config: AppConfig,
notify: Notification,
parent=None,
):
super().__init__(parent)
self.setObjectName("调度队列")
self.config = config
self.notify = notify
setTheme(Theme.AUTO)
layout = QVBoxLayout(self)
self.tools = CommandBar()
self.queue_manager = QueueSettingBox(self.config, self)
# 逐个添加动作
self.tools.addActions(
[
Action(
FluentIcon.ADD_TO, "新建调度队列", triggered=self.add_setting_box
),
Action(
FluentIcon.REMOVE_FROM,
"删除调度队列",
triggered=self.del_setting_box,
),
]
)
self.tools.addSeparator()
self.tools.addActions(
[
Action(
FluentIcon.LEFT_ARROW, "向左移动", triggered=self.left_setting_box
),
Action(
FluentIcon.RIGHT_ARROW, "向右移动", triggered=self.right_setting_box
),
]
)
self.tools.addSeparator()
self.tools.addAction(Action(FluentIcon.ROTATE, "刷新", triggered=self.refresh))
layout.addWidget(self.tools)
layout.addWidget(self.queue_manager)
def add_setting_box(self):
"""添加一个调度队列"""
index = len(self.queue_manager.search_queue()) + 1
qconfig.load(
self.config.app_path / f"config/QueueConfig/调度队列_{index}.json",
self.config.queue_config,
)
self.config.queue_config.set(self.config.queue_config.queueSet_Name, "")
self.config.queue_config.set(self.config.queue_config.queueSet_Enabled, False)
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_0, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_0, "00:00")
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_1, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_1, "00:00")
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_2, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_2, "00:00")
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_3, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_3, "00:00")
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_4, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_4, "00:00")
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_5, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_5, "00:00")
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_6, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_6, "00:00")
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_7, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_7, "00:00")
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_8, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_8, "00:00")
self.config.queue_config.set(self.config.queue_config.time_TimeEnabled_9, False)
self.config.queue_config.set(self.config.queue_config.time_TimeSet_9, "00:00")
self.config.queue_config.set(self.config.queue_config.queue_Member_1, "禁用")
self.config.queue_config.set(self.config.queue_config.queue_Member_2, "禁用")
self.config.queue_config.set(self.config.queue_config.queue_Member_3, "禁用")
self.config.queue_config.set(self.config.queue_config.queue_Member_4, "禁用")
self.config.queue_config.set(self.config.queue_config.queue_Member_5, "禁用")
self.config.queue_config.set(self.config.queue_config.queue_Member_6, "禁用")
self.config.queue_config.set(self.config.queue_config.queue_Member_7, "禁用")
self.config.queue_config.set(self.config.queue_config.queue_Member_8, "禁用")
self.config.queue_config.set(self.config.queue_config.queue_Member_9, "禁用")
self.config.queue_config.set(self.config.queue_config.queue_Member_10, "禁用")
self.config.queue_config.save()
self.queue_manager.add_QueueSettingBox(index)
self.queue_manager.switch_SettingBox(index)
def del_setting_box(self):
"""删除一个调度队列实例"""
name = self.queue_manager.pivot.currentRouteKey()
if name == None:
return None
choice = MessageBox(
"确认",
f"确定要删除 {name} 吗?",
self,
)
if choice.exec():
queue_list = self.queue_manager.search_queue()
move_list = [_ for _ in queue_list if int(_[0][3:]) > int(name[3:])]
index = max(int(name[3:]) - 1, 1)
self.queue_manager.clear_SettingBox()
os.remove(self.config.app_path / f"config/QueueConfig/{name}.json")
for queue in move_list:
if (
self.config.app_path / f"config/QueueConfig/{queue[0]}.json"
).exists():
(
self.config.app_path / f"config/QueueConfig/{queue[0]}.json"
).rename(
self.config.app_path
/ f"config/QueueConfig/调度队列_{int(queue[0][5:])-1}.json",
)
self.queue_manager.show_SettingBox(index)
def left_setting_box(self):
"""向左移动调度队列实例"""
name = self.queue_manager.pivot.currentRouteKey()
if name == None:
return None
index = int(name[5:])
if index == 1:
return None
self.queue_manager.clear_SettingBox()
(self.config.app_path / f"config/QueueConfig/调度队列_{index}.json").rename(
self.config.app_path / f"config/QueueConfig/调度队列_0.json",
)
shutil.move(
str(self.config.app_path / f"config/QueueConfig/调度队列_{index-1}.json"),
str(self.config.app_path / f"config/QueueConfig/调度队列_{index}.json"),
)
(self.config.app_path / f"config/QueueConfig/调度队列_0.json").rename(
self.config.app_path / f"config/QueueConfig/调度队列_{index-1}.json",
)
self.queue_manager.show_SettingBox(index - 1)
def right_setting_box(self):
"""向右移动调度队列实例"""
name = self.queue_manager.pivot.currentRouteKey()
if name == None:
return None
queue_list = self.queue_manager.search_queue()
index = int(name[5:])
if index == len(queue_list):
return None
self.queue_manager.clear_SettingBox()
(self.config.app_path / f"config/QueueConfig/调度队列_{index}.json").rename(
self.config.app_path / f"config/QueueConfig/调度队列_0.json",
)
(self.config.app_path / f"config/QueueConfig/调度队列_{index+1}.json").rename(
self.config.app_path / f"config/QueueConfig/调度队列_{index}.json",
)
(self.config.app_path / f"config/QueueConfig/调度队列_0.json").rename(
self.config.app_path / f"config/QueueConfig/调度队列_{index+1}.json",
)
self.queue_manager.show_SettingBox(index + 1)
def refresh(self):
"""刷新调度队列界面"""
index = int(self.queue_manager.pivot.currentRouteKey()[5:])
self.queue_manager.clear_SettingBox()
self.queue_manager.show_SettingBox(index)
class QueueSettingBox(QWidget):
def __init__(self, config: AppConfig, parent=None):
super().__init__(parent)
self.setObjectName("调度队列管理")
self.config = config
self.pivot = Pivot(self)
self.stackedWidget = QStackedWidget(self)
self.Layout = QVBoxLayout(self)
self.script_list: List[QueueMemberSettingBox] = []
self.Layout.addWidget(self.pivot, 0, QtCore.Qt.AlignHCenter)
self.Layout.addWidget(self.stackedWidget)
self.Layout.setContentsMargins(0, 0, 0, 0)
self.pivot.currentItemChanged.connect(
lambda index: self.switch_SettingBox(int(index[5:]), if_chang_pivot=False)
)
self.show_SettingBox(1)
def show_SettingBox(self, index) -> None:
"""加载所有子界面"""
queue_list = self.search_queue()
for queue in queue_list:
self.add_QueueSettingBox(int(queue[0][5:]))
self.switch_SettingBox(index)
def switch_SettingBox(self, index: int, if_chang_pivot: bool = True) -> None:
"""切换到指定的子界面"""
queue_list = self.search_queue()
if index > len(queue_list):
return None
qconfig.load(
self.config.app_path
/ f"config/QueueConfig/{self.script_list[index-1].objectName()}.json",
self.config.queue_config,
)
if if_chang_pivot:
self.pivot.setCurrentItem(self.script_list[index - 1].objectName())
self.stackedWidget.setCurrentWidget(self.script_list[index - 1])
def clear_SettingBox(self) -> None:
"""清空所有子界面"""
for sub_interface in self.script_list:
self.stackedWidget.removeWidget(sub_interface)
sub_interface.deleteLater()
self.script_list.clear()
self.pivot.clear()
def add_QueueSettingBox(self, uid: int) -> None:
"""添加一个调度队列设置界面"""
maa_setting_box = QueueMemberSettingBox(self.config, uid, self)
self.script_list.append(maa_setting_box)
self.stackedWidget.addWidget(self.script_list[-1])
self.pivot.addItem(routeKey=f"调度队列_{uid}", text=f"调度队列 {uid}")
def search_queue(self) -> list:
"""搜索所有调度队列实例"""
queue_list = []
if (self.config.app_path / "config/QueueConfig").exists():
for json_file in (self.config.app_path / "config/QueueConfig").glob(
"*.json"
):
with json_file.open("r", encoding="utf-8") as f:
info = json.load(f)
queue_list.append([json_file.stem, info["QueueSet"]["Name"]])
return queue_list
class QueueMemberSettingBox(QWidget):
def __init__(self, config: AppConfig, uid: int, parent=None):
super().__init__(parent)
self.setObjectName(f"调度队列_{uid}")
self.config = config
layout = QVBoxLayout()
scrollArea = ScrollArea()
scrollArea.setWidgetResizable(True)
content_widget = QWidget()
content_layout = QVBoxLayout(content_widget)
self.queue_set = self.QueueSetSettingCard(self, self.config.queue_config)
self.time = self.TimeSettingCard(self, self.config.queue_config)
self.task = self.TaskSettingCard(self, self.config)
content_layout.addWidget(self.queue_set)
content_layout.addWidget(self.time)
content_layout.addWidget(self.task)
content_layout.addStretch(1)
scrollArea.setWidget(content_widget)
layout.addWidget(scrollArea)
self.setLayout(layout)
class QueueSetSettingCard(HeaderCardWidget):
def __init__(self, parent=None, queue_config: QueueConfig = None):
super().__init__(parent)
self.setTitle("队列设置")
self.queue_config = queue_config
Layout = QVBoxLayout()
self.card_Name = LineEditSettingCard(
"调度队列名称",
FluentIcon.EDIT,
"调度队列名称",
"用于标识调度队列的名称",
self.queue_config.queueSet_Name,
)
self.card_Enable = SwitchSettingCard(
FluentIcon.HOME,
"状态",
"调度队列状态",
self.queue_config.queueSet_Enabled,
)
Layout.addWidget(self.card_Name)
Layout.addWidget(self.card_Enable)
self.viewLayout.addLayout(Layout)
class TimeSettingCard(HeaderCardWidget):
def __init__(self, parent=None, queue_config: QueueConfig = None):
super().__init__(parent)
self.setTitle("定时设置")
self.queue_config = queue_config
widget_1 = QWidget()
Layout_1 = QVBoxLayout(widget_1)
widget_2 = QWidget()
Layout_2 = QVBoxLayout(widget_2)
Layout = QHBoxLayout()
self.card_Time_0 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 1",
"",
self.queue_config.time_TimeEnabled_0,
self.queue_config.time_TimeSet_0,
)
self.card_Time_1 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 2",
"",
self.queue_config.time_TimeEnabled_1,
self.queue_config.time_TimeSet_1,
)
self.card_Time_2 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 3",
"",
self.queue_config.time_TimeEnabled_2,
self.queue_config.time_TimeSet_2,
)
self.card_Time_3 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 4",
"",
self.queue_config.time_TimeEnabled_3,
self.queue_config.time_TimeSet_3,
)
self.card_Time_4 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 5",
"",
self.queue_config.time_TimeEnabled_4,
self.queue_config.time_TimeSet_4,
)
self.card_Time_5 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 6",
"",
self.queue_config.time_TimeEnabled_5,
self.queue_config.time_TimeSet_5,
)
self.card_Time_6 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 7",
"",
self.queue_config.time_TimeEnabled_6,
self.queue_config.time_TimeSet_6,
)
self.card_Time_7 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 8",
"",
self.queue_config.time_TimeEnabled_7,
self.queue_config.time_TimeSet_7,
)
self.card_Time_8 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 9",
"",
self.queue_config.time_TimeEnabled_8,
self.queue_config.time_TimeSet_8,
)
self.card_Time_9 = TimeEditSettingCard(
FluentIcon.STOP_WATCH,
"定时 10",
"",
self.queue_config.time_TimeEnabled_9,
self.queue_config.time_TimeSet_9,
)
Layout_1.addWidget(self.card_Time_0)
Layout_1.addWidget(self.card_Time_1)
Layout_1.addWidget(self.card_Time_2)
Layout_1.addWidget(self.card_Time_3)
Layout_1.addWidget(self.card_Time_4)
Layout_2.addWidget(self.card_Time_5)
Layout_2.addWidget(self.card_Time_6)
Layout_2.addWidget(self.card_Time_7)
Layout_2.addWidget(self.card_Time_8)
Layout_2.addWidget(self.card_Time_9)
Layout.addWidget(widget_1)
Layout.addWidget(widget_2)
self.viewLayout.addLayout(Layout)
class QueueSetSettingCard(HeaderCardWidget):
def __init__(self, parent=None, queue_config: QueueConfig = None):
super().__init__(parent)
self.setTitle("队列设置")
self.queue_config = queue_config
Layout = QVBoxLayout()
self.card_Name = LineEditSettingCard(
"调度队列名称",
FluentIcon.EDIT,
"调度队列名称",
"用于标识调度队列的名称",
self.queue_config.queueSet_Name,
)
self.card_Enable = SwitchSettingCard(
FluentIcon.HOME,
"状态",
"调度队列状态",
self.queue_config.queueSet_Enabled,
)
Layout.addWidget(self.card_Name)
Layout.addWidget(self.card_Enable)
self.viewLayout.addLayout(Layout)
class TaskSettingCard(HeaderCardWidget):
def __init__(self, parent=None, config: AppConfig = None):
super().__init__(parent)
self.setTitle("定时设置")
self.config = config
self.queue_config = config.queue_config
Layout = QVBoxLayout()
member_list = self.search_member()
self.card_Member_1 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_1,
FluentIcon.APPLICATION,
"任务实例1",
"第一个调起的脚本任务实例",
member_list[0],
member_list[1],
)
self.card_Member_2 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_2,
FluentIcon.APPLICATION,
"任务实例2",
"第二个调起的脚本任务实例",
member_list[0],
member_list[1],
)
self.card_Member_3 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_3,
FluentIcon.APPLICATION,
"任务实例3",
"第三个调起的脚本任务实例",
member_list[0],
member_list[1],
)
self.card_Member_4 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_4,
FluentIcon.APPLICATION,
"任务实例4",
"第四个调起的脚本任务实例",
member_list[0],
member_list[1],
)
self.card_Member_5 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_5,
FluentIcon.APPLICATION,
"任务实例5",
"第五个调起的脚本任务实例",
member_list[0],
member_list[1],
)
self.card_Member_6 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_6,
FluentIcon.APPLICATION,
"任务实例6",
"第六个调起的脚本任务实例",
member_list[0],
member_list[1],
)
self.card_Member_7 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_7,
FluentIcon.APPLICATION,
"任务实例7",
"第七个调起的脚本任务实例",
member_list[0],
member_list[1],
)
self.card_Member_8 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_8,
FluentIcon.APPLICATION,
"任务实例8",
"第八个调起的脚本任务实例",
member_list[0],
member_list[1],
)
self.card_Member_9 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_9,
FluentIcon.APPLICATION,
"任务实例9",
"第九个调起的脚本任务实例",
member_list[0],
member_list[1],
)
self.card_Member_10 = NoOptionComboBoxSettingCard(
self.queue_config.queue_Member_10,
FluentIcon.APPLICATION,
"任务实例10",
"第十个调起的脚本任务实例",
member_list[0],
member_list[1],
)
Layout.addWidget(self.card_Member_1)
Layout.addWidget(self.card_Member_2)
Layout.addWidget(self.card_Member_3)
Layout.addWidget(self.card_Member_4)
Layout.addWidget(self.card_Member_5)
Layout.addWidget(self.card_Member_6)
Layout.addWidget(self.card_Member_7)
Layout.addWidget(self.card_Member_8)
Layout.addWidget(self.card_Member_9)
Layout.addWidget(self.card_Member_10)
self.viewLayout.addLayout(Layout)
def search_member(self) -> list:
"""搜索所有脚本实例"""
member_list_name = ["禁用"]
member_list_text = ["未启用"]
if (self.config.app_path / "config/MaaConfig").exists():
for subdir in (self.config.app_path / "config/MaaConfig").iterdir():
if subdir.is_dir():
member_list_name.append(subdir.name)
with (subdir / "config.json").open("r", encoding="utf-8") as f:
info = json.load(f)
if info["MaaSet"]["Name"] != "":
member_list_text.append(
f"{subdir.name} - {info["MaaSet"]["Name"]}"
)
else:
member_list_text.append(subdir.name)
return [member_list_name, member_list_text]

View File

@@ -52,13 +52,14 @@ from qfluentwidgets import (
ScrollArea,
SpinBox,
FluentIcon,
SwitchButton,
RoundMenu,
setTheme,
Theme,
MessageBox,
MessageBoxBase,
HeaderCardWidget,
BodyLabel,
Dialog,
InfoBar,
InfoBarPosition,
SubtitleLabel,
GroupHeaderCardWidget,
SwitchSettingCard,
@@ -88,21 +89,31 @@ import requests
uiLoader = QUiLoader()
from app import AppConfig
from app.services import Notification, CryptoHandler
from app.services import Notification, CryptoHandler, SystemHandler
from app.utils import Updater, version_text
from .Widget import InputMessageBox, LineEditSettingCard
class Setting(QWidget):
def __init__(self, config: AppConfig, notify: Notification, crypto: CryptoHandler):
super(Setting, self).__init__()
def __init__(
self,
config: AppConfig,
notify: Notification,
crypto: CryptoHandler,
system: SystemHandler,
parent=None,
):
super().__init__(parent)
self.setObjectName("设置")
self.config = config
self.notify = notify
self.crypto = crypto
self.system = system
setTheme(Theme.AUTO)
layout = QVBoxLayout()
@@ -120,6 +131,8 @@ class Setting(QWidget):
self.updater = UpdaterSettingCard(self, self.config)
self.other = OtherSettingCard(self, self.config)
self.function.card_IfAllowSleep.checkedChanged.connect(self.system.set_Sleep)
self.start.card_IfSelfStart.checkedChanged.connect(self.system.set_SelfStart)
self.security.card_changePASSWORD.clicked.connect(self.change_PASSWORD)
self.updater.card_CheckUpdate.clicked.connect(self.check_version)
self.other.card_Tips.clicked.connect(self.show_tips)
@@ -147,7 +160,7 @@ class Setting(QWidget):
while True:
choice = InputMessageBox(
self,
self.parent().parent().parent(),
"未检测到管理密钥,请设置您的管理密钥",
"管理密钥",
"密码",
@@ -157,10 +170,14 @@ class Setting(QWidget):
break
else:
choice = MessageBox(
"确认", "您没有输入管理密钥,确定要暂时跳过这一步吗?", self
"警告",
"您没有设置管理密钥,无法使用本软件,请先设置管理密钥",
self.parent().parent().parent(),
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
break
pass
def change_PASSWORD(self) -> None:
"""修改管理密钥"""
@@ -180,13 +197,20 @@ class Setting(QWidget):
while True:
a = InputMessageBox(
self, "请输入新的管理密钥", "新管理密钥", "密码"
choice = InputMessageBox(
self,
"请输入新的管理密钥",
"新管理密钥",
"密码",
)
if a.exec() and a.input.text() != "":
if choice.exec() and choice.input.text() != "":
# 修改管理密钥
self.crypto.get_PASSWORD(a.input.text())
choice = MessageBox("操作成功", "管理密钥修改成功", self)
self.crypto.get_PASSWORD(choice.input.text())
choice = MessageBox(
"操作成功",
"管理密钥修改成功",
self,
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
@@ -207,7 +231,10 @@ class Setting(QWidget):
while if_change:
choice = InputMessageBox(
self, "请输入旧的管理密钥", "旧管理密钥", "密码"
self,
"请输入旧的管理密钥",
"旧管理密钥",
"密码",
)
if choice.exec() and choice.input.text() != "":
@@ -219,7 +246,10 @@ class Setting(QWidget):
while True:
choice = InputMessageBox(
self, "请输入新的管理密钥", "新管理密钥", "密码"
self,
"请输入新的管理密钥",
"新管理密钥",
"密码",
)
if choice.exec() and choice.input.text() != "":
@@ -228,7 +258,9 @@ class Setting(QWidget):
data, PASSWORD_old, choice.input.text()
)
choice = MessageBox(
"操作成功", "管理密钥修改成功", self
"操作成功",
"管理密钥修改成功",
self,
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
@@ -262,7 +294,43 @@ class Setting(QWidget):
if choice.exec():
break
def check_version(self):
def check_update(self) -> str:
"""检查主程序版本更新,返回更新信息"""
# 从本地版本信息文件获取当前版本信息
with self.config.version_path.open(mode="r", encoding="utf-8") as f:
version_current = json.load(f)
main_version_current = list(
map(int, version_current["main_version"].split("."))
)
# 从远程服务器获取最新版本信息
for _ in range(3):
try:
response = requests.get(
"https://gitee.com/DLmaster_361/AUTO_MAA/raw/main/resources/version.json"
)
version_remote = response.json()
break
except Exception as e:
err = e
time.sleep(0.1)
else:
return f"获取版本信息时出错:\n{err}"
main_version_remote = list(map(int, version_remote["main_version"].split(".")))
# 有版本更新
if main_version_remote > main_version_current:
main_version_info = f" 主程序:{version_text(main_version_current)} --> {version_text(main_version_remote)}\n"
return f"发现新版本:\n{main_version_info} 更新说明:\n{version_remote['announcement'].replace("\n# ","\n ").replace("\n## ","\n - ").replace("\n- ","\n · ")}\n\n是否开始更新?\n\n 注意主程序更新时AUTO_MAA将自动关闭"
else:
return "已是最新版本~"
def check_version(self, if_question: bool = True) -> None:
"""检查版本更新,调起文件下载进程"""
# 从本地版本信息文件获取当前版本信息
@@ -325,13 +393,14 @@ class Setting(QWidget):
)
# 询问是否开始版本更新
choice = MessageBox(
"版本更新",
f"发现新版本:\n{main_version_info}{updater_version_info} 更新说明:\n{version_remote['announcement'].replace("\n# ","\n ").replace("\n## ","\n - ").replace("\n- ","\n · ")}\n\n是否开始更新?\n\n 注意主程序更新时AUTO_MAA将自动关闭",
self,
)
if not choice.exec():
return None
if if_question:
choice = MessageBox(
"版本更新",
f"发现新版本:\n{main_version_info}{updater_version_info} 更新说明:\n{version_remote['announcement'].replace("\n# ","\n ").replace("\n## ","\n - ").replace("\n- ","\n · ")}\n\n是否开始更新?\n\n 注意主程序更新时AUTO_MAA将自动关闭",
self,
)
if not choice.exec():
return None
# 更新更新器
if updater_version_remote > updater_version_current:
@@ -354,7 +423,15 @@ class Setting(QWidget):
# 无版本更新
else:
self.notify.push_notification("已是最新版本~", " ", " ", 3)
InfoBar.success(
title="更新检查",
content="已是最新版本~",
orient=QtCore.Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP_RIGHT,
duration=3000,
parent=self,
)
def update_main(self):
"""更新主程序"""
@@ -388,11 +465,11 @@ class FunctionSettingCard(HeaderCardWidget):
Layout = QVBoxLayout()
self.card_IfSleep = SwitchSettingCard(
self.card_IfAllowSleep = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="启动时阻止系统休眠",
content="仅阻止电脑自动休眠,不会影响屏幕是否熄灭",
configItem=self.config.function_IfSleep,
configItem=self.config.function_IfAllowSleep,
)
self.card_IfSilence = SwitchSettingCard(
@@ -403,7 +480,7 @@ class FunctionSettingCard(HeaderCardWidget):
)
# 添加各组到设置卡中
Layout.addWidget(self.card_IfSleep)
Layout.addWidget(self.card_IfAllowSleep)
Layout.addWidget(self.card_IfSilence)
self.viewLayout.addLayout(Layout)