mirror of
https://github.com/KenanZhu/AutoLibrary.git
synced 2026-06-18 07:23:03 +08:00
feat(autoscript): 将预处理脚本重构为 AutoScript DSL,新增可视化编排与预览对话框
This commit is contained in:
@@ -17,10 +17,10 @@ from PySide6.QtWidgets import (
|
||||
QGroupBox, QSizePolicy
|
||||
)
|
||||
|
||||
from utils.PreprocEngine import PreprocEngine
|
||||
from utils.AutoScriptEngine import AutoScriptEngine
|
||||
|
||||
|
||||
VARIABLE_META = PreprocEngine.VARIABLE_META
|
||||
VARIABLE_META = AutoScriptEngine.VARIABLE_META
|
||||
|
||||
_VAR_COMBO_ITEMS = [
|
||||
(display, varname, vartype)
|
||||
@@ -637,7 +637,7 @@ class ConditionalBlock(QGroupBox):
|
||||
return len(self._actionWidgets)
|
||||
|
||||
|
||||
class ALPreprocOrchDialog(QDialog):
|
||||
class ALAutoScriptOrchDialog(QDialog):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -661,7 +661,7 @@ class ALPreprocOrchDialog(QDialog):
|
||||
self
|
||||
):
|
||||
|
||||
self.setWindowTitle("预处理指令编排 - AutoLibrary")
|
||||
self.setWindowTitle("AutoScript 指令编排 - AutoLibrary")
|
||||
self.setMinimumSize(420, 400)
|
||||
self.setModal(True)
|
||||
mainLayout = QVBoxLayout(self)
|
||||
@@ -31,41 +31,41 @@ class ALScriptHighlighter(QSyntaxHighlighter):
|
||||
keywordFmt.setForeground(QColor("#316BFF"))
|
||||
keywordFmt.setFontWeight(QFont.Weight.Bold)
|
||||
for kw in ["IF", "ELSE IF", "ELSE", "ENDIF", "END IF",
|
||||
"SET", "PASS", "THEN", ".TRUE.", ".FALSE."]:
|
||||
"SET", "PASS", "THEN"]:
|
||||
pattern = r"\b" + kw.replace(" ", r"\s+") + r"\b"
|
||||
self._rules.append((pattern, keywordFmt))
|
||||
|
||||
literalFmt = QTextCharFormat()
|
||||
literalFmt.setForeground(QColor("#C2185B"))
|
||||
literalFmt.setFontWeight(QFont.Weight.Bold)
|
||||
for lit in [".TRUE.", ".FALSE."]:
|
||||
self._rules.append((r"\b" + lit.replace(".", r"\.") + r"\b", literalFmt))
|
||||
opFmt = QTextCharFormat()
|
||||
opFmt.setForeground(QColor("#9C27B0"))
|
||||
for op in [r"\.EQ\.", r"\.NEQ\.", r"\.BGT\.", r"\.BLT\.",
|
||||
r"\.BGE\.", r"\.BLE\.", r"\.ADD\.", r"\.SUB\."]:
|
||||
self._rules.append((op, opFmt))
|
||||
|
||||
varFmt = QTextCharFormat()
|
||||
varFmt.setForeground(QColor("#E65100"))
|
||||
for var in ["RESERVE_BEGIN_TIME", "RESERVE_END_TIME",
|
||||
"RESERVE_DATE", "USERNAME", "USER_ENABLE",
|
||||
"PRIORITY", "CURRENT_TIME", "CURRENT_DATE"]:
|
||||
self._rules.append((r"\b" + var + r"\b", varFmt))
|
||||
|
||||
funcFmt = QTextCharFormat()
|
||||
funcFmt.setForeground(QColor("#2E7D32"))
|
||||
self._rules.append((r"\bTIME\([^)]+\)", funcFmt))
|
||||
self._rules.append((r"\bDATE\([^)]+\)", funcFmt))
|
||||
|
||||
strFmt = QTextCharFormat()
|
||||
strFmt.setForeground(QColor("#388E3C"))
|
||||
self._rules.append((r"'[^']*'", strFmt))
|
||||
|
||||
numFmt = QTextCharFormat()
|
||||
numFmt.setForeground(QColor("#D32F2F"))
|
||||
self._rules.append((r"\b\d+\b", numFmt))
|
||||
|
||||
commentFmt = QTextCharFormat()
|
||||
commentFmt.setForeground(QColor("#999999"))
|
||||
commentFmt.setFontItalic(True)
|
||||
self._rules.append((r"//[^\n]*", commentFmt))
|
||||
|
||||
|
||||
def highlightBlock(
|
||||
self,
|
||||
text
|
||||
@@ -79,7 +79,7 @@ class ALScriptHighlighter(QSyntaxHighlighter):
|
||||
self.setFormat(start, length, fmt)
|
||||
|
||||
|
||||
class ALScriptPreviewDialog(QDialog):
|
||||
class ALAutoScriptPreviewDialog(QDialog):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -88,7 +88,6 @@ class ALScriptPreviewDialog(QDialog):
|
||||
):
|
||||
|
||||
super().__init__(parent)
|
||||
|
||||
self.__fontSize = 13
|
||||
|
||||
self.modifyUi()
|
||||
@@ -104,7 +103,7 @@ class ALScriptPreviewDialog(QDialog):
|
||||
self
|
||||
):
|
||||
|
||||
self.setWindowTitle("预处理脚本预览 - AutoLibrary")
|
||||
self.setWindowTitle("AutoScript 预览 - AutoLibrary")
|
||||
self.setMinimumSize(520, 360)
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
@@ -136,7 +135,6 @@ class ALScriptPreviewDialog(QDialog):
|
||||
self._copyBtn.setToolTip("复制脚本")
|
||||
toolbarLayout.addWidget(self._copyBtn)
|
||||
layout.addLayout(toolbarLayout)
|
||||
|
||||
self._textEdit = QPlainTextEdit(self)
|
||||
self._textEdit.setReadOnly(True)
|
||||
self._textEdit.setLineWrapMode(
|
||||
@@ -18,7 +18,7 @@ from PySide6.QtCore import (
|
||||
from base.MsgBase import MsgBase
|
||||
from operators.AutoLib import AutoLib
|
||||
from utils.JSONReader import JSONReader
|
||||
from utils.PreprocEngine import PreprocEngine
|
||||
from utils.AutoScriptEngine import AutoScriptEngine
|
||||
|
||||
|
||||
class AutoLibWorker(MsgBase, QThread):
|
||||
@@ -161,6 +161,7 @@ class TimerTaskWorker(AutoLibWorker):
|
||||
self.autoLibWorkerIsFinished.connect(self.onTimerTaskIsFinished)
|
||||
self.autoLibWorkerFinishedWithError.connect(self.onTimerTaskFinishedWithError)
|
||||
|
||||
|
||||
def run(
|
||||
self
|
||||
):
|
||||
@@ -173,7 +174,7 @@ class TimerTaskWorker(AutoLibWorker):
|
||||
try:
|
||||
if not self.loadConfigs():
|
||||
raise Exception("配置文件加载失败")
|
||||
self._applyRepeatPreproc()
|
||||
self._applyRepeatAutoScript()
|
||||
auto_lib = AutoLib(
|
||||
self._input_queue,
|
||||
self._output_queue,
|
||||
@@ -206,15 +207,15 @@ class TimerTaskWorker(AutoLibWorker):
|
||||
self.timerTaskWorkerIsFinished.emit(False, self.__timer_task)
|
||||
|
||||
|
||||
def _applyRepeatPreproc(
|
||||
def _applyRepeatAutoScript(
|
||||
self
|
||||
):
|
||||
|
||||
preproc_script = self.__timer_task.get("repeat_preproc", "")
|
||||
if not preproc_script or not preproc_script.strip():
|
||||
auto_script = self.__timer_task.get("repeat_auto_script", "")
|
||||
if not auto_script or not auto_script.strip():
|
||||
return
|
||||
self._showTrace(
|
||||
f"检测到重复定时任务预处理脚本, 开始执行...",
|
||||
f"检测到重复定时任务 AutoScript, 开始执行...",
|
||||
no_log=True
|
||||
)
|
||||
groups = self._user_config.get("groups", [])
|
||||
@@ -224,15 +225,15 @@ class TimerTaskWorker(AutoLibWorker):
|
||||
continue
|
||||
for user in group.get("users", []):
|
||||
try:
|
||||
PreprocEngine.execute(preproc_script, user)
|
||||
AutoScriptEngine.execute(auto_script, user)
|
||||
affected_count += 1
|
||||
except ValueError as e:
|
||||
self._showTrace(
|
||||
f"预处理脚本执行错误 (用户 {user['username']}): {e}",
|
||||
f"AutoScript 执行错误 (用户 {user['username']}): {e}",
|
||||
self.TraceLevel.ERROR
|
||||
)
|
||||
self._showLog(
|
||||
f"预处理脚本执行完毕, "
|
||||
f"AutoScript 执行完毕, "
|
||||
f"影响 {affected_count} 个用户",
|
||||
self.TraceLevel.INFO
|
||||
)
|
||||
|
||||
@@ -12,11 +12,12 @@ import uuid
|
||||
from enum import Enum
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from PySide6.QtCore import Slot, QDateTime
|
||||
from PySide6.QtCore import Slot, QDateTime, QUrl
|
||||
from PySide6.QtGui import QDesktopServices
|
||||
from PySide6.QtWidgets import QLabel, QDialog, QWidget, QSpinBox, QHBoxLayout, QVBoxLayout, QGridLayout, QDateTimeEdit, QGroupBox, QPushButton
|
||||
|
||||
from gui.resources.ui.Ui_ALTimerTaskAddDialog import Ui_ALTimerTaskAddDialog
|
||||
from gui.ALPreprocOrchDialog import ALPreprocOrchDialog
|
||||
from gui.ALAutoScriptOrchDialog import ALAutoScriptOrchDialog
|
||||
from utils.TimerUtils import TimerUtils
|
||||
|
||||
|
||||
@@ -87,32 +88,46 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
||||
self.TimerConfigLayout.addWidget(self.RelativeTimerWidget)
|
||||
self.RelativeTimerWidget.setVisible(False)
|
||||
|
||||
self.PreprocGroupBox = QGroupBox("预处理脚本")
|
||||
self.PreprocLayout = QVBoxLayout(self.PreprocGroupBox)
|
||||
self.PreprocLayout.setContentsMargins(3, 3, 3, 3)
|
||||
self.PreprocLayout.setSpacing(3)
|
||||
|
||||
preproc_btn_layout = QHBoxLayout()
|
||||
self.PreprocSetButton = QPushButton("设置预处理指令")
|
||||
self.PreprocSetButton.setMinimumHeight(25)
|
||||
self.PreprocSetButton.setFixedWidth(130)
|
||||
preproc_btn_layout.addWidget(self.PreprocSetButton)
|
||||
self.PreprocPreviewButton = QPushButton("预览")
|
||||
self.PreprocPreviewButton.setMinimumHeight(25)
|
||||
self.PreprocPreviewButton.setFixedWidth(60)
|
||||
self.PreprocPreviewButton.setEnabled(False)
|
||||
preproc_btn_layout.addWidget(self.PreprocPreviewButton)
|
||||
preproc_btn_layout.addStretch()
|
||||
self.PreprocStatusLabel = QLabel("未设置")
|
||||
self.PreprocStatusLabel.setStyleSheet("color: #969696;")
|
||||
self.PreprocStatusLabel.setFixedHeight(25)
|
||||
preproc_btn_layout.addWidget(self.PreprocStatusLabel)
|
||||
self.PreprocLayout.addLayout(preproc_btn_layout)
|
||||
self.AutoScriptGroupBox = QGroupBox("AutoScript 指令")
|
||||
self.AutoScriptLayout = QVBoxLayout(self.AutoScriptGroupBox)
|
||||
self.AutoScriptLayout.setContentsMargins(3, 3, 3, 3)
|
||||
self.AutoScriptLayout.setSpacing(3)
|
||||
autoScriptBtnLayout = QHBoxLayout()
|
||||
self.AutoScriptSetButton = QPushButton("设置指令")
|
||||
self.AutoScriptSetButton.setMinimumHeight(25)
|
||||
self.AutoScriptSetButton.setFixedWidth(130)
|
||||
autoScriptBtnLayout.addWidget(self.AutoScriptSetButton)
|
||||
self.AutoScriptPreviewButton = QPushButton("预览")
|
||||
self.AutoScriptPreviewButton.setMinimumHeight(25)
|
||||
self.AutoScriptPreviewButton.setFixedWidth(60)
|
||||
self.AutoScriptPreviewButton.setEnabled(False)
|
||||
autoScriptBtnLayout.addWidget(self.AutoScriptPreviewButton)
|
||||
autoScriptBtnLayout.addStretch()
|
||||
self.AutoScriptHelpButton = QPushButton("?")
|
||||
self.AutoScriptHelpButton.setFixedSize(20, 20)
|
||||
self.AutoScriptHelpButton.setToolTip(
|
||||
"AutoScript 是一种轻量级 DSL\n"
|
||||
"用于在重复定时任务执行前,对用户的预约数据进行预处理\n"
|
||||
"\n"
|
||||
"点击查看完整在线文档"
|
||||
)
|
||||
self.AutoScriptHelpButton.setStyleSheet(
|
||||
"QPushButton { border-radius: 10px; border: 1px solid #999; "
|
||||
"font-weight: bold; color: #555; }"
|
||||
"QPushButton:hover { background-color: #E0E0E0; }"
|
||||
)
|
||||
autoScriptBtnLayout.addWidget(self.AutoScriptHelpButton)
|
||||
self.AutoScriptStatusLabel = QLabel("未设置")
|
||||
self.AutoScriptStatusLabel.setStyleSheet("color: #969696;")
|
||||
self.AutoScriptStatusLabel.setFixedHeight(25)
|
||||
autoScriptBtnLayout.addWidget(self.AutoScriptStatusLabel)
|
||||
self.AutoScriptLayout.addLayout(autoScriptBtnLayout)
|
||||
self.ALAddTimerTaskLayout.insertWidget(
|
||||
self.ALAddTimerTaskLayout.indexOf(self.TaskConfigGroupBox) + 1,
|
||||
self.PreprocGroupBox
|
||||
self.AutoScriptGroupBox
|
||||
)
|
||||
self.__repeat_preproc_script = ""
|
||||
self.AutoScriptGroupBox.setVisible(False)
|
||||
self.__auto_script = ""
|
||||
|
||||
|
||||
def connectSignals(
|
||||
@@ -123,35 +138,44 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
||||
self.ConfirmButton.clicked.connect(self.accept)
|
||||
self.TimerTypeComboBox.currentIndexChanged.connect(self.onTimerTypeComboBoxIndexChanged)
|
||||
self.RepeatCheckBox.toggled.connect(self.onRepeatCheckBoxToggled)
|
||||
self.PreprocSetButton.clicked.connect(self._onSetPreproc)
|
||||
self.PreprocPreviewButton.clicked.connect(self._onPreviewPreproc)
|
||||
|
||||
self.AutoScriptSetButton.clicked.connect(self._onSetAutoScript)
|
||||
self.AutoScriptPreviewButton.clicked.connect(self._onPreviewAutoScript)
|
||||
self.AutoScriptHelpButton.clicked.connect(self._onAutoScriptHelp)
|
||||
|
||||
@Slot()
|
||||
def _onSetPreproc(self):
|
||||
dlg = ALPreprocOrchDialog(self, existingScript=self.__repeat_preproc_script)
|
||||
def _onSetAutoScript(self):
|
||||
dlg = ALAutoScriptOrchDialog(self, existingScript=self.__auto_script)
|
||||
if dlg.exec() == QDialog.DialogCode.Accepted:
|
||||
script = dlg.getScript()
|
||||
self.__repeat_preproc_script = script
|
||||
self.__auto_script = script
|
||||
if script:
|
||||
self.PreprocStatusLabel.setText("已设置")
|
||||
self.PreprocStatusLabel.setStyleSheet("color: #4CAF50;")
|
||||
self.PreprocPreviewButton.setEnabled(True)
|
||||
self.AutoScriptStatusLabel.setText("已设置")
|
||||
self.AutoScriptStatusLabel.setStyleSheet("color: #4CAF50;")
|
||||
self.AutoScriptPreviewButton.setEnabled(True)
|
||||
else:
|
||||
self.PreprocStatusLabel.setText("未设置")
|
||||
self.PreprocStatusLabel.setStyleSheet("color: #969696;")
|
||||
self.PreprocPreviewButton.setEnabled(False)
|
||||
self.AutoScriptStatusLabel.setText("未设置")
|
||||
self.AutoScriptStatusLabel.setStyleSheet("color: #969696;")
|
||||
self.AutoScriptPreviewButton.setEnabled(False)
|
||||
dlg.deleteLater()
|
||||
|
||||
@Slot()
|
||||
def _onPreviewAutoScript(self):
|
||||
if not self.__auto_script:
|
||||
return
|
||||
from gui.ALAutoScriptPrevDialog import ALAutoScriptPreviewDialog
|
||||
dlg = ALAutoScriptPreviewDialog(self, self.__auto_script)
|
||||
dlg.exec()
|
||||
dlg.deleteLater()
|
||||
|
||||
|
||||
@Slot()
|
||||
def _onPreviewPreproc(self):
|
||||
if not self.__repeat_preproc_script:
|
||||
return
|
||||
from gui.ALPreProcPrevDialog import ALScriptPreviewDialog
|
||||
dlg = ALScriptPreviewDialog(self, self.__repeat_preproc_script)
|
||||
dlg.exec()
|
||||
dlg.deleteLater()
|
||||
def _onAutoScriptHelp(
|
||||
self
|
||||
):
|
||||
|
||||
QDesktopServices.openUrl(
|
||||
QUrl("https://www.autolibrary.kenanzhu.com/manuals/autoscript")
|
||||
)
|
||||
|
||||
|
||||
def getTimerTask(
|
||||
@@ -186,7 +210,7 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
||||
"status": ALTimerTaskStatus.PENDING,
|
||||
"executed": False,
|
||||
"repeat": self.RepeatCheckBox.isChecked(),
|
||||
"repeat_preproc": self.__repeat_preproc_script,
|
||||
"repeat_auto_script": self.__auto_script,
|
||||
}
|
||||
if task_data["repeat"]:
|
||||
task_data["history"] = [] # repeat history
|
||||
@@ -240,4 +264,5 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
||||
self.ThuCheckBox.setEnabled(checked)
|
||||
self.FriCheckBox.setEnabled(checked)
|
||||
self.SatCheckBox.setEnabled(checked)
|
||||
self.SunCheckBox.setEnabled(checked)
|
||||
self.SunCheckBox.setEnabled(checked)
|
||||
self.AutoScriptGroupBox.setVisible(checked)
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
- ALSeatMapTable: Seat map table class.
|
||||
- ALSeatMapSelectDialog: Seat map select dialog class.
|
||||
- ALTimerTaskAddDialog: Timer task add dialog class.
|
||||
- ALPreprocOrchDialog: Preprocessing script orchestration dialog class.
|
||||
- ALAutoScriptOrchDialog: AutoScript orchestration dialog class.
|
||||
- ALTimerTaskHistoryDialog: Timer task history dialog class.
|
||||
- ALTimerTaskManageWidget: Timer task manage widget class.
|
||||
- ALUserTreeWidget: User tree widget class.
|
||||
|
||||
Reference in New Issue
Block a user