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);
42 TorrentSession::~TorrentSession()
46 emit sessionTerminated();
50 void TorrentSession::loadState()
52 TorrentDownloadInfo info;
53 TorrentsStorage storage(*db_);
54 while (storage.nextTorrent(info)) {
56 qDebug() << "adding " << info.path;
58 addTorrent_(info.path, info.download_path, ParamsMap_t(), true);
60 btSession_.listen_on(settings_->getListenPorts());
63 void TorrentSession::on_alert()
65 std::auto_ptr<alert_t> alertPtr = btSession_.pop_alert();
67 if (alertPtr.get() != NULL) {
69 torrent_alert_t *ta = dynamic_cast<torrent_alert_t*> (alertPtr.get());
73 << "TorrentSession::on_alert(): "
74 << QString::fromStdString(alertPtr->message());
78 if (!ta->handle.is_valid()) {
80 qDebug() << "handle is invalid";
85 TorrentHandle handle(ta->handle);
88 state.hash = Hash2QStr(handle.hash());
89 state.action = TorrentState::action_update;
90 state.state = handle.state();
91 state.progress = handle.progress() * torrent_progress_max;
92 state.down_rate = handle.downloadRate();
93 state.up_rate = handle.uploadRate();
94 state.seeds = handle.numSeeds();
95 state.leeches = handle.numLeeches();
96 state.total_size = handle.getTotalSize();
97 state.total_done = handle.getTotalDone();
100 emit alert(state, params);
106 void TorrentSession::getState()
108 torrents_t::const_iterator p;
109 for (p = torrents_.constBegin(); p != torrents_.constEnd(); ++p) {
110 TorrentHandlePtr handle = *p;
112 QString hash = Hash2QStr(handle->hash());
115 state.name = handle->name();
116 state.action = TorrentState::action_add;
117 state.state = handle->state();
118 state.progress = handle->progress() * torrent_progress_max;
119 state.down_rate = handle->downloadRate();
120 state.up_rate = handle->uploadRate();
121 state.seeds = handle->numSeeds();
122 state.leeches = handle->numLeeches();
123 state.total_size = handle->getTotalSize();
125 emit alert(state, ParamsMap_t());
129 void TorrentSession::addTorrent(const QString &path, const QString &save_path
130 , qtrapids::ParamsMap_t other_params)
132 return addTorrent_(path, save_path, other_params, false);
135 void TorrentSession::addTorrent_(const QString &path, const QString &save_path
136 , const qtrapids::ParamsMap_t &other_params
137 , bool is_restore_session)
139 add_torrent_params_t addParams;
140 QFile torrent_file(path);
141 QDir::home().mkdir(settings_->getTorrentsSubDir());
143 if (!torrent_file.exists()) {
144 qWarning() << "Torrent file " << path << "doesn't exist";
148 QString new_torrent_fname(QDir(settings_->getTorrentsDir())
149 .filePath(QFileInfo(path).fileName()));
150 #ifdef QTRAPIDS_DEBUG
151 qDebug() << "copy to " << new_torrent_fname;
154 torrent_file.copy(new_torrent_fname);
156 #ifdef QTRAPIDS_DEBUG
157 qDebug() << "addTorrent: " << path << " save to " << save_path;
160 boost::intrusive_ptr<libtorrent::torrent_info> tiTmp
161 = new libtorrent::torrent_info
162 (boost::filesystem::path(new_torrent_fname.toStdString()));
163 addParams.ti = tiTmp;
165 QString download_dir;
166 if (!save_path.isEmpty()) {
167 download_dir = save_path;
169 download_dir = settings_->getDownloadDir();
171 // save_path is the only mandatory parameter, rest are optional.
172 addParams.save_path = boost::filesystem::path(download_dir.toStdString());
173 //addParams.storage_mode = libtorrent::storage_mode_allocate;
175 TorrentHandlePtr handle(new TorrentHandle(btSession_.add_torrent(addParams)));
176 QString hash = Hash2QStr(handle->hash());
178 if (!is_restore_session) {
179 db_->addTorrent(hash, path, save_path);
185 state.name = handle->name();
186 state.action = TorrentState::action_add;
187 state.state = handle->state();
188 state.progress = handle->progress() * torrent_progress_max;
189 state.down_rate = handle->downloadRate();
190 state.up_rate = handle->uploadRate();
191 state.seeds = handle->numSeeds();
192 state.leeches = handle->numLeeches();
193 state.total_size = handle->getTotalSize();
195 torrents_[hash] = handle;
197 emit alert(state, ParamsMap_t());
200 void TorrentSession::removeTorrent(const QString &hash)
202 torrents_t::iterator p = torrents_.find(hash);
204 if (p == torrents_.end()) {
205 #ifdef QTRAPIDS_DEBUG
206 qDebug() << "Invalid request to remove torrent with hash " << hash;
211 btSession_.remove_torrent(p.value()->getHandle());
212 } catch (torrent_exception_t e) {
213 qDebug() << // e.what()
220 state.action = TorrentState::action_remove;
221 emit alert(state, ParamsMap_t());
223 db_->removeTorrent(hash);
227 void TorrentSession::setOptions(qtrapids::ParamsMap_t options)
229 qtrapids::ParamsMapConstIterator_t end = options.end();
230 qtrapids::ParamsMapConstIterator_t tmpIter = options.find("net/downloadRate");
233 // Apply settings immediately to Bittorrent session:
234 // NOTE: QHash interface is not quite STL-like
236 if (tmpIter != end) {
237 rate = tmpIter.value().toInt();
238 btSession_.set_download_rate_limit(rate);
241 tmpIter = options.find("net/uploadRate");
242 if (tmpIter != end) {
243 rate = tmpIter.value().toInt();
244 btSession_.set_upload_rate_limit(rate);
247 /// @todo Add more immediately applicable settings here, if needed.
249 // Finally, save settings to persistent storage:
250 settings_->setOptions(options);
254 qtrapids::ParamsMap_t TorrentSession::getOptions()
256 return settings_->getOptions();
260 void TorrentSession::terminateSession()
262 qDebug() << "Terminate called";
263 // Emiting terminate() here causes the server application to quit in main()
267 } // namespace qtrapids