chore: 性能优化
- 调度队列历史记录归入配置类管理 - 添加.gitignore - 工作流删除冗余部分 - 自动代理与人工排查结束后MAA恢复到全局配置 #40 - 网络相关操作由子线程执行
This commit is contained in:
34
.github/workflows/build-app.yml
vendored
34
.github/workflows/build-app.yml
vendored
@@ -102,20 +102,8 @@ jobs:
|
||||
with:
|
||||
name: version_info
|
||||
path: ./
|
||||
- name: Check if release exists
|
||||
id: check_if_release_exists
|
||||
run: |
|
||||
release_id=$(gh release view $(sed 's/\r$//g' <(head -n 1 version_info.txt)) --json id --jq .id || true)
|
||||
if [[ -z $release_id ]]; then
|
||||
echo "release_exists=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "release_exists=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
- name: Create release
|
||||
id: create_release
|
||||
if: steps.check_if_release_exists.outputs.release_exists == 'false'
|
||||
run: |
|
||||
set -xe
|
||||
shopt -s nullglob
|
||||
@@ -124,22 +112,12 @@ jobs:
|
||||
NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 version_info.txt))"
|
||||
NOTES_TAIL="\`\`\`本release通过GitHub Actions自动构建\`\`\`"
|
||||
NOTES="$NOTES_MAIN<br><br>$NOTES_TAIL"
|
||||
gh release create "$TAGNAME" --target "main" --title "$NAME" --notes "$NOTES" artifacts/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
- name: Update release
|
||||
id: update_release
|
||||
if: steps.check_if_release_exists.outputs.release_exists == 'true'
|
||||
run: |
|
||||
set -xe
|
||||
shopt -s nullglob
|
||||
NAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
||||
TAGNAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
||||
NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 version_info.txt))"
|
||||
NOTES_TAIL="\`\`\`本release通过GitHub Actions自动构建\`\`\`"
|
||||
NOTES="$NOTES_MAIN<br><br>$NOTES_TAIL"
|
||||
gh release delete "$TAGNAME" --yes
|
||||
gh release create "$TAGNAME" --target "main" --title "$NAME" --notes "$NOTES" artifacts/*
|
||||
if [ "${{ github.ref_name }}" == "main" ]; then
|
||||
PRERELEASE_FLAG=""
|
||||
else
|
||||
PRERELEASE_FLAG="--prerelease"
|
||||
fi
|
||||
gh release create "$TAGNAME" --target "main" --title "$NAME" --notes "$NOTES" $PRERELEASE_FLAG artifacts/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
- name: Trigger MirrorChyanUploading
|
||||
|
||||
174
.github/workflows/build-pre.yml
vendored
174
.github/workflows/build-pre.yml
vendored
@@ -1,174 +0,0 @@
|
||||
# <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
|
||||
|
||||
name: Build AUTO_MAA_Pre
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
pre_check:
|
||||
name: Pre Checks
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Repo Check
|
||||
id: repo_check
|
||||
run: |
|
||||
if [[ "$GITHUB_REPOSITORY" != "DLmaster361/AUTO_MAA" ]]; then
|
||||
echo "When forking this repository to make your own builds, you have to adjust this check."
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
build_AUTO_MAA:
|
||||
runs-on: windows-latest
|
||||
needs: pre_check
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install flake8 pytest
|
||||
pip install -r requirements.txt
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
||||
- name: Package
|
||||
id: package
|
||||
run: |
|
||||
copy app\utils\package.py .\
|
||||
python package.py
|
||||
- name: Read version
|
||||
id: read_version
|
||||
run: |
|
||||
$MAIN_VERSION=(Get-Content -Path "version_info.txt" -TotalCount 1).Trim()
|
||||
"AUTO_MAA_version=$MAIN_VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
$UPDATER_VERSION=(Get-Content -Path "version_info.txt" -TotalCount 2 | Select-Object -Index 1).Trim()
|
||||
"updater_version=$UPDATER_VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: AUTO_MAA_${{ env.AUTO_MAA_version }}
|
||||
path: |
|
||||
AUTO_MAA_${{ env.AUTO_MAA_version }}.zip
|
||||
- name: Upload Version_Info Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: version_info
|
||||
path: version_info.txt
|
||||
publish_prerelease:
|
||||
name: Publish prerelease
|
||||
needs: build_AUTO_MAA
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: AUTO_MAA_*
|
||||
merge-multiple: true
|
||||
path: artifacts
|
||||
- name: Download Version_Info
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: version_info
|
||||
path: ./
|
||||
- name: Check if release exists
|
||||
id: check_if_release_exists
|
||||
run: |
|
||||
release_id=$(gh release view $(sed 's/\r$//g' <(head -n 1 version_info.txt)) --json id --jq .id || true)
|
||||
if [[ -z $release_id ]]; then
|
||||
echo "release_exists=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "release_exists=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
- name: Create prerelease
|
||||
id: create_prerelease
|
||||
if: steps.check_if_release_exists.outputs.release_exists == 'false'
|
||||
run: |
|
||||
set -xe
|
||||
shopt -s nullglob
|
||||
NAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
||||
TAGNAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
||||
NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 version_info.txt))"
|
||||
NOTES_TAIL="\`\`\`本release通过GitHub Actions自动构建\`\`\`"
|
||||
NOTES="$NOTES_MAIN<br><br>$NOTES_TAIL"
|
||||
gh release create "$TAGNAME" --target "main" --title "$NAME" --notes "$NOTES" --prerelease artifacts/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
- name: Update prerelease
|
||||
id: update_prerelease
|
||||
if: steps.check_if_release_exists.outputs.release_exists == 'true'
|
||||
run: |
|
||||
set -xe
|
||||
shopt -s nullglob
|
||||
NAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
||||
TAGNAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
||||
NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 version_info.txt))"
|
||||
NOTES_TAIL="\`\`\`本release通过GitHub Actions自动构建\`\`\`"
|
||||
NOTES="$NOTES_MAIN<br><br>$NOTES_TAIL"
|
||||
gh release delete "$TAGNAME" --yes
|
||||
gh release create "$TAGNAME" --target "main" --title "$NAME" --notes "$NOTES" --prerelease artifacts/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
- name: Trigger MirrorChyanUploading
|
||||
run: |
|
||||
gh workflow run --repo $GITHUB_REPOSITORY mirrorchyan
|
||||
gh workflow run --repo $GITHUB_REPOSITORY mirrorchyan_release_note
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Setup SSH Key
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts
|
||||
- name: Upload Release to Server
|
||||
run: |
|
||||
scp -r artifacts/* ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }}:/home/user/files/AUTO_MAA/
|
||||
- name: Install obsutil
|
||||
run: |
|
||||
wget https://obs-community.obs.cn-north-1.myhuaweicloud.com/obsutil/current/obsutil_linux_amd64.tar.gz
|
||||
tar -xzvf obsutil_linux_amd64.tar.gz --strip-components=1
|
||||
chmod 755 obsutil
|
||||
./obsutil version
|
||||
- name: Upload Release to Huawei OBS
|
||||
env:
|
||||
OBS_AK: ${{ secrets.OBS_AK }}
|
||||
OBS_SK: ${{ secrets.OBS_SK }}
|
||||
OBS_ENDPOINT: ${{ secrets.OBS_ENDPOINT }}
|
||||
OBS_BUCKET: ${{ secrets.OBS_BUCKET }}
|
||||
run: |
|
||||
./obsutil config -i $OBS_AK -k $OBS_SK -e $OBS_ENDPOINT
|
||||
./obsutil cp artifacts/ obs://$OBS_BUCKET/releases/ -r -f
|
||||
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
config/
|
||||
data/
|
||||
debug/
|
||||
history/
|
||||
resources/notice.json
|
||||
resources/theme_image.json
|
||||
resources/images/Home/BannerTheme.jpg
|
||||
@@ -31,6 +31,7 @@ __license__ = "GPL-3.0 license"
|
||||
|
||||
from .config import QueueConfig, MaaConfig, MaaUserConfig, Config
|
||||
from .main_info_bar import MainInfoBar
|
||||
from .network import Network
|
||||
from .task_manager import Task, TaskManager
|
||||
from .timer import MainTimer
|
||||
|
||||
@@ -40,6 +41,7 @@ __all__ = [
|
||||
"MaaConfig",
|
||||
"MaaUserConfig",
|
||||
"MainInfoBar",
|
||||
"Network",
|
||||
"Task",
|
||||
"TaskManager",
|
||||
"MainTimer",
|
||||
|
||||
@@ -32,8 +32,6 @@ import json
|
||||
import sys
|
||||
import shutil
|
||||
import re
|
||||
import requests
|
||||
import time
|
||||
import base64
|
||||
from datetime import datetime, timedelta
|
||||
from collections import defaultdict
|
||||
@@ -53,6 +51,8 @@ from qfluentwidgets import (
|
||||
from urllib.parse import urlparse
|
||||
from typing import Union, Dict, List
|
||||
|
||||
from .network import Network
|
||||
|
||||
|
||||
class UrlListValidator(ConfigValidator):
|
||||
"""Url list validator"""
|
||||
@@ -319,6 +319,13 @@ class QueueConfig(QConfig):
|
||||
self.queue_Member_9 = OptionsConfigItem("Queue", "Member_9", "禁用")
|
||||
self.queue_Member_10 = OptionsConfigItem("Queue", "Member_10", "禁用")
|
||||
|
||||
self.Data_LastProxyTime = ConfigItem(
|
||||
"Data", "LastProxyTime", "2000-01-01 00:00:00"
|
||||
)
|
||||
self.Data_LastProxyHistory = ConfigItem(
|
||||
"Data", "LastProxyHistory", "暂无历史运行记录"
|
||||
)
|
||||
|
||||
def toDict(self, serialize=True):
|
||||
"""convert config items to `dict`"""
|
||||
items = {}
|
||||
@@ -599,7 +606,7 @@ class MaaUserConfig(QConfig):
|
||||
|
||||
class AppConfig(GlobalConfig):
|
||||
|
||||
VERSION = "4.3.4.1"
|
||||
VERSION = "4.3.4.2"
|
||||
|
||||
gameid_refreshed = Signal()
|
||||
PASSWORD_refreshed = Signal()
|
||||
@@ -614,7 +621,6 @@ class AppConfig(GlobalConfig):
|
||||
self.log_path = self.app_path / "debug/AUTO_MAA.log"
|
||||
self.database_path = self.app_path / "data/data.db"
|
||||
self.config_path = self.app_path / "config/config.json"
|
||||
self.history_path = self.app_path / "history/main.json"
|
||||
self.key_path = self.app_path / "data/key"
|
||||
self.gameid_path = self.app_path / "data/gameid.txt"
|
||||
self.version_path = self.app_path / "resources/version.json"
|
||||
@@ -675,21 +681,18 @@ class AppConfig(GlobalConfig):
|
||||
def get_gameid(self) -> None:
|
||||
|
||||
# 从MAA服务器获取活动关卡信息
|
||||
for _ in range(3):
|
||||
try:
|
||||
response = requests.get(
|
||||
"https://ota.maa.plus/MaaAssistantArknights/api/gui/StageActivity.json",
|
||||
timeout=10,
|
||||
)
|
||||
gameid_infos: List[
|
||||
Dict[str, Union[str, Dict[str, Union[str, int]]]]
|
||||
] = response.json()["Official"]["sideStoryStage"]
|
||||
break
|
||||
except Exception as e:
|
||||
err = e
|
||||
time.sleep(0.1)
|
||||
Network.set_info(
|
||||
mode="get",
|
||||
url="https://ota.maa.plus/MaaAssistantArknights/api/gui/StageActivity.json",
|
||||
)
|
||||
Network.start()
|
||||
Network.loop.exec()
|
||||
if Network.stutus_code == 200:
|
||||
gameid_infos: List[Dict[str, Union[str, Dict[str, Union[str, int]]]]] = (
|
||||
Network.response_json["Official"]["sideStoryStage"]
|
||||
)
|
||||
else:
|
||||
logger.warning(f"无法从MAA服务器获取活动关卡信息:{err}")
|
||||
logger.warning(f"无法从MAA服务器获取活动关卡信息:{Network.error_message}")
|
||||
gameid_infos = []
|
||||
|
||||
gameid_dict = {"value": [], "text": []}
|
||||
@@ -1540,24 +1543,15 @@ class AppConfig(GlobalConfig):
|
||||
def save_history(self, key: str, content: dict) -> None:
|
||||
"""保存历史记录"""
|
||||
|
||||
history = {}
|
||||
if self.history_path.exists():
|
||||
with self.history_path.open(mode="r", encoding="utf-8") as f:
|
||||
history = json.load(f)
|
||||
history[key] = content
|
||||
with self.history_path.open(mode="w", encoding="utf-8") as f:
|
||||
json.dump(history, f, ensure_ascii=False, indent=4)
|
||||
|
||||
def get_history(self, key: str) -> dict:
|
||||
"""获取历史记录"""
|
||||
|
||||
history = {}
|
||||
if self.history_path.exists():
|
||||
with self.history_path.open(mode="r", encoding="utf-8") as f:
|
||||
history = json.load(f)
|
||||
return history.get(
|
||||
key, {"Time": "0000-00-00 00:00", "History": "暂无历史运行记录"}
|
||||
)
|
||||
if key in self.queue_dict:
|
||||
self.queue_dict[key]["Config"].set(
|
||||
self.queue_dict[key]["Config"].Data_LastProxyTime, content["Time"]
|
||||
)
|
||||
self.queue_dict[key]["Config"].set(
|
||||
self.queue_dict[key]["Config"].Data_LastProxyHistory, content["History"]
|
||||
)
|
||||
else:
|
||||
logger.warning(f"保存历史记录时未找到调度队列: {key}")
|
||||
|
||||
|
||||
Config = AppConfig()
|
||||
|
||||
@@ -27,10 +27,7 @@ v4.3
|
||||
|
||||
from loguru import logger
|
||||
from PySide6.QtCore import Qt
|
||||
from qfluentwidgets import (
|
||||
InfoBar,
|
||||
InfoBarPosition,
|
||||
)
|
||||
from qfluentwidgets import InfoBar, InfoBarPosition
|
||||
|
||||
|
||||
class _MainInfoBar:
|
||||
|
||||
120
app/core/network.py
Normal file
120
app/core/network.py
Normal file
@@ -0,0 +1,120 @@
|
||||
# <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.3
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
from PySide6.QtCore import QThread, QEventLoop, QTimer
|
||||
import time
|
||||
import requests
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class _Network(QThread):
|
||||
|
||||
max_retries = 3
|
||||
timeout = 10
|
||||
backoff_factor = 0.1
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
self.if_running = False
|
||||
self.mode = None
|
||||
self.url = None
|
||||
self.loop = QEventLoop()
|
||||
self.wait_loop = QEventLoop()
|
||||
|
||||
@logger.catch
|
||||
def run(self) -> None:
|
||||
"""运行网络请求线程"""
|
||||
|
||||
self.if_running = True
|
||||
|
||||
print(self.url)
|
||||
|
||||
if self.mode == "get":
|
||||
self.get_json(self.url)
|
||||
elif self.mode == "get_file":
|
||||
self.get_file(self.url, self.path)
|
||||
|
||||
self.if_running = False
|
||||
|
||||
def set_info(self, mode: str, url: str, path: Path = None) -> None:
|
||||
"""设置网络请求信息"""
|
||||
|
||||
while self.if_running:
|
||||
QTimer.singleShot(self.backoff_factor * 1000, self.wait_loop.quit)
|
||||
self.wait_loop.exec()
|
||||
|
||||
self.mode = mode
|
||||
self.url = url
|
||||
self.path = path
|
||||
|
||||
self.stutus_code = None
|
||||
self.response_json = None
|
||||
self.error_message = None
|
||||
|
||||
def get_json(self, url: str) -> None:
|
||||
"""通过get方法获取json数据"""
|
||||
|
||||
for _ in range(self.max_retries):
|
||||
try:
|
||||
response = requests.get(url, timeout=self.timeout)
|
||||
self.stutus_code = response.status_code
|
||||
self.response_json = response.json()
|
||||
self.error_message = None
|
||||
break
|
||||
except Exception as e:
|
||||
self.stutus_code = response.status_code if response else None
|
||||
self.response_json = None
|
||||
self.error_message = str(e)
|
||||
time.sleep(self.backoff_factor)
|
||||
|
||||
self.loop.quit()
|
||||
print("quited")
|
||||
|
||||
def get_file(self, url: str, path: Path) -> None:
|
||||
"""通过get方法获取json数据"""
|
||||
|
||||
try:
|
||||
response = requests.get(url, timeout=10)
|
||||
if response.status_code == 200:
|
||||
with open(path, "wb") as file:
|
||||
file.write(response.content)
|
||||
self.stutus_code = response.status_code
|
||||
else:
|
||||
self.stutus_code = response.status_code
|
||||
self.error_message = "下载失败"
|
||||
|
||||
except Exception as e:
|
||||
self.stutus_code = response.status_code if response else None
|
||||
self.error_message = str(e)
|
||||
|
||||
self.loop.quit()
|
||||
print("quited-----")
|
||||
|
||||
|
||||
Network = _Network()
|
||||
@@ -229,37 +229,33 @@ class _TaskManager(QObject):
|
||||
self.task_dict[name].quit()
|
||||
self.task_dict[name].wait()
|
||||
|
||||
def remove_task(self, mode: str, name: str, logs: str):
|
||||
def remove_task(self, mode: str, name: str, logs: list):
|
||||
"""任务结束后的处理"""
|
||||
|
||||
logger.info(f"任务结束:{name}")
|
||||
MainInfoBar.push_info_bar("info", "任务结束", name, 3000)
|
||||
|
||||
self.task_dict[name].deleteLater()
|
||||
|
||||
if len(logs) > 0:
|
||||
time = logs[0][1]["Time"]
|
||||
history = ""
|
||||
for log in logs:
|
||||
Config.save_history(log[0], log[1])
|
||||
history += (
|
||||
f"任务名称:{log[0]},{log[1]["History"].replace("\n","\n ")}\n"
|
||||
)
|
||||
Config.save_history(name, {"Time": time, "History": history})
|
||||
else:
|
||||
Config.save_history(
|
||||
name,
|
||||
{
|
||||
"Time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"History": "没有任务被执行",
|
||||
},
|
||||
)
|
||||
|
||||
self.task_dict.pop(name)
|
||||
Config.running_list.remove(name)
|
||||
|
||||
if "调度队列" in name and "人工排查" not in mode:
|
||||
|
||||
if len(logs) > 0:
|
||||
time = logs[0][1]["Time"]
|
||||
history = ""
|
||||
for log in logs:
|
||||
history += f"任务名称:{log[0]},{log[1]["History"].replace("\n","\n ")}\n"
|
||||
Config.save_history(name, {"Time": time, "History": history})
|
||||
else:
|
||||
Config.save_history(
|
||||
name,
|
||||
{
|
||||
"Time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"History": "没有任务被执行",
|
||||
},
|
||||
)
|
||||
|
||||
if (
|
||||
Config.queue_dict[name]["Config"].get(
|
||||
Config.queue_dict[name]["Config"].queueSet_AfterAccomplish
|
||||
|
||||
@@ -64,8 +64,6 @@ class _MainTimer(QWidget):
|
||||
if not info["Config"].get(info["Config"].queueSet_Enabled):
|
||||
continue
|
||||
|
||||
history = Config.get_history(name)
|
||||
|
||||
data = info["Config"].toDict()
|
||||
|
||||
time_set = [
|
||||
@@ -77,7 +75,8 @@ class _MainTimer(QWidget):
|
||||
curtime = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
if (
|
||||
curtime[11:16] in time_set
|
||||
and curtime != history["Time"][:16]
|
||||
and curtime
|
||||
!= info["Config"].get(info["Config"].Data_LastProxyTime)[:16]
|
||||
and name not in Config.running_list
|
||||
):
|
||||
|
||||
|
||||
@@ -597,6 +597,9 @@ class MaaManager(QObject):
|
||||
if self.isInterruptionRequested:
|
||||
System.kill_process(self.maa_exe_path)
|
||||
|
||||
# 复原MAA配置文件
|
||||
shutil.copy(self.config_path / "Default/gui.json", self.maa_set_path)
|
||||
|
||||
# 更新用户数据
|
||||
updated_info = {_[2]: self.data[_[2]] for _ in self.user_list}
|
||||
self.update_user_info.emit(self.config_path.name, updated_info)
|
||||
|
||||
@@ -870,6 +870,31 @@ class TimeEditSettingCard(SettingCard):
|
||||
self.TimeEdit.setTime(QTime.fromString(value, "HH:mm"))
|
||||
|
||||
|
||||
class HistoryCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, qconfig: QConfig, configItem: ConfigItem, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setTitle("历史运行记录")
|
||||
|
||||
self.qconfig = qconfig
|
||||
self.configItem = configItem
|
||||
|
||||
self.text = TextBrowser()
|
||||
self.text.setMinimumHeight(300)
|
||||
|
||||
if configItem:
|
||||
self.setValue(self.qconfig.get(configItem))
|
||||
configItem.valueChanged.connect(self.setValue)
|
||||
|
||||
self.viewLayout.addWidget(self.text)
|
||||
|
||||
def setValue(self, content: str):
|
||||
if self.configItem:
|
||||
self.qconfig.set(self.configItem, content)
|
||||
|
||||
self.text.setPlainText(content)
|
||||
|
||||
|
||||
class UrlItem(QWidget):
|
||||
"""Url item"""
|
||||
|
||||
|
||||
@@ -143,9 +143,11 @@ class DispatchCenter(QWidget):
|
||||
task.update_log_text.connect(
|
||||
self.script_list["主调度台"].info.log_text.text.setText
|
||||
)
|
||||
task.accomplish.connect(lambda: self.disconnect_main_board(task.name))
|
||||
task.accomplish.connect(
|
||||
lambda logs: self.disconnect_main_board(task.name, logs)
|
||||
)
|
||||
|
||||
def disconnect_main_board(self, name: str) -> None:
|
||||
def disconnect_main_board(self, name: str, logs: list) -> None:
|
||||
"""断开主调度台"""
|
||||
|
||||
self.script_list["主调度台"].top_bar.Lable.hide()
|
||||
@@ -156,9 +158,15 @@ class DispatchCenter(QWidget):
|
||||
self.script_list["主调度台"].top_bar.button.clicked.connect(
|
||||
self.script_list["主调度台"].top_bar.start_task
|
||||
)
|
||||
self.script_list["主调度台"].info.log_text.text.setText(
|
||||
Config.get_history(name)["History"]
|
||||
)
|
||||
if len(logs) > 0:
|
||||
history = ""
|
||||
for log in logs:
|
||||
history += (
|
||||
f"任务名称:{log[0]},{log[1]["History"].replace("\n","\n ")}\n"
|
||||
)
|
||||
self.script_list["主调度台"].info.log_text.text.setText(history)
|
||||
else:
|
||||
self.script_list["主调度台"].info.log_text.text.setText("没有任务被执行")
|
||||
|
||||
def update_top_bar(self):
|
||||
"""更新顶栏"""
|
||||
|
||||
@@ -45,13 +45,11 @@ from qfluentwidgets import (
|
||||
)
|
||||
import re
|
||||
import shutil
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from app.core import Config, MainInfoBar
|
||||
from app.core import Config, MainInfoBar, Network
|
||||
from .Widget import Banner, IconButton
|
||||
|
||||
|
||||
@@ -199,24 +197,21 @@ class Home(QWidget):
|
||||
elif Config.get(Config.function_HomeImageMode) == "主题图像":
|
||||
|
||||
# 从远程服务器获取最新主题图像
|
||||
for _ in range(3):
|
||||
try:
|
||||
response = requests.get(
|
||||
"https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/theme_image.json",
|
||||
timeout=10,
|
||||
)
|
||||
theme_image = response.json()
|
||||
break
|
||||
except Exception as e:
|
||||
err = e
|
||||
time.sleep(0.1)
|
||||
Network.set_info(
|
||||
mode="get",
|
||||
url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/theme_image.json",
|
||||
)
|
||||
Network.start()
|
||||
Network.loop.exec()
|
||||
if Network.stutus_code == 200:
|
||||
theme_image = Network.response_json
|
||||
else:
|
||||
logger.error(f"获取最新主题图像时出错:\n{err}")
|
||||
logger.warning(f"获取最新主题图像时出错:{Network.error_message}")
|
||||
MainInfoBar.push_info_bar(
|
||||
"error",
|
||||
"主题图像获取失败",
|
||||
f"获取最新主题图像信息时出错!",
|
||||
-1,
|
||||
"warning",
|
||||
"获取最新主题图像时出错",
|
||||
f"网络错误:{Network.stutus_code}",
|
||||
5000,
|
||||
)
|
||||
return None
|
||||
|
||||
@@ -239,15 +234,22 @@ class Home(QWidget):
|
||||
> time_local
|
||||
):
|
||||
|
||||
response = requests.get(theme_image["url"], timeout=10)
|
||||
if response.status_code == 200:
|
||||
Network.set_info(
|
||||
mode="get_file",
|
||||
url=theme_image["url"],
|
||||
path=Config.app_path / "resources/images/Home/BannerTheme.jpg",
|
||||
)
|
||||
Network.start()
|
||||
Network.loop.exec()
|
||||
|
||||
with open(
|
||||
Config.app_path / "resources/images/Home/BannerTheme.jpg", "wb"
|
||||
) as file:
|
||||
file.write(response.content)
|
||||
if Network.stutus_code == 200:
|
||||
|
||||
logger.info(f"主题图像「{theme_image["name"]}」下载成功")
|
||||
with (Config.app_path / "resources/theme_image.json").open(
|
||||
mode="w", encoding="utf-8"
|
||||
) as f:
|
||||
json.dump(theme_image, f, ensure_ascii=False, indent=4)
|
||||
|
||||
logger.success(f"主题图像「{theme_image["name"]}」下载成功")
|
||||
MainInfoBar.push_info_bar(
|
||||
"success",
|
||||
"主题图像下载成功",
|
||||
@@ -257,19 +259,14 @@ class Home(QWidget):
|
||||
|
||||
else:
|
||||
|
||||
logger.error("主题图像下载失败")
|
||||
logger.warning(f"下载最新主题图像时出错:{Network.error_message}")
|
||||
MainInfoBar.push_info_bar(
|
||||
"error",
|
||||
"主题图像下载失败",
|
||||
f"主题图像下载失败:{response.status_code}",
|
||||
-1,
|
||||
"warning",
|
||||
"下载最新主题图像时出错",
|
||||
f"网络错误:{Network.stutus_code}",
|
||||
5000,
|
||||
)
|
||||
|
||||
with (Config.app_path / "resources/theme_image.json").open(
|
||||
mode="w", encoding="utf-8"
|
||||
) as f:
|
||||
json.dump(theme_image, f, ensure_ascii=False, indent=4)
|
||||
|
||||
else:
|
||||
|
||||
logger.info("主题图像已是最新")
|
||||
|
||||
@@ -49,15 +49,13 @@ from qfluentwidgets import (
|
||||
PrimaryToolButton,
|
||||
)
|
||||
from PySide6.QtCore import Qt, Signal
|
||||
import requests
|
||||
import time
|
||||
from datetime import datetime
|
||||
from functools import partial
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import shutil
|
||||
|
||||
from app.core import Config, MainInfoBar, TaskManager, MaaConfig, MaaUserConfig
|
||||
from app.core import Config, MainInfoBar, TaskManager, MaaConfig, MaaUserConfig, Network
|
||||
from app.services import Crypto
|
||||
from app.utils import DownloadManager
|
||||
from .Widget import (
|
||||
@@ -337,21 +335,18 @@ class MemberManager(QWidget):
|
||||
return None
|
||||
|
||||
# 从mirrorc服务器获取最新版本信息
|
||||
for _ in range(3):
|
||||
try:
|
||||
response = requests.get(
|
||||
"https://mirrorchyan.com/api/resources/MAA/latest?user_agent=AutoMaaGui&os=win&arch=x64&channel=stable",
|
||||
timeout=10,
|
||||
)
|
||||
maa_info = response.json()
|
||||
break
|
||||
except Exception as e:
|
||||
err = e
|
||||
time.sleep(0.1)
|
||||
Network.set_info(
|
||||
mode="get",
|
||||
url="https://mirrorchyan.com/api/resources/MAA/latest?user_agent=AutoMaaGui&os=win&arch=x64&channel=stable",
|
||||
)
|
||||
Network.start()
|
||||
Network.loop.exec()
|
||||
if Network.stutus_code == 200:
|
||||
maa_info = Network.response_json
|
||||
else:
|
||||
choice = MessageBox(
|
||||
"错误",
|
||||
f"获取版本信息时出错:\n{err}",
|
||||
f"获取版本信息时出错:\n{Network.error_message}",
|
||||
self.window(),
|
||||
)
|
||||
choice.cancelButton.hide()
|
||||
|
||||
@@ -39,7 +39,6 @@ from qfluentwidgets import (
|
||||
FluentIcon,
|
||||
MessageBox,
|
||||
HeaderCardWidget,
|
||||
TextBrowser,
|
||||
CommandBar,
|
||||
)
|
||||
from PySide6.QtCore import Qt
|
||||
@@ -52,6 +51,7 @@ from .Widget import (
|
||||
LineEditSettingCard,
|
||||
TimeEditSettingCard,
|
||||
NoOptionComboBoxSettingCard,
|
||||
HistoryCard,
|
||||
)
|
||||
|
||||
|
||||
@@ -387,7 +387,11 @@ class QueueManager(QWidget):
|
||||
self.queue_set = self.QueueSetSettingCard(self.config, self)
|
||||
self.time = self.TimeSettingCard(self.config, self)
|
||||
self.task = self.TaskSettingCard(self.config, self)
|
||||
self.history = self.HistoryCard(f"调度队列_{uid}", self)
|
||||
self.history = HistoryCard(
|
||||
qconfig=self.config,
|
||||
configItem=self.config.Data_LastProxyHistory,
|
||||
parent=self,
|
||||
)
|
||||
|
||||
content_layout.addWidget(self.queue_set)
|
||||
content_layout.addWidget(self.time)
|
||||
@@ -704,16 +708,3 @@ class QueueManager(QWidget):
|
||||
Layout.addWidget(self.card_Member_10)
|
||||
|
||||
self.viewLayout.addLayout(Layout)
|
||||
|
||||
class HistoryCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, name: str, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setTitle("历史运行记录")
|
||||
|
||||
self.text = TextBrowser()
|
||||
self.text.setMinimumHeight(300)
|
||||
history = Config.get_history(name)
|
||||
self.text.setPlainText(history["History"])
|
||||
|
||||
self.viewLayout.addWidget(self.text)
|
||||
|
||||
@@ -26,11 +26,7 @@ v4.3
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import (
|
||||
QWidget,
|
||||
QApplication,
|
||||
QVBoxLayout,
|
||||
)
|
||||
from PySide6.QtWidgets import QWidget, QVBoxLayout
|
||||
from PySide6.QtCore import Qt
|
||||
from qfluentwidgets import (
|
||||
ScrollArea,
|
||||
@@ -48,14 +44,13 @@ import re
|
||||
import json
|
||||
import time
|
||||
import shutil
|
||||
import requests
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from packaging import version
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Union
|
||||
|
||||
from app.core import Config, MainInfoBar
|
||||
from app.core import Config, MainInfoBar, Network
|
||||
from app.services import Crypto, System, Notify
|
||||
from .Widget import (
|
||||
SwitchSettingCard,
|
||||
@@ -93,7 +88,9 @@ class Setting(QWidget):
|
||||
)
|
||||
self.start.card_IfSelfStart.checkedChanged.connect(System.set_SelfStart)
|
||||
self.security.card_changePASSWORD.clicked.connect(self.change_PASSWORD)
|
||||
self.updater.card_CheckUpdate.clicked.connect(self.check_update)
|
||||
self.updater.card_CheckUpdate.clicked.connect(
|
||||
lambda: self.check_update(if_click=True)
|
||||
)
|
||||
self.other.card_Notice.clicked.connect(self.show_notice)
|
||||
|
||||
content_layout.addWidget(self.function)
|
||||
@@ -263,35 +260,36 @@ class Setting(QWidget):
|
||||
if choice.exec():
|
||||
break
|
||||
|
||||
def check_update(self) -> None:
|
||||
def check_update(self, if_click: bool = False) -> None:
|
||||
"""检查版本更新,调起文件下载进程"""
|
||||
|
||||
current_version = list(map(int, Config.VERSION.split(".")))
|
||||
|
||||
# 从远程服务器获取最新版本信息
|
||||
for _ in range(3):
|
||||
try:
|
||||
response = requests.get(
|
||||
f"https://mirrorchyan.com/api/resources/AUTO_MAA/latest?user_agent=AutoMaaGui¤t_version={version_text(current_version)}&cdk={Crypto.win_decryptor(Config.get(Config.update_MirrorChyanCDK))}&channel={Config.get(Config.update_UpdateType)}",
|
||||
timeout=10,
|
||||
)
|
||||
version_info: Dict[str, Union[int, str, Dict[str, str]]] = (
|
||||
response.json()
|
||||
)
|
||||
break
|
||||
except Exception as e:
|
||||
err = e
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
choice = MessageBox(
|
||||
"错误",
|
||||
f"获取版本信息时出错:\n{err}",
|
||||
self.window(),
|
||||
if Network.if_running and if_click:
|
||||
MainInfoBar.push_info_bar(
|
||||
"warning", "请求速度过快", "上个网络请求还未结束,请稍等片刻", 5000
|
||||
)
|
||||
choice.cancelButton.hide()
|
||||
choice.buttonLayout.insertStretch(1)
|
||||
if choice.exec():
|
||||
return None
|
||||
return None
|
||||
# 从远程服务器获取最新版本信息
|
||||
Network.set_info(
|
||||
mode="get",
|
||||
url=f"https://mirrorchyan.com/api/resources/AUTO_MAA/latest?user_agent=AutoMaaGui¤t_version={version_text(current_version)}&cdk={Crypto.win_decryptor(Config.get(Config.update_MirrorChyanCDK))}&channel={Config.get(Config.update_UpdateType)}",
|
||||
)
|
||||
Network.start()
|
||||
Network.loop.exec()
|
||||
if Network.stutus_code == 200:
|
||||
version_info: Dict[str, Union[int, str, Dict[str, str]]] = (
|
||||
Network.response_json
|
||||
)
|
||||
else:
|
||||
logger.warning(f"获取版本信息时出错:{Network.error_message}")
|
||||
MainInfoBar.push_info_bar(
|
||||
"warning",
|
||||
"获取版本信息时出错",
|
||||
f"网络错误:{Network.stutus_code}",
|
||||
5000,
|
||||
)
|
||||
return None
|
||||
|
||||
if version_info["code"] != 0:
|
||||
|
||||
@@ -415,32 +413,26 @@ class Setting(QWidget):
|
||||
else:
|
||||
MainInfoBar.push_info_bar("success", "更新检查", "已是最新版本~", 3000)
|
||||
|
||||
def show_notice(self, if_show: bool = True):
|
||||
def show_notice(self, if_show: bool = True) -> None:
|
||||
"""显示公告"""
|
||||
|
||||
# 从远程服务器获取最新公告
|
||||
for _ in range(3):
|
||||
try:
|
||||
response = requests.get(
|
||||
"https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/notice.json",
|
||||
timeout=10,
|
||||
)
|
||||
notice = response.json()
|
||||
break
|
||||
except Exception as e:
|
||||
err = e
|
||||
time.sleep(0.1)
|
||||
Network.set_info(
|
||||
mode="get",
|
||||
url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/notice.json",
|
||||
)
|
||||
Network.start()
|
||||
Network.loop.exec()
|
||||
if Network.stutus_code == 200:
|
||||
notice = Network.response_json
|
||||
else:
|
||||
logger.warning(f"获取最新公告时出错:\n{err}")
|
||||
if if_show:
|
||||
choice = Dialog(
|
||||
"网络错误",
|
||||
f"获取最新公告时出错:\n{err}",
|
||||
self,
|
||||
)
|
||||
choice.cancelButton.hide()
|
||||
choice.buttonLayout.insertStretch(1)
|
||||
choice.exec()
|
||||
logger.warning(f"获取最新公告时出错:{Network.error_message}")
|
||||
MainInfoBar.push_info_bar(
|
||||
"warning",
|
||||
"获取最新公告时出错",
|
||||
f"网络错误:{Network.stutus_code}",
|
||||
5000,
|
||||
)
|
||||
return None
|
||||
|
||||
if (Config.app_path / "resources/notice.json").exists():
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
{
|
||||
"main_version": "4.3.4.1",
|
||||
"main_version": "4.3.4.2",
|
||||
"updater_version": "1.0.0.0",
|
||||
"announcement": "\n## 新增功能\n- 屏蔽MuMu模拟器开屏广告功能上线\n- 更新器支持多线程下载\n- 添加强制关闭ADB与模拟器等增强任务项\n## 修复BUG\n- 修复统计信息HTML模板公招匹配错误\n- 修复密码显示按钮动画异常\n- 修复`检测到MAA未能实际执行任务`报错被异常屏蔽\n- 修复MAA超时判定异常失效\n## 程序优化\n- 关机等电源操作添加100s倒计时\n- 人工排查弹窗方法优化\n- 人工排查时自动屏蔽静默操作\n- 公告样式优化",
|
||||
"version_info": {
|
||||
"4.3.4.2": {
|
||||
"程序优化": [
|
||||
"调度队列历史记录归入配置类管理",
|
||||
"添加.gitignore",
|
||||
"工作流删除冗余部分",
|
||||
"自动代理与人工排查结束后MAA恢复到全局配置 #40",
|
||||
"网络相关操作由子线程执行"
|
||||
]
|
||||
},
|
||||
"4.3.4.1": {
|
||||
"新增功能": [
|
||||
"开始任务前自动释放ADB端口"
|
||||
|
||||
Reference in New Issue
Block a user