From 2ca74495615318ea7367b7c56f4b312b333bcb85 Mon Sep 17 00:00:00 2001 From: xiaoming <2014500726@smail.xtu.edu.cn> Date: Tue, 3 Sep 2024 18:57:02 +0800 Subject: [PATCH] Add record script feature Signed-off-by: xiaoming <2014500726@smail.xtu.edu.cn> --- CHANGELOG.md | 4 ++ docs/changelog.md | 2 + src/mainwindow.cpp | 54 +++++++++++++++++++++-- src/sessionswindow/sessionswindow.cpp | 62 +++++++++++++++++++++++++++ src/sessionswindow/sessionswindow.h | 8 ++++ 5 files changed, 127 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dac8c645..21d71582 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,16 @@ en-US: - Automatically use the default configuration if the Profile does not exist on Windows - Add ToolTip to the connection bar - Add system beep support +- Add record script feature +- Fix the small probability memory leak problem zh-CN: - Windows下Profile如果不存在则自动使用默认配置 - 增加连接条ToolTip显示 - 增加系统响铃支持 +- 增加记录脚本功能 +- 修复可能存在的小概率内存泄漏问题 ## [[V0.5.0](https://github.com/QQxiaoming/quardCRT/releases/tag/V0.5.0)] - 2024-08-26 diff --git a/docs/changelog.md b/docs/changelog.md index 5d94378c..82dc995e 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,8 @@ - Automatically use the default configuration if the Profile does not exist on Windows - Add ToolTip to the connection bar - Add system beep support +- Add record script feature +- Fix the small probability memory leak problem ## [[V0.5.0](https://github.com/QQxiaoming/quardCRT/releases/tag/V0.5.0)] - 2024-08-26 diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 039a02e1..4b03748e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -371,6 +371,10 @@ CentralWidget::CentralWidget(QString dir, StartupUIMode mode, QLocale lang, bool if(sessionsWindow->getMainWidget() == widget) { logSessionAction->setChecked(sessionsWindow->isLog()); rawLogSessionAction->setChecked(sessionsWindow->isRawLog()); + bool isRS = sessionsWindow->isRecordingScript(); + startRecordingScriptAction->setEnabled(!isRS); + stopRecordingScriptAction->setEnabled(isRS); + canlcelRecordingScriptAction->setEnabled(isRS); if(hexViewAction->isChecked()) { connect(sessionsWindow,&SessionsWindow::hexDataDup, hexViewWindow,&HexViewWindow::recvData); @@ -938,6 +942,9 @@ CentralWidget::CentralWidget(QString dir, StartupUIMode mode, QLocale lang, bool #else runAction->setEnabled(false); cancelAction->setEnabled(false); + startRecordingScriptAction->setEnabled(false); + stopRecordingScriptAction->setEnabled(false); + canlcelRecordingScriptAction->setEnabled(false); #endif #if defined(Q_OS_MACOS) if(mainWindow) { @@ -1126,9 +1133,6 @@ CentralWidget::CentralWidget(QString dir, StartupUIMode mode, QLocale lang, bool }); // TODO:Unimplemented functions are temporarily closed - startRecordingScriptAction->setEnabled(false); - stopRecordingScriptAction->setEnabled(false); - canlcelRecordingScriptAction->setEnabled(false); createPublicKeyAction->setEnabled(false); publickeyManagerAction->setEnabled(false); tileAction->setEnabled(false); @@ -2195,8 +2199,10 @@ void CentralWidget::menuAndToolBarInit(void) { startRecordingScriptAction = new QAction(this); scriptMenu->addAction(startRecordingScriptAction); stopRecordingScriptAction = new QAction(this); + stopRecordingScriptAction->setEnabled(false); scriptMenu->addAction(stopRecordingScriptAction); canlcelRecordingScriptAction = new QAction(this); + canlcelRecordingScriptAction->setEnabled(false); scriptMenu->addAction(canlcelRecordingScriptAction); addBookmarkAction = new QAction(this); @@ -3369,6 +3375,48 @@ void CentralWidget::menuAndToolBarConnectSignals(void) { connect(cancelAction,&QAction::triggered,this,[=](){ pyRun->cancelScript(); }); + connect(startRecordingScriptAction,&QAction::triggered,this,[=](){ + QWidget *widget = findCurrentFocusWidget(); + if(widget == nullptr) { + return; + } + SessionsWindow *sessionsWindow = widget->property("session").value(); + if(!sessionsWindow->isRecordingScript()) { + sessionsWindow->startRecordingScript(); + } + bool isRS = sessionsWindow->isRecordingScript(); + startRecordingScriptAction->setEnabled(!isRS); + stopRecordingScriptAction->setEnabled(isRS); + canlcelRecordingScriptAction->setEnabled(isRS); + }); + connect(stopRecordingScriptAction,&QAction::triggered,this,[=](){ + QWidget *widget = findCurrentFocusWidget(); + if(widget == nullptr) { + return; + } + SessionsWindow *sessionsWindow = widget->property("session").value(); + if(sessionsWindow->isRecordingScript()) { + sessionsWindow->stopRecordingScript(); + } + bool isRS = sessionsWindow->isRecordingScript(); + startRecordingScriptAction->setEnabled(!isRS); + stopRecordingScriptAction->setEnabled(isRS); + canlcelRecordingScriptAction->setEnabled(isRS); + }); + connect(canlcelRecordingScriptAction,&QAction::triggered,this,[=](){ + QWidget *widget = findCurrentFocusWidget(); + if(widget == nullptr) { + return; + } + SessionsWindow *sessionsWindow = widget->property("session").value(); + if(sessionsWindow->isRecordingScript()) { + sessionsWindow->canlcelRecordingScript(); + } + bool isRS = sessionsWindow->isRecordingScript(); + startRecordingScriptAction->setEnabled(!isRS); + stopRecordingScriptAction->setEnabled(isRS); + canlcelRecordingScriptAction->setEnabled(isRS); + }); #endif connect(addBookmarkAction, &QAction::triggered, this, [&]() { QString path = FileDialog::getExistingDirectory(this,tr("Select a directory"),QDir::homePath()); diff --git a/src/sessionswindow/sessionswindow.cpp b/src/sessionswindow/sessionswindow.cpp index 940f0bc2..0dc40d37 100644 --- a/src/sessionswindow/sessionswindow.cpp +++ b/src/sessionswindow/sessionswindow.cpp @@ -65,6 +65,7 @@ SessionsWindow::SessionsWindow(SessionType tp, QWidget *parent) , vncClient(nullptr) , enableLog(false) , enableRawLog(false) + , enableRecordingScript(false) , enableBroadCast(false) { zmodemUploadPath = QDir::homePath(); zmodemDownloadPath = QDir::homePath(); @@ -1147,6 +1148,67 @@ QString SessionsWindow::getRawLogFileName(void) { return ret; } +int SessionsWindow::startRecordingScript(void) { + int ret = 0; + enableRecordingScript = true; + recordingScript.clear(); + return ret; +} + +int SessionsWindow::stopRecordingScript(void) { + int ret = 0; + QString savefile_name = FileDialog::getSaveFileName(term, tr("Save script..."), + QDir::homePath() + QDate::currentDate().toString("/script-yyyy-MM-dd-") + QTime::currentTime().toString("hh-mm-ss") + ".py", tr("Python files (*.py)")); + if (!savefile_name.isEmpty()) { + QFile scriptFile(savefile_name); + if (!scriptFile.open(QIODevice::WriteOnly|QIODevice::Text)) { + QMessageBox::warning(messageParentWidget, tr("Save script"), tr("Cannot write file %1:\n%2.").arg(savefile_name).arg(scriptFile.errorString())); + ret = -1; + } else { + QTextStream out(&scriptFile); + + out << "#!/usr/bin/env python3\n"; + out << "# -*- coding: utf-8 -*-\n"; + out << "#\n"; + out << "# $interface = \"1.0\"\n"; + out << "# Script generated by QuardCRT\n"; + out << "# Date: " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << "\n"; + out << "#\n"; + out << "# This automatically generated script may need to be\n"; + out << "# edited in order to work correctly.\n"; + out << "\n"; + out << "import sys\n"; + out << "from quardCRT import crt\n"; + out << "\n"; + out << "def main():\n"; + out << " crt.Screen.Synchronous = True\n"; + out << "\n"; + foreach(auto cmd, recordingScript) { + if(cmd.first == 0) { + out << " crt.Screen.Send(\"" << cmd.second.replace("\"", "\\\"") << "\")\n"; + } else { + out << " crt.Screen.WaitForString(\"" << cmd.second.replace("\"", "\\\"") << "\")\n"; + } + } + out << "\n"; + out << "if __name__ == \'__main__\':\n"; + out << " main()\n"; + out << "\n"; + + scriptFile.close(); + } + } + enableRecordingScript = false; + return ret; +} + +int SessionsWindow::canlcelRecordingScript(void) { + int ret = 0; + enableRecordingScript = false; + recordingScript.clear(); + return ret; +} + int SessionsWindow::saveLog(const char *data, int size) { int ret = 0; if(enableLog) { diff --git a/src/sessionswindow/sessionswindow.h b/src/sessionswindow/sessionswindow.h index e22896c2..3486bd67 100644 --- a/src/sessionswindow/sessionswindow.h +++ b/src/sessionswindow/sessionswindow.h @@ -159,6 +159,10 @@ class SessionsWindow : public QObject QString getLogFileName(void); int setRawLog(bool enable); bool isRawLog(void) { return enableRawLog; } + int startRecordingScript(void); + int stopRecordingScript(void); + int canlcelRecordingScript(void); + bool isRecordingScript(void) { return enableRecordingScript; } QString getRawLogFileName(void); void setInBroadCastList(bool enable); bool isInBroadCastList() { return enableBroadCast; } @@ -471,11 +475,15 @@ class SessionsWindow : public QObject QVNCClientWidget *vncClient; bool enableLog; bool enableRawLog; + bool enableRecordingScript; + QList> recordingScript; bool enableBroadCast; QMutex log_file_mutex; QMutex raw_log_file_mutex; + QMutex recording_script_file_mutex; QFile *log_file = nullptr; QFile *raw_log_file = nullptr; + QFile *recording_script_file = nullptr; bool fflush_file = true; QByteArray password_hash; bool locked = false;