From: deztructor Date: Wed, 18 Nov 2009 12:28:48 +0000 (+0000) Subject: Server session persistence is implemented X-Git-Url: http://git.maemo.org/git/?p=qtrapids;a=commitdiff_plain;h=b62e6b5309eb1954c6ea4e1522767a424d76f15d Server session persistence is implemented Now only SQLite database is used as the backend to store session information. Only session information is stored there, common settings (including sqlite db name, download directory etc.) are stored using standard Qt QSettings git-svn-id: file:///svnroot/qtrapids/trunk@37 42ac0dd5-4c8c-4c71-bb3e-ecdfe252ffda --- diff --git a/dbus/com.ixonos.qtrapids.xml b/dbus/com.ixonos.qtrapids.xml index 5c25e77..1496a78 100644 --- a/dbus/com.ixonos.qtrapids.xml +++ b/dbus/com.ixonos.qtrapids.xml @@ -28,6 +28,17 @@ value="qtrapids::ParamsMap_t"/> + + + + + + + + + + diff --git a/src/include/qtrapids/dbus.hpp b/src/include/qtrapids/dbus.hpp index 79d1cd5..bb3671b 100644 --- a/src/include/qtrapids/dbus.hpp +++ b/src/include/qtrapids/dbus.hpp @@ -46,8 +46,8 @@ struct TorrentState { typedef QHash ParamsMap_t; typedef QHash const ParamsMapConst_t; -typedef QHash::iterator ParamsMapIterator_t; -typedef QHash::const_iterator ParamsMapConstIterator_t; +typedef ParamsMap_t::iterator ParamsMapIterator_t; +typedef ParamsMap_t::const_iterator ParamsMapConstIterator_t; static inline QDBusArgument& operator << (QDBusArgument& argument , TorrentState const& state) diff --git a/src/include/qtrapids/info.hpp b/src/include/qtrapids/info.hpp index 81c7017..20d7d6c 100644 --- a/src/include/qtrapids/info.hpp +++ b/src/include/qtrapids/info.hpp @@ -3,8 +3,10 @@ #include -#include -#include +//#include +//#include + +#include namespace qtrapids { @@ -30,7 +32,14 @@ struct TorrentStatus { }; }; -} +struct TorrentDownloadInfo { + QString hash; + QString path; + QString download_path; +}; + + +} // namespace qtrapids #endif // _QTRAPIDS_INFO_HPP_ diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index aee8f2e..60bb5d0 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -17,7 +17,6 @@ SET_SOURCE_FILES_PROPERTIES(./server.cpp ./server.h PROPERTIES GENERATED 1) SET(MOC_HEADERS ./AlertWaiterThread.hpp - ./TorrentHandle.hpp ./TorrentSession.hpp ./server.h ) @@ -26,13 +25,18 @@ SET(SRC ./AlertWaiterThread.cpp ./main.cpp ./server.cpp - ./TorrentHandle.cpp ./TorrentSession.cpp ) QT4_WRAP_CPP(SRC ${MOC_HEADERS} ) -ADD_EXECUTABLE(qtrapids-server ${SRC} ${MOC_HEADERS}) +SET(SRC_NOMOC + ./TorrentHandle.cpp + ./TorrentHandle.hpp + ./ServerDb.hpp +) + +ADD_EXECUTABLE(qtrapids-server ${SRC} ${MOC_HEADERS} ${SRC_NOMOC}) ADD_DEFINITIONS(-DQT_SHARED) TARGET_LINK_LIBRARIES(qtrapids-server diff --git a/src/server/ServerDb.hpp b/src/server/ServerDb.hpp index 342d26a..9bda677 100644 --- a/src/server/ServerDb.hpp +++ b/src/server/ServerDb.hpp @@ -5,6 +5,8 @@ #include #include +#include + namespace qtrapids { @@ -12,12 +14,10 @@ class ServerSettings { public: - ServerSettings(QSettings *settings) + ServerSettings(QSettings &settings) : settings_(settings) { } - ~ServerSettings() { - - } + ~ServerSettings() { } QString getDbEngine() const { return getParamAndStore("db_engine", getDefaultDbEngine()).toString(); @@ -29,11 +29,26 @@ public: } QString getTorrentsDir() const { - QString default_dir(QDir::home().filePath(QString(".") + appName())); - return getParamAndStore("db", default_dir).toString(); + QString default_dir(QDir::home().filePath(getTorrentsSubDir())); + return getParamAndStore("torrents_dir", default_dir).toString(); } + QString getDownloadDir() const { + QString default_dir(QDir::home().absolutePath()); + QString v = getParamAndStore("download/directory", default_dir).toString(); + if (!v.isEmpty()) { + return v; + } else { + settings_.setValue("download/directory", default_dir); + return default_dir; + } + } + + static QString getTorrentsSubDir() { + return QString(".") + appName(); + } + private: ServerSettings(ServerSettings const&); @@ -51,18 +66,34 @@ private: } QVariant getParamAndStore(QString const& name, QVariant default_value) const { - QVariant v(settings_->value(name)); - if (!v.isNull()) { - return v; + return GetSettingsStoreDefault(settings_, name, default_value); + } + + mutable QSettings &settings_; +}; + +namespace { + +class DbAccessor +{ +public: + DbAccessor(QSqlDatabase &db) + : db_(db) { + if (!db_.open()) { + qDebug() << "cant open db"; } + } - settings_->setValue(name, default_value); - return default_value; + ~DbAccessor() { + db_.close(); } - mutable QSettings *settings_; +private: + QSqlDatabase &db_; }; +} + class ServerDb { @@ -72,6 +103,7 @@ public: QString db_name(settings->getDbName()); db_.setDatabaseName(db_name); + qDebug() << "opening db " << db_name; if (!db_.open()) { qDebug() << "cant open db"; return; @@ -89,9 +121,7 @@ public: } void addTorrent(const QString &hash, const QString &path, const QString &save_path) { - if (!db_.open()) { - qDebug() << "cant open db"; - } + DbAccessor dba(db_); QSqlQuery query_add_; query_add_.prepare("INSERT INTO torrents (hash, path, savepath) VALUES (?, ?, ?)"); query_add_.bindValue(0, hash); @@ -101,7 +131,15 @@ public: qDebug() << "cant add torrent info into db: " << query_add_.lastError().text(); } - db_.close(); + } + + void removeTorrent(const QString &hash) { + DbAccessor dba(db_); + QSqlQuery query(QString("DELETE FROM torrents WHERE hash='") + hash + "'"); + if (!query.exec()) { + qDebug() << "cant delete torrent info from db" + << query.lastError().text(); + } } private: @@ -112,6 +150,29 @@ private: QSqlDatabase db_; }; +class TorrentsStorage +{ +public: + + TorrentsStorage(ServerDb &db) + : torrents_("SELECT hash, path, savepath from torrents") { } + + + bool nextTorrent(TorrentDownloadInfo &info) { + if (!torrents_.next()) { + return false; + } + info.hash = torrents_.value(0).toString(); + info.path = torrents_.value(1).toString(); + info.download_path = torrents_.value(2).toString(); + return true; + } + + +private: + QSqlQuery torrents_; +}; + } // namespace qtrapids #endif // _SERVERDB_HPP_ diff --git a/src/server/TorrentSession.cpp b/src/server/TorrentSession.cpp index c6d8b31..94c2465 100644 --- a/src/server/TorrentSession.cpp +++ b/src/server/TorrentSession.cpp @@ -1,7 +1,8 @@ #include "TorrentSession.hpp" #include "TorrentHandle.hpp" #include "AlertWaiterThread.hpp" - +#include "ServerDb.hpp" +#include namespace qtrapids { @@ -12,6 +13,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(); qDBusRegisterMetaType(); @@ -25,17 +28,21 @@ TorrentSession::TorrentSession(QObject *parent, QSettings *settings) connect(alertWaiter_, SIGNAL(alert()), this, SLOT(on_alert())); alertWaiter_->start(); + loadState(); +} +void TorrentSession::loadState() +{ + TorrentDownloadInfo info; + TorrentsStorage storage(*db_); + while (storage.nextTorrent(info)) { + qDebug() << "adding " << info.path; + addTorrent_(info.path, info.download_path, ParamsMap_t(), true); + } } 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) { @@ -46,9 +53,7 @@ void TorrentSession::on_alert() << "QBittorrentSession::on_alert(): " << QString::fromStdString(alertPtr->message()); - if (ta) { - if (!ta->handle.is_valid()) { qDebug() << "handle is invalid"; return; @@ -99,26 +104,50 @@ 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())); + qDebug() << "copy to " << new_torrent_fname; + torrent_file.copy(new_torrent_fname); + qDebug() << "addTorrent: " << path << " save to " << save_path; boost::intrusive_ptr 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; @@ -158,6 +187,7 @@ void TorrentSession::removeTorrent(const QString &hash) state.action = TorrentState::action_remove; emit alert(state, ParamsMap_t()); torrents_.erase(p); + db_->removeTorrent(hash); } diff --git a/src/server/TorrentSession.hpp b/src/server/TorrentSession.hpp index 6240024..1baffac 100644 --- a/src/server/TorrentSession.hpp +++ b/src/server/TorrentSession.hpp @@ -63,9 +63,15 @@ private slots: void on_alert(); private: + + void loadState(); + void addTorrent_(const QString &, const QString &, const qtrapids::ParamsMap_t &, bool); + session_t btSession_; AlertWaiterThread *alertWaiter_; torrents_t torrents_; + std::auto_ptr settings_; + std::auto_ptr db_; }; } // namespace qtrapids