From: lvaatamoinen Date: Wed, 23 Dec 2009 08:53:16 +0000 (+0000) Subject: - Added rate limit preferences to DBus client/server implementation X-Git-Url: http://git.maemo.org/git/?p=qtrapids;a=commitdiff_plain;h=6ae61ea5faec84289c549193b680c32c9d0bf395 - Added rate limit preferences to DBus client/server implementation - Added #ifdefs to reduce debugging output git-svn-id: file:///svnroot/qtrapids/trunk@56 42ac0dd5-4c8c-4c71-bb3e-ecdfe252ffda --- diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index d2ae12d..5546525 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -1,6 +1,6 @@ INCLUDE(${QT_USE_FILE}) -INCLUDE_DIRECTORIES(../include) +INCLUDE_DIRECTORIES(../include ../plugins) FIND_LIBRARY(BOOST_SYSTEM boost_system-mt) IF(${BOOST_SYSTEM} STREQUAL BOOST_SYSTEM-NOTFOUND) diff --git a/src/client/MainWindow.cpp b/src/client/MainWindow.cpp index 5549bb9..8b89ae8 100644 --- a/src/client/MainWindow.cpp +++ b/src/client/MainWindow.cpp @@ -25,9 +25,10 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include #include "DownloadView.h" #include "SeedView.h" @@ -42,10 +43,11 @@ const QString ABOUT_TEXT = QString(QObject::trUtf8("QtRapids, a simple BitTorrent client based on" "\nQt and Libtorrent." "\n\nURL: http://qtrapids.garage.maemo.org/" - "\n\nAuthor(s):\nLassi Väätämöinen, lassi.vaatamoinen@ixonos.com" + "\n\nAuthors:\nLassi Väätämöinen, lassi.vaatamoinen@ixonos.com" "\nDenis Zalevskiy, denis.zalewsky@ixonos.com" "\n\nIxonos Plc, Finland\n")); +const QString PLUGINS_DIR = "plugins"; // Consturctor MainWindow::MainWindow() : @@ -53,9 +55,11 @@ MainWindow::MainWindow() : tabWidget_(NULL), dlView_(NULL), seedView_(NULL), + searchWidget_(NULL), preferencesDialog_(NULL), settings_(QCoreApplication::organizationName() , QCoreApplication::applicationName()), + pluginDirs_(), server_(QtRapidsServer::staticInterfaceName() , "/qtrapids", QDBusConnection::sessionBus()) // torrentHandles_(), @@ -88,6 +92,7 @@ MainWindow::MainWindow() : // TABWIDGET (central widget) tabWidget_ = new QTabWidget(); + tabWidget_->setTabsClosable(true); /// @todo Exception handling dlView_ = new DownloadView(this); @@ -114,21 +119,192 @@ MainWindow::MainWindow() : SLOT(setEnabled(bool))); connect(toolBar, SIGNAL(actionTriggered(QAction*)), this, SLOT(handleToolBarAction(QAction*))); + connect (tabWidget_, SIGNAL(tabCloseRequested(int)), this, SLOT(on_tabWidget_tabCloseRequested(int))); + connect(&server_, SIGNAL(alert(qtrapids::TorrentState, qtrapids::ParamsMap_t)), + this, SLOT(on_alert(qtrapids::TorrentState, qtrapids::ParamsMap_t))); + +// connect(&btSession_, SIGNAL(alert(std::auto_ptr)), +// this, SLOT(on_alert(std::auto_ptr))); + + + LoadPlugins(); + +} + + +MainWindow::~MainWindow() +{ + settings_.setValue("geometry", saveGeometry()); +} + +// ===================== Implements PluginInterface ========================= +/// @todo add PluginInterface parameter to request plugin name +bool MainWindow::setGui(QWidget* widget, PluginWidgetType type, qtrapids::PluginInterface* plugin) +{ +#ifdef QTRAPIDS_DEBUG + qDebug() << "MainWindow::setGui():" << dlView_->currentItem(); +#endif + + if (plugin && plugin->identifier() == "SearchPlugin") { + searchWidget_ = widget; + } else { + return false; + } + + tabWidget_->addTab(widget, tr("Search")); + return true; +} + +/// @todo Add PluginInterface parameter to check which plugin gives the widget, to handle appropriately +void MainWindow::addPluginWidget(QWidget* widget, PluginWidgetType type) +{ +#ifdef QTRAPIDS_DEBUG + qDebug() << "MainWindow::addPluginWidget():" << dlView_->currentItem(); +#endif + + if (type == qtrapids::PluginHostInterface::TAB_PAGE) { + int index = tabWidget_->addTab(widget, tr("Results")); + tabWidget_->setCurrentIndex(index); + //layout_->addWidget(widget); + } +} +void MainWindow::addToolbar(QWidget* widget, PluginWidgetType type) +{ +} + +void MainWindow::addToolItem(QWidget* widget, PluginWidgetType type) +{ +} + +void MainWindow::addMenu(QWidget* widget, PluginWidgetType type) +{ +} + +void MainWindow::addMenuItem(QWidget* widget, PluginWidgetType type) +{ +} + +bool MainWindow::eventRequest(QVariant param, PluginRequest req) +{ + if (req == qtrapids::PluginHostInterface::OPEN_FILE) { + QString sourceFile = param.toString(); + + // Get the source files name from the full path: + QFileInfo fInfo(sourceFile); + QString targetFile = fInfo.fileName(); + targetFile = settings_.value("download/directory").toString() + "/" + targetFile; + + // Copy temoporary file to Downloads directory... + if (!QFile::copy(sourceFile, targetFile)) { + qDebug() << "File copying failed"; + return false; + } else { + // If copying was successful, remove the original temporary file. + QFile::remove(sourceFile); + } + + /// @todo Torrent bencoding validity should be checked before starting(?) + // ...and start the torrent: + on_torrentFileSelected(targetFile); + + } else if (req == qtrapids::PluginHostInterface::READ_BUFFER) { + // Create torrent information from char* buffer and start. + StartTorrentFromBufferData(param.toByteArray().constData(), param.toByteArray().size()); + } + + return true; +} + + +//=========================== PRIVATE ================================ + +void MainWindow::LoadPlugins() +{ + // Get plugin directories from + QStringList pluginDirsTmp = settings_.value("plugins/path").toStringList(); + QStringList nameFilters("*.so"); + + /// @todo enable "application directory" for plugin search in development/debug mode only. In release version + /// search plugins directory under $HOME/.qtrapids or system library paths + pluginDirsTmp << qApp->applicationDirPath(); + pluginDirsTmp.removeDuplicates(); + + foreach (QString dir, pluginDirsTmp) { + pluginDirs_.append(QDir(dir)); + } + + foreach (QDir dir, pluginDirs_) { + + if (dir.cd(PLUGINS_DIR)) { + + foreach (QString fileName, dir.entryList(nameFilters, QDir::Files)) { + QPluginLoader pluginLoader(dir.absoluteFilePath(fileName)); + + // If plugin not loaded from another directory, then load + if (!pluginFileNames_.contains(fileName) && QLibrary::isLibrary(fileName)) { + + if (pluginLoader.load()) { + qDebug() << "Plugin loaded: " << fileName; + } else { + qWarning() << "Plugin load failed: " << pluginLoader.errorString(); + } + + QObject *baseInstance = pluginLoader.instance(); + if (!baseInstance) { + qDebug() << "Base instance = NULL."; + } + + qtrapids::PluginInterface *plugin = qobject_cast(baseInstance); + + if (!plugin) { + qDebug() << "Cast failed."; + } else { + qtrapids::PluginInterface::Info info; + info.directory = dir.path(); + qDebug() << dir.path(); + plugin->initialize(this, info); + pluginFileNames_ += fileName; + } + } else { + qWarning() << "Plugin " + << fileName + << " already loaded from another directory, or not a valid library file"; + } + } + + } else { + qWarning() << PLUGINS_DIR << "directory not accessible or does not exist in " << dir.path(); + } + } +} + + +void MainWindow::RestoreSettings() +{ + + // Restore previous main window geometry: QVariant geometry(settings_.value("geometry")); if (!geometry.isNull()) { qDebug() << "restoring geometry"; restoreGeometry(geometry.toByteArray()); } + + // Restore torrent session settings to server: + qtrapids::ParamsMap_t options; + options["net/downloadRate"] = settings_.value("net/downloadRate").toString(); + options["net/uploadRate"] = settings_.value("net/uploadRate").toString(); + server_.setOptions(options); } -MainWindow::~MainWindow() +// Opens torrent information from buffer data and adds torrent to session +void MainWindow::StartTorrentFromBufferData(char const* data, int size) { - settings_.setValue("geometry", saveGeometry()); + } -// =========================== SLOTS ================================= +// =========================== PRIVATE SLOTS ================================= void MainWindow::on_openAction_clicked() { QFileDialog *dialog = new QFileDialog( this, "Open torrent file", QString(), tr("Torrent files (*.torrent)")); @@ -148,21 +324,25 @@ void MainWindow::on_removeAction_clicked() } } + void MainWindow::on_quitAction_clicked() { close(); } + void MainWindow::on_preferencesAction_clicked() { if (!preferencesDialog_) { - preferencesDialog_ = new PreferencesDialog(this); + preferencesDialog_ = new PreferencesDialog(this, 0, &server_); } + preferencesDialog_->show(); preferencesDialog_->raise(); preferencesDialog_->activateWindow(); } + void MainWindow::on_aboutAction_clicked() { QMessageBox::about(this, tr("About QtRapids"), ABOUT_TEXT); @@ -175,9 +355,27 @@ void MainWindow::on_aboutQtAction_clicked() } +void MainWindow::on_tabWidget_tabCloseRequested(int index) +{ + + int searchWidgetIndex = tabWidget_->indexOf(searchWidget_); + + // Allow closing other tabs than the first two + // TODO The first two may well be closable, just add "show tabs" action for these in the menu + if (index != 0 && index != 1 && index != searchWidgetIndex) { + QWidget *remove = tabWidget_->widget(index); + tabWidget_->removeTab(index); + delete remove; + remove = NULL; + } +} + + void MainWindow::on_downloadItemSelectionChanged() { +#ifdef QTRAPIDS_DEBUG qDebug() << "MainWindow::on_seedItemSelectionChanged():" << dlView_->currentItem(); +#endif if (dlView_->currentItem() != NULL) { emit(itemSelected(true)); } else { @@ -185,9 +383,12 @@ void MainWindow::on_downloadItemSelectionChanged() } } + void MainWindow::on_seedItemSelectionChanged() { +#ifdef QTRAPIDS_DEBUG qDebug() << "MainWindow::on_seedItemSelectionChanged():" << seedView_->currentItem(); +#endif if (seedView_->currentItem() != NULL) { emit(itemSelected(true)); } else { @@ -195,6 +396,7 @@ void MainWindow::on_seedItemSelectionChanged() } } + void MainWindow::handleToolBarAction(QAction* action) { if (action->text() == "Open") { @@ -204,9 +406,12 @@ void MainWindow::handleToolBarAction(QAction* action) } } + void MainWindow::on_torrentFileSelected(const QString& file) { +#ifdef QTRAPIDS_DEBUG qDebug() << " MainWindow::on_torrentFileSelected(): " << file; +#endif // Torrent filename empty, do nothing. if (file == "") { return; @@ -225,9 +430,11 @@ void MainWindow::on_torrentFileSelected(const QString& file) } -void MainWindow::alert(qtrapids::TorrentState info, qtrapids::ParamsMap_t other_info) +void MainWindow::on_alert(qtrapids::TorrentState info, qtrapids::ParamsMap_t other_info) { - std::cerr << "got alert" << std::endl; +#ifdef QTRAPIDS_DEBUG + qDebug() << "got alert"; +#endif dlView_->updateItem(info, other_info); } diff --git a/src/client/MainWindow.h b/src/client/MainWindow.h index 9b55d5b..fb643eb 100644 --- a/src/client/MainWindow.h +++ b/src/client/MainWindow.h @@ -23,6 +23,7 @@ #include #include +#include "PluginInterface.h" #include "proxy.h" class QTabWidget; @@ -37,14 +38,26 @@ class SeedView; /** @author Lassi Väätämöinen */ -class MainWindow : public QMainWindow +class MainWindow : public QMainWindow, public PluginHostInterface { + Q_OBJECT; public: MainWindow(); - ~MainWindow(); + virtual ~MainWindow(); + + // Implemented from PluginHostInterface + virtual bool setGui(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE, qtrapids::PluginInterface* plugin = NULL); + virtual void addPluginWidget(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE); + virtual void addToolbar(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE); + virtual void addToolItem(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE); + virtual void addMenu(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE); + virtual void addMenuItem(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE); + virtual bool eventRequest(QVariant param, PluginRequest req = UNKNOWN_REQUEST); + + void RestoreSettings(); void connectToServer() { qDBusRegisterMetaType(); @@ -54,7 +67,7 @@ public: , SIGNAL(alert(qtrapids::TorrentState , qtrapids::ParamsMap_t)) , this - , SLOT(alert(qtrapids::TorrentState + , SLOT(on_alert(qtrapids::TorrentState , qtrapids::ParamsMap_t))); server_.getState(); } @@ -70,18 +83,26 @@ private slots: void on_preferencesAction_clicked(); void on_aboutAction_clicked(); void on_aboutQtAction_clicked(); + void on_tabWidget_tabCloseRequested(int index); void on_downloadItemSelectionChanged(); void on_seedItemSelectionChanged(); void handleToolBarAction(QAction* action); void on_torrentFileSelected(const QString& file); - void alert(qtrapids::TorrentState, qtrapids::ParamsMap_t); + void on_alert(qtrapids::TorrentState, qtrapids::ParamsMap_t); private: + void LoadPlugins(); + void StartTorrentFromBufferData(char const* data, int size); + +private: QTabWidget *tabWidget_; DownloadView *dlView_; SeedView *seedView_; + QWidget *searchWidget_; PreferencesDialog *preferencesDialog_; QSettings settings_; + QList pluginDirs_; + QStringList pluginFileNames_; //std::vector< std::auto_ptr const > torrentHandles_; diff --git a/src/client/PreferencesDialog.cpp b/src/client/PreferencesDialog.cpp index e541e90..f404336 100644 --- a/src/client/PreferencesDialog.cpp +++ b/src/client/PreferencesDialog.cpp @@ -22,32 +22,60 @@ #include #include #include +#include #include #include #include +#include "qtrapids/dbus.hpp" +#include "proxy.h" #include "PreferencesDialog.h" -PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags f) : + + +PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags f, QtRapidsServer *server) : QDialog(parent, f), // Superclass dirLineEdit_(NULL), dialogButtons_(NULL), + uploadRateSpinBox_(NULL), + downloadRateSpinBox_(NULL), + server_(server), settings_() { setWindowTitle("Preferences"); QBoxLayout *verticalBox = new QBoxLayout(QBoxLayout::TopToBottom); - QBoxLayout *horizontalBox1 = new QBoxLayout(QBoxLayout::LeftToRight); + //QBoxLayout *horizontalBox1 = new QBoxLayout(QBoxLayout::LeftToRight); + QGridLayout *grid = new QGridLayout; setLayout(verticalBox); - verticalBox->addLayout(horizontalBox1); + verticalBox->addLayout(grid); QLabel *dirLabel = new QLabel(tr("Download directory: ")); dirLineEdit_ = new QLineEdit(this); QPushButton *browseDirButton = new QPushButton(tr("Browse..")); - - horizontalBox1->addWidget(dirLabel); - horizontalBox1->addWidget(dirLineEdit_); - horizontalBox1->addWidget(browseDirButton); + + QLabel *uploadLabel = new QLabel(tr("Max. upload rate: ")); + QLabel *downloadLabel = new QLabel(tr("Max. download rate: ")); + uploadRateSpinBox_ = new QSpinBox(this); + downloadRateSpinBox_ = new QSpinBox(this); + + grid->addWidget(dirLabel, 0, 0); + grid->addWidget(dirLineEdit_, 0, 1); + grid->addWidget(browseDirButton, 0, 2); + + grid->addWidget(uploadLabel, 1, 0); + grid->addWidget(uploadRateSpinBox_, 1, 1); + grid->addWidget(downloadLabel, 2, 0); + grid->addWidget(downloadRateSpinBox_, 2, 1); + + uploadRateSpinBox_->setRange(0, 1000); + uploadRateSpinBox_->setSuffix(" kB/s"); + downloadRateSpinBox_->setRange(0, 1000); + downloadRateSpinBox_->setSuffix(" kB/s"); + +// horizontalBox1->addWidget(dirLabel); +// horizontalBox1->addWidget(dirLineEdit_); +// horizontalBox1->addWidget(browseDirButton); connect(browseDirButton, SIGNAL(clicked()), this, SLOT(on_browseDirButtonClicked())); @@ -95,7 +123,7 @@ void PreferencesDialog::on_buttonClicked(QAbstractButton* button) case QDialogButtonBox::AcceptRole : qDebug() << "PreferencesDialog: OK"; WriteSettings(); - close(); + done(QDialog::Accepted); break; case QDialogButtonBox::ApplyRole : qDebug() << "PreferencesDialog: APPLY"; @@ -103,7 +131,7 @@ void PreferencesDialog::on_buttonClicked(QAbstractButton* button) break; case QDialogButtonBox::RejectRole : qDebug() << "PreferencesDialog: CANCEL"; - close(); + done(QDialog::Rejected); break; default: return; @@ -117,6 +145,7 @@ void PreferencesDialog::on_downloadDirectorySelected(const QString& directory) if (directory == "") return; + dirLineEdit_->clear(); dirLineEdit_->insert(directory); /// @todo check that user has privileges to write to this directory. @@ -126,16 +155,37 @@ void PreferencesDialog::on_downloadDirectorySelected(const QString& directory) // ========================= Private functions ========================== void PreferencesDialog::WriteSettings() { + int ulRate = 1000*uploadRateSpinBox_->value(); + int dlRate = 1000*downloadRateSpinBox_->value(); + settings_.setValue("download/directory", dirLineEdit_->text()); - + //settings_.setValue("net/uploadRate", ulRate); + //settings_.setValue("net/downloadRate", dlRate); + // NOTE: We might need to call QSettigns::sync() here to instantly write settings. // settings are written also by QSettings() destructor and by event loop at regular interval. + + // If server pointer was given, apply settings immediately. + if (server_) { + /// @todo Use DBus interface + /// @todo Set parameters for server + /// @todo Add speedlimit functionality to Server. + qtrapids::ParamsMap_t options; + options["net/downloadRate"] = QString::number(dlRate); + options["net/uploadRate"] = QString::number(ulRate); + server_->setOptions(options); +// btSession_->setUploadRateLimit(ulRate); +// btSession_->setDownloadRateLimit(dlRate); + } + } void PreferencesDialog::ReadSettings() { dirLineEdit_->insert(settings_.value("download/directory").toString()); - + uploadRateSpinBox_->setValue(settings_.value("net/uploadRate").toInt()/1000); + downloadRateSpinBox_->setValue(settings_.value("net/downloadRate").toInt()/1000); + // NOTE: We might need to call QSettigns::sync() here to instantly write settings. // settings are written also by QSettings() destructor and by event loop at regular interval. } diff --git a/src/client/PreferencesDialog.h b/src/client/PreferencesDialog.h index 387a1e5..653152f 100644 --- a/src/client/PreferencesDialog.h +++ b/src/client/PreferencesDialog.h @@ -26,8 +26,12 @@ class QAbstractButton; class QLineEdit; +class QSpinBox; class QDialogButtonBox; +class QtRapidsServer; + + /** @author Lassi Väätämöinen */ @@ -37,7 +41,7 @@ class PreferencesDialog : public QDialog Q_OBJECT public: - PreferencesDialog(QWidget* parent = 0, Qt::WindowFlags f = 0); + PreferencesDialog(QWidget* parent = 0, Qt::WindowFlags f = 0, QtRapidsServer *server = 0); ~PreferencesDialog(); @@ -49,8 +53,13 @@ private slots: private: QLineEdit *dirLineEdit_; QDialogButtonBox *dialogButtons_; + QSpinBox *uploadRateSpinBox_, *downloadRateSpinBox_; + + QtRapidsServer *server_; + QSettings settings_; +private: // Private functions: void WriteSettings(); void ReadSettings(); diff --git a/src/client/main.cpp b/src/client/main.cpp index 9198bb1..9c5a020 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -38,6 +38,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); MainWindow mainWindow; mainWindow.connectToServer(); + mainWindow.RestoreSettings(); // mainWindow->setGeometry(QApplication::desktop()->screenGeometry()); mainWindow.show(); diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index 3c5a61e..c2edb1a 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -37,12 +37,12 @@ class PluginInterface; /** @author Lassi Väätämöinen */ -class MainWindow : public QMainWindow, public qtrapids::PluginHostInterface { +class MainWindow : public QMainWindow, public qtrapids::PluginHostInterface +{ Q_OBJECT - + public: MainWindow(); - virtual ~MainWindow(); // Implemented from PluginHostInterface diff --git a/src/gui/PreferencesDialog.h b/src/gui/PreferencesDialog.h index 629acb7..03e624f 100644 --- a/src/gui/PreferencesDialog.h +++ b/src/gui/PreferencesDialog.h @@ -60,6 +60,7 @@ private: qtrapids::QBittorrentSession *const btSession_; QSettings settings_; +private: // Private functions: void WriteSettings(); void ReadSettings(); diff --git a/src/include/qtrapids/dbus.hpp b/src/include/qtrapids/dbus.hpp index bb3671b..173afbf 100644 --- a/src/include/qtrapids/dbus.hpp +++ b/src/include/qtrapids/dbus.hpp @@ -52,7 +52,9 @@ typedef ParamsMap_t::const_iterator ParamsMapConstIterator_t; static inline QDBusArgument& operator << (QDBusArgument& argument , TorrentState const& state) { +#ifdef QTRAPIDS_DEBUG std::cout << "serialize" << std::endl; +#endif argument.beginStructure(); argument << state.hash << state.name << (uint)(state.action) << state.state << state.progress << state.down_rate << state.up_rate << state.seeds @@ -64,7 +66,9 @@ static inline QDBusArgument& operator << (QDBusArgument& argument static inline QDBusArgument const& operator >> (QDBusArgument const& argument , TorrentState& state) { +#ifdef QTRAPIDS_DEBUG std::cout << "deserialize" << std::endl; +#endif argument.beginStructure(); uint action; argument >> state.hash >> state.name >> action >> state.state >> state.progress @@ -79,7 +83,10 @@ static inline QDBusArgument& operator << (QDBusArgument& argument , ParamsMapConst_t& params) { ParamsMapConstIterator_t p; +#ifdef QTRAPIDS_DEBUG std::cout << "serialize params" << std::endl; +#endif + argument.beginMap(); for (p = params.constBegin(); p != params.constEnd(); ++p) { argument.beginMapEntry(); @@ -95,7 +102,9 @@ static inline QDBusArgument const& operator >> (QDBusArgument const& argument { ParamsMapConstIterator_t p; QString key, value; +#ifdef QTRAPIDS_DEBUG std::cout << "deserialize params" << std::endl; +#endif argument.beginMap(); for (p = params.constBegin(); p != params.constEnd(); ++p) { argument.beginMapEntry(); diff --git a/src/server/ServerDb.hpp b/src/server/ServerDb.hpp index fa31059..557a9f7 100644 --- a/src/server/ServerDb.hpp +++ b/src/server/ServerDb.hpp @@ -1,6 +1,7 @@ #ifndef _SERVERDB_HPP_ #define _SERVERDB_HPP_ +#include #include #include #include diff --git a/src/server/TorrentSession.cpp b/src/server/TorrentSession.cpp index b5d6e9d..38140b1 100644 --- a/src/server/TorrentSession.cpp +++ b/src/server/TorrentSession.cpp @@ -29,6 +29,13 @@ TorrentSession::TorrentSession(QObject *parent, QSettings *settings) alertWaiter_->start(); loadState(); + + // Lets force applying rate limits to local network also, at least for testing. + // Also, on the N900 device, rate limiting is necessary due to limited processign power + session_settings_t sessionSettings; + sessionSettings.ignore_limits_on_local_network = false; + btSession_.set_settings(sessionSettings); + } void TorrentSession::loadState() @@ -36,7 +43,9 @@ void TorrentSession::loadState() TorrentDownloadInfo info; TorrentsStorage storage(*db_); while (storage.nextTorrent(info)) { +#ifdef QTRAPIDS_DEBUG qDebug() << "adding " << info.path; +#endif addTorrent_(info.path, info.download_path, ParamsMap_t(), true); } btSession_.listen_on(settings_->getListenPorts()); @@ -50,13 +59,17 @@ void TorrentSession::on_alert() torrent_alert_t *ta = dynamic_cast (alertPtr.get()); +#ifdef QTRAPIDS_DEBUG qDebug() - << "QBittorrentSession::on_alert(): " + << "TorrentSession::on_alert(): " << QString::fromStdString(alertPtr->message()); +#endif if (ta) { if (!ta->handle.is_valid()) { +#ifdef QTRAPIDS_DEBUG qDebug() << "handle is invalid"; +#endif return; } @@ -123,10 +136,16 @@ void TorrentSession::addTorrent_(const QString &path, const QString &save_path QString new_torrent_fname(QDir(settings_->getTorrentsDir()) .filePath(QFileInfo(path).fileName())); +#ifdef QTRAPIDS_DEBUG qDebug() << "copy to " << new_torrent_fname; - torrent_file.copy(new_torrent_fname); +#endif + torrent_file.copy(new_torrent_fname); + +#ifdef QTRAPIDS_DEBUG qDebug() << "addTorrent: " << path << " save to " << save_path; +#endif + boost::intrusive_ptr tiTmp = new libtorrent::torrent_info (boost::filesystem::path(new_torrent_fname.toStdString())); @@ -172,7 +191,9 @@ void TorrentSession::removeTorrent(const QString &hash) torrents_t::iterator p = torrents_.find(hash); if (p == torrents_.end()) { +#ifdef QTRAPIDS_DEBUG qDebug() << "Invalid request to remove torrent with hash " << hash; +#endif return; } try { @@ -191,11 +212,34 @@ void TorrentSession::removeTorrent(const QString &hash) db_->removeTorrent(hash); } + void TorrentSession::setOptions(qtrapids::ParamsMap_t options) { + qtrapids::ParamsMapConstIterator_t end = options.end(); + qtrapids::ParamsMapConstIterator_t tmpIter = options.find("net/downloadRate"); + int rate = -1; + + // Apply settings immediately to Bittorrent session: + // NOTE: QHash interface is not quite STL-like + + if (tmpIter != end) { + rate = tmpIter.value().toInt(); + btSession_.set_download_rate_limit(rate); + } + + tmpIter = options.find("net/uploadRate"); + if (tmpIter != end) { + rate = tmpIter.value().toInt(); + btSession_.set_upload_rate_limit(rate); + } + + /// @todo Add more immediately applicable settings here, if needed. + + // Finally, save settings to persistent storage: settings_->setOptions(options); } + qtrapids::ParamsMap_t TorrentSession::getOptions() { return settings_->getOptions(); diff --git a/src/server/TorrentSession.hpp b/src/server/TorrentSession.hpp index 4f56050..799f62b 100644 --- a/src/server/TorrentSession.hpp +++ b/src/server/TorrentSession.hpp @@ -28,6 +28,7 @@ typedef QWeakPointer settings_weak_ptr; class AlertWaiterThread; typedef libtorrent::session session_t; typedef libtorrent::session const* session_cptr; +typedef libtorrent::session_settings session_settings_t; typedef libtorrent::add_torrent_params add_torrent_params_t; typedef libtorrent::alert alert_t;