FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period)

This commit is contained in:
Christophe Dumez 2010-01-24 11:57:15 +00:00
parent 540da69d61
commit 48dbaf05ae
9 changed files with 160 additions and 20 deletions

View file

@ -1,5 +1,6 @@
* Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.2.0
- FEATURE: User can set alternative speed limits for fast toggling
- FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period)
* Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0
- FEATURE: Graphical User Interface can be disabled at compilation time (headless running)

View file

@ -116,6 +116,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
connect(BTSession, SIGNAL(trackerAuthenticationRequired(QTorrentHandle&)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle&)));
connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString)));
connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString)));
connect(BTSession, SIGNAL(alternativeSpeedsModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool)));
qDebug("create tabWidget");
tabs = new QTabWidget();
@ -181,7 +182,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
// Create status bar
status_bar = new StatusBar(QMainWindow::statusBar(), BTSession);
connect(actionUse_alternative_speed_limits, SIGNAL(triggered()), status_bar, SLOT(toggleAlternativeSpeeds()));
connect(status_bar, SIGNAL(alternativeSpeedsToggled(bool)), this, SLOT(updateAltSpeedsBtn(bool)));
show();

111
src/bandwidthscheduler.h Normal file
View file

@ -0,0 +1,111 @@
#ifndef BANDWIDTHSCHEDULER_H
#define BANDWIDTHSCHEDULER_H
#include <QTimer>
#include <QTime>
#include <QDateTime>
#include "preferences.h"
#include <iostream>
class BandwidthScheduler: public QTimer {
Q_OBJECT
private:
bool in_alternative_mode;
public:
BandwidthScheduler(QObject *parent): QTimer(parent), in_alternative_mode(false) {
Q_ASSERT(Preferences::isSchedulerEnabled());
// Signal shot, we call start() again manually
setSingleShot(true);
// Connect Signals/Slots
connect(this, SIGNAL(timeout()), this, SLOT(switchMode()));
}
public slots:
void start() {
Q_ASSERT(Preferences::isSchedulerEnabled());
QTime startAltSpeeds = Preferences::getSchedulerStartTime();
QTime endAltSpeeds = Preferences::getSchedulerEndTime();
if(startAltSpeeds == endAltSpeeds) {
std::cerr << "Error: bandwidth scheduler have the same start time and end time." << std::endl;
std::cerr << "The bandwidth scheduler will be disabled" << std::endl;
stop();
emit switchToAlternativeMode(false);
return;
}
// Determine what the closest QTime is
QTime now = QTime::currentTime();
uint time_to_start = secsTo(now, startAltSpeeds);
uint time_to_end = secsTo(now, endAltSpeeds);
if(time_to_end < time_to_start) {
// We should be in alternative mode
in_alternative_mode = true;
// Start counting
QTimer::start(time_to_end*1000);
} else {
// We should be in normal mode
in_alternative_mode = false;
// Start counting
QTimer::start(time_to_start*1000);
}
// Send signal to notify BTSession
emit switchToAlternativeMode(in_alternative_mode);
}
void switchMode() {
// Get the day this mode was started (either today or yesterday)
QDate current_date = QDateTime::currentDateTime().toLocalTime().date();
int day = current_date.dayOfWeek();
if(in_alternative_mode) {
// It is possible that starttime was yesterday
if(QTime::currentTime().secsTo(Preferences::getSchedulerStartTime()) > 0) {
current_date.addDays(-1); // Go to yesterday
day = current_date.day();
}
}
// Check if the day is in scheduler days
// Notify BTSession only if necessary
switch(Preferences::getSchedulerDays()) {
case EVERY_DAY:
emit switchToAlternativeMode(!in_alternative_mode);
break;
case WEEK_ENDS:
if(day == Qt::Saturday || day == Qt::Sunday)
emit switchToAlternativeMode(!in_alternative_mode);
break;
case WEEK_DAYS:
if(day != Qt::Saturday && day != Qt::Sunday)
emit switchToAlternativeMode(!in_alternative_mode);
break;
default:
// Convert our enum index to Qt enum index
int scheduler_day = ((int)Preferences::getSchedulerDays()) - 2;
if(day == scheduler_day)
emit switchToAlternativeMode(!in_alternative_mode);
break;
}
// Call start again
start();
}
signals:
void switchToAlternativeMode(bool alternative);
private:
// Qt function can return negative values and we
// don't want that
uint secsTo(QTime now, QTime t) {
int diff = now.secsTo(t);
if(diff < 0) {
// 86400 seconds in a day
diff += 86400;
}
Q_ASSERT(diff >= 0);
return diff;
}
};
#endif // BANDWIDTHSCHEDULER_H

View file

