Merge branch 'DLMS_dev' into dev
This commit is contained in:
@@ -562,7 +562,10 @@ class GlobalConfig(QConfig):
|
|||||||
notify_IfSendErrorOnly = ConfigItem(
|
notify_IfSendErrorOnly = ConfigItem(
|
||||||
"Notify", "IfSendErrorOnly", False, BoolValidator()
|
"Notify", "IfSendErrorOnly", False, BoolValidator()
|
||||||
)
|
)
|
||||||
notify_MailAddress = ConfigItem("Notify", "MailAddress", "")
|
notify_SMTPServerAddress = ConfigItem("Notify", "SMTPServerAddress", "")
|
||||||
|
notify_AuthorizationCode = ConfigItem("Notify", "AuthorizationCode", "")
|
||||||
|
notify_FromAddress = ConfigItem("Notify", "FromAddress", "")
|
||||||
|
notify_ToAddress = ConfigItem("Notify", "ToAddress", "")
|
||||||
notify_IfServerChan = ConfigItem("Notify", "IfServerChan", False, BoolValidator())
|
notify_IfServerChan = ConfigItem("Notify", "IfServerChan", False, BoolValidator())
|
||||||
notify_ServerChanKey = ConfigItem("Notify", "ServerChanKey", "")
|
notify_ServerChanKey = ConfigItem("Notify", "ServerChanKey", "")
|
||||||
notify_ServerChanChannel = ConfigItem("Notify", "ServerChanChannel", "")
|
notify_ServerChanChannel = ConfigItem("Notify", "ServerChanChannel", "")
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ from email.utils import formataddr
|
|||||||
|
|
||||||
from serverchan_sdk import sc_send
|
from serverchan_sdk import sc_send
|
||||||
|
|
||||||
from app.core import Config
|
from app.core import Config, MainInfoBar
|
||||||
|
from app.services.security import Crypto
|
||||||
|
|
||||||
|
|
||||||
class Notification:
|
class Notification:
|
||||||
@@ -57,73 +58,97 @@ class Notification:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def send_mail(self, title, content):
|
def send_mail(self, title, content):
|
||||||
"""使用官方专用邮箱推送邮件通知"""
|
"""推送邮件通知"""
|
||||||
|
|
||||||
# 声明:此邮箱为AUTO_MAA项目组资产,未经授权不得私自使用
|
|
||||||
# 注意:此声明注释只有使用者更换发信邮箱时才能删除,本条规则优先级高于GPLv3
|
|
||||||
|
|
||||||
if Config.global_config.get(Config.global_config.notify_IfSendMail):
|
if Config.global_config.get(Config.global_config.notify_IfSendMail):
|
||||||
|
|
||||||
# 第三方 SMTP 服务配置
|
|
||||||
mail_host = "smtp.163.com" # 设置服务器
|
|
||||||
mail_sender = "AUTO_MAA_server@163.com" # 用户名
|
|
||||||
mail_key = "SYrq87nDLD4RNB5T" # 授权码 24/11/15
|
|
||||||
|
|
||||||
# 定义邮件正文
|
|
||||||
message = MIMEText(content, "plain", "utf-8")
|
|
||||||
message["From"] = formataddr(
|
|
||||||
(
|
|
||||||
Header("AUTO_MAA通知服务", "utf-8").encode(),
|
|
||||||
"AUTO_MAA_server@163.com",
|
|
||||||
)
|
|
||||||
) # 发件人显示的名字
|
|
||||||
message["To"] = formataddr(
|
|
||||||
(
|
|
||||||
Header("AUTO_MAA用户", "utf-8").encode(),
|
|
||||||
Config.global_config.get(Config.global_config.notify_MailAddress),
|
|
||||||
)
|
|
||||||
) # 收件人显示的名字
|
|
||||||
message["Subject"] = Header(title, "utf-8")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
smtpObj = smtplib.SMTP_SSL(mail_host, 465) # 465为SMTP_SSL默认端口
|
# 定义邮件正文
|
||||||
smtpObj.login(mail_sender, mail_key)
|
message = MIMEText(content, "plain", "utf-8")
|
||||||
|
message["From"] = formataddr(
|
||||||
|
(
|
||||||
|
Header("AUTO_MAA通知服务", "utf-8").encode(),
|
||||||
|
"AUTO_MAA_server@163.com",
|
||||||
|
)
|
||||||
|
) # 发件人显示的名字
|
||||||
|
message["To"] = formataddr(
|
||||||
|
(
|
||||||
|
Header("AUTO_MAA用户", "utf-8").encode(),
|
||||||
|
Config.global_config.get(Config.global_config.notify_ToAddress),
|
||||||
|
)
|
||||||
|
) # 收件人显示的名字
|
||||||
|
message["Subject"] = Header(title, "utf-8")
|
||||||
|
|
||||||
|
smtpObj = smtplib.SMTP_SSL(
|
||||||
|
Config.global_config.get(
|
||||||
|
Config.global_config.notify_SMTPServerAddress
|
||||||
|
),
|
||||||
|
465,
|
||||||
|
)
|
||||||
|
smtpObj.login(
|
||||||
|
Config.global_config.get(Config.global_config.notify_FromAddress),
|
||||||
|
Crypto.win_decryptor(
|
||||||
|
Config.global_config.get(
|
||||||
|
Config.global_config.notify_AuthorizationCode
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
smtpObj.sendmail(
|
smtpObj.sendmail(
|
||||||
mail_sender,
|
Config.global_config.get(Config.global_config.notify_FromAddress),
|
||||||
Config.global_config.get(Config.global_config.notify_MailAddress),
|
Config.global_config.get(Config.global_config.notify_ToAddress),
|
||||||
message.as_string(),
|
message.as_string(),
|
||||||
)
|
)
|
||||||
return True
|
|
||||||
except smtplib.SMTPException as e:
|
|
||||||
return f"发送邮件时出错:\n{e}"
|
|
||||||
finally:
|
|
||||||
smtpObj.quit()
|
smtpObj.quit()
|
||||||
|
logger.success("邮件发送成功")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"发送邮件时出错:\n{e}")
|
||||||
|
MainInfoBar.push_info_bar("error", "发送邮件时出错", f"{e}", -1)
|
||||||
|
|
||||||
def ServerChanPush(self, title, content):
|
def ServerChanPush(self, title, content):
|
||||||
"""使用Server酱推送通知"""
|
"""使用Server酱推送通知"""
|
||||||
|
|
||||||
if Config.global_config.get(Config.global_config.notify_IfServerChan):
|
if Config.global_config.get(Config.global_config.notify_IfServerChan):
|
||||||
send_key = Config.global_config.get(Config.global_config.notify_ServerChanKey)
|
send_key = Config.global_config.get(
|
||||||
|
Config.global_config.notify_ServerChanKey
|
||||||
|
)
|
||||||
option = {}
|
option = {}
|
||||||
is_valid = lambda s: s == "" or (s == '|'.join(s.split('|')) and (s.count('|') == 0 or all(s.split('|'))))
|
is_valid = lambda s: s == "" or (
|
||||||
|
s == "|".join(s.split("|")) and (s.count("|") == 0 or all(s.split("|")))
|
||||||
|
)
|
||||||
"""
|
"""
|
||||||
is_valid => True, 如果启用的话需要正确设置Tag和Channel。
|
is_valid => True, 如果启用的话需要正确设置Tag和Channel。
|
||||||
允许空的Tag和Channel即不启用,但不允许例如a||b,|a|b,a|b|,||||
|
允许空的Tag和Channel即不启用,但不允许例如a||b,|a|b,a|b|,||||
|
||||||
"""
|
"""
|
||||||
send_tag = Config.global_config.get(Config.global_config.notify_ServerChanTag)
|
send_tag = Config.global_config.get(
|
||||||
send_channel = Config.global_config.get(Config.global_config.notify_ServerChanChannel)
|
Config.global_config.notify_ServerChanTag
|
||||||
|
)
|
||||||
|
send_channel = Config.global_config.get(
|
||||||
|
Config.global_config.notify_ServerChanChannel
|
||||||
|
)
|
||||||
|
|
||||||
if is_valid(send_tag):
|
if is_valid(send_tag):
|
||||||
option['tags'] = send_tag
|
option["tags"] = send_tag
|
||||||
else:
|
else:
|
||||||
option['tags'] = ''
|
option["tags"] = ""
|
||||||
logger.warning('请正确设置Auto_MAA中ServerChan的Tag。')
|
logger.warning("请正确设置Auto_MAA中ServerChan的Tag。")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning",
|
||||||
|
"Server酱通知推送异常",
|
||||||
|
"请正确设置Auto_MAA中ServerChan的Tag。",
|
||||||
|
-1,
|
||||||
|
)
|
||||||
|
|
||||||
if is_valid(send_channel):
|
if is_valid(send_channel):
|
||||||
option['channel'] = send_channel
|
option["channel"] = send_channel
|
||||||
else:
|
else:
|
||||||
option['channel'] = ''
|
option["channel"] = ""
|
||||||
logger.warning('请正确设置Auto_MAA中ServerChan的Channel。')
|
logger.warning("请正确设置Auto_MAA中ServerChan的Channel。")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning",
|
||||||
|
"Server酱通知推送异常",
|
||||||
|
"请正确设置Auto_MAA中ServerChan的Channel。",
|
||||||
|
-1,
|
||||||
|
)
|
||||||
|
|
||||||
response = sc_send(send_key, title, content, option)
|
response = sc_send(send_key, title, content, option)
|
||||||
if response["code"] == 0:
|
if response["code"] == 0:
|
||||||
@@ -132,21 +157,24 @@ class Notification:
|
|||||||
else:
|
else:
|
||||||
logger.info("Server酱推送通知失败")
|
logger.info("Server酱推送通知失败")
|
||||||
logger.error(response)
|
logger.error(response)
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"error",
|
||||||
|
"Server酱通知推送失败",
|
||||||
|
f'使用Server酱推送通知时出错:\n{response["data"]['error']}',
|
||||||
|
-1,
|
||||||
|
)
|
||||||
return f'使用Server酱推送通知时出错:\n{response["data"]['error']}'
|
return f'使用Server酱推送通知时出错:\n{response["data"]['error']}'
|
||||||
|
|
||||||
def CompanyWebHookBotPush(self, title, content):
|
def CompanyWebHookBotPush(self, title, content):
|
||||||
"""使用企业微信群机器人推送通知"""
|
"""使用企业微信群机器人推送通知"""
|
||||||
if Config.global_config.get(Config.global_config.notify_IfCompanyWebHookBot):
|
if Config.global_config.get(Config.global_config.notify_IfCompanyWebHookBot):
|
||||||
content = f'{title}\n{content}'
|
content = f"{title}\n{content}"
|
||||||
data = {
|
data = {"msgtype": "text", "text": {"content": content}}
|
||||||
"msgtype": "text",
|
|
||||||
"text": {
|
|
||||||
"content": content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
url=Config.global_config.get(Config.global_config.notify_CompanyWebHookBotUrl),
|
url=Config.global_config.get(
|
||||||
json=data
|
Config.global_config.notify_CompanyWebHookBotUrl
|
||||||
|
),
|
||||||
|
json=data,
|
||||||
)
|
)
|
||||||
if response.json()["errcode"] == 0:
|
if response.json()["errcode"] == 0:
|
||||||
logger.info("企业微信群机器人推送通知成功")
|
logger.info("企业微信群机器人推送通知成功")
|
||||||
@@ -154,7 +182,15 @@ class Notification:
|
|||||||
else:
|
else:
|
||||||
logger.info("企业微信群机器人推送通知失败")
|
logger.info("企业微信群机器人推送通知失败")
|
||||||
logger.error(response.json())
|
logger.error(response.json())
|
||||||
return f'使用企业微信群机器人推送通知时出错:\n{response.json()["errmsg"]}'
|
MainInfoBar.push_info_bar(
|
||||||
|
"error",
|
||||||
|
"企业微信群机器人通知推送失败",
|
||||||
|
f'使用企业微信群机器人推送通知时出错:\n{response.json()["errmsg"]}',
|
||||||
|
-1,
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
f'使用企业微信群机器人推送通知时出错:\n{response.json()["errmsg"]}'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
Notify = Notification()
|
Notify = Notification()
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import sqlite3
|
|||||||
import hashlib
|
import hashlib
|
||||||
import random
|
import random
|
||||||
import secrets
|
import secrets
|
||||||
|
import base64
|
||||||
|
import win32crypt
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
from Crypto.PublicKey import RSA
|
from Crypto.PublicKey import RSA
|
||||||
@@ -83,8 +85,8 @@ class CryptoHandler:
|
|||||||
private_key_local = AES_key.encrypt(pad(private_key.exportKey(), 32))
|
private_key_local = AES_key.encrypt(pad(private_key.exportKey(), 32))
|
||||||
(Config.app_path / "data/key/private_key.bin").write_bytes(private_key_local)
|
(Config.app_path / "data/key/private_key.bin").write_bytes(private_key_local)
|
||||||
|
|
||||||
def encryptx(self, note: str) -> bytes:
|
def AUTO_encryptor(self, note: str) -> bytes:
|
||||||
"""加密数据"""
|
"""使用AUTO_MAA的算法加密数据"""
|
||||||
|
|
||||||
# 读取RSA公钥
|
# 读取RSA公钥
|
||||||
public_key_local = RSA.import_key(
|
public_key_local = RSA.import_key(
|
||||||
@@ -95,8 +97,8 @@ class CryptoHandler:
|
|||||||
encrypted = cipher.encrypt(note.encode("utf-8"))
|
encrypted = cipher.encrypt(note.encode("utf-8"))
|
||||||
return encrypted
|
return encrypted
|
||||||
|
|
||||||
def decryptx(self, note: bytes, PASSWORD: str) -> str:
|
def AUTO_decryptor(self, note: bytes, PASSWORD: str) -> str:
|
||||||
"""解密数据"""
|
"""使用AUTO_MAA的算法解密数据"""
|
||||||
|
|
||||||
# 读入RSA私钥密文、盐与校验哈希值
|
# 读入RSA私钥密文、盐与校验哈希值
|
||||||
private_key_local = (
|
private_key_local = (
|
||||||
@@ -150,7 +152,9 @@ class CryptoHandler:
|
|||||||
# 使用旧管理密钥解密
|
# 使用旧管理密钥解密
|
||||||
user_data["Password"] = []
|
user_data["Password"] = []
|
||||||
for i in range(len(data)):
|
for i in range(len(data)):
|
||||||
user_data["Password"].append(self.decryptx(data[i][12], PASSWORD_old))
|
user_data["Password"].append(
|
||||||
|
self.AUTO_decryptor(data[i][12], PASSWORD_old)
|
||||||
|
)
|
||||||
cur.close()
|
cur.close()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
@@ -169,7 +173,7 @@ class CryptoHandler:
|
|||||||
cur.execute(
|
cur.execute(
|
||||||
"UPDATE adminx SET password = ? WHERE mode = ? AND uid = ?",
|
"UPDATE adminx SET password = ? WHERE mode = ? AND uid = ?",
|
||||||
(
|
(
|
||||||
self.encryptx(user_data["Password"][i]),
|
self.AUTO_encryptor(user_data["Password"][i]),
|
||||||
data[i][15],
|
data[i][15],
|
||||||
data[i][16],
|
data[i][16],
|
||||||
),
|
),
|
||||||
@@ -181,6 +185,27 @@ class CryptoHandler:
|
|||||||
cur.close()
|
cur.close()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
|
def win_encryptor(
|
||||||
|
self, note: str, description: str = None, entropy: bytes = None
|
||||||
|
) -> str:
|
||||||
|
"""使用Windows DPAPI加密数据"""
|
||||||
|
|
||||||
|
encrypted = win32crypt.CryptProtectData(
|
||||||
|
note.encode("utf-8"), description, entropy, None, None, 0
|
||||||
|
)
|
||||||
|
return base64.b64encode(encrypted).decode("utf-8")
|
||||||
|
|
||||||
|
def win_decryptor(self, note: str, entropy: bytes = None) -> str:
|
||||||
|
"""使用Windows DPAPI解密数据"""
|
||||||
|
|
||||||
|
if note == "":
|
||||||
|
return ""
|
||||||
|
|
||||||
|
decrypted = win32crypt.CryptUnprotectData(
|
||||||
|
base64.b64decode(note), entropy, None, None, 0
|
||||||
|
)
|
||||||
|
return decrypted[1].decode("utf-8")
|
||||||
|
|
||||||
def search_member(self) -> List[Dict[str, Union[Path, list]]]:
|
def search_member(self) -> List[Dict[str, Union[Path, list]]]:
|
||||||
"""搜索所有脚本实例及其用户数据库路径"""
|
"""搜索所有脚本实例及其用户数据库路径"""
|
||||||
|
|
||||||
@@ -197,7 +222,9 @@ class CryptoHandler:
|
|||||||
def check_PASSWORD(self, PASSWORD: str) -> bool:
|
def check_PASSWORD(self, PASSWORD: str) -> bool:
|
||||||
"""验证管理密钥"""
|
"""验证管理密钥"""
|
||||||
|
|
||||||
return bool(self.decryptx(self.encryptx(""), PASSWORD) != "管理密钥错误")
|
return bool(
|
||||||
|
self.AUTO_decryptor(self.AUTO_encryptor(""), PASSWORD) != "管理密钥错误"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
Crypto = CryptoHandler()
|
Crypto = CryptoHandler()
|
||||||
|
|||||||
@@ -44,14 +44,15 @@ from qfluentwidgets import (
|
|||||||
TimeEdit,
|
TimeEdit,
|
||||||
OptionsConfigItem,
|
OptionsConfigItem,
|
||||||
)
|
)
|
||||||
|
|
||||||
from typing import Union, List
|
from typing import Union, List
|
||||||
|
|
||||||
|
from app.services import Crypto
|
||||||
|
|
||||||
class InputMessageBox(MessageBoxBase):
|
|
||||||
|
class LineEditMessageBox(MessageBoxBase):
|
||||||
"""输入对话框"""
|
"""输入对话框"""
|
||||||
|
|
||||||
def __init__(self, parent, title: str, content: str, mode: str, list: list = None):
|
def __init__(self, parent, title: str, content: str, mode: str):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.title = SubtitleLabel(title)
|
self.title = SubtitleLabel(title)
|
||||||
|
|
||||||
@@ -60,10 +61,6 @@ class InputMessageBox(MessageBoxBase):
|
|||||||
self.input.setClearButtonEnabled(True)
|
self.input.setClearButtonEnabled(True)
|
||||||
elif mode == "密码":
|
elif mode == "密码":
|
||||||
self.input = PasswordLineEdit()
|
self.input = PasswordLineEdit()
|
||||||
elif mode == "选择":
|
|
||||||
self.input = ComboBox()
|
|
||||||
self.input.addItems(list)
|
|
||||||
self.input.setCurrentIndex(-1)
|
|
||||||
|
|
||||||
self.input.setPlaceholderText(content)
|
self.input.setPlaceholderText(content)
|
||||||
|
|
||||||
@@ -72,8 +69,8 @@ class InputMessageBox(MessageBoxBase):
|
|||||||
self.viewLayout.addWidget(self.input)
|
self.viewLayout.addWidget(self.input)
|
||||||
|
|
||||||
|
|
||||||
class SetMessageBox(MessageBoxBase):
|
class ComboBoxMessageBox(MessageBoxBase):
|
||||||
"""输入对话框"""
|
"""选择对话框"""
|
||||||
|
|
||||||
def __init__(self, parent, title: str, content: List[str], list: List[List[str]]):
|
def __init__(self, parent, title: str, content: List[str], list: List[List[str]]):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@@ -98,7 +95,7 @@ class SetMessageBox(MessageBoxBase):
|
|||||||
|
|
||||||
|
|
||||||
class LineEditSettingCard(SettingCard):
|
class LineEditSettingCard(SettingCard):
|
||||||
"""Setting card with switch button"""
|
"""Setting card with LineEdit"""
|
||||||
|
|
||||||
textChanged = Signal(str)
|
textChanged = Signal(str)
|
||||||
|
|
||||||
@@ -138,7 +135,49 @@ class LineEditSettingCard(SettingCard):
|
|||||||
self.LineEdit.setText(content)
|
self.LineEdit.setText(content)
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordLineEditSettingCard(SettingCard):
|
||||||
|
"""Setting card with PasswordLineEdit"""
|
||||||
|
|
||||||
|
textChanged = Signal(str)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
text,
|
||||||
|
icon: Union[str, QIcon, FluentIconBase],
|
||||||
|
title,
|
||||||
|
content=None,
|
||||||
|
configItem: ConfigItem = None,
|
||||||
|
parent=None,
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__(icon, title, content, parent)
|
||||||
|
self.configItem = configItem
|
||||||
|
self.LineEdit = PasswordLineEdit(self)
|
||||||
|
self.LineEdit.setMinimumWidth(250)
|
||||||
|
self.LineEdit.setPlaceholderText(text)
|
||||||
|
|
||||||
|
if configItem:
|
||||||
|
self.setValue(qconfig.get(configItem))
|
||||||
|
configItem.valueChanged.connect(self.setValue)
|
||||||
|
|
||||||
|
self.hBoxLayout.addWidget(self.LineEdit, 0, Qt.AlignRight)
|
||||||
|
self.hBoxLayout.addSpacing(16)
|
||||||
|
|
||||||
|
self.LineEdit.textChanged.connect(self.__textChanged)
|
||||||
|
|
||||||
|
def __textChanged(self, content: str):
|
||||||
|
self.setValue(Crypto.win_encryptor(content))
|
||||||
|
self.textChanged.emit(content)
|
||||||
|
|
||||||
|
def setValue(self, content: str):
|
||||||
|
if self.configItem:
|
||||||
|
qconfig.set(self.configItem, content)
|
||||||
|
|
||||||
|
self.LineEdit.setText(Crypto.win_decryptor(content))
|
||||||
|
|
||||||
|
|
||||||
class SpinBoxSettingCard(SettingCard):
|
class SpinBoxSettingCard(SettingCard):
|
||||||
|
"""Setting card with SpinBox"""
|
||||||
|
|
||||||
textChanged = Signal(int)
|
textChanged = Signal(int)
|
||||||
|
|
||||||
|
|||||||
@@ -59,10 +59,10 @@ import shutil
|
|||||||
from app.core import Config, MainInfoBar, Task_manager
|
from app.core import Config, MainInfoBar, Task_manager
|
||||||
from app.services import Crypto
|
from app.services import Crypto
|
||||||
from .Widget import (
|
from .Widget import (
|
||||||
InputMessageBox,
|
LineEditMessageBox,
|
||||||
LineEditSettingCard,
|
LineEditSettingCard,
|
||||||
SpinBoxSettingCard,
|
SpinBoxSettingCard,
|
||||||
SetMessageBox,
|
ComboBoxMessageBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -123,16 +123,15 @@ class MemberManager(QWidget):
|
|||||||
def add_setting_box(self):
|
def add_setting_box(self):
|
||||||
"""添加一个脚本实例"""
|
"""添加一个脚本实例"""
|
||||||
|
|
||||||
choice = InputMessageBox(
|
choice = ComboBoxMessageBox(
|
||||||
self.window(),
|
self.window(),
|
||||||
"选择一个脚本类型并添加相应脚本实例",
|
"选择一个脚本类型以添加相应脚本实例",
|
||||||
"选择脚本类型",
|
["选择脚本类型"],
|
||||||
"选择",
|
[["MAA"]],
|
||||||
["MAA"],
|
|
||||||
)
|
)
|
||||||
if choice.exec() and choice.input.currentIndex() != -1:
|
if choice.exec() and choice.input[0].currentIndex() != -1:
|
||||||
|
|
||||||
if choice.input.currentText() == "MAA":
|
if choice.input[0].currentText() == "MAA":
|
||||||
|
|
||||||
index = len(self.member_manager.search_member()) + 1
|
index = len(self.member_manager.search_member()) + 1
|
||||||
|
|
||||||
@@ -295,7 +294,7 @@ class MemberManager(QWidget):
|
|||||||
def show_password(self):
|
def show_password(self):
|
||||||
|
|
||||||
if Config.PASSWORD == "":
|
if Config.PASSWORD == "":
|
||||||
choice = InputMessageBox(
|
choice = LineEditMessageBox(
|
||||||
self.window(),
|
self.window(),
|
||||||
"请输入管理密钥",
|
"请输入管理密钥",
|
||||||
"管理密钥",
|
"管理密钥",
|
||||||
@@ -694,7 +693,7 @@ class MaaSettingBox(QWidget):
|
|||||||
user_list = [_[0] for _ in data if _[15] == "simple"]
|
user_list = [_[0] for _ in data if _[15] == "simple"]
|
||||||
set_list = ["自定义基建"]
|
set_list = ["自定义基建"]
|
||||||
|
|
||||||
choice = SetMessageBox(
|
choice = ComboBoxMessageBox(
|
||||||
self.window(),
|
self.window(),
|
||||||
"用户选项配置",
|
"用户选项配置",
|
||||||
["选择要配置的用户", "选择要配置的选项"],
|
["选择要配置的用户", "选择要配置的选项"],
|
||||||
@@ -734,7 +733,7 @@ class MaaSettingBox(QWidget):
|
|||||||
user_list = [_[0] for _ in data if _[15] == "beta"]
|
user_list = [_[0] for _ in data if _[15] == "beta"]
|
||||||
set_list = ["MAA日常配置", "MAA剿灭配置"]
|
set_list = ["MAA日常配置", "MAA剿灭配置"]
|
||||||
|
|
||||||
choice = SetMessageBox(
|
choice = ComboBoxMessageBox(
|
||||||
self.window(),
|
self.window(),
|
||||||
"用户选项配置",
|
"用户选项配置",
|
||||||
["选择要配置的用户", "选择要配置的选项"],
|
["选择要配置的用户", "选择要配置的选项"],
|
||||||
@@ -989,7 +988,7 @@ class MaaSettingBox(QWidget):
|
|||||||
item = QTableWidgetItem("******")
|
item = QTableWidgetItem("******")
|
||||||
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
|
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
|
||||||
else:
|
else:
|
||||||
result = Crypto.decryptx(value, Config.PASSWORD)
|
result = Crypto.AUTO_decryptor(value, Config.PASSWORD)
|
||||||
item = QTableWidgetItem(result)
|
item = QTableWidgetItem(result)
|
||||||
if result == "管理密钥错误":
|
if result == "管理密钥错误":
|
||||||
item.setFlags(
|
item.setFlags(
|
||||||
@@ -1056,7 +1055,7 @@ class MaaSettingBox(QWidget):
|
|||||||
item = QTableWidgetItem("******")
|
item = QTableWidgetItem("******")
|
||||||
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
|
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
|
||||||
else:
|
else:
|
||||||
result = Crypto.decryptx(value, Config.PASSWORD)
|
result = Crypto.AUTO_decryptor(value, Config.PASSWORD)
|
||||||
item = QTableWidgetItem(result)
|
item = QTableWidgetItem(result)
|
||||||
if result == "管理密钥错误":
|
if result == "管理密钥错误":
|
||||||
item.setFlags(
|
item.setFlags(
|
||||||
@@ -1127,7 +1126,7 @@ class MaaSettingBox(QWidget):
|
|||||||
games[game_in.strip()] = game_out.strip()
|
games[game_in.strip()] = game_out.strip()
|
||||||
text = games.get(text, text)
|
text = games.get(text, text)
|
||||||
if item.column() == 11: # 密码
|
if item.column() == 11: # 密码
|
||||||
text = Crypto.encryptx(text)
|
text = Crypto.AUTO_encryptor(text)
|
||||||
|
|
||||||
# 保存至本地数据库
|
# 保存至本地数据库
|
||||||
if text != "":
|
if text != "":
|
||||||
@@ -1145,7 +1144,7 @@ class MaaSettingBox(QWidget):
|
|||||||
self.update_user_info("normal")
|
self.update_user_info("normal")
|
||||||
return None
|
return None
|
||||||
if item.column() == 6: # 密码
|
if item.column() == 6: # 密码
|
||||||
text = Crypto.encryptx(text)
|
text = Crypto.AUTO_encryptor(text)
|
||||||
|
|
||||||
# 保存至本地数据库
|
# 保存至本地数据库
|
||||||
if text != "":
|
if text != "":
|
||||||
@@ -1227,7 +1226,7 @@ class MaaSettingBox(QWidget):
|
|||||||
Config.cur.execute(
|
Config.cur.execute(
|
||||||
"INSERT INTO adminx VALUES('新用户','手机号码(官服)/B站ID(B服)','Official',-1,'y','2000-01-01','1-7','-','-','n','n','n',?,'无',0,?,?)",
|
"INSERT INTO adminx VALUES('新用户','手机号码(官服)/B站ID(B服)','Official',-1,'y','2000-01-01','1-7','-','-','n','n','n',?,'无',0,?,?)",
|
||||||
(
|
(
|
||||||
Crypto.encryptx("未设置"),
|
Crypto.AUTO_encryptor("未设置"),
|
||||||
set_book[0],
|
set_book[0],
|
||||||
set_book[1],
|
set_book[1],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import requests
|
|||||||
from app.core import Config, MainInfoBar
|
from app.core import Config, MainInfoBar
|
||||||
from app.services import Crypto, System
|
from app.services import Crypto, System
|
||||||
from app.utils import Updater
|
from app.utils import Updater
|
||||||
from .Widget import InputMessageBox, LineEditSettingCard
|
from .Widget import LineEditMessageBox, LineEditSettingCard, PasswordLineEditSettingCard
|
||||||
|
|
||||||
|
|
||||||
class Setting(QWidget):
|
class Setting(QWidget):
|
||||||
@@ -136,7 +136,7 @@ class Setting(QWidget):
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
choice = InputMessageBox(
|
choice = LineEditMessageBox(
|
||||||
self.window(),
|
self.window(),
|
||||||
"未检测到管理密钥,请设置您的管理密钥",
|
"未检测到管理密钥,请设置您的管理密钥",
|
||||||
"管理密钥",
|
"管理密钥",
|
||||||
@@ -162,7 +162,7 @@ class Setting(QWidget):
|
|||||||
|
|
||||||
while if_change:
|
while if_change:
|
||||||
|
|
||||||
choice = InputMessageBox(
|
choice = LineEditMessageBox(
|
||||||
self.window(),
|
self.window(),
|
||||||
"请输入旧的管理密钥",
|
"请输入旧的管理密钥",
|
||||||
"旧管理密钥",
|
"旧管理密钥",
|
||||||
@@ -177,7 +177,7 @@ class Setting(QWidget):
|
|||||||
# 获取新的管理密钥
|
# 获取新的管理密钥
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
choice = InputMessageBox(
|
choice = LineEditMessageBox(
|
||||||
self.window(),
|
self.window(),
|
||||||
"请输入新的管理密钥",
|
"请输入新的管理密钥",
|
||||||
"新管理密钥",
|
"新管理密钥",
|
||||||
@@ -557,7 +557,7 @@ class NotifySettingCard(HeaderCardWidget):
|
|||||||
super().__init__(
|
super().__init__(
|
||||||
FluentIcon.SETTING,
|
FluentIcon.SETTING,
|
||||||
"推送邮件通知",
|
"推送邮件通知",
|
||||||
"通过AUTO_MAA官方通知服务邮箱推送任务结果",
|
"通过电子邮箱推送任务结果",
|
||||||
parent,
|
parent,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -567,18 +567,42 @@ class NotifySettingCard(HeaderCardWidget):
|
|||||||
content="是否启用邮件通知功能",
|
content="是否启用邮件通知功能",
|
||||||
configItem=Config.global_config.notify_IfSendMail,
|
configItem=Config.global_config.notify_IfSendMail,
|
||||||
)
|
)
|
||||||
self.card_MailAddress = LineEditSettingCard(
|
self.card_SMTPServerAddress = LineEditSettingCard(
|
||||||
text="请输入邮箱地址",
|
text="请输入SMTP服务器地址",
|
||||||
icon=FluentIcon.PAGE_RIGHT,
|
icon=FluentIcon.PAGE_RIGHT,
|
||||||
title="邮箱地址",
|
title="SMTP服务器地址",
|
||||||
|
content="发信邮箱的SMTP服务器地址",
|
||||||
|
configItem=Config.global_config.notify_SMTPServerAddress,
|
||||||
|
)
|
||||||
|
self.card_FromAddress = LineEditSettingCard(
|
||||||
|
text="请输入发信邮箱地址",
|
||||||
|
icon=FluentIcon.PAGE_RIGHT,
|
||||||
|
title="发信邮箱地址",
|
||||||
|
content="发送通知的邮箱地址",
|
||||||
|
configItem=Config.global_config.notify_FromAddress,
|
||||||
|
)
|
||||||
|
self.card_AuthorizationCode = PasswordLineEditSettingCard(
|
||||||
|
text="请输入发信邮箱授权码",
|
||||||
|
icon=FluentIcon.PAGE_RIGHT,
|
||||||
|
title="发信邮箱授权码",
|
||||||
|
content="发送通知的邮箱授权码",
|
||||||
|
configItem=Config.global_config.notify_AuthorizationCode,
|
||||||
|
)
|
||||||
|
self.card_ToAddress = LineEditSettingCard(
|
||||||
|
text="请输入收信邮箱地址",
|
||||||
|
icon=FluentIcon.PAGE_RIGHT,
|
||||||
|
title="收信邮箱地址",
|
||||||
content="接收通知的邮箱地址",
|
content="接收通知的邮箱地址",
|
||||||
configItem=Config.global_config.notify_MailAddress,
|
configItem=Config.global_config.notify_ToAddress,
|
||||||
)
|
)
|
||||||
|
|
||||||
widget = QWidget()
|
widget = QWidget()
|
||||||
Layout = QVBoxLayout(widget)
|
Layout = QVBoxLayout(widget)
|
||||||
Layout.addWidget(self.card_IfSendMail)
|
Layout.addWidget(self.card_IfSendMail)
|
||||||
Layout.addWidget(self.card_MailAddress)
|
Layout.addWidget(self.card_SMTPServerAddress)
|
||||||
|
Layout.addWidget(self.card_FromAddress)
|
||||||
|
Layout.addWidget(self.card_AuthorizationCode)
|
||||||
|
Layout.addWidget(self.card_ToAddress)
|
||||||
self.viewLayout.setContentsMargins(0, 0, 0, 0)
|
self.viewLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
self.viewLayout.setSpacing(0)
|
self.viewLayout.setSpacing(0)
|
||||||
self.addGroupWidget(widget)
|
self.addGroupWidget(widget)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"main_version": "4.2.2.5",
|
"main_version": "4.2.3.0",
|
||||||
"updater_version": "1.1.1.3",
|
"updater_version": "1.1.1.3",
|
||||||
"announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n- 初步完成`托管bilibili游戏隐私政策`功能\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n- 修复窗口记忆功能失效问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置",
|
"announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n- 初步完成`托管bilibili游戏隐私政策`功能\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n- 修复窗口记忆功能失效问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置\n- 邮箱推送功能调整,改由用户提供发信邮箱",
|
||||||
"proxy_list": [
|
"proxy_list": [
|
||||||
"",
|
"",
|
||||||
"https://gitproxy.click/",
|
"https://gitproxy.click/",
|
||||||
|
|||||||
Reference in New Issue
Block a user