implement qcronscheduler, tests update

This commit is contained in:
2017-04-28 01:47:42 +03:00
parent 8be4cc6e82
commit 1b4d1d6944
55 changed files with 412 additions and 144 deletions

View File

@ -25,6 +25,7 @@
#include "abstractextitemaggregator.h"
#include "awdebug.h"
#include "qcronscheduler.h"
AbstractExtItem::AbstractExtItem(QWidget *parent, const QString filePath)
@ -70,12 +71,32 @@ void AbstractExtItem::copyDefaults(AbstractExtItem *_other) const
_other->setActive(isActive());
_other->setApiVersion(apiVersion());
_other->setComment(comment());
_other->setCron(cron());
_other->setInterval(interval());
_other->setName(name());
_other->setSocket(socket());
}
void AbstractExtItem::startTimer()
{
if (!socket().isEmpty())
// check if there is active socket setup
return;
else if (!cron().isEmpty())
// check if there is active scheduler
return;
else if (m_times == 1)
// check if it is time to update
emit(requestDataUpdate());
// update counter value
if (m_times >= interval())
m_times = 0;
m_times++;
}
QString AbstractExtItem::writtableConfig() const
{
QString path = m_fileName;
@ -103,6 +124,12 @@ QString AbstractExtItem::comment() const
}
QString AbstractExtItem::cron() const
{
return m_cron;
}
QString AbstractExtItem::fileName() const
{
return m_fileName;
@ -171,6 +198,28 @@ void AbstractExtItem::setComment(const QString _comment)
}
void AbstractExtItem::setCron(const QString _cron)
{
qCDebug(LOG_LIB) << "Cron string" << _cron;
// deinit module first
if (m_scheduler) {
disconnect(m_scheduler, SIGNAL(activated()), this,
SIGNAL(requestDataUpdate()));
delete m_scheduler;
}
m_cron = _cron;
if (cron().isEmpty())
return;
// init scheduler
m_scheduler = new QCronScheduler(this);
m_scheduler->parse(cron());
connect(m_scheduler, SIGNAL(activated()), this,
SIGNAL(requestDataUpdate()));
}
void AbstractExtItem::setInterval(const int _interval)
{
qCDebug(LOG_LIB) << "Interval" << _interval;
@ -217,8 +266,6 @@ void AbstractExtItem::setSocket(const QString _socket)
deinitSocket();
m_socketFile = _socket;
if (socket().isEmpty())
return;
}
@ -260,9 +307,15 @@ void AbstractExtItem::readConfiguration()
setActive(
settings.value(QString("X-AW-Active"), QVariant(isActive())).toString()
== QString("true"));
setInterval(settings.value(QString("X-AW-Interval"), interval()).toInt());
setNumber(settings.value(QString("X-AW-Number"), number()).toInt());
setSocket(settings.value(QString("X-AW-Socket"), socket()).toString());
// interval definition
QVariant value = settings.value(QString("X-AW-Interval"), interval());
if (value.type() == QVariant::Int)
setInterval(value.toInt());
else
setCron(value.toString());
settings.endGroup();
}
@ -287,7 +340,9 @@ void AbstractExtItem::writeConfiguration() const
settings.setValue(QString("Comment"), comment());
settings.setValue(QString("X-AW-ApiVersion"), apiVersion());
settings.setValue(QString("X-AW-Active"), QVariant(isActive()).toString());
settings.setValue(QString("X-AW-Interval"), interval());
settings.setValue(QString("X-AW-Interval"),
cron().isEmpty() ? QVariant(interval())
: QVariant(cron()));
settings.setValue(QString("X-AW-Number"), number());
settings.setValue(QString("X-AW-Socket"), socket());
settings.endGroup();
@ -298,5 +353,5 @@ void AbstractExtItem::writeConfiguration() const
void AbstractExtItem::newConnectionReceived()
{
emit(socketActivated());
emit(requestDataUpdate());
}

View File

