UI: StatisticsPage: Add active period hours.

This commit is contained in:
Nodir Temirkhodjaev 2018-08-31 16:35:35 +05:00
parent 6daaffb8ea
commit f4a06fd032
15 changed files with 276 additions and 68 deletions

View File

@ -132,6 +132,26 @@ void Test::debugStatTrafStep(SqliteDb *sqliteDb, const char *name,
qDebug() << "--";
}
void Test::activePeriod()
{
const QDate d1(2018, 8, 31);
const QTime t1(15, 35, 24);
const QDateTime dt1(d1, t1);
const qint64 unixTime = dt1.toSecsSinceEpoch();
const qint32 unixDay = DateUtil::getUnixDay(unixTime);
const qint32 unixHour = DateUtil::getUnixHour(unixTime);
QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 0, 24));
QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 15, 15));
QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 15, 16));
QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 15, 10));
QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 16, 15));
QVERIFY(!DateUtil::isHourBetween(unixHour, unixDay, 24, 0));
QVERIFY(!DateUtil::isHourBetween(unixHour, unixDay, 16, 14));
QVERIFY(!DateUtil::isHourBetween(unixHour, unixDay, 16, 24));
}
void Test::monthStart()
{
const QDate d1(2018, 1, 8);

View File

@ -11,6 +11,7 @@ class Test : public QObject
private slots:
void dbWriteRead();
void activePeriod();
void monthStart();
private:

View File

@ -18,6 +18,9 @@ FirewallConf::FirewallConf(QObject *parent) :
m_logStat(false),
m_appBlockAll(true),
m_appAllowAll(false),
m_activePeriodEnabled(false),
m_activePeriodFrom(0),
m_activePeriodTo(0),
m_monthStart(DEFAULT_MONTH_START),
m_trafHourKeepDays(DEFAULT_TRAF_HOUR_KEEP_DAYS),
m_trafDayKeepDays(DEFAULT_TRAF_DAY_KEEP_DAYS),
@ -110,6 +113,30 @@ void FirewallConf::setAppAllowAll(bool appAllowAll)
}
}
void FirewallConf::setActivePeriodEnabled(bool activePeriodEnabled)
{
if (m_activePeriodEnabled != activePeriodEnabled) {
m_activePeriodEnabled = activePeriodEnabled;
emit activePeriodEnabledChanged();
}
}
void FirewallConf::setActivePeriodFrom(int activePeriodFrom)
{
if (m_activePeriodFrom != activePeriodFrom) {
m_activePeriodFrom = uint(activePeriodFrom);
emit activePeriodFromChanged();
}
}
void FirewallConf::setActivePeriodTo(int activePeriodTo)
{
if (m_activePeriodTo != activePeriodTo) {
m_activePeriodTo = uint(activePeriodTo);
emit activePeriodToChanged();
}
}
void FirewallConf::setMonthStart(int monthStart)
{
if (m_monthStart != monthStart) {
@ -263,6 +290,10 @@ void FirewallConf::copyFlags(const FirewallConf &o)
setPasswordHash(o.passwordHash());
setAppGroupBits(o.appGroupBits());
setActivePeriodEnabled(o.activePeriodEnabled());
setActivePeriodFrom(o.activePeriodFrom());
setActivePeriodTo(o.activePeriodTo());
setMonthStart(o.monthStart());
setTrafHourKeepDays(o.trafHourKeepDays());
setTrafDayKeepDays(o.trafDayKeepDays());

View File

@ -27,6 +27,9 @@ class FirewallConf : public QObject
Q_PROPERTY(bool logStat READ logStat WRITE setLogStat NOTIFY logStatChanged)
Q_PROPERTY(bool appBlockAll READ appBlockAll WRITE setAppBlockAll NOTIFY appBlockAllChanged)
Q_PROPERTY(bool appAllowAll READ appAllowAll WRITE setAppAllowAll NOTIFY appAllowAllChanged)
Q_PROPERTY(bool activePeriodEnabled READ activePeriodEnabled WRITE setActivePeriodEnabled NOTIFY activePeriodEnabledChanged)
Q_PROPERTY(int activePeriodFrom READ activePeriodFrom WRITE setActivePeriodFrom NOTIFY activePeriodFromChanged)
Q_PROPERTY(int activePeriodTo READ activePeriodTo WRITE setActivePeriodTo NOTIFY activePeriodToChanged)
Q_PROPERTY(int monthStart READ monthStart WRITE setMonthStart NOTIFY monthStartChanged)
Q_PROPERTY(int trafHourKeepDays READ trafHourKeepDays WRITE setTrafHourKeepDays NOTIFY trafHourKeepDaysChanged)
Q_PROPERTY(int trafDayKeepDays READ trafDayKeepDays WRITE setTrafDayKeepDays NOTIFY trafDayKeepDaysChanged)
@ -84,6 +87,15 @@ public:
bool appAllowAll() const { return m_appAllowAll; }
void setAppAllowAll(bool appAllowAll);
bool activePeriodEnabled() const { return m_activePeriodEnabled; }
void setActivePeriodEnabled(bool activePeriodEnabled);
int activePeriodFrom() const { return m_activePeriodFrom; }
void setActivePeriodFrom(int activePeriodFrom);
int activePeriodTo() const { return m_activePeriodTo; }
void setActivePeriodTo(int activePeriodTo);
int monthStart() const { return m_monthStart; }
void setMonthStart(int monthStart);
@ -142,6 +154,9 @@ signals:
void logStatChanged();
void appBlockAllChanged();
void appAllowAllChanged();
void activePeriodEnabledChanged();
void activePeriodFromChanged();
void activePeriodToChanged();
void monthStartChanged();
void trafHourKeepDaysChanged();
void trafDayKeepDaysChanged();
@ -174,6 +189,10 @@ private:
uint m_appBlockAll : 1;
uint m_appAllowAll : 1;
uint m_activePeriodEnabled : 1;
uint m_activePeriodFrom : 5;
uint m_activePeriodTo : 5;
uint m_monthStart : 5;
int m_trafHourKeepDays;

View File

@ -182,7 +182,8 @@ void DatabaseManager::logProcNew(quint32 pid, const QString &appPath)
qint64 appId = getAppId(appPath);
if (appId == INVALID_APP_ID) {
appId = createAppId(appPath);
const qint64 unixTime = DateUtil::getUnixTime();
appId = createAppId(appPath, unixTime);
}
m_sqliteDb->commitTransaction();
@ -235,69 +236,77 @@ void DatabaseManager::logStatTraf(quint16 procCount, const quint32 *procTrafByte
m_sqliteDb->beginTransaction();
// Insert Statemets
const QStmtList insertTrafAppStmts = QStmtList()
<< getTrafficStmt(DatabaseSql::sqlInsertTrafAppHour, trafHour)
<< getTrafficStmt(DatabaseSql::sqlInsertTrafAppDay, trafDay)
<< getTrafficStmt(DatabaseSql::sqlInsertTrafAppMonth, trafMonth)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppTotal, -1);
// Store the data
const bool isActivePeriod = !m_conf->activePeriodEnabled()
|| DateUtil::isHourBetween(trafHour, trafDay,
m_conf->activePeriodFrom(),
m_conf->activePeriodTo());
const QStmtList insertTrafStmts = QStmtList()
<< getTrafficStmt(DatabaseSql::sqlInsertTrafHour, trafHour)
<< getTrafficStmt(DatabaseSql::sqlInsertTrafDay, trafDay)
<< getTrafficStmt(DatabaseSql::sqlInsertTrafMonth, trafMonth);
if (isActivePeriod) {
// Insert Statements
const QStmtList insertTrafAppStmts = QStmtList()
<< getTrafficStmt(DatabaseSql::sqlInsertTrafAppHour, trafHour)
<< getTrafficStmt(DatabaseSql::sqlInsertTrafAppDay, trafDay)
<< getTrafficStmt(DatabaseSql::sqlInsertTrafAppMonth, trafMonth)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppTotal, -1);
// Update Statemets
const QStmtList updateTrafAppStmts = QStmtList()
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppHour, trafHour)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppDay, trafDay)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppMonth, trafMonth)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppTotal, -1);
const QStmtList insertTrafStmts = QStmtList()
<< getTrafficStmt(DatabaseSql::sqlInsertTrafHour, trafHour)
<< getTrafficStmt(DatabaseSql::sqlInsertTrafDay, trafDay)
<< getTrafficStmt(DatabaseSql::sqlInsertTrafMonth, trafMonth);
const QStmtList updateTrafStmts = QStmtList()
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafHour, trafHour)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafDay, trafDay)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafMonth, trafMonth);
// Update Statements
const QStmtList updateTrafAppStmts = QStmtList()
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppHour, trafHour)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppDay, trafDay)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppMonth, trafMonth)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafAppTotal, -1);
for (int i = 0; i < procCount; ++i) {
quint32 pid = *procTrafBytes++;
const bool inactive = (pid & 1) != 0;
const quint32 inBytes = *procTrafBytes++;
const quint32 outBytes = *procTrafBytes++;
const QStmtList updateTrafStmts = QStmtList()
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafHour, trafHour)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafDay, trafDay)
<< getTrafficStmt(DatabaseSql::sqlUpdateTrafMonth, trafMonth);
if (inactive) {
pid ^= 1;
}
for (int i = 0; i < procCount; ++i) {
quint32 pid = *procTrafBytes++;
const bool inactive = (pid & 1) != 0;
const quint32 inBytes = *procTrafBytes++;
const quint32 outBytes = *procTrafBytes++;
const int procIndex = m_appIndexes.value(pid, INVALID_APP_INDEX);
if (procIndex == INVALID_APP_INDEX) {
qCritical(CLOG_DATABASE_MANAGER()) << "UI & Driver's states mismatch.";
abort();
}
if (inBytes || outBytes) {
qint64 appId = m_appIds.at(procIndex);
// Was the app cleared?
if (appId == INVALID_APP_ID) {
appId = createAppId(m_appPaths.at(procIndex));
replaceAppIdAt(procIndex, appId);
if (inactive) {
pid ^= 1;
}
// Update or insert app bytes
updateTrafficList(insertTrafAppStmts, updateTrafAppStmts,
inBytes, outBytes, appId);
const int procIndex = m_appIndexes.value(pid, INVALID_APP_INDEX);
if (procIndex == INVALID_APP_INDEX) {
qCritical(CLOG_DATABASE_MANAGER()) << "UI & Driver's states mismatch.";
abort();
}
// Update or insert total bytes
updateTrafficList(insertTrafStmts, updateTrafStmts,
inBytes, outBytes);
if (inBytes || outBytes) {
qint64 appId = m_appIds.at(procIndex);
// Update quota traffic bytes
m_quotaManager->addTraf(inBytes);
}
// Was the app cleared?
if (appId == INVALID_APP_ID) {
appId = createAppId(m_appPaths.at(procIndex), unixTime);
replaceAppIdAt(procIndex, appId);
}
if (inactive) {
logClearApp(pid, procIndex);
// Update or insert app bytes
updateTrafficList(insertTrafAppStmts, updateTrafAppStmts,
inBytes, outBytes, appId);
// Update or insert total bytes
updateTrafficList(insertTrafStmts, updateTrafStmts,
inBytes, outBytes);
// Update quota traffic bytes
m_quotaManager->addTraf(inBytes);
}
if (inactive) {
logClearApp(pid, procIndex);
}
}
}
@ -361,7 +370,7 @@ void DatabaseManager::deleteApp(qint64 appId)
{
clearAppId(appId);
// Delete Statemets
// Delete Statements
const QStmtList deleteAppStmts = QStmtList()
<< getAppStmt(DatabaseSql::sqlDeleteAppTrafHour, appId)
<< getAppStmt(DatabaseSql::sqlDeleteAppTrafDay, appId)
@ -401,12 +410,11 @@ qint64 DatabaseManager::getAppId(const QString &appPath)
return appId;
}
qint64 DatabaseManager::createAppId(const QString &appPath)
qint64 DatabaseManager::createAppId(const QString &appPath, qint64 unixTime)
{
qint64 appId = INVALID_APP_ID;
SqliteStmt *stmt = getSqliteStmt(DatabaseSql::sqlInsertAppId);
const qint64 unixTime = DateUtil::getUnixTime();
stmt->bindText(1, appPath);
stmt->bindInt64(2, unixTime);

View File

@ -67,7 +67,7 @@ private:
void logClearApp(quint32 pid, int index);
qint64 getAppId(const QString &appPath);
qint64 createAppId(const QString &appPath);
qint64 createAppId(const QString &appPath, qint64 unixTime);
void updateTrafficList(const QStmtList &insertStmtList,
const QStmtList &updateStmtList,

View File

@ -9,6 +9,8 @@
<file>qml/controls/ScrollBarControl.qml</file>
<file>qml/controls/SpinCombo.qml</file>
<file>qml/controls/SpinComboRow.qml</file>
<file>qml/controls/SpinDouble.qml</file>
<file>qml/controls/SpinDoubleRow.qml</file>
<file>qml/controls/SwipeViewControl.qml</file>
<file>qml/controls/TextAreaFrame.qml</file>
<file>qml/controls/TextContextMenu.qml</file>

View File

@ -238,6 +238,9 @@ bool FortSettings::readConfIni(FirewallConf &conf) const
m_ini->endGroup();
m_ini->beginGroup("stat");
conf.setActivePeriodEnabled(iniBool("activePeriodEnabled"));
conf.setActivePeriodFrom(iniInt("activePeriodFrom"));
conf.setActivePeriodTo(iniInt("activePeriodTo"));
conf.setMonthStart(iniInt("monthStart", DEFAULT_MONTH_START));
conf.setTrafHourKeepDays(iniInt("trafHourKeepDays", DEFAULT_TRAF_HOUR_KEEP_DAYS));
conf.setTrafDayKeepDays(iniInt("trafDayKeepDays", DEFAULT_TRAF_DAY_KEEP_DAYS));
@ -270,6 +273,9 @@ bool FortSettings::writeConfIni(const FirewallConf &conf)
m_ini->endGroup();
m_ini->beginGroup("stat");
setIniValue("activePeriodEnabled", conf.activePeriodEnabled());
setIniValue("activePeriodFrom", conf.activePeriodFrom());
setIniValue("activePeriodTo", conf.activePeriodTo());
setIniValue("monthStart", conf.monthStart(), DEFAULT_MONTH_START);
setIniValue("trafHourKeepDays", conf.trafHourKeepDays(), DEFAULT_TRAF_HOUR_KEEP_DAYS);
setIniValue("trafDayKeepDays", conf.trafDayKeepDays(), DEFAULT_TRAF_DAY_KEEP_DAYS);

Binary file not shown.

View File

@ -88,17 +88,17 @@
<context>
<name>FortSettings</name>
<message>
<location filename="../fortsettings.cpp" line="205"/>
<location filename="../fortsettings.cpp" line="202"/>
<source>Can&apos;t write .ini file</source>
<translation>Не удалось записать .ini файл</translation>
</message>
<message>
<location filename="../fortsettings.cpp" line="220"/>
<location filename="../fortsettings.cpp" line="217"/>
<source>Can&apos;t create .conf file</source>
<translation>Не удалось создать .conf файл</translation>
</message>
<message>
<location filename="../fortsettings.cpp" line="215"/>
<location filename="../fortsettings.cpp" line="212"/>
<source>Can&apos;t create backup .conf file</source>
<translation>Не удалось создать бэкап .conf файла</translation>
</message>
@ -158,12 +158,12 @@
<context>
<name>TaskInfo</name>
<message>
<location filename="../task/taskinfo.cpp" line="48"/>
<location filename="../task/taskinfo.cpp" line="47"/>
<source>Update Checker</source>
<translation>Проверка обновлений</translation>
</message>
<message>
<location filename="../task/taskinfo.cpp" line="50"/>
<location filename="../task/taskinfo.cpp" line="49"/>
<source>TAS-IX Addresses Downloader</source>
<translation>Загрузчик TAS-IX адресов</translation>
</message>
@ -511,32 +511,37 @@
<translation>3 года</translation>
</message>
<message>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="76"/>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="68"/>
<source>Active period, hours:</source>
<translation>Активный период, часы</translation>
</message>
<message>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="121"/>
<source>Month starts on:</source>
<translation>Месяц начинается с:</translation>
</message>
<message>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="102"/>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="147"/>
<source>Keep days for &apos;Hourly&apos;:</source>
<translation>Хранить дней для &apos;Почасовая&apos;:</translation>
</message>
<message>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="125"/>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="170"/>
<source>Keep days for &apos;Daily&apos;:</source>
<translation>Хранить дней для &apos;Ежедневная&apos;:</translation>
</message>
<message>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="148"/>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="193"/>
<source>Keep months for &apos;Monthly&apos;:</source>
<translation>Хранить месяцев для &apos;Ежемесячная&apos;:</translation>
</message>
<message>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="173"/>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="218"/>
<source>Day&apos;s Quota:</source>
<translation>Квота на день</translation>
</message>
<message>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="197"/>
<location filename="../qml/pages/log/TrafOptionsButton.qml" line="242"/>
<source>Month&apos;s Quota:</source>
<translation>Квота на месяц</translation>
</message>

View File

@ -0,0 +1,33 @@
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
RowLayout {
readonly property alias field1: field1
readonly property alias field2: field2
property real fieldPreferredWidth
SpinBox {
id: field1
Layout.fillWidth: true
Layout.preferredWidth: fieldPreferredWidth
Layout.minimumWidth: fieldPreferredWidth
editable: true
from: 0
to: 9999
}
SpinBox {
id: field2
Layout.fillWidth: true
Layout.preferredWidth: fieldPreferredWidth
Layout.minimumWidth: fieldPreferredWidth
editable: true
from: 0
to: 9999
}
}

View File

@ -0,0 +1,25 @@
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
import com.fortfirewall 1.0
RowLayout {
Layout.fillWidth: true
readonly property alias checkBox: checkBox
readonly property alias field1: spinDouble.field1
readonly property alias field2: spinDouble.field2
CheckBox {
id: checkBox
Layout.fillWidth: true
}
SpinDouble {
id: spinDouble
Layout.maximumWidth: implicitWidth
fieldPreferredWidth: 140
}
}

View File

@ -62,6 +62,51 @@ ButtonPopup {
}
ColumnLayout {
SpinDoubleRow {
checkBox {
text: translationManager.trTrigger
&& qsTranslate("qml", "Active period, hours:")
checked: firewallConf.activePeriodEnabled
onCheckedChanged: {
const value = checkBox.checked;
if (firewallConf.activePeriodEnabled == value)
return;
firewallConf.activePeriodEnabled = value;
setConfFlagsEdited();
}
}
field1 {
from: 0
to: 24
value: firewallConf.activePeriodFrom
onValueChanged: {
const value = field1.value;
if (firewallConf.activePeriodFrom == value)
return;
firewallConf.activePeriodFrom = value;
setConfFlagsEdited();
}
}
field2 {
from: 0
to: 24
value: firewallConf.activePeriodTo
onValueChanged: {
const value = field2.value;
if (firewallConf.activePeriodTo == value)
return;
firewallConf.activePeriodTo = value;
setConfFlagsEdited();
}
}
}
SpinComboRow {
values: {
var arr = [];

View File

@ -80,3 +80,13 @@ QString DateUtil::formatDateTime(qint64 unixTime, const QString &format)
const QDateTime dt = QDateTime::fromSecsSinceEpoch(unixTime);
return QLocale().toString(dt, format);
}
bool DateUtil::isHourBetween(qint32 unixHour, qint32 unixDay,
int fromHour, int toHour)
{
const int hour = unixHour - unixDay;
return fromHour <= toHour
? (hour >= fromHour && hour <= toHour)
: (hour == 0 || hour >= fromHour || hour <= toHour);
}

View File

@ -29,6 +29,9 @@ public:
static QString formatMonth(qint64 unixTime);
static QString formatDateTime(qint64 unixTime, const QString &format);
static bool isHourBetween(qint32 unixHour, qint32 unixDay,
int fromHour, int toHour);
};
#endif // DATEUTIL_H