X-Git-Url: http://git.maemo.org/git/?p=qtrapids;a=blobdiff_plain;f=src%2Fserver%2FTorrentSession.cpp;h=d9d2b95990eb55e52b650f9a8a8eb5fc87082184;hp=c2fb92be88322b76a5fcbbf2eb0037212f5eba34;hb=1d97c0a567b80cf9fc67791669debfe3aa9c4c84;hpb=d27c2db830de9a65d6a419479ee598cbf3697746 diff --git a/src/server/TorrentSession.cpp b/src/server/TorrentSession.cpp index c2fb92b..d9d2b95 100644 --- a/src/server/TorrentSession.cpp +++ b/src/server/TorrentSession.cpp @@ -1,7 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2010 by Ixonos Plc * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; version 2 of the License. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ #include "TorrentSession.hpp" #include "TorrentHandle.hpp" #include "AlertWaiterThread.hpp" - +#include "ServerDb.hpp" +#include namespace qtrapids { @@ -9,165 +27,258 @@ namespace qtrapids TorrentSession::TorrentSession(QObject *parent, QSettings *settings) - : QObject(parent) - , btSession_() - , alertWaiter_(new AlertWaiterThread(&btSession_, this)) + : QObject(parent) + , btSession_() + , alertWaiter_(new AlertWaiterThread(&btSession_, this)) + , settings_(new ServerSettings(*settings)) + , db_(new ServerDb(settings_.get())) { - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - new QtRapidsServer(this); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + new QtRapidsServer(this); + + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/qtrapids", this); + dbus.registerService("com.ixonos.qtrapids"); + + alertWaiter_->allAlerts(); + connect(alertWaiter_, SIGNAL(alert()), this, SLOT(on_alert())); + 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); + +} - QDBusConnection dbus = QDBusConnection::sessionBus(); - dbus.registerObject("/qtrapids", this); - dbus.registerService("com.ixonos.qtrapids"); - alertWaiter_->allAlerts(); - connect(alertWaiter_, SIGNAL(alert()), this, SLOT(on_alert())); - alertWaiter_->start(); +TorrentSession::~TorrentSession() +{ + alertWaiter_->stop(); + alertWaiter_->wait(); + emit sessionTerminated(); +} +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()); } void TorrentSession::on_alert() -//NOTE: al parameter not necessarily needed here, as we pop_alert() now! { - - //qDebug() << "QBittorrentSession:on_alert(" << al << ")"; - // if (al) - // qDebug() << "on_alert():" << QString::fromStdString(al->message()); - - std::auto_ptr alertPtr = btSession_.pop_alert(); - - if (alertPtr.get() != NULL) - { - - torrent_alert_t *ta = dynamic_cast (alertPtr.get()); - - qDebug() - << "QBittorrentSession::on_alert(): " - << QString::fromStdString(alertPtr->message()); - - - if (ta) - { - - if (!ta->handle.is_valid()) - { - qDebug() << "handle is invalid"; - return; - } - - TorrentHandle handle(ta->handle); - TorrentState state; - - state.hash = Hash2QStr(handle.hash()); - state.action = TorrentState::action_update; - state.state = handle.state(); - state.progress = handle.progress() * torrent_progress_max; - state.down_rate = handle.downloadRate(); - state.up_rate = handle.uploadRate(); - state.seeds = handle.numSeeds(); - state.leeches = handle.numLeeches(); - - ParamsMap_t params; - emit alert(state, params); - } - - } + std::auto_ptr alertPtr = btSession_.pop_alert(); + + if (alertPtr.get() != NULL) { + + torrent_alert_t *ta = dynamic_cast (alertPtr.get()); + +#ifdef QTRAPIDS_DEBUG + qDebug() + << "TorrentSession::on_alert(): " + << QString::fromStdString(alertPtr->message()); +#endif + + if (ta) { + if (!ta->handle.is_valid()) { +#ifdef QTRAPIDS_DEBUG + qDebug() << "handle is invalid"; +#endif + return; + } + + TorrentHandle handle(ta->handle); + TorrentState state; + + state.hash = Hash2QStr(handle.hash()); + state.action = TorrentState::action_update; + state.state = handle.state(); + state.progress = handle.progress() * torrent_progress_max; + state.down_rate = handle.downloadRate(); + state.up_rate = handle.uploadRate(); + state.seeds = handle.numSeeds(); + state.leeches = handle.numLeeches(); + state.total_size = handle.getTotalSize(); + state.total_done = handle.getTotalDone(); + + ParamsMap_t params; + emit alert(state, params); + } + + } } void TorrentSession::getState() { - torrents_t::const_iterator p; - for (p = torrents_.constBegin(); p != torrents_.constEnd(); ++p) - { - TorrentHandlePtr handle = *p; - TorrentState state; - QString hash = Hash2QStr(handle->hash()); - - state.hash = hash; - state.name = handle->name(); - state.action = TorrentState::action_add; - state.state = handle->state(); - state.progress = handle->progress() * torrent_progress_max; - state.down_rate = handle->downloadRate(); - state.up_rate = handle->uploadRate(); - state.seeds = handle->numSeeds(); - state.leeches = handle->numLeeches(); - state.total_size = handle->getTotalSize(); - - emit alert(state, ParamsMap_t()); - } + torrents_t::const_iterator p; + for (p = torrents_.constBegin(); p != torrents_.constEnd(); ++p) { + TorrentHandlePtr handle = *p; + TorrentState state; + QString hash = Hash2QStr(handle->hash()); + + state.hash = hash; + state.name = handle->name(); + state.action = TorrentState::action_add; + state.state = handle->state(); + state.progress = handle->progress() * torrent_progress_max; + state.down_rate = handle->downloadRate(); + state.up_rate = handle->uploadRate(); + state.seeds = handle->numSeeds(); + state.leeches = handle->numLeeches(); + state.total_size = handle->getTotalSize(); + + emit alert(state, ParamsMap_t()); + } } void TorrentSession::addTorrent(const QString &path, const QString &save_path , qtrapids::ParamsMap_t other_params) { - add_torrent_params_t addParams; - QFile torrent_file(path); - if (!torrent_file.exists()) - { - qWarning() << "Torrent file " << path << "doesn't exist"; - return; - } - - qDebug() << "addTorrent: " << path << " save to " << save_path; - boost::intrusive_ptr tiTmp - = new libtorrent::torrent_info - (boost::filesystem::path(path.toStdString())); - addParams.ti = tiTmp; - - // save_path is the only mandatory parameter, rest are optional. - addParams.save_path = boost::filesystem::path(save_path.toStdString()); - //addParams.storage_mode = libtorrent::storage_mode_allocate; - - TorrentHandlePtr handle(new TorrentHandle(btSession_.add_torrent(addParams))); - QString hash = Hash2QStr(handle->hash()); - - TorrentState state; - - state.hash = hash; - state.name = handle->name(); - state.action = TorrentState::action_add; - state.state = handle->state(); - state.progress = handle->progress() * torrent_progress_max; - state.down_rate = handle->downloadRate(); - state.up_rate = handle->uploadRate(); - state.seeds = handle->numSeeds(); - state.leeches = handle->numLeeches(); - state.total_size = handle->getTotalSize(); - - torrents_[hash] = handle; - - emit alert(state, ParamsMap_t()); + return addTorrent_(path, save_path, other_params, false); +} + +void TorrentSession::addTorrent_(const QString &path, const QString &save_path + , const qtrapids::ParamsMap_t &other_params + , bool is_restore_session) +{ + add_torrent_params_t addParams; + QFile torrent_file(path); + QDir::home().mkdir(settings_->getTorrentsSubDir()); + + if (!torrent_file.exists()) { + qWarning() << "Torrent file " << path << "doesn't exist"; + return; + } + + QString new_torrent_fname(QDir(settings_->getTorrentsDir()) + .filePath(QFileInfo(path).fileName())); +#ifdef QTRAPIDS_DEBUG + qDebug() << "copy to " << 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())); + addParams.ti = tiTmp; + + QString download_dir; + if (!save_path.isEmpty()) { + download_dir = save_path; + } else { + download_dir = settings_->getDownloadDir(); + } + // save_path is the only mandatory parameter, rest are optional. + addParams.save_path = boost::filesystem::path(download_dir.toStdString()); + //addParams.storage_mode = libtorrent::storage_mode_allocate; + + TorrentHandlePtr handle(new TorrentHandle(btSession_.add_torrent(addParams))); + QString hash = Hash2QStr(handle->hash()); + + if (!is_restore_session) { + db_->addTorrent(hash, path, save_path); + } + + TorrentState state; + + state.hash = hash; + state.name = handle->name(); + state.action = TorrentState::action_add; + state.state = handle->state(); + state.progress = handle->progress() * torrent_progress_max; + state.down_rate = handle->downloadRate(); + state.up_rate = handle->uploadRate(); + state.seeds = handle->numSeeds(); + state.leeches = handle->numLeeches(); + state.total_size = handle->getTotalSize(); + + torrents_[hash] = handle; + + emit alert(state, ParamsMap_t()); } void TorrentSession::removeTorrent(const QString &hash) { - torrents_t::iterator p = torrents_.find(hash); - - if (p == torrents_.end()) - { - qDebug() << "Invalid request to remove torrent with hash " << hash; - return; - } - try - { - btSession_.remove_torrent(p.value()->getHandle()); - } - catch (torrent_exception_t e) - { - qDebug() << // e.what() - "exception catched" - ; - } - - TorrentState state; - state.hash = hash; - state.action = TorrentState::action_remove; - emit alert(state, ParamsMap_t()); - torrents_.erase(p); + 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 { + btSession_.remove_torrent(p.value()->getHandle()); + } catch (torrent_exception_t e) { + qDebug() << // e.what() + "exception catched" + ; + } + + TorrentState state; + state.hash = hash; + state.action = TorrentState::action_remove; + emit alert(state, ParamsMap_t()); + torrents_.erase(p); + 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(); +} + + +void TorrentSession::terminateSession() +{ + qDebug() << "Terminate called"; + // Emiting terminate() here causes the server application to quit in main() + emit terminate(); +} + } // namespace qtrapids