@ -46,6 +46,7 @@
#endif
#include "torrentpersistentdata.h"
#include "httpserver.h"
#include "bandwidthscheduler.h"
#include <libtorrent/extensions/ut_metadata.hpp>
#ifdef LIBTORRENT_0_15
#include <libtorrent/extensions/lt_trackers.hpp>
@ -173,9 +174,10 @@ Bittorrent::~Bittorrent() {
if(filterParser)
delete filterParser;
delete downloader;
if(FSWatcher) {
if(FSWatcher)
delete FSWatcher;
}
if(bd_scheduler)
delete bd_scheduler;
// HTTP Server
if(httpServer)
delete httpServer;
@ -313,6 +315,15 @@ void Bittorrent::configureSession() {
// Enabled
setUploadRateLimit(up_limit*1024);
}
if(Preferences::isSchedulerEnabled()) {
if(!bd_scheduler) {
bd_scheduler = new BandwidthScheduler(this);
connect(bd_scheduler, SIGNAL(switchToAlternativeMode(bool)), this, SLOT(useAlternativeSpeedsLimit(bool)));
}
bd_scheduler->start();
} else {
if(bd_scheduler) delete bd_scheduler;
}
#ifndef DISABLE_GUI
// Resolve countries
qDebug("Loading country resolution settings");
@ -587,6 +598,20 @@ bool Bittorrent::initWebUi(QString username, QString password, int port) {
return success;
}
void Bittorrent::useAlternativeSpeedsLimit(bool alternative) {
// Save new state to remember it on startup
Preferences::setAltBandwidthEnabled(alternative);
// Apply settings to the bittorrent session
if(alternative) {
s->set_download_rate_limit(Preferences::getAltGlobalDownloadLimit()*1024);
s->set_upload_rate_limit(Preferences::getAltGlobalUploadLimit()*1024);
} else {
s->set_download_rate_limit(Preferences::getGlobalDownloadLimit()*1024);
s->set_upload_rate_limit(Preferences::getGlobalUploadLimit()*1024);
}
emit alternativeSpeedsModeChanged(alternative);
}
void Bittorrent::takeETASamples() {
bool change = false;;
foreach(const QString &hash, ETA_samples.keys()) {

View file

@ -55,6 +55,7 @@ class QTimer;
class FileSystemWatcher;
class FilterParserThread;
class HttpServer;
class BandwidthScheduler;
class TrackerInfos {
public:
@ -92,6 +93,7 @@ private:
// Bittorrent
session *s;
QPointer<QTimer> timerAlerts;
QPointer<BandwidthScheduler> bd_scheduler;
QMap<QUrl, QString> savepath_fromurl;
QHash<QString, QHash<QString, TrackerInfos> > trackersInfos;
QStringList torrentsToPausedAfterChecking;
@ -182,6 +184,7 @@ public slots:
void startUpTorrents();
session_proxy asyncDeletion();
void recheckTorrent(QString hash);
void useAlternativeSpeedsLimit(bool alternative);
/* Needed by Web UI */
void pauseAllTorrents();
void pauseTorrent(QString hash);
@ -261,6 +264,7 @@ signals:
void metadataReceived(QTorrentHandle &h);
void savePathChanged(QTorrentHandle &h);
void newConsoleMessage(QString msg);
void alternativeSpeedsModeChanged(bool alternative);
};
#endif

View file

@ -37,7 +37,7 @@ public:
}
~FeedList() {
//delete unread_item;
delete unread_item;
}
void itemAdded(QTreeWidgetItem *item, RssFile* file) {

View file

@ -204,7 +204,8 @@ HEADERS += misc.h \
stacktrace.h \
torrentpersistentdata.h \
filesystemwatcher.h \
preferences.h
preferences.h \
bandwidthscheduler.h
contains(DEFINES, DISABLE_GUI) {
HEADERS += headlessloader.h

View file

@ -64,6 +64,7 @@ private:
public:
StatusBar(QStatusBar *bar, Bittorrent *BTSession): bar(bar), BTSession(BTSession) {
connect(BTSession, SIGNAL(alternativeSpeedsModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool)));
container = new QWidget();
layout = new QGridLayout(container);
layout->setVerticalSpacing(0);
@ -198,17 +199,7 @@ public slots:
}
void toggleAlternativeSpeeds() {
bool alt = !Preferences::isAltBandwidthEnabled();
Preferences::setAltBandwidthEnabled(alt);
if(alt) {
BTSession->getSession()->set_download_rate_limit(Preferences::getAltGlobalDownloadLimit()*1024);
BTSession->getSession()->set_upload_rate_limit(Preferences::getAltGlobalUploadLimit()*1024);
} else {
BTSession->getSession()->set_download_rate_limit(Preferences::getGlobalDownloadLimit()*1024);
BTSession->getSession()->set_upload_rate_limit(Preferences::getGlobalUploadLimit()*1024);
}
updateAltSpeedsBtn(alt);
emit alternativeSpeedsToggled(alt);
BTSession->useAlternativeSpeedsLimit(!Preferences::isAltBandwidthEnabled());
}
void capDownloadSpeed() {
@ -246,8 +237,6 @@ public slots:
}
}
signals:
void alternativeSpeedsToggled(bool alternative);
};
#endif // STATUSBAR_H

View file

@ -1661,6 +1661,12 @@ QGroupBox {
<property name="enabled">
<bool>false</bool>
</property>
<property name="displayFormat">
<string>hh:mm</string>
</property>
<property name="calendarPopup">
<bool>false</bool>
</property>
<property name="time">
<time>
<hour>8</hour>
@ -1685,6 +1691,9 @@ QGroupBox {
<property name="enabled">
<bool>false</bool>
</property>
<property name="displayFormat">
<string>hh:mm</string>
</property>
<property name="time">
<time>
<hour>20</hour>
@ -1789,8 +1798,8 @@ QGroupBox {
<rect>
<x>0</x>
<y>0</y>
<width>620</width>
<height>490</height>
<width>466</width>
<height>415</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_20">