1 #include "TorrentSession.hpp"
2 #include "TorrentHandle.hpp"
3 #include "AlertWaiterThread.hpp"
4 #include "ServerDb.hpp"
5 #include <qtrapids/error.hpp>
12 TorrentSession::TorrentSession(QObject *parent, QSettings *settings)
15 , alertWaiter_(new AlertWaiterThread(&btSession_, this))
16 , settings_(new ServerSettings(*settings))
17 , db_(new ServerDb(settings_.get()))
19 qDBusRegisterMetaType<qtrapids::TorrentState>();
20 qDBusRegisterMetaType<qtrapids::ParamsMap_t>();
21 new QtRapidsServer(this);
23 QDBusConnection dbus = QDBusConnection::sessionBus();
24 dbus.registerObject("/qtrapids", this);
25 dbus.registerService("com.ixonos.qtrapids");
27 alertWaiter_->allAlerts();
28 connect(alertWaiter_, SIGNAL(alert()), this, SLOT(on_alert()));
29 alertWaiter_->start();
33 // Lets force applying rate limits to local network also, at least for testing.
34 // Also, on the N900 device, rate limiting is necessary due to limited processign power
35 session_settings_t sessionSettings;
36 sessionSettings.ignore_limits_on_local_network = false;
37 btSession_.set_settings(sessionSettings);
41 void TorrentSession::loadState()
43 TorrentDownloadInfo info;
44 TorrentsStorage storage(*db_);
45 while (storage.nextTorrent(info)) {
47 qDebug() << "adding " << info.path;
49 addTorrent_(info.path, info.download_path, ParamsMap_t(), true);
51 btSession_.listen_on(settings_->getListenPorts());
54 void TorrentSession::on_alert()
56 std::auto_ptr<alert_t> alertPtr = btSession_.pop_alert();
58 if (alertPtr.get() != NULL) {
60 torrent_alert_t *ta = dynamic_cast<torrent_alert_t*> (alertPtr.get());
64 << "TorrentSession::on_alert(): "
65 << QString::fromStdString(alertPtr->message());
69 if (!ta->handle.is_valid()) {
71 qDebug() << "handle is invalid";
76 TorrentHandle handle(ta->handle);
79 state.hash = Hash2QStr(handle.hash());
80 state.action = TorrentState::action_update;
81 state.state = handle.state();
82 state.progress = handle.progress() * torrent_progress_max;
83 state.down_rate = handle.downloadRate();
84 state.up_rate = handle.uploadRate();
85 state.seeds = handle.numSeeds();
86 state.leeches = handle.numLeeches();
87 state.total_size = handle.getTotalSize();
88 state.total_done = handle.getTotalDone();
91 emit alert(state, params);
97 void TorrentSession::getState()
99 torrents_t::const_iterator p;
100 for (p = torrents_.constBegin(); p != torrents_.constEnd(); ++p) {
101 TorrentHandlePtr handle = *p;
103 QString hash = Hash2QStr(handle->hash());
106 state.name = handle->name();
107 state.action = TorrentState::action_add;
108 state.state = handle->state();
109 state.progress = handle->progress() * torrent_progress_max;
110 state.down_rate = handle->downloadRate();
111 state.up_rate = handle->uploadRate();
112 state.seeds = handle->numSeeds();
113 state.leeches = handle->numLeeches();
114 state.total_size = handle->getTotalSize();
116 emit alert(state, ParamsMap_t());
120 void TorrentSession::addTorrent(const QString &path, const QString &save_path
121 , qtrapids::ParamsMap_t other_params)
123 return addTorrent_(path, save_path, other_params, false);
126 void TorrentSession::addTorrent_(const QString &path, const QString &save_path
127 , const qtrapids::ParamsMap_t &other_params
128 , bool is_restore_session)
130 add_torrent_params_t addParams;
131 QFile torrent_file(path);
132 QDir::home().mkdir(settings_->getTorrentsSubDir());
134 if (!torrent_file.exists()) {
135 qWarning() << "Torrent file " << path << "doesn't exist";
139 QString new_torrent_fname(QDir(settings_->getTorrentsDir())
140 .filePath(QFileInfo(path).fileName()));
141 #ifdef QTRAPIDS_DEBUG
142 qDebug() << "copy to " << new_torrent_fname;
145 torrent_file.copy(new_torrent_fname);
147 #ifdef QTRAPIDS_DEBUG
148 qDebug() << "addTorrent: " << path << " save to " << save_path;
151 boost::intrusive_ptr<libtorrent::torrent_info> tiTmp
152 = new libtorrent::torrent_info
153 (boost::filesystem::path(new_torrent_fname.toStdString()));
154 addParams.ti = tiTmp;
156 QString download_dir;
157 if (!save_path.isEmpty()) {
158 download_dir = save_path;
160 download_dir = settings_->getDownloadDir();
162 // save_path is the only mandatory parameter, rest are optional.
163 addParams.save_path = boost::filesystem::path(download_dir.toStdString());
164 //addParams.storage_mode = libtorrent::storage_mode_allocate;
166 TorrentHandlePtr handle(new TorrentHandle(btSession_.add_torrent(addParams)));
167 QString hash = Hash2QStr(handle->hash());
169 if (!is_restore_session) {
170 db_->addTorrent(hash, path, save_path);
176 state.name = handle->name();
177 state.action = TorrentState::action_add;
178 state.state = handle->state();
179 state.progress = handle->progress() * torrent_progress_max;
180 state.down_rate = handle->downloadRate();
181 state.up_rate = handle->uploadRate();
182 state.seeds = handle->numSeeds();
183 state.leeches = handle->numLeeches();
184 state.total_size = handle->getTotalSize();
186 torrents_[hash] = handle;
188 emit alert(state, ParamsMap_t());
191 void TorrentSession::removeTorrent(const QString &hash)
193 torrents_t::iterator p = torrents_.find(hash);
195 if (p == torrents_.end()) {
196 #ifdef QTRAPIDS_DEBUG
197 qDebug() << "Invalid request to remove torrent with hash " << hash;
202 btSession_.remove_torrent(p.value()->getHandle());
203 } catch (torrent_exception_t e) {
204 qDebug() << // e.what()
211 state.action = TorrentState::action_remove;
212 emit alert(state, ParamsMap_t());
214 db_->removeTorrent(hash);
218 void TorrentSession::setOptions(qtrapids::ParamsMap_t options)
220 qtrapids::ParamsMapConstIterator_t end = options.end();
221 qtrapids::ParamsMapConstIterator_t tmpIter = options.find("net/downloadRate");
224 // Apply settings immediately to Bittorrent session:
225 // NOTE: QHash interface is not quite STL-like
227 if (tmpIter != end) {
228 rate = tmpIter.value().toInt();
229 btSession_.set_download_rate_limit(rate);
232 tmpIter = options.find("net/uploadRate");
233 if (tmpIter != end) {
234 rate = tmpIter.value().toInt();
235 btSession_.set_upload_rate_limit(rate);
238 /// @todo Add more immediately applicable settings here, if needed.
240 // Finally, save settings to persistent storage:
241 settings_->setOptions(options);
245 qtrapids::ParamsMap_t TorrentSession::getOptions()
247 return settings_->getOptions();
251 } // namespace qtrapids