@ -22,6 +22,7 @@
#include <QVariant>
class QCronScheduler;
class QLocalServer;
class AbstractExtItem : public QDialog
@ -30,6 +31,7 @@ class AbstractExtItem : public QDialog
Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(int apiVersion READ apiVersion WRITE setApiVersion)
Q_PROPERTY(QString comment READ comment WRITE setComment)
Q_PROPERTY(QString cron READ cron WRITE setCron)
Q_PROPERTY(QString fileName READ fileName)
Q_PROPERTY(int interval READ interval WRITE setInterval)
Q_PROPERTY(QString name READ name WRITE setName)
@ -45,10 +47,12 @@ public:
virtual AbstractExtItem *copy(const QString _fileName, const int _number)
= 0;
virtual void copyDefaults(AbstractExtItem *_other) const;
virtual void startTimer();
QString writtableConfig() const;
// get methods
int apiVersion() const;
QString comment() const;
QString cron() const;
QString fileName() const;
int interval() const;
bool isActive() const;
@ -61,6 +65,7 @@ public:
void setApiVersion(const int _apiVersion = 0);
void setActive(const bool _state = true);
void setComment(const QString _comment = QString("empty"));
void setCron(const QString _cron = "");
void setInterval(const int _interval = 1);
void setName(const QString _name = QString("none"));
void setNumber(int _number = -1);
@ -68,7 +73,7 @@ public:
signals:
void dataReceived(const QVariantHash &data);
void socketActivated();
void requestDataUpdate();
public slots:
virtual void deinitSocket();
@ -76,19 +81,22 @@ public slots:
virtual void readConfiguration();
virtual QVariantHash run() = 0;
virtual int showConfiguration(const QVariant args = QVariant()) = 0;
bool tryDelete() const;
virtual bool tryDelete() const;
virtual void writeConfiguration() const;
private slots:
void newConnectionReceived();
private:
QCronScheduler *m_scheduler = nullptr;
QString m_fileName = QString("/dev/null");
int m_times = 0;
virtual void translate() = 0;
// properties
int m_apiVersion = 0;
bool m_active = true;
QString m_comment = QString("empty");
QString m_cron = "";
int m_interval = 1;
QString m_name = QString("none");
int m_number = -1;

View File

