Added build script of Debian
[qtrapids] / src / server / TorrentSession.cpp
index c6d8b31..d9d2b95 100644 (file)
@@ -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 <qtrapids/error.hpp>
 
 namespace qtrapids
 {
@@ -12,6 +30,8 @@ TorrentSession::TorrentSession(QObject *parent, QSettings *settings)
                : QObject(parent)
                , btSession_()
                , alertWaiter_(new AlertWaiterThread(&btSession_, this))
+               , settings_(new ServerSettings(*settings))
+               , db_(new ServerDb(settings_.get()))
 {
        qDBusRegisterMetaType<qtrapids::TorrentState>();
        qDBusRegisterMetaType<qtrapids::ParamsMap_t>();
@@ -20,37 +40,62 @@ TorrentSession::TorrentSession(QObject *parent, QSettings *settings)
        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);
+       
 }
 
-void TorrentSession::on_alert()
-//NOTE: al parameter not necessarily needed here, as we pop_alert() now!
+
+TorrentSession::~TorrentSession()
 {
+       alertWaiter_->stop();
+       alertWaiter_->wait();
+       emit sessionTerminated();
+}
+
 
-       //qDebug() << "QBittorrentSession:on_alert(" << al << ")";
-       //      if (al)
-       //              qDebug() << "on_alert():" << QString::fromStdString(al->message());
+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()
+{
        std::auto_ptr<alert_t> alertPtr = btSession_.pop_alert();
 
        if (alertPtr.get() != NULL) {
 
                torrent_alert_t *ta = dynamic_cast<torrent_alert_t*> (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;
                        }
 
@@ -65,7 +110,9 @@ void TorrentSession::on_alert()
                        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);
                }
@@ -99,26 +146,56 @@ void TorrentSession::getState()
 void TorrentSession::addTorrent(const QString &path, const QString &save_path
                                 , qtrapids::ParamsMap_t other_params)
 {
+       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<libtorrent::torrent_info> tiTmp
        = new libtorrent::torrent_info
-       (boost::filesystem::path(path.toStdString()));
+       (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(save_path.toStdString());
+       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;
@@ -142,7 +219,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 {
@@ -158,7 +237,48 @@ void TorrentSession::removeTorrent(const QString &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