save for christmas

This commit is contained in:
2024-12-20 13:01:34 +01:00
parent 2ec7b61682
commit 7bfb7f5a3b
19 changed files with 624 additions and 92 deletions

View File

@@ -324,9 +324,9 @@ bool CommandLineParser::extendedVersion() {
bool CommandLineParser::alwaysDownloadConfig() {
if (m_parser.isSet(m_alwaysDownloadConfigOption)) {
m_alwaysDownloadConfig = m_parser.value(m_alwaysDownloadConfigOption);
qCritical() << "m_alwaysDownloadConfigOption IS SET" << m_alwaysDownloadConfig;
// qCritical() << "m_alwaysDownloadConfigOption IS SET" << m_alwaysDownloadConfig;
}
qCritical() << "m_alwaysDownloadConfig" << m_alwaysDownloadConfig;
// qCritical() << "m_alwaysDownloadConfig" << m_alwaysDownloadConfig;
return m_alwaysDownloadConfig == "false" ? false : true;
}

View File

@@ -2,6 +2,7 @@
#include "update.h"
#include "worker.h"
#include "utils.h"
#include "process/command.h"
#include <QRegularExpression>
#include <QDebug>

View File

@@ -4,8 +4,8 @@
#include <QObject>
#include <QStringList>
#include <optional>
#include <QCoreApplication>
#include "process/command.h"
#include "ismas/ismas_client.h"
class Worker;

View File

@@ -31,6 +31,7 @@
#include "worker.h"
#include "mainwindow.h"
#include "utils.h"
// #include "process/command.h"
#include <QThread>
#include <QtWidgets>
@@ -199,5 +200,9 @@ int main(int argc, char *argv[]) {
mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
mw.showFullScreen();
// test
worker.dcUpdate();
// worker.summary();
return a.exec();
}

View File

@@ -11,6 +11,8 @@
#include <QDebug>
#include <QScrollBar>
#include <QEvent>
#include <QColor>
#include <QColorDialog>
MainWindow::MainWindow(Worker *worker, QWidget *parent)
@@ -21,16 +23,16 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
, m_progressRunning(false)
, m_updateStep(UpdateDcEvent::UpdateStep::NONE) {
ui->setupUi(this);
this->setStatusBar(new QStatusBar(this));
QFont f;
f.setStyleHint(QFont::Monospace);
f.setWeight(QFont::Bold);
f.setFamily("Misc Fixed");
f.setPixelSize(12);
f.setPointSize(11);
this->statusBar()->setFont(f);
ui->setupUi(this);
ui->updateProgress->setRange(0, 100);
ui->updateProgress->reset();
@@ -38,15 +40,15 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
QString start = QDateTime::currentDateTime().toString(Qt::ISODate);
lst << QString("Start: ") + start.leftJustified(m_width-10);
lst << QString("").leftJustified(m_width-3, '=');
lst << QString("Update tool version: %1 - %2 %3").arg(APP_VERSION).arg(APP_BUILD_DATE).arg(APP_BUILD_TIME).leftJustified(m_width-3);
lst << QString("Machine number : %1 ").arg(m_worker->machineNr()).leftJustified(m_width-3);
lst << QString("Customer number : %1 ").arg(m_worker->customerNr()).leftJustified(m_width-3);
lst << QString("Zone number : %1 (%2)").arg(m_worker->zoneNr()).arg(Utils::zoneName(m_worker->zoneNr())).leftJustified(m_width-3);
lst << QString("APISM version : %1").arg(m_worker->apismVersion()).leftJustified(m_width-3);
lst << QString("Update tool version : %1 - %2 %3").arg(APP_VERSION).arg(APP_BUILD_DATE).arg(APP_BUILD_TIME).leftJustified(m_width-3);
lst << QString("Machine number : %1 ").arg(m_worker->machineNr()).leftJustified(m_width-3);
lst << QString("Customer number : %1 ").arg(m_worker->customerNr()).leftJustified(m_width-3);
lst << QString("Zone number : %1 (%2)").arg(m_worker->zoneNr()).arg(Utils::zoneName(m_worker->zoneNr())).leftJustified(m_width-3);
lst << QString("APISM version : %1").arg(m_worker->apismVersion()).leftJustified(m_width-3);
lst << QString("").leftJustified(m_width-3, '=');
ui->updateStatus->setText(lst.join('\n'));
ui->updateStatus->setEnabled(true);
ui->updateLabel->setText(lst.join('\n'));
ui->updateLabel->setEnabled(true);
// ui->updateStatus->installEventFilter(this);
m_startTimer = new QTimer(this);
@@ -78,11 +80,15 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
}
connect(ui->exit, SIGNAL(clicked()),this,SLOT(onQuit()));
connect(m_worker, SIGNAL(showSummary(QString)),this,SLOT(onShowSummary(QString)));
connect(m_worker, SIGNAL(disableExit()),this,SLOT(onDisableExit()));
connect(m_worker, SIGNAL(showDcDownload(QString)),this,SLOT(onShowDcDownload(QString)));
connect(m_worker, SIGNAL(setDcDownloadProgress(int)),this,SLOT(onSetDcDownloadProgress(int)));
connect(m_worker, SIGNAL(enableExit()),this,SLOT(onEnableExit()));
connect(m_worker, SIGNAL(stopStartTimer()),this,SLOT(onStopStartTimer()));
connect(m_worker, SIGNAL(restartExitTimer()),this,SLOT(onRestartExitTimer()));
connect(m_worker, SIGNAL(appendText(QString,QString)),this,SLOT(onAppendText(QString,QString)));
connect(m_worker, SIGNAL(insertText(QString)),this,SLOT(onInsertText(QString)), Qt::DirectConnection);
connect(m_worker, SIGNAL(showErrorMessage(QString,QString)),this, SLOT(onShowErrorMessage(QString,QString)));
connect(m_worker, SIGNAL(showStatusMessage(QString,QString)),this, SLOT(onShowStatusMessage(QString,QString)));
connect(m_worker, SIGNAL(showErrorMessage(QStringList)),this, SLOT(onShowErrorMessage(QStringList)));
@@ -91,6 +97,29 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
connect(m_worker, SIGNAL(replaceLast(QStringList,QString)),this, SLOT(onReplaceLast(QStringList,QString)));
}
void MainWindow::onShowSummary(QString text) {
// QString s = ui->updateLabel->text();
QString s("\n");
ui->updateLabel->setText(s);
ui->updateLabel->hide();
ui->stepLabel->hide();
s += text;
ui->updateStatus->setText(s);
}
void MainWindow::onSetDcDownloadProgress(int v) {
ui->updateProgress->setValue(v);
}
void MainWindow::onShowDcDownload(QString version) {
m_targetDcVersion = version;
ui->exit->setEnabled(false);
ui->stepLabel->setText(QString("Device controller update. Target version: %1").arg(version).leftJustified(m_width-3));
}
MainWindow::~MainWindow() {
delete m_startTimer;
delete m_exitTimer;
@@ -199,6 +228,12 @@ void MainWindow::scrollDownTextEdit() {
ui->updateStatus->ensureCursorVisible();
}
void MainWindow::onInsertText(QString text) {
scrollDownTextEdit();
ui->updateStatus->textCursor().insertText(text);
}
void MainWindow::onAppendText(QString text, QString suffix) {
// Utils::printInfoMsg(QString("ON APPEND CALLED AT ")
// + QDateTime::currentDateTime().toString(Qt::ISODateWithMs));

View File

@@ -36,8 +36,11 @@ public:
UpdateDcEvent::UpdateStep updateStep() const { return m_updateStep; }
void setUpdateStep(UpdateDcEvent::UpdateStep updateStep) { m_updateStep = updateStep; }
QString targetDcVersion() {return m_targetDcVersion; }
public slots:
void onAppendText(QString, QString suffix = "");
void onInsertText(QString);
void onReplaceLast(QStringList, QString suffix = "");
void onReplaceLast(QString, QString suffix = "");
void onShowErrorMessage(QString, QString);
@@ -48,6 +51,9 @@ public slots:
void onRestartExitTimer();
void onEnableExit();
void onDisableExit();
void onShowDcDownload(QString);
void onSetDcDownloadProgress(int);
void onShowSummary(QString);
#if EMERGENCY_LEAVE_BL==1
void emergencyLeaveBL();
#endif
@@ -74,5 +80,6 @@ private:
//int m_progressValue;
UpdateDcEvent::UpdateStep m_updateStep;
QTimer *m_statusTimer;
QString m_targetDcVersion;
};
#endif // MAINWINDOW_H

View File

@@ -12,7 +12,10 @@
</property>
<property name="font">
<font>
<family>Source Code Pro</family>
<family>Misc Fixed</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="windowTitle">
@@ -29,21 +32,28 @@
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="2">
<widget class="QPushButton" name="exit">
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="stepLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>18</height>
</size>
</property>
<property name="font">
<font>
<family>Misc Fixed</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Exit</string>
<string/>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QProgressBar" name="updateProgress">
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="3" colspan="3">
<item row="3" column="0" colspan="3">
<widget class="QTextEdit" name="updateStatus">
<property name="enabled">
<bool>true</bool>
@@ -52,9 +62,16 @@
<font>
<family>Misc Fixed</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
@@ -64,6 +81,44 @@
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2" colspan="3">
<widget class="QLabel" name="updateLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="font">
<font>
<family>Misc Fixed</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QProgressBar" name="updateProgress">
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QPushButton" name="exit">
<property name="text">
<string>Exit</string>
</property>
</widget>
</item>
</layout>

View File

@@ -1,4 +1,5 @@
#include "command.h"
#include "worker.h"
#include <QProcess>
#include <QDebug>
@@ -7,12 +8,15 @@
#include <QDateTime>
#include <QMutexLocker>
Command::Command(QString const &command, int start_timeout, int finish_timeout)
: m_command(command.trimmed())
, m_commandResult("")
, m_waitForStartTimeout(start_timeout)
, m_waitForFinishTimeout(finish_timeout)
, m_exitCode(-1) {
, m_exitCode(-1)
, m_p(nullptr)
, m_worker(nullptr) {
}
QString Command::getCommandResult(bool reset) const {
@@ -31,13 +35,52 @@ QString Command::getCommandResult(bool reset) const {
void Command::readyReadStandardOutput() {
QMutexLocker locker(&m_mtx);
QProcess *p = (QProcess *)sender();
m_commandResult += p->readAllStandardOutput();
if (p) {
QString s = p->readAllStandardOutput();
if (m_worker) {
int i = -1;
if ((i = s.indexOf("<DC-VERSION>")) != -1) {
s = s.mid(i+12).trimmed();
if ((i = s.indexOf("\"")) != -1) {
s = s.mid(i+1);
if ((i = s.indexOf("\"")) != -1) {
s = s.mid(0, i).trimmed();
}
}
emit m_worker->showDcDownload(s);
} else
if ((i = s.indexOf("<PROGRESS>")) != -1) {
bool ok;
int v = s.mid(i+10).trimmed().toInt(&ok);
if (ok) {
emit m_worker->setDcDownloadProgress(v);
emit m_worker->insertText(s.mid(0,i) + "\n");
}
} else
if ((i = s.indexOf("<DC-UPDATE-FINISH>")) != -1) {
m_worker->summary();
// qApp->exit(0);
} else
if ((i = s.indexOf("<DC-UPDATE-SUCCESS>")) != -1) {
m_worker->summary();
} else
if ((i = s.indexOf("<DC-UPDATE-FAILURE>")) != -1) {
m_worker->summary();
//qApp->exit(-1);
} else {
emit m_worker->insertText(s);
}
}
m_commandResult += s;
}
}
void Command::readyReadStandardError() {
QProcess *p = (QProcess *)sender();
QByteArray buf = p->readAllStandardError();
qCritical() << buf;
if (p) {
QByteArray buf = p->readAllStandardError();
qCritical() << buf;
}
}
void Command::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) {
@@ -52,6 +95,31 @@ void Command::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) {
disconnect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(readyReadStandardError()));
}
bool Command::start(QString workingDirectory, QStringList args) {
if (!QDir::setCurrent(workingDirectory)) {
qCritical() << "SET WORKING_DIRECTORY" << workingDirectory
<< "FAILED FOR" << m_command;
return false;
}
if (m_p != nullptr) {
delete m_p;
}
m_p = new QProcess(this);
m_p->setWorkingDirectory(workingDirectory);
m_p->setProcessChannelMode(QProcess::MergedChannels);
connect(m_p, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()));
connect(m_p, SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()));
if (!args.isEmpty()) {
m_p->start(m_command, args);
} else {
m_p->start(m_command);
}
return m_p->waitForStarted(m_waitForStartTimeout);
}
bool Command::execute(QString workingDirectory, QStringList args) {
if (!QDir::setCurrent(workingDirectory)) {

View File

@@ -9,7 +9,7 @@
#include <QProcess>
#include <QMutex>
class Worker;
class Command : public QObject {
Q_OBJECT
@@ -19,6 +19,8 @@ class Command : public QObject {
int m_waitForFinishTimeout;
int m_exitCode;
mutable QMutex m_mtx;
QProcess *m_p;
Worker *m_worker;
public:
explicit Command(QString const &command,
int start_timeout = 100000,
@@ -28,8 +30,11 @@ public:
QString command() const { return m_command; }
bool execute(QString workingDirectory, QStringList args = QStringList());
bool start(QString workingDirectory, QStringList args = QStringList());
int exitCode() const { return m_exitCode; }
void setWorker(Worker *worker) {m_worker = worker; }
private slots:
void readyReadStandardOutput();
void readyReadStandardError();

View File

@@ -13,9 +13,65 @@
#include <QDir>
#include <QDirIterator>
#include <QRegularExpression>
#include <QProcess>
#include <QJsonDocument>
#include <QJsonValue>
#include <QJsonObject>
#include <QJsonArray>
#include <fstream>
QVector<QPair<QString, QString>> Utils::installedPackages() {
QVector<QPair<QString, QString>> vec;
if (QFile::exists("/usr/bin/ptuPackageVersions")) {
QProcess p;
QStringList params;
params << "-c" << R"(/usr/bin/ptuPackageVersions -i -o json)";
p.start("bash", params);
p.waitForFinished();
QString r = p.readAllStandardOutput();
// ptuPackageVersions returns a json-array
QJsonArray const &ja = QJsonDocument::fromJson(r.remove(QRegExp("\\n")).toUtf8()).array();
if (!ja.empty()) {
qCritical() << __LINE__;
// transform the array into an object, containing the objects
// of the array (christian needs it this way)
foreach (QJsonValue const &value, ja) {
if (value.isObject()) {
QJsonObject obj = value.toObject();
QStringList keys = obj.keys();
if (!keys.isEmpty()) {
QString const &k = keys.first();
QJsonValue const &v = obj.value(k);
if (v.isObject()) {
obj = v.toObject();
if (obj.keys().contains("Version")) {
QJsonValue const &w = obj.value("Version");
if (w.isString()) {
QString s = w.toString();
QPair<QString, QString> p(k, s);
vec.push_back(p);
}
}
}
}
}
}
} else {
qCritical() << __func__ << ":" << __LINE__
<< "ERROR array return by ptuPackageVersions empty";
}
} else {
qCritical() << __func__ << ":" << __LINE__
<< "ERROR executing ptuPackageVersions";
}
return vec;
}
int Utils::read1stLineOfFile(QString fileName) {
QFile f(fileName);
if (f.exists()) {

View File

@@ -9,6 +9,7 @@
#include <QDateTime>
#include <QDir>
#include <QDebug>
#include <QPair>
namespace Utils {
int read1stLineOfFile(QString fileName);
@@ -33,6 +34,8 @@ namespace Utils {
QString getParentName();
bool isATBQTRunning();
QVector<QPair<QString, QString>> installedPackages();
}
#endif // UTILS_H_INCLUDED

View File

@@ -26,6 +26,7 @@
#include "progress_event.h"
#include "mainwindow.h"
#include "utils.h"
#include "process/command.h"
QString const Worker::UPDATE_STEP_OK ( " [ ok]");
QString const Worker::UPDATE_STEP_DONE ( " [done]");
@@ -176,9 +177,14 @@ Worker::Worker(int customerNr,
, m_filesToUpdate()
, m_updateProcessRunning(true)
, m_mainWindow(nullptr) /* contains plugin */
, m_dcDownloadFirmware(new Command("/opt/app/tools/atbupdate/ATBDownloadDCFirmware --read-dc-version true"))
//, m_withoutIsmasDirectPort(true) /* useful for testing */ {
, m_withoutIsmasDirectPort(false) /* useful for testing */ {
m_start = QDateTime::currentDateTime();
m_dcDownloadFirmware->setWorker(this);
// TODO: turn object into singleton
instance = this;
m_lastFailedUpdateStep = UPDATE_STEP::NONE;
@@ -284,6 +290,8 @@ void Worker::privateUpdate() {
return;
}
return;
QString func(__PRETTY_FUNCTION__);
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::STARTED));
@@ -1267,6 +1275,7 @@ QString Worker::getPluginVersion(QString const &pluginFileName) const {
QStringList Worker::getDCVersion() const {
QStringList lst = (QStringList() << "N/A" << "N/A");
#if 0
Update const *up = update();
if (up) {
hwinf const *caPlugin = up->hw();
@@ -1288,6 +1297,7 @@ QStringList Worker::getDCVersion() const {
}
}
}
#endif
return lst;
}
@@ -1500,3 +1510,78 @@ PSAInstalled Worker::getPSAInstalled() {
return psaInstalled;
}
bool Worker::dcUpdate() {
return m_dcDownloadFirmware->start("/opt/app/tools/atbupdate");
}
void Worker::summary() {
QString summary, first, second, line, tmp;
QVector<QPair<QString, QString>> vec = Utils::installedPackages();
int max_first = 0, max_second = 0;
for (int i = 0; i < vec.size(); ++i) {
max_first = std::max(max_first, vec[i].first.length());
max_second = std::max(max_second, vec[i].second.length());
}
max_first += 5;
summary = "UPDATE SUMMARY\n\n";
first = QString("%1").arg("start", max_first, QChar(' '));
tmp = QString("%1").arg(start().toString(Qt::ISODate));
second = QString("%1").arg(tmp, -max_second, QChar(' '));
line = first + ": " + second;
summary += line + "\n";
first = QString("%1").arg("update tool version", max_first, QChar(' '));
tmp = QString("%1 - %2 %3").arg(APP_VERSION).arg(APP_BUILD_DATE).arg(APP_BUILD_TIME);
second = QString("%1").arg(tmp, -max_second, QChar(' '));
line = first + ": " + second;
summary += line + "\n";
first = QString("%1").arg("machine number", max_first, QChar(' '));
tmp = QString("%1").arg(machineNr());
second = QString("%1").arg(tmp, -max_second, QChar(' '));
line = first + ": " + second;
summary += line + "\n";
first = QString("%1").arg("customer number", max_first, QChar(' '));
tmp = QString("%1").arg(customerNr());
second = QString("%1").arg(tmp, -max_second, QChar(' '));
line = first + ": " + second;
summary += line + "\n";
first = QString("%1").arg("zone number", max_first, QChar(' '));
tmp = QString("%1").arg(zoneNr());
second = QString("%1").arg(tmp, -max_second, QChar(' '));
line = first + ": " + second;
summary += line + "\n";
if (m_mainWindow) {
tmp = m_mainWindow->targetDcVersion();
if (!tmp.isEmpty()) {
first = QString("%1").arg("target device controller", max_first, QChar(' '));
second = QString("%1").arg(tmp, -max_second, QChar(' '));
line = first + ": " + second;
summary += line + "\n";
}
}
first = QString("%1").arg("apism", max_first, QChar(' '));
tmp = QString("%1").arg(apismVersion());
second = QString("%1").arg(tmp, -max_second, QChar(' '));
line = first + ": " + second;
summary += line + "\n";
for (int i = 0; i < vec.size(); ++i) {
first = QString("%1").arg(vec[i].first, max_first, QChar(' '));
second = QString("%1").arg(vec[i].second, -max_second, QChar(' '));
line = first + ": " + second;
summary += line + "\n";
}
emit showSummary(summary);
}

View File

@@ -15,7 +15,6 @@
#include <optional>
#include <initializer_list>
#include "update.h"
#include "git/git_client.h"
#include "ismas/ismas_client.h"
#include "utils.h"
@@ -135,6 +134,8 @@
#define ISMAS_UPDATE_REQUESTS (10)
#define CHECK_UPDATE_TRIGGER_SET "Check update trigger ..."
class Command;
class Update;
class MainWindow;
class hwinf;
class Worker : public QThread{
@@ -189,6 +190,7 @@ class Worker : public QThread{
QStringList m_ismasTriggerStatusMessage;
MainWindow *m_mainWindow;
Command *m_dcDownloadFirmware;
bool m_withoutIsmasDirectPort;
QString m_apismVersion;
@@ -458,8 +460,13 @@ public:
Update *update() { return m_update; }
Update const *update() const { return m_update; }
bool dcUpdate();
void summary();
QDateTime start() { return m_start; }
signals:
void appendText(QString, QString suffix = "");
void insertText(QString);
void replaceLast(QString, QString);
void replaceLast(QStringList, QString);
void showErrorMessage(QString title, QString description);
@@ -470,6 +477,9 @@ signals:
void restartExitTimer();
void enableExit();
void disableExit();
void showDcDownload(QString);
void showSummary(QString);
void setDcDownloadProgress(int);
private slots:
bool updateTriggerSet();
@@ -487,6 +497,8 @@ private:
bool computeFilesToDownload();
bool execOpkgCommands();
QDateTime m_start;
static const QMap<UPDATE_STEP, const char*> smap;
// CONSOLE()