@ -50,7 +50,7 @@ ExtNetworkRequest::ExtNetworkRequest(QWidget *parent, const QString filePath)
connect(m_manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(networkReplyReceived(QNetworkReply *)));
connect(this, SIGNAL(socketActivated()), this, SLOT(sendRequest()));
connect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest()));
}
@ -60,7 +60,7 @@ ExtNetworkRequest::~ExtNetworkRequest()
disconnect(m_manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(networkReplyReceived(QNetworkReply *)));
disconnect(this, SIGNAL(socketActivated()), this, SLOT(sendRequest()));
disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest()));
m_manager->deleteLater();
delete ui;
@ -119,16 +119,9 @@ void ExtNetworkRequest::readConfiguration()
QVariantHash ExtNetworkRequest::run()
{
if (!canRun())
if (m_isRunning)
return m_values;
if (m_times == 1)
sendRequest();
// update value
if (m_times >= interval())
m_times = 0;
m_times++;
startTimer();
return m_values;
}
@ -202,12 +195,6 @@ void ExtNetworkRequest::sendRequest()
}
bool ExtNetworkRequest::canRun() const
{
return ((isActive()) && (!m_isRunning) && (socket().isEmpty()));
}
void ExtNetworkRequest::initUrl()
{
m_url = QUrl(m_stringUrl);

View File

@ -59,7 +59,6 @@ private:
QUrl m_url;
bool m_isRunning = false;
Ui::ExtNetworkRequest *ui = nullptr;
bool canRun() const;
void initUrl();
void translate();
// properties

View File

@ -60,7 +60,7 @@ ExtQuotes::ExtQuotes(QWidget *parent, const QString filePath)
connect(m_manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(quotesReplyReceived(QNetworkReply *)));
connect(this, SIGNAL(socketActivated()), this, SLOT(sendRequest()));
connect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest()));
}
@ -70,7 +70,7 @@ ExtQuotes::~ExtQuotes()
disconnect(m_manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(quotesReplyReceived(QNetworkReply *)));
disconnect(this, SIGNAL(socketActivated()), this, SLOT(sendRequest()));
disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest()));
m_manager->deleteLater();
delete ui;
@ -128,16 +128,9 @@ void ExtQuotes::readConfiguration()
QVariantHash ExtQuotes::run()
{
if (!canRun())
if (m_isRunning)
return m_values;
if (m_times == 1)
sendRequest();
// update value
if (m_times >= interval())
m_times = 0;
m_times++;
startTimer();
return m_values;
}
@ -254,12 +247,6 @@ void ExtQuotes::sendRequest()
}
bool ExtQuotes::canRun() const
{
return ((isActive()) && (!m_isRunning) && (socket().isEmpty()));
}
void ExtQuotes::initUrl()
{
// init query

View File

@ -62,7 +62,6 @@ private:
QUrl m_url;
bool m_isRunning = false;
Ui::ExtQuotes *ui = nullptr;
bool canRun() const;
void initUrl();
void translate();
// properties

View File

@ -49,7 +49,7 @@ ExtScript::ExtScript(QWidget *parent, const QString filePath)
SLOT(updateValue()));
m_process->waitForFinished(0);
connect(this, SIGNAL(socketActivated()), this, SLOT(startProcess()));
connect(this, SIGNAL(requestDataUpdate()), this, SLOT(startProcess()));
}
@ -61,7 +61,7 @@ ExtScript::~ExtScript()
SLOT(updateValue()));
m_process->kill();
m_process->deleteLater();
disconnect(this, SIGNAL(socketActivated()), this, SLOT(startProcess()));
disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(startProcess()));
delete ui;
}
@ -203,8 +203,8 @@ QString ExtScript::applyFilters(QString _value) const
qCInfo(LOG_LIB) << "Found filter" << filt;
QVariantMap filter = m_jsonFilters[filt].toMap();
if (filter.isEmpty()) {
qCWarning(LOG_LIB) << "Could not find filter" << _value
<< "in the json";
qCWarning(LOG_LIB)
<< "Could not find filter" << _value << "in the json";
continue;
}
for (auto f : filter.keys())
@ -273,19 +273,11 @@ void ExtScript::readJsonFilters()
}
#include <QThread>
QVariantHash ExtScript::run()
{
if (!canRun())
if (m_process->state() != QProcess::NotRunning)
return m_values;
if (m_times == 1)
startProcess();
// update value
if (m_times >= interval())
m_times = 0;
m_times++;
startTimer();
return m_values;
}
@ -401,13 +393,6 @@ void ExtScript::updateValue()
}
bool ExtScript::canRun() const
{
return ((isActive()) && (m_process->state() == QProcess::NotRunning)
&& (socket().isEmpty()));
}
void ExtScript::translate()
{
ui->label_name->setText(i18n("Name"));

View File

@ -80,7 +80,6 @@ private slots:
private:
QProcess *m_process = nullptr;
Ui::ExtScript *ui = nullptr;
bool canRun() const;
void translate();
// properties
QString m_executable = QString("/usr/bin/true");

View File

@ -45,7 +45,7 @@ ExtUpgrade::ExtUpgrade(QWidget *parent, const QString filePath)
connect(m_process, SIGNAL(finished(int)), this, SLOT(updateValue()));
m_process->waitForFinished(0);
connect(this, SIGNAL(socketActivated()), this, SLOT(startProcess()));
connect(this, SIGNAL(requestDataUpdate()), this, SLOT(startProcess()));
}
@ -55,7 +55,7 @@ ExtUpgrade::~ExtUpgrade()
m_process->kill();
m_process->deleteLater();
disconnect(this, SIGNAL(socketActivated()), this, SLOT(startProcess()));
disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(startProcess()));
delete ui;
}
@ -145,16 +145,9 @@ void ExtUpgrade::readConfiguration()
QVariantHash ExtUpgrade::run()
{
if (!isActive())
if (m_process->state() != QProcess::NotRunning)
return m_values;
if (m_times == 1)
startProcess();
// update value
if (m_times >= interval())
m_times = 0;
m_times++;
startTimer();
return m_values;
}
@ -240,13 +233,6 @@ void ExtUpgrade::updateValue()
}
bool ExtUpgrade::canRun()
{
return ((isActive()) && (m_process->state() == QProcess::NotRunning)
&& (socket().isEmpty()));
}
void ExtUpgrade::translate()
{
ui->label_name->setText(i18n("Name"));

View File

@ -62,7 +62,6 @@ private slots:
private:
QProcess *m_process = nullptr;
Ui::ExtUpgrade *ui = nullptr;
bool canRun();
void translate();
// properties
QString m_executable = QString("/usr/bin/true");

View File

@ -59,7 +59,7 @@ ExtWeather::ExtWeather(QWidget *parent, const QString filePath)
connect(m_manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(weatherReplyReceived(QNetworkReply *)));
connect(this, SIGNAL(socketActivated()), this, SLOT(sendRequest()));
connect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest()));
}
@ -69,7 +69,7 @@ ExtWeather::~ExtWeather()
disconnect(m_manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(weatherReplyReceived(QNetworkReply *)));
disconnect(this, SIGNAL(socketActivated()), this, SLOT(sendRequest()));
disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest()));
m_manager->deleteLater();
delete m_providerObject;
@ -270,16 +270,9 @@ void ExtWeather::readJsonMap()
QVariantHash ExtWeather::run()
{
if ((!isActive()) || (m_isRunning))
if (m_isRunning)
return m_values;
if (m_times == 1)
sendRequest();
// update value
if (m_times >= interval())
m_times = 0;
m_times++;
startTimer();
return m_values;
}
@ -379,12 +372,6 @@ void ExtWeather::weatherReplyReceived(QNetworkReply *reply)
}
bool ExtWeather::canRun()
{
return ((isActive()) && (!m_isRunning) && (socket().isEmpty()));
}
void ExtWeather::initProvider()
{
delete m_providerObject;

View File

@ -79,7 +79,6 @@ private:
AbstractWeatherProvider *m_providerObject = nullptr;
bool m_isRunning = false;
Ui::ExtWeather *ui = nullptr;
bool canRun();
void initProvider();
void translate();
// properties

View File

@ -0,0 +1,158 @@
/***************************************************************************
* 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 "qcronscheduler.h"
#include <QDateTime>
#include <QTimer>
#include "awdebug.h"
QCronScheduler::QCronScheduler(QObject *parent)
: QObject(parent)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
m_timer = new QTimer(this);
m_timer->setSingleShot(false);
m_timer->setInterval(60 * 1000);
connect(m_timer, SIGNAL(timeout()), this, SLOT(expired()));
m_timer->start();
}
QCronScheduler::~QCronScheduler()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
m_timer->stop();
delete m_timer;
}
void QCronScheduler::parse(const QString &timer)
{
qCDebug(LOG_LIB) << "Parse timer string" << timer;
QStringList fields = timer.split(' ');
if (fields.count() != 5)
return;
m_schedule.minutes = parseField(fields.at(1), 0, 59);
m_schedule.hours = parseField(fields.at(2), 0, 23);
m_schedule.days = parseField(fields.at(3), 1, 31);
m_schedule.months = parseField(fields.at(4), 1, 12);
m_schedule.weekdays = parseField(fields.at(5), 1, 7);
}
void QCronScheduler::expired()
{
QDateTime now = QDateTime::currentDateTime();
if (m_schedule.minutes.contains(now.time().minute())
&& m_schedule.hours.contains(now.time().hour())
&& m_schedule.days.contains(now.date().day())
&& m_schedule.months.contains(now.date().month())
&& m_schedule.weekdays.contains(now.date().dayOfWeek()))
emit(activated());
}
QList<int> QCronScheduler::parseField(const QString &value, const int min,
const int max) const
{
qCDebug(LOG_LIB) << "Parse field" << value << "with corner values" << min
<< max;
QList<int> parsed;
auto fields = value.split(',');
for (auto &field : fields) {
QCronField parsedField;
parsedField.fromRange(field.split('/').first(), min, max);
if (field.contains('/')) {
bool status;
parsedField.div = field.split('/', QString::SkipEmptyParts)
.at(1)
.toInt(&status);
if (!status)
parsedField.div = 1;
}
// append
parsed.append(parsedField.toList());
}
return parsed;
}
void QCronScheduler::QCronField::fromRange(const QString &range, const int min,
const int max)
{
qCDebug(LOG_LIB) << "Parse field from range" << range
<< "with corner values" << min << max;
if (range == '*') {
this->min = min;
this->max = max;
} else if (range.contains('-')) {
auto interval = range.split('-', QString::SkipEmptyParts);
if (interval.count() != 2)
return;
bool status;
// minimal value
this->min = std::max(min, interval.at(0).toInt(&status));
if (!status)
this->min = -1;
// maximal value
this->max = std::min(max, interval.at(1).toInt(&status));
if (!status)
this->max = -1;
// error check
if (this->min > this->max)
std::swap(this->min, this->max);
} else {
bool status;
int value = range.toInt(&status);
if (!status || (value < min) || (value > max))
value = -1;
this->min = value;
this->max = value;
}
}
QList<int> QCronScheduler::QCronField::toList()
{
// error checking
if ((min == -1) || (max == -1))
return QList<int>();
QList<int> output;
for (auto i = min; i <= max; ++i) {
if (i % div != 0)
continue;
output.append(i);
}
std::sort(output.begin(), output.end());
return output;
}

View File

@ -0,0 +1,64 @@
/***************************************************************************
* 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/ *
***************************************************************************/
#ifndef QCRONSCHEDULER_H
#define QCRONSCHEDULER_H
#include "QObject"
class QTimer;
class QCronScheduler : public QObject
{
Q_OBJECT
public:
typedef struct {
QList<int> minutes;
QList<int> hours;
QList<int> days;
QList<int> months;
QList<int> weekdays;
} QCronRunSchedule;
typedef struct {
int min = -1;
int max = -1;
int div = 1;
void fromRange(const QString &range, const int min, const int max);
QList<int> toList();
} QCronField;
explicit QCronScheduler(QObject *parent);
virtual ~QCronScheduler();
void parse(const QString &timer);
signals:
void activated();
private slots:
void expired();
private:
QCronRunSchedule m_schedule;
QTimer *m_timer = nullptr;
QList<int> parseField(const QString &value, const int min,
const int max) const;
};
#endif /* QCRONSCHEDULER_H */