Add monitor non interactive mode and add traffic counter for tunnel proxy
This commit is contained in:
parent
1694a43098
commit
8081c7804e
@ -328,6 +328,7 @@ void TunnelProxyServer::onClientDataAvailable(const QUuid &clientId, const QByte
|
||||
}
|
||||
|
||||
qCDebug(dcTunnelProxyServerTraffic()) << "Client data available" << tunnelProxyClient << qUtf8Printable(data);
|
||||
tunnelProxyClient->addRxDataCount(data.count());
|
||||
|
||||
if (tunnelProxyClient->type() == TunnelProxyClient::TypeClient) {
|
||||
// Send the data to the server using slip encoded frame
|
||||
@ -344,8 +345,11 @@ void TunnelProxyServer::onClientDataAvailable(const QUuid &clientId, const QByte
|
||||
frame.socketAddress = clientConnection->socketAddress();
|
||||
frame.data = data;
|
||||
qCDebug(dcTunnelProxyServerTraffic()) << "--> Tunnel data to server socket address" << clientConnection->socketAddress() << "to" << clientConnection->serverConnection() << "\n" << data;
|
||||
clientConnection->serverConnection()->transportClient()->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame)));
|
||||
QByteArray rawData = SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame));
|
||||
clientConnection->serverConnection()->transportClient()->sendData(rawData);
|
||||
clientConnection->serverConnection()->transportClient()->addTxDataCount(rawData.count());
|
||||
m_troughputCounter += data.count();
|
||||
|
||||
} else if (tunnelProxyClient->type() == TunnelProxyClient::TypeServer) {
|
||||
// Data coming from a connected server connection
|
||||
if (tunnelProxyClient->slipEnabled()) {
|
||||
@ -376,7 +380,8 @@ void TunnelProxyServer::onClientDataAvailable(const QUuid &clientId, const QByte
|
||||
|
||||
qCDebug(dcTunnelProxyServerTraffic()) << "--> Tunnel data from server socket" << frame.socketAddress << "to" << clientConnection << "\n" << frame.data;
|
||||
clientConnection->transportClient()->sendData(frame.data);
|
||||
m_troughputCounter += data.count();
|
||||
clientConnection->transportClient()->addTxDataCount(frame.data.count());
|
||||
m_troughputCounter += frame.data.count();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
@ -33,6 +33,7 @@
|
||||
#include <QCommandLineOption>
|
||||
|
||||
#include "monitor.h"
|
||||
#include "noninteractivemonitor.h"
|
||||
#include "../version.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -58,6 +59,10 @@ int main(int argc, char *argv[])
|
||||
QCommandLineOption socketOption(QStringList() << "s" << "socket", "The socket descriptor for the nymea-remoteproxy monitor socket. Default is /tmp/nymea-remoteproxy-monitor.sock", "socket");
|
||||
socketOption.setDefaultValue("/tmp/nymea-remoteproxy-monitor.sock");
|
||||
parser.addOption(socketOption);
|
||||
|
||||
QCommandLineOption noninteractiveOption(QStringList() << "n" << "non-interactive", "Connect to the server, list all data and close the connection. This works only for the tunnelproxy.");
|
||||
parser.addOption(noninteractiveOption);
|
||||
|
||||
parser.process(application);
|
||||
|
||||
// Check socket file
|
||||
@ -72,7 +77,13 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Monitor monitor(parser.value(socketOption));
|
||||
if (parser.isSet(noninteractiveOption)) {
|
||||
NonInteractiveMonitor *monitor = new NonInteractiveMonitor(parser.value(socketOption));
|
||||
Q_UNUSED(monitor);
|
||||
} else {
|
||||
Monitor *monitor = new Monitor(parser.value(socketOption));
|
||||
Q_UNUSED(monitor);
|
||||
}
|
||||
|
||||
return application.exec();
|
||||
}
|
||||
|
||||
@ -5,11 +5,14 @@ TEMPLATE = app
|
||||
|
||||
HEADERS += \
|
||||
monitorclient.h \
|
||||
noninteractivemonitor.h \
|
||||
terminalwindow.h \
|
||||
monitor.h
|
||||
monitor.h \
|
||||
utils.h
|
||||
|
||||
SOURCES += main.cpp \
|
||||
monitorclient.cpp \
|
||||
noninteractivemonitor.cpp \
|
||||
terminalwindow.cpp \
|
||||
monitor.cpp
|
||||
|
||||
|
||||
101
monitor/noninteractivemonitor.cpp
Normal file
101
monitor/noninteractivemonitor.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License as published by the Free Software Foundation,
|
||||
* GNU version 3. this project 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 this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "noninteractivemonitor.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
NonInteractiveMonitor::NonInteractiveMonitor(const QString &serverName, QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
m_monitorClient = new MonitorClient(serverName, this);
|
||||
connect(m_monitorClient, &MonitorClient::connected, this, &NonInteractiveMonitor::onConnected);
|
||||
|
||||
m_monitorClient->connectMonitor();
|
||||
}
|
||||
|
||||
void NonInteractiveMonitor::onConnected()
|
||||
{
|
||||
connect(m_monitorClient, &MonitorClient::dataReady, this, [](const QVariantMap &dataMap){
|
||||
qInfo().noquote() << "---------------------------------------------------------------------";
|
||||
qInfo().noquote() << "Server name:" << dataMap.value("serverName", "-").toString();
|
||||
qInfo().noquote() << "Server version:" << dataMap.value("serverVersion", "-").toString();
|
||||
qInfo().noquote() << "API version:" << dataMap.value("apiVersion", "-").toString();
|
||||
qInfo().noquote() << "Total client count:" << dataMap.value("tunnelProxyStatistic").toMap().value("totalClientCount", 0).toInt();
|
||||
qInfo().noquote() << "Server connections:" << dataMap.value("tunnelProxyStatistic").toMap().value("serverConnectionsCount", 0).toInt();
|
||||
qInfo().noquote() << "Client connections:" << dataMap.value("tunnelProxyStatistic").toMap().value("clientConnectionsCount", 0).toInt();
|
||||
qInfo().noquote() << "Data troughput:" << Utils::humanReadableTraffic(dataMap.value("tunnelProxyStatistic").toMap().value("troughput", 0).toInt()) + " / s";
|
||||
qInfo().noquote() << "---------------------------------------------------------------------";
|
||||
|
||||
QVariantMap tunnelProxyMap = dataMap.value("tunnelProxyStatistic").toMap();
|
||||
foreach (const QVariant &serverVariant, tunnelProxyMap.value("tunnelConnections").toList()) {
|
||||
QVariantMap serverMap = serverVariant.toMap();
|
||||
QVariantList clientList = serverMap.value("clientConnections").toList();
|
||||
|
||||
// Server line
|
||||
QString serverConnectionTime = QDateTime::fromTime_t(serverMap.value("timestamp").toUInt()).toString("dd.MM.yyyy hh:mm:ss");
|
||||
QString serverLinePrint;
|
||||
if (clientList.isEmpty()) {
|
||||
serverLinePrint.prepend("├──");
|
||||
} else {
|
||||
serverLinePrint.prepend("├┬─");
|
||||
}
|
||||
|
||||
serverLinePrint += QString("%1 | %2 RX: %3 TX: %4 | %5")
|
||||
.arg(serverConnectionTime)
|
||||
.arg(serverMap.value("address").toString(), - 15)
|
||||
.arg(Utils::humanReadableTraffic(serverMap.value("rxDataCount").toInt()), - 9)
|
||||
.arg(Utils::humanReadableTraffic(serverMap.value("txDataCount").toInt()), - 9)
|
||||
.arg(serverMap.value("name").toString());
|
||||
|
||||
qInfo().noquote() << serverLinePrint;
|
||||
|
||||
for (int cc = 0; cc < clientList.count(); cc++) {
|
||||
QVariantMap clientMap = clientList.at(cc).toMap();
|
||||
QString clientLinePrint;
|
||||
if (cc >= clientList.count() - 1) {
|
||||
clientLinePrint.append("│└─");
|
||||
} else {
|
||||
clientLinePrint.prepend("│├─");
|
||||
}
|
||||
|
||||
clientLinePrint += QString("%1 | %2 RX: %3 TX: %4 | %5")
|
||||
.arg(QDateTime::fromTime_t(clientMap.value("timestamp").toUInt()).toString("dd.MM.yyyy hh:mm:ss"))
|
||||
.arg(clientMap.value("address").toString(), - 15)
|
||||
.arg(Utils::humanReadableTraffic(serverMap.value("rxDataCount").toInt()), - 9)
|
||||
.arg(Utils::humanReadableTraffic(serverMap.value("txDataCount").toInt()), - 9)
|
||||
.arg(clientMap.value("name").toString(), -30);
|
||||
|
||||
qInfo().noquote() << clientLinePrint;
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
});
|
||||
|
||||
}
|
||||
48
monitor/noninteractivemonitor.h
Normal file
48
monitor/noninteractivemonitor.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License as published by the Free Software Foundation,
|
||||
* GNU version 3. this project 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 this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef NONINTERACTIVEMONITOR_H
|
||||
#define NONINTERACTIVEMONITOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include "monitorclient.h"
|
||||
|
||||
class NonInteractiveMonitor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NonInteractiveMonitor(const QString &serverName, QObject *parent = nullptr);
|
||||
|
||||
private:
|
||||
MonitorClient *m_monitorClient = nullptr;
|
||||
|
||||
private slots:
|
||||
void onConnected();
|
||||
|
||||
};
|
||||
|
||||
#endif // NONINTERACTIVEMONITOR_H
|
||||
@ -26,6 +26,7 @@
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "terminalwindow.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QDebug>
|
||||
@ -95,33 +96,6 @@ TerminalWindow::~TerminalWindow()
|
||||
cleanup();
|
||||
}
|
||||
|
||||
QString TerminalWindow::getDurationString(uint timestamp)
|
||||
{
|
||||
uint duration = QDateTime::currentDateTimeUtc().toTime_t() - timestamp;
|
||||
int seconds = static_cast<int>(duration % 60);
|
||||
duration /= 60;
|
||||
int minutes = static_cast<int>(duration % 60);
|
||||
duration /= 60;
|
||||
int hours = static_cast<int>(duration % 24);
|
||||
return QString::asprintf("%02d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
QString TerminalWindow::humanReadableTraffic(int bytes)
|
||||
{
|
||||
double dataCount = bytes;
|
||||
QStringList list;
|
||||
list << "KB" << "MB" << "GB" << "TB";
|
||||
|
||||
QStringListIterator i(list);
|
||||
QString unit("B");
|
||||
|
||||
while(dataCount >= 1024.0 && i.hasNext()) {
|
||||
unit = i.next();
|
||||
dataCount /= 1024.0;
|
||||
}
|
||||
return QString().setNum(dataCount,'f',2) + " " + unit;
|
||||
}
|
||||
|
||||
void TerminalWindow::resizeWindow()
|
||||
{
|
||||
int terminalSizeX;
|
||||
@ -196,8 +170,8 @@ void TerminalWindow::paintHeader()
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalClientCount").toInt())
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("tunnelCount", 0).toInt())
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTunnelCount").toInt())
|
||||
.arg(humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("troughput", 0).toInt()) + " / s", - 13)
|
||||
.arg(humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTraffic").toInt()), - 10)
|
||||
.arg(Utils::humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("troughput", 0).toInt()) + " / s", - 13)
|
||||
.arg(Utils::humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTraffic").toInt()), - 10)
|
||||
.arg(windowName);
|
||||
break;
|
||||
case ViewTunnels:
|
||||
@ -210,8 +184,8 @@ void TerminalWindow::paintHeader()
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalClientCount").toInt())
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("tunnelCount", 0).toInt())
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTunnelCount").toInt())
|
||||
.arg(humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("troughput", 0).toInt()) + " / s", - 13)
|
||||
.arg(humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTraffic").toInt()), - 10)
|
||||
.arg(Utils::humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("troughput", 0).toInt()) + " / s", - 13)
|
||||
.arg(Utils::humanReadableTraffic(m_dataMap.value("proxyStatistic").toMap().value("total").toMap().value("totalTraffic").toInt()), - 10)
|
||||
.arg(windowName);
|
||||
break;
|
||||
case ViewTunnelProxy:
|
||||
@ -223,7 +197,7 @@ void TerminalWindow::paintHeader()
|
||||
.arg(m_dataMap.value("tunnelProxyStatistic").toMap().value("totalClientCount", 0).toInt())
|
||||
.arg(m_dataMap.value("tunnelProxyStatistic").toMap().value("serverConnectionsCount", 0).toInt())
|
||||
.arg(m_dataMap.value("tunnelProxyStatistic").toMap().value("clientConnectionsCount", 0).toInt())
|
||||
.arg(humanReadableTraffic(m_dataMap.value("tunnelProxyStatistic").toMap().value("troughput", 0).toInt()) + " / s", - 13)
|
||||
.arg(Utils::humanReadableTraffic(m_dataMap.value("tunnelProxyStatistic").toMap().value("troughput", 0).toInt()) + " / s", - 13)
|
||||
.arg(windowName);
|
||||
break;
|
||||
}
|
||||
@ -258,8 +232,8 @@ void TerminalWindow::paintContentClients()
|
||||
.arg(clientConnectionTime)
|
||||
.arg(clientMap.value("duration").toString())
|
||||
.arg(clientMap.value("address").toString(), - 16)
|
||||
.arg(humanReadableTraffic(rxDataCountBytes), - 10)
|
||||
.arg(humanReadableTraffic(txDataCountBytes), - 10)
|
||||
.arg(Utils::humanReadableTraffic(rxDataCountBytes), - 10)
|
||||
.arg(Utils::humanReadableTraffic(txDataCountBytes), - 10)
|
||||
.arg((clientMap.value("authenticated").toBool() ? "A" : "-"))
|
||||
.arg((clientMap.value("tunnelConnected").toBool() ? "T" : "-"))
|
||||
.arg(clientMap.value("name").toString(), -30);
|
||||
@ -284,8 +258,8 @@ void TerminalWindow::paintContentTunnels()
|
||||
|
||||
QString tunnelPrint = QString("%1 | %2 | %3 | %4 | %5 (%6) <---> %7 (%8)")
|
||||
.arg(tunnelConnectionTime)
|
||||
.arg(getDurationString(timeStamp))
|
||||
.arg(humanReadableTraffic(clientOne.value("rxDataCount").toInt() + clientOne.value("txDataCount").toInt()), - 10)
|
||||
.arg(Utils::getDurationString(timeStamp))
|
||||
.arg(Utils::humanReadableTraffic(clientOne.value("rxDataCount").toInt() + clientOne.value("txDataCount").toInt()), - 10)
|
||||
.arg(clientOne.value("userName").toString())
|
||||
.arg(clientOne.value("name").toString())
|
||||
.arg(clientOne.value("address").toString())
|
||||
@ -312,8 +286,8 @@ void TerminalWindow::paintContentTunnelProxy()
|
||||
QString serverLinePrint = QString("%1 | %2 | RX: %3 | TX: %4 | %5")
|
||||
.arg(serverConnectionTime)
|
||||
.arg(serverMap.value("address").toString(), - 16)
|
||||
.arg(humanReadableTraffic(rxDataCountBytes), - 10)
|
||||
.arg(humanReadableTraffic(txDataCountBytes), - 10)
|
||||
.arg(Utils::humanReadableTraffic(rxDataCountBytes), - 10)
|
||||
.arg(Utils::humanReadableTraffic(txDataCountBytes), - 10)
|
||||
.arg(serverMap.value("name").toString(), -30);
|
||||
|
||||
QVariantList clientList = serverMap.value("clientConnections").toList();
|
||||
@ -343,8 +317,8 @@ void TerminalWindow::paintContentTunnelProxy()
|
||||
QString clientLinePrint = QString("%1 | %2 | RX: %3 | TX: %4 | %5")
|
||||
.arg(QDateTime::fromTime_t(clientMap.value("timestamp").toUInt()).toString("dd.MM.yyyy hh:mm:ss"))
|
||||
.arg(clientMap.value("address").toString(), - 16)
|
||||
.arg(humanReadableTraffic(clientMap.value("rxDataCount").toInt()), - 10)
|
||||
.arg(humanReadableTraffic(clientMap.value("txDataCount").toInt()), - 10)
|
||||
.arg(Utils::humanReadableTraffic(clientMap.value("rxDataCount").toInt()), - 10)
|
||||
.arg(Utils::humanReadableTraffic(clientMap.value("txDataCount").toInt()), - 10)
|
||||
.arg(clientMap.value("name").toString(), -30);
|
||||
|
||||
mvwprintw(m_contentWindow, i, 6, "%s", clientLinePrint.trimmed().toLatin1().constData());
|
||||
@ -437,7 +411,7 @@ void TerminalWindow::refreshWindow(const QVariantMap &dataMap)
|
||||
|
||||
foreach (const QVariant &clientVariant, statisticMap.value("clients").toList()) {
|
||||
QVariantMap clientMap = clientVariant.toMap();
|
||||
clientMap.insert("duration", getDurationString(clientMap.value("timestamp").toUInt()));
|
||||
clientMap.insert("duration", Utils::getDurationString(clientMap.value("timestamp").toUInt()));
|
||||
m_clientHash.insert(clientMap.value("id").toString(), clientMap);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,9 +68,6 @@ private:
|
||||
QVariantMap m_dataMap;
|
||||
QHash<QString, QVariantMap> m_clientHash;
|
||||
|
||||
QString getDurationString(uint timestamp);
|
||||
|
||||
QString humanReadableTraffic(int bytes);
|
||||
|
||||
// content paint methods
|
||||
void resizeWindow();
|
||||
|
||||
65
monitor/utils.h
Normal file
65
monitor/utils.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License as published by the Free Software Foundation,
|
||||
* GNU version 3. this project 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 this project.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under contact@nymea.io
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
|
||||
class Utils {
|
||||
|
||||
public:
|
||||
Utils() = default;
|
||||
|
||||
inline static QString getDurationString(uint timestamp) {
|
||||
uint duration = QDateTime::currentDateTimeUtc().toTime_t() - timestamp;
|
||||
int seconds = static_cast<int>(duration % 60);
|
||||
duration /= 60;
|
||||
int minutes = static_cast<int>(duration % 60);
|
||||
duration /= 60;
|
||||
int hours = static_cast<int>(duration % 24);
|
||||
return QString::asprintf("%02d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
inline static QString humanReadableTraffic(int bytes) {
|
||||
double dataCount = bytes;
|
||||
QStringList list;
|
||||
list << "KB" << "MB" << "GB" << "TB";
|
||||
|
||||
QStringListIterator i(list);
|
||||
QString unit("B");
|
||||
|
||||
while(dataCount >= 1024.0 && i.hasNext()) {
|
||||
unit = i.next();
|
||||
dataCount /= 1024.0;
|
||||
}
|
||||
return QString().setNum(dataCount,'f',2) + " " + unit;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // UTILS_H
|
||||
Reference in New Issue
Block a user