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();
89 emit alert(state, params);
95 void TorrentSession::getState()
97 torrents_t::const_iterator p;
98 for (p = torrents_.constBegin(); p != torrents_.constEnd(); ++p) {
99 TorrentHandlePtr handle = *p;
101 QString hash = Hash2QStr(handle->hash());
104 state.name = handle->name();
105 state.action = TorrentState::action_add;
106 state.state = handle->state();
107 state.progress = handle->progress() * torrent_progress_max;
108 state.down_rate = handle->downloadRate();
109 state.up_rate = handle->uploadRate();
110 state.seeds = handle->numSeeds();
111 state.leeches = handle->numLeeches();
112 state.total_size = handle->getTotalSize();
114 emit alert(state, ParamsMap_t());
118 void TorrentSession::addTorrent(const QString &path, const QString &save_path
119 , qtrapids::ParamsMap_t other_params)
121 return addTorrent_(path, save_path, other_params, false);
124 void TorrentSession::addTorrent_(const QString &path, const QString &save_path
125 , const qtrapids::ParamsMap_t &other_params
126 , bool is_restore_session)
128 add_torrent_params_t addParams;
129 QFile torrent_file(path);
130 QDir::home().mkdir(settings_->getTorrentsSubDir());
132 if (!torrent_file.exists()) {
133 qWarning() << "Torrent file " << path << "doesn't exist";
137 QString new_torrent_fname(QDir(settings_->getTorrentsDir())
138 .filePath(QFileInfo(path).fileName()));
139 #ifdef QTRAPIDS_DEBUG
140 qDebug() << "copy to " << new_torrent_fname;
143 torrent_file.copy(new_torrent_fname);
145 #ifdef QTRAPIDS_DEBUG
146 qDebug() << "addTorrent: " << path << " save to " << save_path;
149 boost::intrusive_ptr<libtorrent::torrent_info> tiTmp
150 = new libtorrent::torrent_info
151 (boost::filesystem::path(new_torrent_fname.toStdString()));
152 addParams.ti = tiTmp;
154 QString download_dir;
155 if (!save_path.isEmpty()) {
156 download_dir = save_path;
158 download_dir = settings_->getDownloadDir();
160 // save_path is the only mandatory parameter, rest are optional.
161 addParams.save_path = boost::filesystem::path(download_dir.toStdString());
162 //addParams.storage_mode = libtorrent::storage_mode_allocate;
164 TorrentHandlePtr handle(new TorrentHandle(btSession_.add_torrent(addParams)));
165 QString hash = Hash2QStr(handle->hash());
167 if (!is_restore_session) {
168 db_->addTorrent(hash, path, save_path);
174 state.name = handle->name();
175 state.action = TorrentState::action_add;
176 state.state = handle->state();
177 state.progress = handle->progress() * torrent_progress_max;
178 state.down_rate = handle->downloadRate();
179 state.up_rate = handle->uploadRate();
180 state.seeds = handle->numSeeds();
181 state.leeches = handle->numLeeches();
182 state.total_size = handle->getTotalSize();
184 torrents_[hash] = handle;
186 emit alert(state, ParamsMap_t());
189 void TorrentSession::removeTorrent(const QString &hash)
191 torrents_t::iterator p = torrents_.find(hash);
193 if (p == torrents_.end()) {
194 #ifdef QTRAPIDS_DEBUG
195 qDebug() << "Invalid request to remove torrent with hash " << hash;
200 btSession_.remove_torrent(p.value()->getHandle());
201 } catch (torrent_exception_t e) {
202 qDebug() << // e.what()
209 state.action = TorrentState::action_remove;
210 emit alert(state, ParamsMap_t());
212 db_->removeTorrent(hash);
216 void TorrentSession::setOptions(qtrapids::ParamsMap_t options)
218 qtrapids::ParamsMapConstIterator_t end = options.end();
219 qtrapids::ParamsMapConstIterator_t tmpIter = options.find("net/downloadRate");
222 // Apply settings immediately to Bittorrent session:
223 // NOTE: QHash interface is not quite STL-like
225 if (tmpIter != end) {
226 rate = tmpIter.value().toInt();
227 btSession_.set_download_rate_limit(rate);
230 tmpIter = options.find("net/uploadRate");
231 if (tmpIter != end) {
232 rate = tmpIter.value().toInt();
233 btSession_.set_upload_rate_limit(rate);
236 /// @todo Add more immediately applicable settings here, if needed.
238 // Finally, save settings to persistent storage:
239 settings_->setOptions(options);
243 qtrapids::ParamsMap_t TorrentSession::getOptions()
245 return settings_->getOptions();
249 } // namespace qtrapids