Server methods to store/get options
[qtrapids] / src / server / TorrentSession.cpp
1 #include "TorrentSession.hpp"
2 #include "TorrentHandle.hpp"
3 #include "AlertWaiterThread.hpp"
4 #include "ServerDb.hpp"
5 #include <qtrapids/error.hpp>
6
7 namespace qtrapids
8 {
9
10
11
12 TorrentSession::TorrentSession(QObject *parent, QSettings *settings)
13                 : QObject(parent)
14                 , btSession_()
15                 , alertWaiter_(new AlertWaiterThread(&btSession_, this))
16                 , settings_(new ServerSettings(*settings))
17                 , db_(new ServerDb(settings_.get()))
18 {
19         qDBusRegisterMetaType<qtrapids::TorrentState>();
20         qDBusRegisterMetaType<qtrapids::ParamsMap_t>();
21         new QtRapidsServer(this);
22
23         QDBusConnection dbus = QDBusConnection::sessionBus();
24         dbus.registerObject("/qtrapids", this);
25         dbus.registerService("com.ixonos.qtrapids");
26
27         alertWaiter_->allAlerts();
28         connect(alertWaiter_, SIGNAL(alert()), this, SLOT(on_alert()));
29         alertWaiter_->start();
30
31         loadState();
32 }
33
34 void TorrentSession::loadState()
35 {
36         TorrentDownloadInfo info;
37         TorrentsStorage storage(*db_);
38         while (storage.nextTorrent(info)) {
39                 qDebug() << "adding " << info.path;
40                 addTorrent_(info.path, info.download_path, ParamsMap_t(), true);
41         }
42         btSession_.listen_on(settings_->getListenPorts());
43 }
44
45 void TorrentSession::on_alert()
46 {
47         std::auto_ptr<alert_t> alertPtr = btSession_.pop_alert();
48
49         if (alertPtr.get() != NULL) {
50
51                 torrent_alert_t *ta = dynamic_cast<torrent_alert_t*> (alertPtr.get());
52
53                 qDebug()
54                 << "QBittorrentSession::on_alert(): "
55                 << QString::fromStdString(alertPtr->message());
56
57                 if (ta) {
58                         if (!ta->handle.is_valid()) {
59                                 qDebug() << "handle is invalid";
60                                 return;
61                         }
62
63                         TorrentHandle handle(ta->handle);
64                         TorrentState state;
65
66                         state.hash = Hash2QStr(handle.hash());
67                         state.action = TorrentState::action_update;
68                         state.state = handle.state();
69                         state.progress = handle.progress() * torrent_progress_max;
70                         state.down_rate = handle.downloadRate();
71                         state.up_rate = handle.uploadRate();
72                         state.seeds = handle.numSeeds();
73                         state.leeches = handle.numLeeches();
74
75                         ParamsMap_t params;
76                         emit alert(state, params);
77                 }
78
79         }
80 }
81
82 void TorrentSession::getState()
83 {
84         torrents_t::const_iterator p;
85         for (p = torrents_.constBegin(); p != torrents_.constEnd(); ++p) {
86                 TorrentHandlePtr handle = *p;
87                 TorrentState state;
88                 QString hash = Hash2QStr(handle->hash());
89
90                 state.hash = hash;
91                 state.name = handle->name();
92                 state.action = TorrentState::action_add;
93                 state.state = handle->state();
94                 state.progress = handle->progress() * torrent_progress_max;
95                 state.down_rate = handle->downloadRate();
96                 state.up_rate = handle->uploadRate();
97                 state.seeds = handle->numSeeds();
98                 state.leeches = handle->numLeeches();
99                 state.total_size = handle->getTotalSize();
100
101                 emit alert(state, ParamsMap_t());
102         }
103 }
104
105 void TorrentSession::addTorrent(const QString &path, const QString &save_path
106                                 , qtrapids::ParamsMap_t other_params)
107 {
108         return addTorrent_(path, save_path, other_params, false);
109 }
110
111 void TorrentSession::addTorrent_(const QString &path, const QString &save_path
112                                  , const qtrapids::ParamsMap_t &other_params
113                                  , bool is_restore_session)
114 {
115         add_torrent_params_t addParams;
116         QFile torrent_file(path);
117         QDir::home().mkdir(settings_->getTorrentsSubDir());
118
119         if (!torrent_file.exists()) {
120                 qWarning() << "Torrent file " << path << "doesn't exist";
121                 return;
122         }
123
124         QString new_torrent_fname(QDir(settings_->getTorrentsDir())
125                                   .filePath(QFileInfo(path).fileName()));
126         qDebug() << "copy to " << new_torrent_fname;
127         torrent_file.copy(new_torrent_fname);
128
129         qDebug() << "addTorrent: " << path << " save to " << save_path;
130         boost::intrusive_ptr<libtorrent::torrent_info> tiTmp
131         = new libtorrent::torrent_info
132         (boost::filesystem::path(new_torrent_fname.toStdString()));
133         addParams.ti = tiTmp;
134
135         QString download_dir;
136         if (!save_path.isEmpty()) {
137                 download_dir = save_path;
138         } else {
139                 download_dir = settings_->getDownloadDir();
140         }
141         // save_path is the only mandatory parameter, rest are optional.
142         addParams.save_path = boost::filesystem::path(download_dir.toStdString());
143         //addParams.storage_mode = libtorrent::storage_mode_allocate;
144
145         TorrentHandlePtr handle(new TorrentHandle(btSession_.add_torrent(addParams)));
146         QString hash = Hash2QStr(handle->hash());
147
148         if (!is_restore_session) {
149                 db_->addTorrent(hash, path, save_path);
150         }
151
152         TorrentState state;
153
154         state.hash = hash;
155         state.name = handle->name();
156         state.action = TorrentState::action_add;
157         state.state = handle->state();
158         state.progress = handle->progress() * torrent_progress_max;
159         state.down_rate = handle->downloadRate();
160         state.up_rate = handle->uploadRate();
161         state.seeds = handle->numSeeds();
162         state.leeches = handle->numLeeches();
163         state.total_size = handle->getTotalSize();
164
165         torrents_[hash] = handle;
166
167         emit alert(state, ParamsMap_t());
168 }
169
170 void TorrentSession::removeTorrent(const QString &hash)
171 {
172         torrents_t::iterator p = torrents_.find(hash);
173
174         if (p == torrents_.end()) {
175                 qDebug() << "Invalid request to remove torrent with hash " << hash;
176                 return;
177         }
178         try {
179                 btSession_.remove_torrent(p.value()->getHandle());
180         } catch (torrent_exception_t e) {
181                 qDebug() << // e.what()
182                 "exception catched"
183                 ;
184         }
185
186         TorrentState state;
187         state.hash = hash;
188         state.action = TorrentState::action_remove;
189         emit alert(state, ParamsMap_t());
190         torrents_.erase(p);
191         db_->removeTorrent(hash);
192 }
193
194 void TorrentSession::setOptions(qtrapids::ParamsMap_t options)
195 {
196         settings_->setOptions(options);
197 }
198
199 qtrapids::ParamsMap_t TorrentSession::getOptions()
200 {
201         return settings_->getOptions();
202 }
203
204
205 } // namespace qtrapids