value="qtrapids::ParamsMap_t"/>
</signal>
+ <method name="getOptions">
+ <arg type="a{ss}" direction="out" name="options"/>
+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0"
+ value="qtrapids::ParamsMap_t"/>
+ </method>
+
+ <method name="setOption">
+ <arg type="s" direction="in" name="name"/>
+ <arg type="s" direction="in" name="value"/>
+ </method>
+
</interface>
</node>
typedef QHash<QString, QString> ParamsMap_t;
typedef QHash<QString, QString> const ParamsMapConst_t;
-typedef QHash<QString, QString>::iterator ParamsMapIterator_t;
-typedef QHash<QString, QString>::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)
#include <libtorrent/torrent_handle.hpp>
-#include <limits>
-#include <stdint.h>
+//#include <limits>
+//#include <stdint.h>
+
+#include <QString>
namespace qtrapids
{
};
};
-}
+struct TorrentDownloadInfo {
+ QString hash;
+ QString path;
+ QString download_path;
+};
+
+
+} // namespace qtrapids
#endif // _QTRAPIDS_INFO_HPP_
SET(MOC_HEADERS
./AlertWaiterThread.hpp
- ./TorrentHandle.hpp
./TorrentSession.hpp
./server.h
)
./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
#include <QtSql>
#include <QDir>
+#include <qtrapids/settings.hpp>
+
namespace qtrapids
{
{
public:
- ServerSettings(QSettings *settings)
+ ServerSettings(QSettings &settings)
: settings_(settings) { }
- ~ServerSettings() {
-
- }
+ ~ServerSettings() { }
QString getDbEngine() const {
return getParamAndStore("db_engine", getDefaultDbEngine()).toString();
}
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&);
}
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
{
QString db_name(settings->getDbName());
db_.setDatabaseName(db_name);
+ qDebug() << "opening db " << db_name;
if (!db_.open()) {
qDebug() << "cant open db";
return;
}
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);
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:
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_
#include "TorrentSession.hpp"
#include "TorrentHandle.hpp"
#include "AlertWaiterThread.hpp"
-
+#include "ServerDb.hpp"
+#include <qtrapids/error.hpp>
namespace qtrapids
{
: QObject(parent)
, btSession_()
, alertWaiter_(new AlertWaiterThread(&btSession_, this))
+ , settings_(new ServerSettings(*settings))
+ , db_(new ServerDb(settings_.get()))
{
qDBusRegisterMetaType<qtrapids::TorrentState>();
qDBusRegisterMetaType<qtrapids::ParamsMap_t>();
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<alert_t> alertPtr = btSession_.pop_alert();
if (alertPtr.get() != NULL) {
<< "QBittorrentSession::on_alert(): "
<< QString::fromStdString(alertPtr->message());
-
if (ta) {
-
if (!ta->handle.is_valid()) {
qDebug() << "handle is invalid";
return;
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<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;
state.action = TorrentState::action_remove;
emit alert(state, ParamsMap_t());
torrents_.erase(p);
+ db_->removeTorrent(hash);
}
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<ServerSettings> settings_;
+ std::auto_ptr<ServerDb> db_;
};
} // namespace qtrapids