From ce94a1214d93b8f3b45c3e623db08429394e80b0 Mon Sep 17 00:00:00 2001 From: Spiros Date: Sat, 1 Jun 2024 20:21:32 +0300 Subject: [PATCH] Order NVMe values --- CMakeLists.txt | 1 + jsonparser.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ jsonparser.h | 20 ++++++++++++++++++ mainwindow.cpp | 42 ++++++++++++++++++++++++++++---------- mainwindow.h | 5 +++-- 5 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 jsonparser.cpp create mode 100644 jsonparser.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 439724a..300b776 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ else() ${PROJECT_SOURCES} custombutton.h custombutton.cpp statusdot.h statusdot.cpp + jsonparser.h jsonparser.cpp ) endif() diff --git a/jsonparser.cpp b/jsonparser.cpp new file mode 100644 index 0000000..b8164a9 --- /dev/null +++ b/jsonparser.cpp @@ -0,0 +1,55 @@ +#include "jsonparser.h" + +JsonParser::JsonParser() +{ +} + +QVector> JsonParser::parse(const QString &json) +{ + QVector> data; + QStringList lines = json.split('\n'); + bool found = false; + bool skip = false; + + for (const QString &line : lines) { + QString trimmedLine = line.trimmed(); + if (trimmedLine.contains("[")) { + skip = true; + continue; + } + if (trimmedLine.contains("]")) { + skip = false; + continue; + } + if (skip) { + continue; + } + if (trimmedLine.contains("nvme_smart_health_information_log")) { + found = true; + continue; + } + if (found) { + if (trimmedLine.contains("}")) { + break; + } + int colon_pos = trimmedLine.indexOf(":"); + if (colon_pos != -1) { + QString key = removeQuotes(trimmedLine.left(colon_pos)); + QString valueString = trimmedLine.mid(colon_pos + 1).trimmed(); + valueString.chop(1); + int value = valueString.toInt(); + data.append(qMakePair(key, value)); + } + } + } + return data; +} + +QString JsonParser::removeQuotes(const QString &s) +{ + QString result = s.trimmed(); + if (result.length() >= 2 && result.front() == '"' && result.back() == '"') { + return result.mid(1, result.size() - 2); + } + return result; +} diff --git a/jsonparser.h b/jsonparser.h new file mode 100644 index 0000000..d9c49d5 --- /dev/null +++ b/jsonparser.h @@ -0,0 +1,20 @@ +#ifndef JSONPARSER_H +#define JSONPARSER_H + +#include +#include +#include +#include + +class JsonParser +{ +public: + JsonParser(); + + QVector> parse(const QString &json); + +private: + QString removeQuotes(const QString &s); +}; + +#endif diff --git a/mainwindow.cpp b/mainwindow.cpp index d60ff57..e6e4f7d 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -57,7 +57,10 @@ void MainWindow::scanDevices() QJsonArray devices = jsonObj["devices"].toArray(); QJsonObject globalObj; QString globalHealth; + QVector> globalNvmeSmartOrdered; bool firstTime = true; + bool globalIsNvme = false; + for (const QJsonValue &value : devices) { QJsonObject device = value.toObject(); @@ -87,6 +90,7 @@ void MainWindow::scanDevices() temperature = QString::number(temperatureInt) + " °C"; } + QVector> nvmeSmartOrdered; if (!isNvme) { for (const QJsonValue &attr : attributes) { QJsonObject attrObj = attr.toObject(); @@ -95,6 +99,9 @@ void MainWindow::scanDevices() break; } } + } else { + JsonParser parser; + nvmeSmartOrdered = parser.parse(allOutput); } if (healthPassed && !caution) { @@ -117,7 +124,11 @@ void MainWindow::scanDevices() button->setAutoExclusive(true); connect(button, &QPushButton::clicked, this, [=]() { - populateWindow(localObj, health); + if (isNvme) { + populateWindow(localObj, health, nvmeSmartOrdered); + } else { + populateWindow(localObj, health); + } }); if (firstTime) { @@ -125,13 +136,22 @@ void MainWindow::scanDevices() globalHealth = health; button->setChecked(true); firstTime = false; + globalIsNvme = isNvme; + if (isNvme) { + globalNvmeSmartOrdered = nvmeSmartOrdered; + } } } horizontalLayout->addStretch(); - populateWindow(globalObj, globalHealth); + + if (globalIsNvme) { + populateWindow(globalObj, globalHealth, globalNvmeSmartOrdered); + } else { + populateWindow(globalObj, globalHealth); + } } -void MainWindow::populateWindow(const QJsonObject &localObj, const QString &health) +void MainWindow::populateWindow(const QJsonObject &localObj, const QString &health, const QVector>& nvmeLogOrdered) { QJsonArray attributes = localObj["ata_smart_attributes"].toObject()["table"].toArray(); QJsonObject nvmeLog = localObj["nvme_smart_health_information_log"].toObject(); @@ -290,17 +310,17 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal if (protocol != "NVMe") { addSmartAttributesTable(attributes); } else { - addNvmeLogTable(nvmeLog); + addNvmeLogTable(nvmeLogOrdered); } } -void MainWindow::addNvmeLogTable(const QJsonObject &nvmeLog) +void MainWindow::addNvmeLogTable(const QVector>& nvmeLogOrdered) { tableWidget->setColumnCount(4); tableWidget->setHorizontalHeaderLabels({"", "ID", "Attribute Name", "Raw Values"}); tableWidget->verticalHeader()->setVisible(false); tableWidget->setItemDelegateForColumn(0, new StatusDot(tableWidget)); - tableWidget->setRowCount(nvmeLog.size()); + tableWidget->setRowCount(nvmeLogOrdered.size()); for (int i = 0; i < tableWidget->columnCount(); ++i) { QTableWidgetItem *headerItem = tableWidget->horizontalHeaderItem(i); @@ -314,16 +334,16 @@ void MainWindow::addNvmeLogTable(const QJsonObject &nvmeLog) } int row = 0; - for (auto smartItem = nvmeLog.constBegin(); smartItem != nvmeLog.constEnd(); ++smartItem) { - QString id = QString("%1").arg(row, 2, 16, QChar('0')).toUpper(); + for (const QPair &pair : nvmeLogOrdered) { + QString id = QString("%1").arg(row + 1, 2, 16, QChar('0')).toUpper(); - QString name = smartItem.key().replace("_", " "); + QString key = pair.first; + QString name = key.replace("_", " "); name = toTitleCase(name); - QString raw = QString::number(smartItem.value().toInt()); + QString raw = QString::number(pair.second); raw = QString("%1").arg(raw.toUInt(nullptr), 14, 16, QChar('0')).toUpper(); - QColor statusColor; statusColor = Qt::green; // For now leave it all green diff --git a/mainwindow.h b/mainwindow.h index 1979ad5..50a0899 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -13,6 +13,7 @@ #include "statusdot.h" #include "custombutton.h" +#include "jsonparser.h" #include "./ui_mainwindow.h" QT_BEGIN_NAMESPACE @@ -39,8 +40,8 @@ private: QTableWidget *tableWidget; void scanDevices(); - void populateWindow(const QJsonObject &tempObj, const QString &health); - void addNvmeLogTable(const QJsonObject &nvmeLog); + void populateWindow(const QJsonObject &tempObj, const QString &health, const QVector>& nvmeLogOrdered = QVector>()); + void addNvmeLogTable(const QVector>& nvmeLogOrdered); void addSmartAttributesTable(const QJsonArray &attributes); QString getSmartctlOutput(const QStringList &arguments, bool root); QString toTitleCase(const QString& sentence);