32
30
#include "global.h"
33
31
#include "interface.h"
34
32
#include "interfacestatistics.h"
33
#include "statisticsmodel.h"
35
34
#include "syncstats/statsfactory.h"
37
static const char statistics_prefix[] = "/statistics_";
39
static const char doc_name[] = "statistics";
41
static const char attrib_calendar[] = "calendar";
42
static const char attrib_version[] = "version";
43
static const char attrib_updated[] = "lastUpdated";
44
static const char attrib_span[] = "span";
45
static const char attrib_rx[] = "rxBytes";
46
static const char attrib_tx[] = "txBytes";
48
static const char* intervals[] = { "hour", "day", "week", "month", "year" };
35
#include "storage/sqlstorage.h"
36
#include "storage/xmlstorage.h"
38
static bool statsLessThan( const StatsRule& s1, const StatsRule& s2 )
40
if ( s1.startDate < s2.startDate )
50
46
InterfaceStatistics::InterfaceStatistics( Interface* interface )
48
mInterface( interface ),
52
49
mSaveTimer( new QTimer() ),
53
mInterface( interface ),
50
mWarnTimer( new QTimer() ),
51
mEntryTimer( new QTimer() ),
52
mTrafficChanged( false )
56
StatisticsModel * s = new StatisticsModel( StatisticsModel::Hour, this );
57
mModels.insert( StatisticsModel::Hour, s );
58
s = new StatisticsModel( StatisticsModel::Day, this );
59
mModels.insert( StatisticsModel::Day, s );
60
s = new StatisticsModel( StatisticsModel::Week, this );
61
mModels.insert( StatisticsModel::Week, s );
62
s = new StatisticsModel( StatisticsModel::Month, this );
63
mModels.insert( StatisticsModel::Month, s );
64
s = new StatisticsModel( StatisticsModel::Year, this );
65
mModels.insert( StatisticsModel::Year, s );
54
StatisticsModel * s = new StatisticsModel( KNemoStats::Hour, this );
55
mModels.insert( KNemoStats::Hour, s );
56
s = new StatisticsModel( KNemoStats::Day, this );
57
mModels.insert( KNemoStats::Day, s );
58
s = new StatisticsModel( KNemoStats::Week, this );
59
mModels.insert( KNemoStats::Week, s );
60
s = new StatisticsModel( KNemoStats::Month, this );
61
mModels.insert( KNemoStats::Month, s );
62
s = new StatisticsModel( KNemoStats::Year, this );
63
mModels.insert( KNemoStats::Year, s );
64
s = new StatisticsModel( KNemoStats::BillPeriod, this );
65
mModels.insert( KNemoStats::BillPeriod, s );
66
s = new StatisticsModel( KNemoStats::HourArchive, this );
67
mModels.insert( KNemoStats::HourArchive, s );
69
foreach ( StatisticsModel *s, mModels )
71
mStorageData.saveFromId.insert( s->periodType(), 0 );
67
74
connect( mSaveTimer, SIGNAL( timeout() ), this, SLOT( saveStatistics() ) );
75
connect( mWarnTimer, SIGNAL( timeout() ), this, SLOT( checkWarnings() ) );
76
connect( mEntryTimer, SIGNAL( timeout() ), this, SLOT( checkValidEntry() ) );
78
KUrl dir( generalSettings->statisticsDir );
79
sql = new SqlStorage( mInterface->ifaceName() );
81
syncWithExternal( mStorageData.lastSaved );
73
85
InterfaceStatistics::~InterfaceStatistics()
75
87
mSaveTimer->stop();
80
if ( mInterface->getSettings().customBilling )
82
mInterface->getSettings().billingStart = mBillingStart;
83
KConfig *config = KGlobal::config().data();
84
KConfigGroup interfaceGroup( config, confg_interface + mInterface->getName() );
85
interfaceGroup.writeEntry( conf_billingStart, mBillingStart );
90
QString InterfaceStatistics::typeToElem( enum StatisticsModel::GroupType t )
94
while ( v > StatisticsModel::Hour )
102
void InterfaceStatistics::clearStatistics()
104
foreach( StatisticsModel * s, mModels )
106
emit currentEntryChanged();
109
void InterfaceStatistics::loadConfig()
111
mCalendar = KCalendarSystem::create( mInterface->getSettings().calendar );
112
// TODO: Test for a KDE release that contains SVN commit 1013534
113
KGlobal::locale()->setCalendar( mCalendar->calendarType() );
114
foreach( StatisticsModel * s, mModels )
115
s->setCalendar( mCalendar );
117
mWarningDone = false;
118
mBillingStart = mInterface->getSettings().billingStart;
96
QSqlDatabase::removeDatabase( mInterface->ifaceName() );
99
void InterfaceStatistics::saveStatistics( bool fullSave )
101
sql->saveStats( &mStorageData, &mModels, &mStatsRules, fullSave );
104
bool InterfaceStatistics::loadStats()
106
KUrl dir( generalSettings->statisticsDir );
107
if ( !dir.isLocalFile() )
112
if ( sql->dbExists() )
114
loaded = sql->loadStats( &mStorageData, &mModels, &mStatsRules );
115
qSort( mStatsRules.begin(), mStatsRules.end(), statsLessThan );
120
loaded = xml.loadStats( mInterface->ifaceName(), &mStorageData, &mModels );
124
hoursToArchive( QDateTime::currentDateTime() );
125
checkRebuild( mStorageData.calendar->calendarType(), true );
129
if ( !mStorageData.calendar )
131
mStorageData.calendar = KCalendarSystem::create( mInterface->settings().calendar );
132
foreach( StatisticsModel * s, mModels )
134
s->setCalendar( mStorageData.calendar );
140
/**********************************
141
* Stats Entry Generators *
142
**********************************/
144
void InterfaceStatistics::resetWarnings( int modelType )
146
for ( int i = 0; i < mInterface->settings().warnRules.count(); ++i )
148
if ( modelType == mInterface->settings().warnRules[i].periodUnits )
149
mInterface->settings().warnRules[i].warnDone = false;
153
void InterfaceStatistics::hoursToArchive( const QDateTime &dateTime )
155
bool removedRow = false;
156
StatisticsModel* hours = mModels.value( KNemoStats::Hour );
157
StatisticsModel* hourArchives = mModels.value( KNemoStats::HourArchive );
160
while ( hours->rowCount() )
162
if ( hours->dateTime( 0 ) <= dateTime.addDays( -1 ) )
164
QList<QStandardItem*> row = hours->takeRow( 0 );
165
hourArchives->appendRow( row );
166
hourArchives->setId( mStorageData.nextHourId );
167
mStorageData.nextHourId++;
175
for ( int i = 0; i < hours->rowCount(); ++i )
177
hours->setId( i, i );
179
mStorageData.saveFromId.insert( hours->periodType(), 0 );
180
mStorageData.saveFromId.insert( hourArchives->periodType(), hourArchives->id( 0 ) );
184
void InterfaceStatistics::genNewHour( const QDateTime &dateTime )
186
hoursToArchive( dateTime );
188
StatisticsModel* hours = mModels.value( KNemoStats::Hour );
190
if ( hours->dateTime() == dateTime )
193
int ruleIndex = ruleForDate( dateTime.date() );
194
if ( ruleIndex >= 0 && isOffpeak( mStatsRules[ruleIndex], dateTime ) )
196
hours->addTrafficType( KNemoStats::OffpeakTraffic );
199
hours->createEntry( dateTime );
201
resetWarnings( hours->periodType() );
204
bool InterfaceStatistics::genNewCalendarType( const QDate &date, const KNemoStats::PeriodUnits stype )
206
if ( stype < KNemoStats::Day || stype > KNemoStats::Year )
209
StatisticsModel * model = mModels.value( stype );
210
if ( model->rowCount() &&
211
model->date().addDays( model->days() ) > date )
216
int weekStartDay = mStorageData.calendar->weekStartDay();
220
case KNemoStats::Day:
223
case KNemoStats::Week:
224
dayOf = mStorageData.calendar->dayOfWeek( date );
225
if ( dayOf >= weekStartDay )
226
newDate = date.addDays( weekStartDay - dayOf );
228
newDate = date.addDays( weekStartDay - mStorageData.calendar->daysInWeek( date ) - dayOf );
230
case KNemoStats::Month:
231
dayOf = mStorageData.calendar->day( date );
232
newDate = date.addDays( 1 - dayOf );
234
case KNemoStats::Year:
235
dayOf = mStorageData.calendar->dayOfYear( date );
236
newDate = date.addDays( 1 - dayOf );
242
mModels.value( stype )->createEntry( QDateTime( newDate, QTime() ) );
243
resetWarnings( stype );
248
// Return true if at least one daily statistic entry is in a span of days
249
bool InterfaceStatistics::daysInSpan( const QDate& date, int days )
251
StatisticsModel *model = mModels.value( KNemoStats::Day );
252
if ( !model->rowCount() )
255
QDate nextRuleStart = date.addDays( days );
256
for ( int i = model->rowCount() - 1; i >= 0; --i )
258
// No others will be valid after this; stop early
259
if ( model->date( i ) < date )
261
if ( model->date( i ) < nextRuleStart && model->date( i ) >= date )
267
QDate InterfaceStatistics::nextBillPeriodStart( const StatsRule &rules, const QDate &date )
271
int modelType = rules.periodUnits;
274
case KNemoStats::Day:
275
nextDate = date.addDays( rules.periodCount );
277
case KNemoStats::Week:
279
for ( int i = 0; i < rules.periodCount; ++i )
280
nextDate = nextDate.addDays( mStorageData.calendar->daysInWeek( nextDate ) );
282
default:// KNemoStats::Month:
283
nextDate = mStorageData.calendar->addMonths( date, rules.periodCount );
284
// Example: one month starting Jan 31 = Jan 31 -> Mar 1
285
// This seems the most common way to handle late start dates
286
if ( mStorageData.calendar->day( nextDate ) < mStorageData.calendar->day( date ) )
287
nextDate = nextDate.addDays( 1 );
293
void InterfaceStatistics::genNewBillPeriod( const QDate &date )
295
int ruleIndex = ruleForDate( date );
299
StatisticsModel * billing = mModels.value( KNemoStats::BillPeriod );
302
if ( mStatsRules.count() > ruleIndex+1 )
303
nextRuleStart = mStatsRules.at( ruleIndex+1 ).startDate;
305
// Harder to find whether we should skip generating a new billing entry
306
if ( nextRuleStart.isValid() && billing->rowCount() && billing->date().addDays( billing->days() ) >= nextRuleStart )
311
// Given a calendar day and a billing period start date, find a
312
// billing period that the day belongs in.
315
if ( !billing->rowCount() ||
316
billing->date() < mStatsRules.at( ruleIndex ).startDate )
318
nextStartDate = mStatsRules.at( ruleIndex ).startDate;
322
nextStartDate = billing->date();
327
newDate = nextStartDate;
328
nextStartDate = nextBillPeriodStart( mStatsRules.at( ruleIndex ), newDate );
329
days = newDate.daysTo( nextStartDate );
330
} while ( nextStartDate <= date || !daysInSpan( newDate, days ) );
332
// Truncate a billing period if necessary
333
if ( nextRuleStart.isValid() && nextRuleStart < nextStartDate )
334
days = newDate.daysTo( nextRuleStart );
336
if ( billing->rowCount() && newDate == billing->date() )
339
billing->createEntry( QDateTime( newDate, QTime() ), billing->rowCount(), days );
341
resetWarnings( KNemoStats::BillPeriod );
345
// END STATS ENTRY GENERATORS
347
void InterfaceStatistics::configChanged()
352
QString origCalendarType;
353
if ( mStorageData.calendar )
354
origCalendarType = mStorageData.calendar->calendarType();
356
if ( mInterface->settings().calendar != origCalendarType )
358
mStorageData.calendar = KCalendarSystem::create( mInterface->settings().calendar );
360
foreach( StatisticsModel * s, mModels )
362
s->setCalendar( mStorageData.calendar );
364
if ( !origCalendarType.isEmpty() )
366
StatisticsModel *hours = mModels.value( KNemoStats::Hour );
367
StatisticsModel *days = mModels.value( KNemoStats::Day );
368
for ( int i = 0; i < days->rowCount(); ++i )
370
days->updateDateText( i );
372
for ( int i = 0; i < hours->rowCount(); ++i )
374
hours->updateDateText( i );
379
checkRebuild( origCalendarType );
120
381
if ( generalSettings->saveInterval > 0 )
122
383
mSaveTimer->setInterval( generalSettings->saveInterval * 1000 );
123
384
mSaveTimer->start();
127
void InterfaceStatistics::configChanged()
130
QString oldType = mCalendar->calendarType();
132
checkRebuild( oldType );
135
void InterfaceStatistics::loadStatsGroup( const KCalendarSystem * cal, const QDomElement& parentItem,
136
StatisticsModel* statistics )
138
QDomNode n = parentItem.namedItem( typeToElem(statistics->type()) + "s" );
141
QDomNode node = n.firstChild();
142
while ( !node.isNull() )
144
QDomElement element = node.toElement();
145
if ( !element.isNull() )
147
// The following attributes are particular to each statistic category
151
int year = element.attribute( typeToElem(StatisticsModel::Year) ).toInt();
152
int month = element.attribute( typeToElem(StatisticsModel::Month), "1" ).toInt();
153
int day = element.attribute( typeToElem(StatisticsModel::Day), "1" ).toInt();
154
cal->setDate( date, year, month, day );
156
if ( date.isValid() )
158
int days = element.attribute( attrib_span ).toInt();
159
switch ( statistics->type() )
161
case StatisticsModel::Hour:
162
time = QTime( element.attribute( typeToElem(StatisticsModel::Hour) ).toInt(), 0 );
164
case StatisticsModel::Month:
165
// Old format had no span, so daysInMonth using gregorian
167
days = date.daysInMonth();
168
if ( cal->day( date ) != 1 ||
169
days != cal->daysInMonth( date ) )
172
case StatisticsModel::Year:
173
// Old format had no span, so daysInYear using gregorian
175
days = date.daysInYear();
177
case StatisticsModel::Day:
183
statistics->appendStats( QDateTime( date, time ), days,
184
element.attribute( attrib_rx ).toULongLong(),
185
element.attribute( attrib_tx ).toULongLong() );
188
node = node.nextSibling();
193
void InterfaceStatistics::saveStatsGroup( QDomDocument& doc, const StatisticsModel* statistics )
197
QDomElement elements = doc.createElement( QString( typeToElem(statistics->type()) ) + "s" );
198
for ( int i = 0; i < statistics->rowCount(); ++i )
200
QDomElement element = doc.createElement( typeToElem(statistics->type()) );
201
QDate date = statistics->date( i );
202
element.setAttribute( typeToElem(StatisticsModel::Day), mCalendar->day( date ) );
203
element.setAttribute( typeToElem(StatisticsModel::Month), mCalendar->month( date ) );
204
element.setAttribute( typeToElem(StatisticsModel::Year), mCalendar->year( date ) );
205
if ( statistics->type() == StatisticsModel::Hour )
206
element.setAttribute( typeToElem(StatisticsModel::Hour), statistics->dateTime( i ).time().hour() );
207
else if ( statistics->type() > StatisticsModel::Day )
208
element.setAttribute( attrib_span, statistics->days( i ) );
209
element.setAttribute( attrib_rx, statistics->rxBytes( i ) );
210
element.setAttribute( attrib_tx, statistics->txBytes( i ) );
211
elements.appendChild( element );
213
QDomElement statElement = doc.elementsByTagName( doc_name ).at( 0 ).toElement();
214
statElement.appendChild( elements );
217
void InterfaceStatistics::loadStatistics()
219
QDomDocument doc( doc_name );
220
KUrl dir( generalSettings->statisticsDir );
221
if ( !dir.isLocalFile() )
223
QFile file( dir.path() + statistics_prefix + mInterface->getName() );
225
if ( !file.open( QIODevice::ReadOnly ) )
227
if ( !doc.setContent( &file ) )
234
QDomElement root = doc.documentElement();
236
uint updated = root.attribute( attrib_updated ).toUInt();
238
// If unknown or empty calendar it will default to gregorian
239
KCalendarSystem *inCal = KCalendarSystem::create( root.attribute( attrib_calendar ) );
240
foreach( StatisticsModel * s, mModels )
241
loadStatsGroup( inCal, root, s );
243
checkRebuild( inCal->calendarType() );
245
syncWithExternal( updated );
387
foreach ( StatisticsModel * s, mModels )
389
resetWarnings( s->periodType() );
394
mWarnTimer->setInterval( 2000 );
398
int InterfaceStatistics::ruleForDate( const QDate &date )
400
for( int i = mStatsRules.count() - 1; i >= 0; --i )
402
if ( date >= mStatsRules[i].startDate )
248
408
void InterfaceStatistics::syncWithExternal( uint updated )
250
ExternalStats *v = StatsFactory::stats( mInterface );
410
ExternalStats *v = StatsFactory::stats( mInterface, mStorageData.calendar );
254
414
v->importIfaceStats();
255
415
const StatisticsModel *syncDays = v->days();
256
416
const StatisticsModel *syncHours = v->hours();
257
StatisticsModel *days = mModels.value( StatisticsModel::Day );
258
StatisticsModel *hours = mModels.value( StatisticsModel::Hour );
417
StatisticsModel *days = mModels.value( KNemoStats::Day );
418
StatisticsModel *hours = mModels.value( KNemoStats::Hour );
259
419
QDateTime curDateTime = QDateTime( QDate::currentDate(), QTime( QDateTime::currentDateTime().time().hour(), 0 ) );
421
for ( int i = 0; i < syncHours->rowCount(); ++i )
423
QDateTime syncDateTime = syncHours->dateTime( i );
425
if ( hours->rowCount() && hours->dateTime() > syncDateTime )
427
if ( !hours->rowCount() || hours->dateTime() < syncDateTime )
428
genNewHour( syncDateTime );
430
foreach ( KNemoStats::TrafficType t, hours->trafficTypes() )
432
hours->addRxBytes( syncHours->rxBytes( i ), t );
433
hours->addTxBytes( syncHours->txBytes( i ), t );
261
437
for ( int i = 0; i < syncDays->rowCount(); ++i )
263
439
QDate syncDate = syncDays->date( i );
267
443
if ( !days->rowCount() || days->date() < syncDate )
269
genNewDay( syncDate );
270
genNewWeek( syncDate );
271
genNewMonth( syncDate );
272
genNewYear( syncDate );
445
genNewCalendarType( syncDate, KNemoStats::Day );
446
genNewCalendarType( syncDate, KNemoStats::Week );
447
genNewCalendarType( syncDate, KNemoStats::Month );
448
genNewCalendarType( syncDate, KNemoStats::Year );
449
genNewBillPeriod( syncDate );
275
452
foreach( StatisticsModel * s, mModels )
277
if ( s->type() == StatisticsModel::Hour )
454
if ( s->periodType() == KNemoStats::Hour || s->periodType() == KNemoStats::HourArchive )
280
457
s->addRxBytes( v->addBytes( s->rxBytes(), syncDays->rxBytes( i ) ) );
281
458
s->addTxBytes( v->addBytes( s->txBytes(), syncDays->txBytes( i ) ) );
459
for ( int j = hours->rowCount() - 1; j >= 0; --j )
461
if ( hours->date( j ) == syncDate )
463
foreach( KNemoStats::TrafficType t, hours->trafficTypes( j ) )
465
if ( t == KNemoStats::AllTraffic )
467
s->addRxBytes( hours->rxBytes( j, t ), t );
468
s->addTxBytes( hours->txBytes( j, t ), t );
471
else if ( hours->date( j ) < syncDate )
284
for ( int i = 0; i < syncHours->rowCount(); ++i )
286
QDateTime syncDateTime = syncHours->dateTime( i );
288
if ( hours->rowCount() && hours->dateTime() > syncDateTime )
290
if ( !hours->rowCount() || hours->dateTime() < syncDateTime )
291
genNewHour( syncDateTime );
293
hours->addRxBytes( v->addBytes( hours->rxBytes(), syncHours->rxBytes( i ) ) );
294
hours->addTxBytes( v->addBytes( hours->txBytes(), syncHours->txBytes( i ) ) );
296
477
StatsPair lag = v->addLagged( updated, days );
297
478
if ( lag.rxBytes > 0 || lag.txBytes > 0 )
299
480
if ( lag.rxBytes || lag.txBytes )
301
482
genNewHour( curDateTime );
302
genNewDay( curDateTime.date() );
303
genNewWeek( curDateTime.date() );
304
genNewMonth( curDateTime.date() );
305
genNewYear( curDateTime.date() );
483
genNewCalendarType( curDateTime.date(), KNemoStats::Day );
484
genNewCalendarType( curDateTime.date(), KNemoStats::Week );
485
genNewCalendarType( curDateTime.date(), KNemoStats::Month );
486
genNewCalendarType( curDateTime.date(), KNemoStats::Year );
487
genNewBillPeriod( curDateTime.date() );
307
489
foreach ( StatisticsModel * s, mModels )
309
s->addRxBytes( lag.rxBytes );
310
s->addTxBytes( lag.txBytes );
491
if ( s->periodType() == KNemoStats::HourArchive )
493
foreach ( KNemoStats::TrafficType t, hours->trafficTypes() )
495
s->addRxBytes( lag.rxBytes, t );
496
s->addTxBytes( lag.txBytes, t );
317
void InterfaceStatistics::saveStatistics()
319
QDomDocument doc( doc_name );
320
QDomElement docElement = doc.createElement( doc_name );
321
docElement.setAttribute( attrib_calendar, mCalendar->calendarType() );
322
docElement.setAttribute( attrib_version, "1.3" );
323
docElement.setAttribute( attrib_updated, QDateTime::currentDateTime().toTime_t() );
324
doc.appendChild( docElement );
326
foreach( StatisticsModel * s, mModels )
327
saveStatsGroup( doc, s );
329
KUrl dir( generalSettings->statisticsDir );
330
if ( !dir.isLocalFile() )
504
bool InterfaceStatistics::isOffpeak( const StatsRule &rules, const QDateTime &curDT )
506
if ( !rules.logOffpeak )
509
bool isOffpeak = false;
510
QTime curHour = QTime( curDT.time().hour(), 0 );
512
// This block just tests weekly hours
513
if ( rules.offpeakStartTime < rules.offpeakEndTime &&
514
curHour >= rules.offpeakStartTime && curHour < rules.offpeakEndTime )
518
else if ( rules.offpeakStartTime > rules.offpeakEndTime &&
519
( curHour >= rules.offpeakStartTime || curHour < rules.offpeakEndTime ) )
524
if ( rules.weekendIsOffpeak )
526
int dow = mStorageData.calendar->dayOfWeek( curDT.date() );
527
if ( rules.weekendDayStart <= rules.weekendDayEnd && rules.weekendDayStart <= dow )
529
QDateTime dayBegin = curDT.addDays( dow - rules.weekendDayStart );
530
dayBegin = QDateTime( dayBegin.date(), rules.weekendTimeStart );
531
QDateTime end = curDT.addDays( rules.weekendDayEnd - dow );
532
end = QDateTime( end.date(), rules.weekendTimeEnd );
534
if ( dayBegin <= curDT && curDT < end )
537
else if ( rules.weekendDayStart > rules.weekendDayEnd &&
538
( dow >= rules.weekendDayStart || dow <= rules.weekendDayEnd ) )
540
QDateTime dayBegin = curDT.addDays( rules.weekendDayStart - dow );
541
dayBegin = QDateTime( dayBegin.date(), rules.weekendTimeStart );
542
QDateTime end = curDT.addDays( mStorageData.calendar->daysInWeek( curDT.date() ) - dow + rules.weekendDayEnd );
543
end = QDateTime( end.date(), rules.weekendTimeEnd );
545
if ( dayBegin <= curDT && curDT < end )
554
/**************************************
555
* Rebuilding Statistics *
556
**************************************/
558
int InterfaceStatistics::rebuildHours( StatisticsModel *s, const StatsRule &rules, const QDate &start, const QDate &nextRuleStart )
560
if ( !s->rowCount() )
563
int i = s->rowCount();
564
while ( i > 0 && s->date( i - 1 ) >= start )
567
if ( nextRuleStart.isValid() && s->date( i ) >= nextRuleStart )
570
s->resetTrafficTypes( i );
571
if ( isOffpeak( rules, s->dateTime( i ) ) )
573
s->setTraffic( i, s->rxBytes( i ), s->txBytes( i ), KNemoStats::OffpeakTraffic );
574
s->addTrafficType( KNemoStats::OffpeakTraffic, i );
577
if ( mStorageData.saveFromId.value( s->periodType() ) > s->id( i ) )
579
mStorageData.saveFromId.insert( s->periodType(), s->id( i ) );
585
int InterfaceStatistics::rebuildDay( int dayIndex, int hourIndex, StatisticsModel *hours )
587
QMap<KNemoStats::TrafficType, QPair<quint64, quint64> > dayTraffic;
588
StatisticsModel *days = mModels.value( KNemoStats::Day );
589
while ( hourIndex >= 0 && hours->date( hourIndex ) > days->date( dayIndex ).addDays( 1 ) )
593
while ( hourIndex >= 0 && hours->date( hourIndex ) == days->date( dayIndex ) )
595
foreach ( KNemoStats::TrafficType t, hours->trafficTypes( hourIndex ) )
597
if ( t == KNemoStats::AllTraffic )
599
quint64 rx = hours->rxBytes( hourIndex, t ) + dayTraffic.value( t ).first;
600
quint64 tx = hours->txBytes( hourIndex, t ) + dayTraffic.value( t ).second;
601
dayTraffic.insert( t, QPair<quint64, quint64>( rx, tx ) );
605
foreach (KNemoStats::TrafficType t, dayTraffic.keys() )
607
days->setTraffic( dayIndex, dayTraffic.value( t ).first, dayTraffic.value( t ).second, t );
608
days->addTrafficType( t, dayIndex );
613
// A rebuild of hours and days never changes the number of entries
614
// We just change what bytes count as off-peak
615
void InterfaceStatistics::rebuildBaseUnits( const StatsRule &rules, const QDate &start, const QDate &nextRuleStart )
620
StatisticsModel *hours = mModels.value( KNemoStats::Hour );
621
StatisticsModel *hourArchives = mModels.value( KNemoStats::HourArchive );
622
StatisticsModel *days = mModels.value( KNemoStats::Day );
623
sql->loadHourArchives( hourArchives, start, nextRuleStart );
624
if ( hourArchives->rowCount() )
625
mStorageData.saveFromId.insert( hourArchives->periodType(), hourArchives->id( 0 ) );
627
rebuildHours( hourArchives, rules, start, nextRuleStart );
628
rebuildHours( hours, rules, start, nextRuleStart );
630
if ( hours->rowCount() )
631
hIndex = hours->rowCount() - 1;
632
if ( hourArchives->rowCount() )
633
haIndex = hourArchives->rowCount() - 1;
635
if ( !days->rowCount() )
333
QFile file( dir.path() + statistics_prefix + mInterface->getName() );
334
if ( file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
336
file.write( doc.toByteArray() );
337
fsync( file.handle() );
638
int dayIndex = days->rowCount();
639
while ( dayIndex > 0 && days->date( dayIndex - 1 ) >= start )
642
if ( nextRuleStart.isValid() && days->date( dayIndex ) >= nextRuleStart )
645
days->resetTrafficTypes( dayIndex );
646
if ( rules.logOffpeak )
648
haIndex = rebuildDay( dayIndex, haIndex, hourArchives );
649
hIndex = rebuildDay( dayIndex, hIndex, hours );
652
if ( mStorageData.saveFromId.value( days->periodType() ) > days->id( dayIndex ) )
654
mStorageData.saveFromId.insert( days->periodType(), days->id( dayIndex ) );
344
660
* and a requested rebuild date, how far back to we actually need to go
345
661
* to accuratly rebuild statistics from the daily stats.
347
QDate InterfaceStatistics::setRebuildDate( StatisticsModel* statistics,
348
const QDate &recalcDate )
663
QDate InterfaceStatistics::prepareRebuild( StatisticsModel* statistics, const QDate &startDate )
350
QDate returnDate = recalcDate;
351
if ( statistics->type() <= StatisticsModel::Day )
665
QDate newStartDate = startDate;
666
if ( statistics->periodType() <= KNemoStats::Day ||
667
statistics->periodType() > KNemoStats::Year )
354
// Keep removing entries and rolling back returnDate while
355
// entry's start date + days > returnDate
356
for ( int i = statistics->rowCount() - 1; i >= 0; --i )
670
for ( int i = 0; i < statistics->rowCount(); ++i )
358
672
int days = statistics->days( i );
359
QDate date = statistics->date( i ).addDays( days );
360
if ( date > mModels.value( StatisticsModel::Day )->date( 0 ) &&
361
( date > returnDate || days < 1 )
673
QDate nextPeriodStart = statistics->date( i ).addDays( days );
675
if ( statistics->periodType() == KNemoStats::BillPeriod )
364
if ( returnDate > statistics->date( i ) )
365
returnDate = statistics->date( i );
366
statistics->removeRow( i );
677
// Have to check if a billing period's truncation changed
678
int ruleIndex = ruleForDate( statistics->date( i ) );
681
QDate nextFullPeriodStart = nextBillPeriodStart( mStatsRules.at( ruleIndex ), statistics->date( i ) );
682
if ( nextFullPeriodStart > nextPeriodStart )
684
if ( mStatsRules.count() == ruleIndex+1 ||
685
mStatsRules.at( ruleIndex + 1 ).startDate != nextPeriodStart )
687
// Truncation changed
688
// This will make sure the entry gets rebuilt
689
nextPeriodStart = nextFullPeriodStart;
694
if ( nextPeriodStart > startDate )
696
if ( statistics->date( i ) < startDate )
698
newStartDate = statistics->date( i );
700
if ( statistics->rowCount() && mStorageData.saveFromId.value( statistics->periodType() ) > statistics->id( i ) )
702
mStorageData.saveFromId.insert( statistics->periodType(), statistics->id( i ) );
704
statistics->removeRows( i, statistics->rowCount() - i );
372
// now take care of instances when we're going earlier than the first recorded stats.
373
if ( statistics->type() == StatisticsModel::Week )
375
returnDate = returnDate.addDays( 1 - mCalendar->dayOfWeek( returnDate ) );
376
while ( returnDate > recalcDate )
377
returnDate = returnDate.addDays( -mCalendar->daysInWeek( returnDate ) );
379
else if ( statistics->type() == StatisticsModel::Year )
381
returnDate = returnDate.addDays( 1 - mCalendar->dayOfYear( returnDate ) );
382
while ( returnDate > recalcDate )
383
returnDate = returnDate.addDays( mCalendar->daysInYear( returnDate ) );
389
void InterfaceStatistics::amendStats( int i, StatisticsModel* model )
391
StatisticsModel *days = mModels.value( StatisticsModel::Day );
392
model->addRxBytes( days->rxBytes( i ) );
393
model->addTxBytes( days->txBytes( i ) );
396
void InterfaceStatistics::doRebuild( const QDate &date, int groups )
398
QDate recalcDate( date );
399
bool partial = false;
712
void InterfaceStatistics::amendStats( int i, const StatisticsModel *source, StatisticsModel* dest )
714
foreach ( KNemoStats::TrafficType t, source->trafficTypes( i ) )
716
dest->addRxBytes( source->rxBytes( i, t ), t );
717
dest->addTxBytes( source->txBytes( i, t ), t );
718
dest->addTrafficType( t );
722
void InterfaceStatistics::rebuildCalendarPeriods( const QDate &requestedStart, bool weekOnly )
401
725
QDate monthStart;
403
726
QDate walkbackDate;
406
s.append( recalcDate );
408
if ( groups & StatisticsModel::Week )
410
weekStart = setRebuildDate( mModels.value( StatisticsModel::Week), recalcDate );
411
s.append( weekStart );
413
if ( groups & StatisticsModel::Month )
415
monthStart = setRebuildDate( mModels.value( StatisticsModel::Month), recalcDate );
417
mBillingStart = monthStart;
418
if ( recalcDate > monthStart )
730
weekStart = prepareRebuild( mModels.value( KNemoStats::Week), requestedStart );
731
s.append( weekStart );
734
monthStart = prepareRebuild( mModels.value( KNemoStats::Month), requestedStart );
420
735
s.append( monthStart );
422
if ( groups & StatisticsModel::Year )
424
yearStart = setRebuildDate( mModels.value( StatisticsModel::Year ), recalcDate );
425
s.append( yearStart );
428
738
// Now find how far back we'll need to go
430
740
walkbackDate = s.first();
432
StatisticsModel *days = mModels.value( StatisticsModel::Day );
742
StatisticsModel *days = mModels.value( KNemoStats::Day );
433
743
for ( int i = 0; i < days->rowCount(); ++i )
435
745
QDate day = days->date( i );
436
746
if ( day < walkbackDate )
439
if ( groups & StatisticsModel::Week && day >= weekStart )
442
amendStats( i, mModels.value( StatisticsModel::Week ) );
445
if ( groups & StatisticsModel::Month && day >= monthStart )
448
StatisticsModel *month = mModels.value( StatisticsModel::Month );
452
amendStats( i, month );
456
genNewMonth( monthStart, recalcDate );
457
amendStats( i, month );
458
// Partial month created; next period will begin on recalcDate
459
mBillingStart = recalcDate;
463
if ( groups & StatisticsModel::Year && day >= yearStart )
466
amendStats( i, mModels.value( StatisticsModel::Year ) );
471
void InterfaceStatistics::checkRebuild( QString oldType )
473
if ( oldType != mCalendar->calendarType() )
475
KUrl dir( generalSettings->statisticsDir );
476
if ( dir.isLocalFile() )
478
QFile file( dir.path() + statistics_prefix + mInterface->getName() );
479
file.copy( dir.path() + statistics_prefix + mInterface->getName() +
480
QString( "_%1.bak" ).arg( QDateTime::currentDateTime().toString( "yyyy-MM-dd-hhmmss" ) ) );
482
int modThese = StatisticsModel::Week | StatisticsModel::Year;
483
QDate date = mModels.value( StatisticsModel::Day )->date( 0 );
484
doRebuild( date, modThese );
487
StatisticsModel *month = mModels.value( StatisticsModel::Month );
488
if ( mInterface->getSettings().customBilling == false )
490
if ( oldType != mCalendar->calendarType() || mAllMonths == false )
492
mBillingStart = month->date( 0 ).addDays( 1 - mCalendar->day( month->date( 0 ) ) );
496
QDate nextStart = nextMonthDate( mBillingStart );
497
if ( mBillingStart.daysTo( nextStart ) != month->days()
498
|| mBillingStart != month->date() )
499
doRebuild( mBillingStart, StatisticsModel::Month );
502
for ( int i = 0; i < month->rowCount(); ++i )
504
QDate date = month->date( i );
505
if ( mCalendar->day( date ) != 1 ||
506
month->days( i ) != mCalendar->daysInMonth( date ) )
749
if ( day >= weekStart )
751
genNewCalendarType( day, KNemoStats::Week );
752
amendStats( i, mModels.value( KNemoStats::Day ), mModels.value( KNemoStats::Week ) );
755
if ( !weekOnly && day >= monthStart )
757
genNewCalendarType( day, KNemoStats::Month );
758
amendStats( i, mModels.value( KNemoStats::Day ), mModels.value( KNemoStats::Month ) );
765
// Build years from months...save time
766
QDate yearStart = prepareRebuild( mModels.value( KNemoStats::Year ), requestedStart );
767
StatisticsModel *months = mModels.value( KNemoStats::Month );
768
for ( int i = 0; i < months->rowCount(); ++i )
770
QDate day = months->date( i );
771
if ( day < yearStart )
773
genNewCalendarType( day, KNemoStats::Year );
774
amendStats( i, mModels.value( KNemoStats::Month ), mModels.value( KNemoStats::Year ) );
778
void InterfaceStatistics::rebuildBillPeriods( const QDate &requestedStart )
781
StatisticsModel *days = mModels.value( KNemoStats::Day );
782
StatisticsModel *billPeriods = mModels.value( KNemoStats::BillPeriod );
784
if ( billPeriods->rowCount() )
785
walkbackDate = prepareRebuild( mModels.value( KNemoStats::BillPeriod), requestedStart );
787
walkbackDate = days->date( 0 );
789
for ( int i = 0; i < days->rowCount(); ++i )
791
QDate day = days->date( i );
793
if ( day >= walkbackDate )
795
genNewBillPeriod( day );
796
amendStats( i, mModels.value( KNemoStats::Day ), mModels.value( KNemoStats::BillPeriod ) );
801
void InterfaceStatistics::prependStatsRule( QList<StatsRule> &rules )
803
qSort( rules.begin(), rules.end(), statsLessThan );
804
StatisticsModel * days = mModels.value( KNemoStats::Day );
805
if ( rules.count() == 0 ||
806
( days->rowCount() > 0 && rules[0].startDate > days->date( 0 ) )
810
if ( days->rowCount() )
811
date = days->date( 0 );
813
date = QDate::currentDate();
815
s.startDate = date.addDays( 1 - mStorageData.calendar->day( date ) );
820
void InterfaceStatistics::checkRebuild( const QString &oldCalendar, bool force )
822
QList<StatsRule> newRules = mInterface->settings().statsRules;
823
bool forceWeek = false;
825
if ( oldCalendar != mInterface->settings().calendar )
827
StatisticsModel *hours = mModels.value( KNemoStats::Hour );
828
StatisticsModel *days = mModels.value( KNemoStats::Day );
829
for ( int i = 0; i < days->rowCount(); ++i )
831
days->updateDateText( i );
833
for ( int i = 0; i < hours->rowCount(); ++i )
835
hours->updateDateText( i );
839
if ( mModels.value( KNemoStats::Week )->rowCount() )
841
QDate testDate = mModels.value( KNemoStats::Week )->date( 0 );
842
if ( mStorageData.calendar->dayOfWeek( testDate ) != mStorageData.calendar->weekStartDay() )
846
bool doBilling = newRules.count();
847
int oldRuleCount = mStatsRules.count();
851
mModels.value( KNemoStats::BillPeriod )->clearRows();
852
mStorageData.saveFromId.insert( KNemoStats::BillPeriod, 0 );
855
// This is just a dummy for calculation
856
prependStatsRule( newRules );
857
prependStatsRule( mStatsRules );
859
if ( !oldRuleCount && mStatsRules[0] == newRules[0] && newRules.count() > mStatsRules.count() )
860
bpBeginDate = mModels.value( KNemoStats::Day )->date( 0 );
864
for ( int i = 0; i < newRules.count(); ++i )
867
bool rulesMatch = ( newRules[i] == mStatsRules[j] );
872
if ( newRules.count() > i + 1 )
873
nextRuleStart = newRules[i+1].startDate;
874
if ( !recalcPos.isValid() )
875
recalcPos = newRules[i].startDate;
876
rebuildBaseUnits( newRules[i], newRules[i].startDate, nextRuleStart );
880
// rules match, now scan forward to see if we need to extend new rule
881
if ( newRules.count() > i + 1 )
885
// Here we want to skip over any intermediary old rules that will
886
// get taken care of when we recalculate this section.
887
for ( k = 0; k < mStatsRules.count(); ++k )
889
if ( mStatsRules[k].startDate > newRules[i].startDate &&
890
mStatsRules[k].startDate < newRules[i+1].startDate )
895
if ( !recalcPos.isValid() )
896
recalcPos = mStatsRules[j].startDate;
901
rebuildBaseUnits( newRules[i], mStatsRules[first].startDate, newRules[i+1].startDate );
904
// We're out of new rules but there's more old ones
905
// so rebuild from next old rule's date using final new rule.
906
else if ( mStatsRules.count() > j + 1 )
909
if ( !recalcPos.isValid() )
910
recalcPos = mStatsRules[j+1].startDate;
911
rebuildBaseUnits( newRules[i], recalcPos, nextRuleStart );
913
if ( mStatsRules.count() > j + 1 )
921
mStatsRules = newRules;
923
recalcPos = mModels.value( KNemoStats::Day )->date( 0 );
925
if ( recalcPos.isValid() )
927
rebuildCalendarPeriods( recalcPos );
931
rebuildBillPeriods( recalcPos );
934
else if ( forceWeek )
936
rebuildCalendarPeriods( mModels.value( KNemoStats::Day )->date( 0 ), true );
939
mStatsRules = mInterface->settings().statsRules;
940
if ( mStatsRules.count() )
941
prependStatsRule( mStatsRules );
943
if ( recalcPos.isValid() )
945
saveStatistics( true );
948
mTrafficChanged = true;
512
949
emit currentEntryChanged();
516
* Find the next billing period's date.
517
* This is complicated by a few things:
518
* 1. it calculates the date according to whatever calendar type the
519
* the statistics are using
520
* 2. the period can span one or more localized months
521
* 3. termination dates can be awkward (e.g. if a period starts on
522
* Dec 30 and spans 2 months, which day should it end on?)
524
QDate InterfaceStatistics::nextMonthDate( const QDate &date )
526
QDate nextDate( date );
527
int length = mInterface->getSettings().billingMonths;
528
for ( int i = 0; i < length; i++ )
531
mCalendar->setDate( refDay, mCalendar->year( nextDate ), mCalendar->month( nextDate ), 1 );
532
refDay = refDay.addDays( mCalendar->daysInMonth( refDay ) );
534
nextDate = nextDate.addDays( mCalendar->daysInMonth( nextDate ) );
536
// Ensure we don't get weird spans like Jan 31 -> Mar 2
537
// Instead, days will drift to a value that all months can handle.
538
// Test for problematic dates in config module!
539
if ( mCalendar->day( mBillingStart ) > 1 )
541
while ( mCalendar->month( nextDate ) != mCalendar->month( refDay ) )
542
nextDate = nextDate.addDays( -1 );
549
* Return true if at least one daily statistic entry is in a span of days
551
bool InterfaceStatistics::daysInSpan( const QDate& date, int days )
553
StatisticsModel *model = mModels.value( StatisticsModel::Day );
554
if ( !model->rowCount() )
557
QDate endDate = date.addDays( days );
558
for ( int i = model->rowCount() - 1; i >= 0; --i )
560
// No others will be valid after this; stop early
561
if ( model->date( i ) < date )
563
if ( model->date( i ) < endDate && model->date( i ) >= date )
569
void InterfaceStatistics::genNewHour( const QDateTime &dateTime )
571
StatisticsModel* hours = mModels.value( StatisticsModel::Hour );
574
while ( hours->rowCount() )
576
if ( hours->dateTime( 0 ) <= dateTime.addDays( -1 ) )
577
hours->removeRow( 0 );
582
if ( hours->dateTime() == dateTime )
585
hours->appendStats( dateTime, 0 );
587
if ( mInterface->getSettings().warnType == NotifyHour ||
588
mInterface->getSettings().warnType == NotifyRoll24Hour )
589
mWarningDone = false;
592
void InterfaceStatistics::genNewDay( const QDate &date )
594
StatisticsModel * model = mModels.value( StatisticsModel::Day );
595
if ( model->rowCount() &&
596
model->date().addDays( model->days() ) > date )
599
mModels.value( StatisticsModel::Day )->appendStats( date, 1 );
601
if ( mInterface->getSettings().warnType == NotifyDay ||
602
mInterface->getSettings().warnType == NotifyRoll7Day ||
603
mInterface->getSettings().warnType == NotifyRoll30Day )
604
mWarningDone = false;
607
void InterfaceStatistics::genNewWeek( const QDate &date )
609
StatisticsModel * model = mModels.value( StatisticsModel::Week );
610
if ( model->rowCount() &&
611
model->date().addDays( model->days() ) > date )
614
int dow = mCalendar->dayOfWeek( date );
615
// ISO8601: week always starts on a Monday
616
QDate newDate = date.addDays( 1 - dow );
617
model->appendStats( newDate, mCalendar->daysInWeek( newDate ) );
620
void InterfaceStatistics::genNewMonth( const QDate &date, QDate endDate )
622
StatisticsModel * model = mModels.value( StatisticsModel::Month );
623
if ( model->rowCount() &&
624
model->date().addDays( model->days() ) > date )
628
// Partial month. Very little to do.
629
if ( endDate.isValid() )
631
days = date.daysTo( endDate );
632
if ( daysInSpan( date, date.daysTo( endDate ) ) )
634
mModels.value( StatisticsModel::Month )->appendStats( date, days );
639
// partial month contains no daily stats, so advance start date
640
// and get a new period below
641
mBillingStart = date.addDays( days );
645
// Given a calendar day and a billing period start date, find a
646
// billing period that the day belongs in.
648
QDate nextMonthStart = mBillingStart;
651
newDate = nextMonthStart;
652
nextMonthStart = nextMonthDate( newDate );
653
days = newDate.daysTo( nextMonthStart );
654
} while ( nextMonthStart <= date || !daysInSpan( newDate, days ) );
656
mBillingStart = newDate;
657
mModels.value( StatisticsModel::Month )->appendStats( newDate, days );
659
if ( mInterface->getSettings().warnType == NotifyMonth )
660
mWarningDone = false;
663
void InterfaceStatistics::genNewYear( const QDate &date )
665
StatisticsModel * model = mModels.value( StatisticsModel::Year );
666
if ( model->rowCount() &&
667
model->date().addDays( model->days() ) > date )
670
int doy = mCalendar->dayOfYear( date );
671
QDate newDate = date.addDays( 1 - doy );
672
mModels.value( StatisticsModel::Year )->appendStats( newDate, mCalendar->daysInYear( newDate ) );
675
void InterfaceStatistics::checkValidEntry( QDateTime curDateTime )
952
// END REBUILDING STATISTICS
955
void InterfaceStatistics::checkValidEntry()
958
QDateTime curDateTime = QDateTime::currentDateTime();
677
959
QDate curDate = curDateTime.date();
678
StatisticsModel *days = mModels.value( StatisticsModel::Day );
960
StatisticsModel *days = mModels.value( KNemoStats::Day );
680
StatisticsModel *hours = mModels.value( StatisticsModel::Hour );
681
if ( !hours->rowCount() || hours->dateTime().addSecs( 3600 ) < curDateTime )
962
StatisticsModel *hours = mModels.value( KNemoStats::Hour );
963
if ( !hours->rowCount() || hours->dateTime().addSecs( 3600 ) <= curDateTime )
682
965
genNewHour( QDateTime( curDate, QTime( curDateTime.time().hour(), 0 ) ) );
684
968
if ( !days->rowCount() || days->date() < curDate )
686
genNewDay( curDate );
687
genNewWeek( curDate );
688
genNewMonth( curDate );
689
genNewYear( curDate );
693
void InterfaceStatistics::checkThreshold( quint64 currentBytes )
695
int warnMult = pow( 1024, mInterface->getSettings().warnUnits );
696
quint64 thresholdBytes = mInterface->getSettings().warnThreshold * warnMult;
697
if ( currentBytes > thresholdBytes )
700
emit warnTraffic( thresholdBytes, currentBytes );
704
void InterfaceStatistics::oneUnit( const StatisticsModel* model )
706
if ( mInterface->getSettings().warnTotalTraffic )
707
checkThreshold( model->totalBytes() );
709
checkThreshold( model->rxBytes() );
712
void InterfaceStatistics::rollingUnit( const StatisticsModel* model, int days )
715
QDateTime lowerLimit = model->dateTime().addDays( -days );
717
for ( int i = model->rowCount() - 1; i >= 0; --i )
719
if ( model->dateTime( i ) > lowerLimit )
970
genNewCalendarType( curDate, KNemoStats::Day );
971
genNewCalendarType( curDate, KNemoStats::Week );
972
genNewCalendarType( curDate, KNemoStats::Month );
973
genNewCalendarType( curDate, KNemoStats::Year );
974
genNewBillPeriod( curDate );
976
// The fancy short date may need updating
977
for ( int i = 0; i < hours->rowCount(); ++i )
978
hours->updateDateText( i );
981
QDateTime ndt = curDateTime.addSecs( 3600 - curDateTime.time().minute()*60 - curDateTime.time().second() );
983
int secs = curDateTime.secsTo( ndt );
984
mEntryTimer->setInterval( secs * 1000 );
985
mEntryTimer->start();
988
void InterfaceStatistics::checkWarnings()
990
if ( !mTrafficChanged )
992
mTrafficChanged = false;
994
QList<WarnRule> warn = mInterface->settings().warnRules;
995
for ( int wi=0; wi < warn.count(); ++wi )
997
if ( warn[wi].warnDone || !warn[wi].threshold > 0.0 )
1001
StatisticsModel *model = 0;
1003
model = mModels.value( warn[wi].periodUnits );
1007
int lowerIndex = model->rowCount() - warn[wi].periodCount;
1009
for ( int i = model->rowCount() - 1; i >= 0; --i )
721
if ( mInterface->getSettings().warnTotalTraffic )
722
total += model->totalBytes( i );
1011
if ( i >= lowerIndex )
1013
switch ( warn[wi].trafficDirection )
1015
case KNemoStats::TrafficIn:
1016
if ( warn[wi].trafficType == KNemoStats::PeakOffpeak )
1017
total += model->rxBytes( i );
1018
else if ( warn[wi].trafficType == KNemoStats::Offpeak )
1019
total += model->rxBytes( i, KNemoStats::OffpeakTraffic );
1021
total += model->rxBytes( i ) - model->rxBytes( i, KNemoStats::OffpeakTraffic );
1023
case KNemoStats::TrafficOut:
1024
if ( warn[wi].trafficType == KNemoStats::PeakOffpeak )
1025
total += model->txBytes( i );
1026
else if ( warn[wi].trafficType == KNemoStats::Offpeak )
1027
total += model->txBytes( i, KNemoStats::OffpeakTraffic );
1029
total += model->txBytes( i ) - model->txBytes( i, KNemoStats::OffpeakTraffic );
1032
if ( warn[wi].trafficType == KNemoStats::PeakOffpeak )
1033
total += model->totalBytes( i );
1034
else if ( warn[wi].trafficType == KNemoStats::Offpeak )
1035
total += model->totalBytes( i, KNemoStats::OffpeakTraffic );
1037
total += model->totalBytes( i ) - model->totalBytes( i, KNemoStats::OffpeakTraffic );
724
total += model->rxBytes( i );
1044
int warnMult = pow( 1024, warn[wi].trafficUnits );
1045
quint64 thresholdBytes = warn[wi].threshold * warnMult;
1046
if ( total > thresholdBytes )
1048
emit warnTraffic( warn[wi].customText, thresholdBytes, total );
1049
mInterface->settings().warnRules[wi].warnDone = true;
729
checkThreshold( total );
732
void InterfaceStatistics::checkTrafficLimit()
1056
/******************************
1057
* Public Interface *
1058
******************************/
1059
void InterfaceStatistics::clearStatistics()
734
int wtype = mInterface->getSettings().warnType;
736
if ( !mWarningDone && mInterface->getSettings().warnThreshold > 0.0 )
1061
foreach( StatisticsModel * s, mModels )
1063
mStorageData.nextHourId = 0;
1064
foreach ( StatisticsModel *s, mModels )
741
oneUnit( mModels.value( StatisticsModel::Hour ) );
744
oneUnit( mModels.value( StatisticsModel::Day ) );
747
oneUnit( mModels.value( StatisticsModel::Month ) );
749
case NotifyRoll24Hour:
750
rollingUnit( mModels.value( StatisticsModel::Hour ), 24 );
753
rollingUnit( mModels.value( StatisticsModel::Day ), 7 );
755
case NotifyRoll30Day:
756
rollingUnit( mModels.value( StatisticsModel::Day ), 30 );
1066
mStorageData.saveFromId.insert( s->periodType(), 0 );
1068
sql->clearStats( &mStorageData );
1070
mTrafficChanged = true;
1071
emit currentEntryChanged();
762
1074
void InterfaceStatistics::addRxBytes( unsigned long bytes )