mirror of
https://github.com/arcan1s/awesome-widgets.git
synced 2025-04-24 23:47:20 +00:00
783 lines
28 KiB
C++
783 lines
28 KiB
C++
/***************************************************************************
|
|
* This file is part of awesome-widgets *
|
|
* *
|
|
* awesome-widgets is free software: you can redistribute it and/or *
|
|
* modify it under the terms of the GNU General Public License as *
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
* License, or (at your option) any later version. *
|
|
* *
|
|
* awesome-widgets 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 awesome-widgets. If not, see http://www.gnu.org/licenses/ *
|
|
***************************************************************************/
|
|
|
|
#include "awkeys.h"
|
|
|
|
#include <QtConcurrent/QtConcurrent>
|
|
#include <QDir>
|
|
#include <QInputDialog>
|
|
#include <QJSEngine>
|
|
#include <QNetworkInterface>
|
|
#include <QRegExp>
|
|
#include <QSettings>
|
|
#include <QStandardPaths>
|
|
#include <QThread>
|
|
|
|
#include "awdataaggregator.h"
|
|
#include "awdataengineaggregator.h"
|
|
#include "awdebug.h"
|
|
#include "awkeysaggregator.h"
|
|
#include "extquotes.h"
|
|
#include "extscript.h"
|
|
#include "extupgrade.h"
|
|
#include "extweather.h"
|
|
#include "graphicalitem.h"
|
|
#include "version.h"
|
|
|
|
|
|
AWKeys::AWKeys(QObject *parent)
|
|
: QObject(parent)
|
|
{
|
|
qSetMessagePattern(LOG_FORMAT);
|
|
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
|
|
foreach (const QString metadata, getBuildData())
|
|
qCDebug(LOG_AW) << metadata;
|
|
|
|
#ifdef BUILD_FUTURE
|
|
// thread pool
|
|
m_threadPool = new QThreadPool(this);
|
|
#endif /* BUILD_FUTURE */
|
|
|
|
aggregator = new AWKeysAggregator(this);
|
|
dataAggregator = new AWDataAggregator(this);
|
|
// transfer signal from AWDataAggregator object to QML ui
|
|
connect(dataAggregator, SIGNAL(toolTipPainted(const QString)), this,
|
|
SIGNAL(needToolTipToBeUpdated(const QString)));
|
|
connect(this, SIGNAL(needToBeUpdated()), this, SLOT(updateTextData()));
|
|
}
|
|
|
|
|
|
AWKeys::~AWKeys()
|
|
{
|
|
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
|
|
|
|
// extensions
|
|
delete graphicalItems;
|
|
delete extQuotes;
|
|
delete extScripts;
|
|
delete extUpgrade;
|
|
delete extWeather;
|
|
|
|
// core
|
|
delete dataEngineAggregator;
|
|
delete m_threadPool;
|
|
delete aggregator;
|
|
delete dataAggregator;
|
|
}
|
|
|
|
|
|
void AWKeys::initDataAggregator(const QVariantMap tooltipParams)
|
|
{
|
|
qCDebug(LOG_AW) << "Tooltip parameters" << tooltipParams;
|
|
|
|
dataAggregator->setParameters(tooltipParams);
|
|
}
|
|
|
|
|
|
void AWKeys::initKeys(const QString currentPattern, const int interval,
|
|
const int limit)
|
|
{
|
|
qCDebug(LOG_AW) << "Pattern" << currentPattern;
|
|
qCDebug(LOG_AW) << "Interval" << interval;
|
|
qCDebug(LOG_AW) << "Queue limit" << limit;
|
|
|
|
// init
|
|
m_pattern = currentPattern;
|
|
if (dataEngineAggregator == nullptr) {
|
|
dataEngineAggregator = new AWDataEngineAggregator(this, interval);
|
|
connect(this, SIGNAL(dropSourceFromDataengine(QString)),
|
|
dataEngineAggregator, SLOT(dropSource(QString)));
|
|
} else
|
|
dataEngineAggregator->setInterval(interval);
|
|
#ifdef BUILD_FUTURE
|
|
m_threadPool->setMaxThreadCount(limit == 0 ? QThread::idealThreadCount()
|
|
: limit);
|
|
#endif /* BUILD_FUTURE */
|
|
updateCache();
|
|
|
|
return dataEngineAggregator->reconnectSources();
|
|
}
|
|
|
|
|
|
void AWKeys::setAggregatorProperty(const QString key, const QVariant value)
|
|
{
|
|
qCDebug(LOG_AW) << "Key" << key;
|
|
qCDebug(LOG_AW) << "Value" << value;
|
|
|
|
aggregator->setProperty(key.toUtf8().constData(), value);
|
|
}
|
|
|
|
|
|
void AWKeys::setWrapNewLines(const bool wrap)
|
|
{
|
|
qCDebug(LOG_AW) << "Is wrapping enabled" << wrap;
|
|
|
|
m_wrapNewLines = wrap;
|
|
}
|
|
|
|
|
|
void AWKeys::updateCache()
|
|
{
|
|
// update network and hdd list
|
|
addKeyToCache(QString("hdd"));
|
|
addKeyToCache(QString("net"));
|
|
}
|
|
|
|
|
|
QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const
|
|
{
|
|
qCDebug(LOG_AW) << "Should be sorted" << sorted;
|
|
qCDebug(LOG_AW) << "Filter" << regexp;
|
|
|
|
QStringList allKeys;
|
|
// weather
|
|
for (int i = extWeather->activeItems().count() - 1; i >= 0; i--) {
|
|
allKeys.append(
|
|
extWeather->activeItems().at(i)->tag(QString("weatherId")));
|
|
allKeys.append(
|
|
extWeather->activeItems().at(i)->tag(QString("weather")));
|
|
allKeys.append(
|
|
extWeather->activeItems().at(i)->tag(QString("humidity")));
|
|
allKeys.append(
|
|
extWeather->activeItems().at(i)->tag(QString("pressure")));
|
|
allKeys.append(
|
|
extWeather->activeItems().at(i)->tag(QString("temperature")));
|
|
allKeys.append(
|
|
extWeather->activeItems().at(i)->tag(QString("timestamp")));
|
|
}
|
|
// time
|
|
allKeys.append(QString("time"));
|
|
allKeys.append(QString("isotime"));
|
|
allKeys.append(QString("shorttime"));
|
|
allKeys.append(QString("longtime"));
|
|
allKeys.append(QString("ctime"));
|
|
// uptime
|
|
allKeys.append(QString("uptime"));
|
|
allKeys.append(QString("cuptime"));
|
|
// cpuclock & cpu
|
|
for (int i = QThread::idealThreadCount() - 1; i >= 0; i--) {
|
|
allKeys.append(QString("cpucl%1").arg(i));
|
|
allKeys.append(QString("cpu%1").arg(i));
|
|
}
|
|
allKeys.append(QString("cpucl"));
|
|
allKeys.append(QString("cpu"));
|
|
// temperature
|
|
for (int i = m_devices[QString("temp")].count() - 1; i >= 0; i--)
|
|
allKeys.append(QString("temp%1").arg(i));
|
|
// gputemp
|
|
allKeys.append(QString("gputemp"));
|
|
// gpu
|
|
allKeys.append(QString("gpu"));
|
|
// memory
|
|
allKeys.append(QString("memmb"));
|
|
allKeys.append(QString("memgb"));
|
|
allKeys.append(QString("memfreemb"));
|
|
allKeys.append(QString("memfreegb"));
|
|
allKeys.append(QString("memtotmb"));
|
|
allKeys.append(QString("memtotgb"));
|
|
allKeys.append(QString("memusedmb"));
|
|
allKeys.append(QString("memusedgb"));
|
|
allKeys.append(QString("mem"));
|
|
// swap
|
|
allKeys.append(QString("swapmb"));
|
|
allKeys.append(QString("swapgb"));
|
|
allKeys.append(QString("swapfreemb"));
|
|
allKeys.append(QString("swapfreegb"));
|
|
allKeys.append(QString("swaptotmb"));
|
|
allKeys.append(QString("swaptotgb"));
|
|
allKeys.append(QString("swap"));
|
|
// hdd
|
|
for (int i = m_devices[QString("mount")].count() - 1; i >= 0; i--) {
|
|
allKeys.append(QString("hddmb%1").arg(i));
|
|
allKeys.append(QString("hddgb%1").arg(i));
|
|
allKeys.append(QString("hddfreemb%1").arg(i));
|
|
allKeys.append(QString("hddfreegb%1").arg(i));
|
|
allKeys.append(QString("hddtotmb%1").arg(i));
|
|
allKeys.append(QString("hddtotgb%1").arg(i));
|
|
allKeys.append(QString("hdd%1").arg(i));
|
|
}
|
|
// hdd speed
|
|
for (int i = m_devices[QString("disk")].count() - 1; i >= 0; i--) {
|
|
allKeys.append(QString("hddr%1").arg(i));
|
|
allKeys.append(QString("hddw%1").arg(i));
|
|
}
|
|
// hdd temp
|
|
for (int i = m_devices[QString("hdd")].count() - 1; i >= 0; i--)
|
|
allKeys.append(QString("hddtemp%1").arg(i));
|
|
// network
|
|
for (int i = m_devices[QString("net")].count() - 1; i >= 0; i--) {
|
|
allKeys.append(QString("downunits%1").arg(i));
|
|
allKeys.append(QString("upunits%1").arg(i));
|
|
allKeys.append(QString("downkb%1").arg(i));
|
|
allKeys.append(QString("down%1").arg(i));
|
|
allKeys.append(QString("upkb%1").arg(i));
|
|
allKeys.append(QString("up%1").arg(i));
|
|
}
|
|
allKeys.append(QString("downunits"));
|
|
allKeys.append(QString("upunits"));
|
|
allKeys.append(QString("downkb"));
|
|
allKeys.append(QString("down"));
|
|
allKeys.append(QString("upkb"));
|
|
allKeys.append(QString("up"));
|
|
allKeys.append(QString("netdev"));
|
|
// battery
|
|
allKeys.append(QString("ac"));
|
|
QStringList allBatteryDevices
|
|
= QDir(QString("/sys/class/power_supply"))
|
|
.entryList(QStringList() << QString("BAT*"),
|
|
QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
|
|
for (int i = allBatteryDevices.count() - 1; i >= 0; i--)
|
|
allKeys.append(QString("bat%1").arg(i));
|
|
allKeys.append(QString("bat"));
|
|
// player
|
|
allKeys.append(QString("album"));
|
|
allKeys.append(QString("artist"));
|
|
allKeys.append(QString("duration"));
|
|
allKeys.append(QString("progress"));
|
|
allKeys.append(QString("title"));
|
|
allKeys.append(QString("dalbum"));
|
|
allKeys.append(QString("dartist"));
|
|
allKeys.append(QString("dtitle"));
|
|
allKeys.append(QString("salbum"));
|
|
allKeys.append(QString("sartist"));
|
|
allKeys.append(QString("stitle"));
|
|
// ps
|
|
allKeys.append(QString("pscount"));
|
|
allKeys.append(QString("pstotal"));
|
|
allKeys.append(QString("ps"));
|
|
// package manager
|
|
for (int i = extUpgrade->activeItems().count() - 1; i >= 0; i--)
|
|
allKeys.append(
|
|
extUpgrade->activeItems().at(i)->tag(QString("pkgcount")));
|
|
// quotes
|
|
for (int i = extQuotes->activeItems().count() - 1; i >= 0; i--) {
|
|
allKeys.append(extQuotes->activeItems().at(i)->tag(QString("ask")));
|
|
allKeys.append(extQuotes->activeItems().at(i)->tag(QString("askchg")));
|
|
allKeys.append(
|
|
extQuotes->activeItems().at(i)->tag(QString("percaskchg")));
|
|
allKeys.append(extQuotes->activeItems().at(i)->tag(QString("bid")));
|
|
allKeys.append(extQuotes->activeItems().at(i)->tag(QString("bidchg")));
|
|
allKeys.append(
|
|
extQuotes->activeItems().at(i)->tag(QString("percbidchg")));
|
|
allKeys.append(extQuotes->activeItems().at(i)->tag(QString("price")));
|
|
allKeys.append(
|
|
extQuotes->activeItems().at(i)->tag(QString("pricechg")));
|
|
allKeys.append(
|
|
extQuotes->activeItems().at(i)->tag(QString("percpricechg")));
|
|
}
|
|
// custom
|
|
for (int i = extScripts->activeItems().count() - 1; i >= 0; i--)
|
|
allKeys.append(extScripts->activeItems().at(i)->tag(QString("custom")));
|
|
// desktop
|
|
allKeys.append(QString("desktop"));
|
|
allKeys.append(QString("ndesktop"));
|
|
allKeys.append(QString("tdesktops"));
|
|
// load average
|
|
allKeys.append(QString("la15"));
|
|
allKeys.append(QString("la5"));
|
|
allKeys.append(QString("la1"));
|
|
// bars
|
|
QStringList graphicalItemsKeys;
|
|
foreach (GraphicalItem *item, graphicalItems->items())
|
|
graphicalItemsKeys.append(item->tag());
|
|
graphicalItemsKeys.sort();
|
|
for (int i = graphicalItemsKeys.count() - 1; i >= 0; i--)
|
|
allKeys.append(graphicalItemsKeys.at(i));
|
|
|
|
// sort if required
|
|
if (sorted)
|
|
allKeys.sort();
|
|
|
|
return allKeys.filter(QRegExp(regexp));
|
|
}
|
|
|
|
|
|
QStringList AWKeys::getHddDevices() const
|
|
{
|
|
QStringList devices = m_devices[QString("hdd")];
|
|
// required by selector in the UI
|
|
devices.insert(0, QString("disable"));
|
|
devices.insert(0, QString("auto"));
|
|
|
|
return devices;
|
|
}
|
|
|
|
|
|
QString AWKeys::infoByKey(QString key) const
|
|
{
|
|
qCDebug(LOG_AW) << "Requested key" << key;
|
|
|
|
key.remove(QRegExp(QString("^bar[0-9]{1,}")));
|
|
if (key.startsWith(QString("custom")))
|
|
return extScripts->itemByTagNumber(
|
|
key.remove(QString("custom")).toInt())
|
|
->uniq();
|
|
else if (key.contains(QRegExp(QString("^hdd[rw]"))))
|
|
return QString("%1").arg(m_devices[QString(
|
|
"disk")][key.remove(QRegExp(QString("hdd[rw]"))).toInt()]);
|
|
else if (key.contains(QRegExp(
|
|
QString("^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)"))))
|
|
return QString("%1").arg(m_devices[QString(
|
|
"mount")][key
|
|
.remove(QRegExp(QString(
|
|
"^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)")))
|
|
.toInt()]);
|
|
else if (key.startsWith(QString("hddtemp")))
|
|
return QString("%1").arg(
|
|
m_devices[QString("hdd")][key.remove(QString("hddtemp")).toInt()]);
|
|
else if (key.contains(QRegExp(QString("^(down|up)[0-9]"))))
|
|
return QString("%1").arg(m_devices[QString(
|
|
"net")][key.remove(QRegExp(QString("^(down|up)"))).toInt()]);
|
|
else if (key.startsWith(QString("pkgcount")))
|
|
return extUpgrade->itemByTagNumber(
|
|
key.remove(QString("pkgcount")).toInt())
|
|
->uniq();
|
|
else if (key.contains(QRegExp(QString("(^|perc)(ask|bid|price)(chg|)"))))
|
|
return extQuotes->itemByTagNumber(
|
|
key.remove(QRegExp(QString(
|
|
"(^|perc)(ask|bid|price)(chg|)")))
|
|
.toInt())
|
|
->uniq();
|
|
else if (key.contains(QRegExp(
|
|
QString("(weather|weatherId|humidity|pressure|temperature)"))))
|
|
return extWeather
|
|
->itemByTagNumber(
|
|
key
|
|
.remove(QRegExp(QString(
|
|
"(weather|weatherId|humidity|pressure|temperature)")))
|
|
.toInt())
|
|
->uniq();
|
|
else if (key.startsWith(QString("temp")))
|
|
return QString("%1").arg(
|
|
m_devices[QString("temp")][key.remove(QString("temp")).toInt()]);
|
|
|
|
return QString("(none)");
|
|
}
|
|
|
|
|
|
// HACK this method requires to define tag value from bar from UI interface
|
|
QString AWKeys::valueByKey(QString key) const
|
|
{
|
|
qCDebug(LOG_AW) << "Requested key" << key;
|
|
|
|
return values.value(key.remove(QRegExp(QString("^bar[0-9]{1,}"))),
|
|
QString(""));
|
|
}
|
|
|
|
|
|
void AWKeys::editItem(const QString type)
|
|
{
|
|
qCDebug(LOG_AW) << "Item type" << type;
|
|
|
|
if (type == QString("graphicalitem")) {
|
|
graphicalItems->setConfigArgs(dictKeys(
|
|
true, QString("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)")));
|
|
return graphicalItems->editItems();
|
|
} else if (type == QString("extquotes")) {
|
|
return extQuotes->editItems();
|
|
} else if (type == QString("extscript")) {
|
|
return extScripts->editItems();
|
|
} else if (type == QString("extupgrade")) {
|
|
return extUpgrade->editItems();
|
|
} else if (type == QString("extweather")) {
|
|
return extWeather->editItems();
|
|
}
|
|
}
|
|
|
|
|
|
void AWKeys::addDevice(const QString source)
|
|
{
|
|
qCDebug(LOG_AW) << "Source" << source;
|
|
|
|
QRegExp diskRegexp
|
|
= QRegExp(QString("disk/(?:md|sd|hd)[a-z|0-9]_.*/Rate/(?:rblk)"));
|
|
QRegExp mountRegexp = QRegExp(QString("partitions/.*/filllevel"));
|
|
|
|
if (source.contains(diskRegexp)) {
|
|
QString device = source;
|
|
device.remove(QString("/Rate/rblk"));
|
|
addKeyToCache(QString("disk"), device);
|
|
} else if (source.contains(mountRegexp)) {
|
|
QString device = source;
|
|
device.remove(QString("partitions")).remove(QString("/filllevel"));
|
|
addKeyToCache(QString("mount"), device);
|
|
} else if (source.startsWith(QString("lmsensors"))) {
|
|
addKeyToCache(QString("temp"), source);
|
|
}
|
|
}
|
|
|
|
|
|
void AWKeys::dataUpdated(const QString &sourceName,
|
|
const Plasma::DataEngine::Data &data)
|
|
{
|
|
// do not log these parameters
|
|
if (sourceName == QString("update")) {
|
|
qCInfo(LOG_AW) << "Update data";
|
|
return emit(needToBeUpdated());
|
|
}
|
|
|
|
#ifdef BUILD_FUTURE
|
|
// run concurrent data update
|
|
QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, sourceName,
|
|
data);
|
|
#else /* BUILD_FUTURE */
|
|
return setDataBySource(sourceName, data);
|
|
#endif /* BUILD_FUTURE */
|
|
}
|
|
|
|
|
|
void AWKeys::loadKeysFromCache()
|
|
{
|
|
QString fileName = QString("%1/awesomewidgets.ndx")
|
|
.arg(QStandardPaths::writableLocation(
|
|
QStandardPaths::GenericCacheLocation));
|
|
qCInfo(LOG_AW) << "Cache file" << fileName;
|
|
QSettings cache(fileName, QSettings::IniFormat);
|
|
|
|
foreach (QString group, cache.childGroups()) {
|
|
cache.beginGroup(group);
|
|
m_devices.remove(group);
|
|
foreach (QString key, cache.allKeys())
|
|
m_devices[group].append(cache.value(key).toString());
|
|
cache.endGroup();
|
|
}
|
|
|
|
return reinitKeys();
|
|
}
|
|
|
|
|
|
void AWKeys::reinitKeys()
|
|
{
|
|
// renew extensions
|
|
// delete them if any
|
|
delete graphicalItems;
|
|
graphicalItems = nullptr;
|
|
delete extQuotes;
|
|
extQuotes = nullptr;
|
|
delete extScripts;
|
|
extScripts = nullptr;
|
|
delete extUpgrade;
|
|
extUpgrade = nullptr;
|
|
delete extWeather;
|
|
extWeather = nullptr;
|
|
// create
|
|
graphicalItems
|
|
= new ExtItemAggregator<GraphicalItem>(nullptr, QString("desktops"));
|
|
extQuotes = new ExtItemAggregator<ExtQuotes>(nullptr, QString("quotes"));
|
|
extScripts = new ExtItemAggregator<ExtScript>(nullptr, QString("scripts"));
|
|
extUpgrade = new ExtItemAggregator<ExtUpgrade>(nullptr, QString("upgrade"));
|
|
extWeather = new ExtItemAggregator<ExtWeather>(nullptr, QString("weather"));
|
|
|
|
// init
|
|
QStringList allKeys = dictKeys();
|
|
|
|
#ifdef BUILD_TESTING
|
|
// not documented feature - place all available tags
|
|
m_pattern = m_pattern.replace(QString("$ALL"), [allKeys]() {
|
|
QStringList strings;
|
|
foreach (QString tag, allKeys)
|
|
strings.append(QString("%1: $%1").arg(tag));
|
|
return strings.join(QString(" | "));
|
|
}());
|
|
#endif /* BUILD_TESTING */
|
|
|
|
// append lists
|
|
// bars
|
|
m_foundBars = [allKeys](QString pattern) {
|
|
QStringList selectedKeys;
|
|
foreach (QString key, allKeys)
|
|
if ((key.startsWith(QString("bar")))
|
|
&& (pattern.contains(QString("$%1").arg(key)))) {
|
|
qCInfo(LOG_AW) << "Found bar" << key;
|
|
selectedKeys.append(key);
|
|
}
|
|
if (selectedKeys.isEmpty())
|
|
qCWarning(LOG_AW) << "No bars found";
|
|
return selectedKeys;
|
|
}(m_pattern);
|
|
|
|
// main key list
|
|
m_foundKeys = [allKeys](QString pattern) {
|
|
QStringList selectedKeys;
|
|
foreach (QString key, allKeys)
|
|
if ((!key.startsWith(QString("bar")))
|
|
&& (pattern.contains(QString("$%1").arg(key)))) {
|
|
qCInfo(LOG_AW) << "Found key" << key;
|
|
selectedKeys.append(key);
|
|
}
|
|
if (selectedKeys.isEmpty())
|
|
qCWarning(LOG_AW) << "No keys found";
|
|
return selectedKeys;
|
|
}(m_pattern);
|
|
|
|
// lambdas
|
|
m_foundLambdas = [](QString pattern) {
|
|
QStringList selectedKeys;
|
|
// substring inside ${{ }} (with brackets) which should not contain ${{
|
|
QRegularExpression lambdaRegexp(
|
|
QString("\\$\\{\\{((?!\\$\\{\\{).)*?\\}\\}"));
|
|
lambdaRegexp.setPatternOptions(
|
|
QRegularExpression::DotMatchesEverythingOption);
|
|
|
|
QRegularExpressionMatchIterator it = lambdaRegexp.globalMatch(pattern);
|
|
while (it.hasNext()) {
|
|
QRegularExpressionMatch match = it.next();
|
|
QString lambda = match.captured();
|
|
// drop brakets
|
|
lambda.remove(QRegExp(QString("^\\$\\{\\{")));
|
|
lambda.remove(QRegExp(QString("\\}\\}$")));
|
|
// append
|
|
qCInfo(LOG_AW) << "Found lambda" << lambda;
|
|
selectedKeys.append(lambda);
|
|
}
|
|
if (selectedKeys.isEmpty())
|
|
qCWarning(LOG_AW) << "No lambdas found";
|
|
return selectedKeys;
|
|
}(m_pattern);
|
|
|
|
// set key data to aggregator
|
|
aggregator->setDevices(m_devices);
|
|
}
|
|
|
|
|
|
void AWKeys::updateTextData()
|
|
{
|
|
#ifdef BUILD_FUTURE
|
|
QFuture<QString> text = QtConcurrent::run(m_threadPool, [this]() {
|
|
calculateValues();
|
|
return parsePattern(m_pattern);
|
|
});
|
|
#else /* BUILD_FUTURE */
|
|
calculateValues();
|
|
QString text = parsePattern(m_pattern);
|
|
#endif /* BUILD_FUTURE */
|
|
|
|
emit(needTextToBeUpdated(text));
|
|
emit(dataAggregator->updateData(values));
|
|
}
|
|
|
|
|
|
void AWKeys::addKeyToCache(const QString type, const QString key)
|
|
{
|
|
qCDebug(LOG_AW) << "Key type" << type;
|
|
qCDebug(LOG_AW) << "Key" << key;
|
|
|
|
QString fileName = QString("%1/awesomewidgets.ndx")
|
|
.arg(QStandardPaths::writableLocation(
|
|
QStandardPaths::GenericCacheLocation));
|
|
qCInfo(LOG_AW) << "Cache file" << fileName;
|
|
QSettings cache(fileName, QSettings::IniFormat);
|
|
|
|
cache.beginGroup(type);
|
|
QStringList cachedValues;
|
|
foreach (QString key, cache.allKeys())
|
|
cachedValues.append(cache.value(key).toString());
|
|
|
|
if (type == QString("hdd")) {
|
|
QStringList allDevices
|
|
= QDir(QString("/dev")).entryList(QDir::System, QDir::Name);
|
|
QStringList devices
|
|
= allDevices.filter(QRegExp(QString("^[hms]d[a-z]$")));
|
|
foreach (QString dev, devices) {
|
|
QString device = QString("/dev/%1").arg(dev);
|
|
if (cachedValues.contains(device))
|
|
continue;
|
|
qCInfo(LOG_AW) << "Found new key" << device << "for type" << type;
|
|
cache.setValue(
|
|
QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')),
|
|
device);
|
|
}
|
|
} else if (type == QString("net")) {
|
|
QList<QNetworkInterface> rawInterfaceList
|
|
= QNetworkInterface::allInterfaces();
|
|
foreach (QNetworkInterface interface, rawInterfaceList) {
|
|
QString device = interface.name();
|
|
if (cachedValues.contains(device))
|
|
continue;
|
|
qCInfo(LOG_AW) << "Found new key" << device << "for type" << type;
|
|
cache.setValue(
|
|
QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')),
|
|
device);
|
|
}
|
|
} else {
|
|
if (cachedValues.contains(key))
|
|
return;
|
|
qCInfo(LOG_AW) << "Found new key" << key << "for type" << type;
|
|
cache.setValue(
|
|
QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), key);
|
|
}
|
|
cache.endGroup();
|
|
|
|
cache.sync();
|
|
return loadKeysFromCache();
|
|
}
|
|
|
|
|
|
// HACK this method is required since I could not define some values by using
|
|
// specified pattern. Usually they are values which depend on several others
|
|
void AWKeys::calculateValues()
|
|
{
|
|
// hddtot*
|
|
foreach (QString device, m_devices[QString("mount")]) {
|
|
int index = m_devices[QString("mount")].indexOf(device);
|
|
values[QString("hddtotmb%1").arg(index)] = QString("%1").arg(
|
|
values[QString("hddfreemb%1").arg(index)].toFloat()
|
|
+ values[QString("hddmb%1").arg(index)].toFloat(),
|
|
5, 'f', 0);
|
|
values[QString("hddtotgb%1").arg(index)] = QString("%1").arg(
|
|
values[QString("hddfreegb%1").arg(index)].toFloat()
|
|
+ values[QString("hddgb%1").arg(index)].toFloat(),
|
|
5, 'f', 1);
|
|
}
|
|
|
|
// memtot*
|
|
values[QString("memtotmb")]
|
|
= QString("%1").arg(values[QString("memusedmb")].toInt()
|
|
+ values[QString("memfreemb")].toInt(),
|
|
5);
|
|
values[QString("memtotgb")]
|
|
= QString("%1").arg(values[QString("memusedgb")].toFloat()
|
|
+ values[QString("memfreegb")].toFloat(),
|
|
5, 'f', 1);
|
|
// mem
|
|
values[QString("mem")]
|
|
= QString("%1").arg(100.0 * values[QString("memmb")].toFloat()
|
|
/ values[QString("memtotmb")].toFloat(),
|
|
5, 'f', 1);
|
|
|
|
// up, down, upkb, downkb, upunits, downunits
|
|
int netIndex = m_devices[QString("net")].indexOf(values[QString("netdev")]);
|
|
values[QString("down")] = values[QString("down%1").arg(netIndex)];
|
|
values[QString("downkb")] = values[QString("downkb%1").arg(netIndex)];
|
|
values[QString("downunits")] = values[QString("downunits%1").arg(netIndex)];
|
|
values[QString("up")] = values[QString("up%1").arg(netIndex)];
|
|
values[QString("upkb")] = values[QString("upkb%1").arg(netIndex)];
|
|
values[QString("upunits")] = values[QString("upunits%1").arg(netIndex)];
|
|
|
|
// swaptot*
|
|
values[QString("swaptotmb")]
|
|
= QString("%1").arg(values[QString("swapmb")].toInt()
|
|
+ values[QString("swapfreemb")].toInt(),
|
|
5);
|
|
values[QString("swaptotgb")]
|
|
= QString("%1").arg(values[QString("swapgb")].toFloat()
|
|
+ values[QString("swapfreegb")].toFloat(),
|
|
5, 'f', 1);
|
|
// swap
|
|
values[QString("swap")]
|
|
= QString("%1").arg(100.0 * values[QString("swapmb")].toFloat()
|
|
/ values[QString("swaptotmb")].toFloat(),
|
|
5, 'f', 1);
|
|
|
|
// lambdas
|
|
foreach (QString key, m_foundLambdas)
|
|
values[key] = [this](QString key) {
|
|
QJSEngine engine;
|
|
// apply $this values
|
|
key.replace(QString("$this"), values[key]);
|
|
foreach (QString lambdaKey, m_foundKeys)
|
|
key.replace(QString("$%1").arg(lambdaKey), values[lambdaKey]);
|
|
qCInfo(LOG_AW) << "Expression" << key;
|
|
QJSValue result = engine.evaluate(key);
|
|
if (result.isError()) {
|
|
qCWarning(LOG_AW) << "Uncaught exception at line"
|
|
<< result.property("lineNumber").toInt()
|
|
<< ":" << result.toString();
|
|
return QString();
|
|
} else {
|
|
return result.toString();
|
|
}
|
|
}(key);
|
|
}
|
|
|
|
|
|
QString AWKeys::parsePattern(QString pattern) const
|
|
{
|
|
// screen sign
|
|
pattern.replace(QString("$$"), QString("$\\$\\"));
|
|
|
|
// lambdas
|
|
foreach (QString key, m_foundLambdas)
|
|
pattern.replace(QString("${{%1}}").arg(key), values[key]);
|
|
|
|
// main keys
|
|
foreach (QString key, m_foundKeys)
|
|
pattern.replace(QString("$%1").arg(key),
|
|
[](QString key, QString value) {
|
|
if ((!key.startsWith(QString("custom")))
|
|
&& (!key.startsWith(QString("weather"))))
|
|
value.replace(QString(" "), QString(" "));
|
|
return value;
|
|
}(key, values[key]));
|
|
|
|
// bars
|
|
foreach (QString bar, m_foundBars) {
|
|
GraphicalItem *item = graphicalItems->itemByTag(bar);
|
|
QString key = bar;
|
|
key.remove(QRegExp(QString("^bar[0-9]{1,}")));
|
|
if (item->type() == GraphicalItem::Graph)
|
|
pattern.replace(QString("$%1").arg(bar),
|
|
item->image([](const QList<float> data) {
|
|
return QVariant::fromValue<QList<float>>(data);
|
|
}(dataAggregator->getData(key))));
|
|
else
|
|
pattern.replace(QString("$%1").arg(bar), item->image(values[key]));
|
|
}
|
|
|
|
// prepare strings
|
|
pattern.replace(QString("$\\$\\"), QString("$$"));
|
|
if (m_wrapNewLines)
|
|
pattern.replace(QString("\n"), QString("<br>"));
|
|
|
|
return pattern;
|
|
}
|
|
|
|
|
|
void AWKeys::setDataBySource(const QString &sourceName, const QVariantMap &data)
|
|
{
|
|
qCDebug(LOG_AW) << "Source" << sourceName;
|
|
qCDebug(LOG_AW) << "Data" << data;
|
|
|
|
// first list init
|
|
QStringList tags = aggregator->keysFromSource(sourceName);
|
|
if (tags.isEmpty())
|
|
tags = aggregator->registerSource(sourceName,
|
|
data[QString("units")].toString());
|
|
|
|
// update data or drop source if there are no matches
|
|
if (tags.isEmpty()) {
|
|
qCDebug(LOG_AW) << "Source" << sourceName << "not found";
|
|
emit(dropSourceFromDataengine(sourceName));
|
|
} else {
|
|
#ifdef BUILD_FUTURE
|
|
m_mutex.lock();
|
|
#endif /* BUILD_FUTURE */
|
|
// HACK workaround for time values which are stored in the different
|
|
// path
|
|
QVariant value = sourceName == QString("Local")
|
|
? data[QString("DateTime")]
|
|
: data[QString("value")];
|
|
std::for_each(tags.cbegin(), tags.cend(),
|
|
[this, value](const QString tag) {
|
|
values[tag] = aggregator->formater(value, tag);
|
|
});
|
|
#ifdef BUILD_FUTURE
|
|
m_mutex.unlock();
|
|
#endif /* BUILD_FUTURE */
|
|
}
|
|
}
|