File indexing completed on 2024-06-16 05:07:33
0001 /* 0002 SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "network.h" 0008 0009 #include <QDateTime> 0010 #include <QDebug> 0011 #include <QFile> 0012 #include <QHash> 0013 #include <QProcess> 0014 #include <QStandardPaths> 0015 0016 #include <KLocalizedString> 0017 #include <KPluginFactory> 0018 0019 #include "networkconstants.h" 0020 #include "networklogging.h" 0021 0022 using namespace KSysGuard; 0023 0024 NetworkPlugin::NetworkPlugin(QObject *parent, const QVariantList &args) 0025 : ProcessDataProvider(parent, args) 0026 { 0027 const auto executable = NetworkConstants::HelperLocation; 0028 if (!QFile::exists(executable)) { 0029 qCWarning(KSYSGUARD_PLUGIN_NETWORK) << "Could not find ksgrd_network_helper"; 0030 return; 0031 } 0032 0033 qCDebug(KSYSGUARD_PLUGIN_NETWORK) << "Network plugin loading"; 0034 qCDebug(KSYSGUARD_PLUGIN_NETWORK) << "Found helper at" << qPrintable(executable); 0035 0036 m_inboundSensor = new ProcessAttribute(QStringLiteral("netInbound"), i18nc("@title", "Download Speed"), this); 0037 m_inboundSensor->setShortName(i18nc("@title", "Download")); 0038 m_inboundSensor->setUnit(KSysGuard::UnitByteRate); 0039 m_inboundSensor->setVisibleByDefault(true); 0040 m_outboundSensor = new ProcessAttribute(QStringLiteral("netOutbound"), i18nc("@title", "Upload Speed"), this); 0041 m_outboundSensor->setShortName(i18nc("@title", "Upload")); 0042 m_outboundSensor->setUnit(KSysGuard::UnitByteRate); 0043 m_outboundSensor->setVisibleByDefault(true); 0044 0045 addProcessAttribute(m_inboundSensor); 0046 addProcessAttribute(m_outboundSensor); 0047 0048 m_process = new QProcess(this); 0049 m_process->setProgram(executable); 0050 0051 connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [this](int exitCode, QProcess::ExitStatus status) { 0052 if (exitCode != 0 || status != QProcess::NormalExit) { 0053 qCWarning(KSYSGUARD_PLUGIN_NETWORK) << "Helper process terminated abnormally:" << m_process->readAllStandardError().trimmed(); 0054 } 0055 }); 0056 0057 connect(m_process, &QProcess::readyReadStandardOutput, this, [this]() { 0058 while (m_process->canReadLine()) { 0059 const QString line = QString::fromUtf8(m_process->readLine()); 0060 0061 // Each line consists of: timestamp|PID|pid|IN|in_bytes|OUT|out_bytes 0062 const auto parts = QStringView(line).split(QLatin1Char('|'), Qt::SkipEmptyParts); 0063 if (parts.size() < 7) { 0064 continue; 0065 } 0066 0067 long pid = parts.at(2).toLong(); 0068 0069 auto timeStamp = QDateTime::currentDateTimeUtc(); 0070 timeStamp.setTime(QTime::fromString(parts.at(0).toString(), QStringLiteral("HH:mm:ss"))); 0071 0072 auto bytesIn = parts.at(4).toUInt(); 0073 auto bytesOut = parts.at(6).toUInt(); 0074 0075 auto process = getProcess(pid); 0076 if (!process) { 0077 return; 0078 } 0079 0080 m_inboundSensor->setData(process, bytesIn); 0081 m_outboundSensor->setData(process, bytesOut); 0082 } 0083 }); 0084 } 0085 0086 void NetworkPlugin::handleEnabledChanged(bool enabled) 0087 { 0088 if (enabled) { 0089 qCDebug(KSYSGUARD_PLUGIN_NETWORK) << "Network plugin enabled, starting helper"; 0090 m_process->start(); 0091 } else { 0092 qCDebug(KSYSGUARD_PLUGIN_NETWORK) << "Network plugin disabled, stopping helper"; 0093 m_process->terminate(); 0094 } 0095 } 0096 0097 K_PLUGIN_FACTORY_WITH_JSON(PluginFactory, "networkplugin.json", registerPlugin<NetworkPlugin>();) 0098 0099 #include "network.moc"