2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
4 * Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * In addition, as a special exception, the copyright holders give permission to
21 * link this program with the OpenSSL project's "OpenSSL" library (or with
22 * modified versions of it that use the same license as the "OpenSSL" library),
23 * and distribute the linked executables. You must obey the GNU General Public
24 * License in all respects for all of the code used other than "OpenSSL". If you
25 * modify file(s), you may extend this exception to your version of the file(s),
26 * but you are not obligated to do so. If you do not wish to do so, delete this
27 * exception statement from your version.
34 #include <libtorrent/add_torrent_params.hpp>
35 #include <libtorrent/fwd.hpp>
36 #include <libtorrent/socket.hpp>
37 #include <libtorrent/torrent_handle.hpp>
38 #include <libtorrent/torrent_status.hpp>
48 #include "base/tagset.h"
50 #include "speedmonitor.h"
52 #include "torrentinfo.h"
57 struct LoadTorrentParams
;
59 enum class MoveStorageMode
65 enum class MaintenanceJob
74 lt::operation_t operation
;
77 class TorrentImpl final
: public QObject
, public Torrent
79 Q_DISABLE_COPY_MOVE(TorrentImpl
)
80 Q_DECLARE_TR_FUNCTIONS(BitTorrent::TorrentImpl
)
83 TorrentImpl(Session
*session
, lt::session
*nativeSession
84 , const lt::torrent_handle
&nativeHandle
, const LoadTorrentParams
¶ms
);
85 ~TorrentImpl() override
;
89 InfoHash
infoHash() const override
;
90 QString
name() const override
;
91 QDateTime
creationDate() const override
;
92 QString
creator() const override
;
93 QString
comment() const override
;
94 bool isPrivate() const override
;
95 qlonglong
totalSize() const override
;
96 qlonglong
wantedSize() const override
;
97 qlonglong
completedSize() const override
;
98 qlonglong
pieceLength() const override
;
99 qlonglong
wastedSize() const override
;
100 QString
currentTracker() const override
;
102 QString
savePath(bool actual
= false) const override
;
103 QString
rootPath(bool actual
= false) const override
;
104 QString
contentPath(bool actual
= false) const override
;
106 bool useTempPath() const override
;
108 bool isAutoTMMEnabled() const override
;
109 void setAutoTMMEnabled(bool enabled
) override
;
110 QString
category() const override
;
111 bool belongsToCategory(const QString
&category
) const override
;
112 bool setCategory(const QString
&category
) override
;
114 TagSet
tags() const override
;
115 bool hasTag(const QString
&tag
) const override
;
116 bool addTag(const QString
&tag
) override
;
117 bool removeTag(const QString
&tag
) override
;
118 void removeAllTags() override
;
120 int filesCount() const override
;
121 int piecesCount() const override
;
122 int piecesHave() const override
;
123 qreal
progress() const override
;
124 QDateTime
addedTime() const override
;
125 qreal
ratioLimit() const override
;
126 int seedingTimeLimit() const override
;
128 QString
filePath(int index
) const override
;
129 QString
fileName(int index
) const override
;
130 qlonglong
fileSize(int index
) const override
;
131 QStringList
absoluteFilePaths() const override
;
132 QVector
<DownloadPriority
> filePriorities() const override
;
134 TorrentInfo
info() const override
;
135 bool isSeed() const override
;
136 bool isPaused() const override
;
137 bool isQueued() const override
;
138 bool isForced() const override
;
139 bool isChecking() const override
;
140 bool isDownloading() const override
;
141 bool isUploading() const override
;
142 bool isCompleted() const override
;
143 bool isActive() const override
;
144 bool isInactive() const override
;
145 bool isErrored() const override
;
146 bool isSequentialDownload() const override
;
147 bool hasFirstLastPiecePriority() const override
;
148 TorrentState
state() const override
;
149 bool hasMetadata() const override
;
150 bool hasMissingFiles() const override
;
151 bool hasError() const override
;
152 bool hasFilteredPieces() const override
;
153 int queuePosition() const override
;
154 QVector
<TrackerEntry
> trackers() const override
;
155 QVector
<QUrl
> urlSeeds() const override
;
156 QString
error() const override
;
157 qlonglong
totalDownload() const override
;
158 qlonglong
totalUpload() const override
;
159 qlonglong
activeTime() const override
;
160 qlonglong
finishedTime() const override
;
161 qlonglong
seedingTime() const override
;
162 qlonglong
eta() const override
;
163 QVector
<qreal
> filesProgress() const override
;
164 int seedsCount() const override
;
165 int peersCount() const override
;
166 int leechsCount() const override
;
167 int totalSeedsCount() const override
;
168 int totalPeersCount() const override
;
169 int totalLeechersCount() const override
;
170 int completeCount() const override
;
171 int incompleteCount() const override
;
172 QDateTime
lastSeenComplete() const override
;
173 QDateTime
completedTime() const override
;
174 qlonglong
timeSinceUpload() const override
;
175 qlonglong
timeSinceDownload() const override
;
176 qlonglong
timeSinceActivity() const override
;
177 int downloadLimit() const override
;
178 int uploadLimit() const override
;
179 bool superSeeding() const override
;
180 bool isDHTDisabled() const override
;
181 bool isPEXDisabled() const override
;
182 bool isLSDDisabled() const override
;
183 QVector
<PeerInfo
> peers() const override
;
184 QBitArray
pieces() const override
;
185 QBitArray
downloadingPieces() const override
;
186 QVector
<int> pieceAvailability() const override
;
187 qreal
distributedCopies() const override
;
188 qreal
maxRatio() const override
;
189 int maxSeedingTime() const override
;
190 qreal
realRatio() const override
;
191 int uploadPayloadRate() const override
;
192 int downloadPayloadRate() const override
;
193 qlonglong
totalPayloadUpload() const override
;
194 qlonglong
totalPayloadDownload() const override
;
195 int connectionsCount() const override
;
196 int connectionsLimit() const override
;
197 qlonglong
nextAnnounce() const override
;
198 QVector
<qreal
> availableFileFractions() const override
;
200 void setName(const QString
&name
) override
;
201 void setSequentialDownload(bool enable
) override
;
202 void setFirstLastPiecePriority(bool enabled
) override
;
203 void pause() override
;
204 void resume(TorrentOperatingMode mode
= TorrentOperatingMode::AutoManaged
) override
;
205 void move(QString path
) override
;
206 void forceReannounce(int index
= -1) override
;
207 void forceDHTAnnounce() override
;
208 void forceRecheck() override
;
209 void renameFile(int index
, const QString
&path
) override
;
210 void prioritizeFiles(const QVector
<DownloadPriority
> &priorities
) override
;
211 void setRatioLimit(qreal limit
) override
;
212 void setSeedingTimeLimit(int limit
) override
;
213 void setUploadLimit(int limit
) override
;
214 void setDownloadLimit(int limit
) override
;
215 void setSuperSeeding(bool enable
) override
;
216 void setDHTDisabled(bool disable
) override
;
217 void setPEXDisabled(bool disable
) override
;
218 void setLSDDisabled(bool disable
) override
;
219 void flushCache() const override
;
220 void addTrackers(const QVector
<TrackerEntry
> &trackers
) override
;
221 void replaceTrackers(const QVector
<TrackerEntry
> &trackers
) override
;
222 void addUrlSeeds(const QVector
<QUrl
> &urlSeeds
) override
;
223 void removeUrlSeeds(const QVector
<QUrl
> &urlSeeds
) override
;
224 bool connectPeer(const PeerAddress
&peerAddress
) override
;
225 void clearPeers() override
;
227 QString
createMagnetURI() const override
;
229 bool needSaveResumeData() const;
232 lt::torrent_handle
nativeHandle() const;
234 void handleAlert(const lt::alert
*a
);
235 void handleStateUpdate(const lt::torrent_status
&nativeStatus
);
236 void handleTempPathChanged();
237 void handleCategorySavePathChanged();
238 void handleAppendExtensionToggled();
239 void saveResumeData();
240 void handleMoveStorageJobFinished(bool hasOutstandingJob
);
241 void fileSearchFinished(const QString
&savePath
, const QStringList
&fileNames
);
243 QString
actualStorageLocation() const;
246 using EventTrigger
= std::function
<void ()>;
249 void updateStatus(const lt::torrent_status
&nativeStatus
);
252 void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert
*p
);
253 void handleFileCompletedAlert(const lt::file_completed_alert
*p
);
254 void handleFileErrorAlert(const lt::file_error_alert
*p
);
255 #ifdef QBT_USES_LIBTORRENT2
256 void handleFilePrioAlert(const lt::file_prio_alert
*p
);
258 void handleFileRenamedAlert(const lt::file_renamed_alert
*p
);
259 void handleFileRenameFailedAlert(const lt::file_rename_failed_alert
*p
);
260 void handleMetadataReceivedAlert(const lt::metadata_received_alert
*p
);
261 void handlePerformanceAlert(const lt::performance_alert
*p
) const;
262 void handleSaveResumeDataAlert(const lt::save_resume_data_alert
*p
);
263 void handleSaveResumeDataFailedAlert(const lt::save_resume_data_failed_alert
*p
);
264 void handleTorrentCheckedAlert(const lt::torrent_checked_alert
*p
);
265 void handleTorrentFinishedAlert(const lt::torrent_finished_alert
*p
);
266 void handleTorrentPausedAlert(const lt::torrent_paused_alert
*p
);
267 void handleTorrentResumedAlert(const lt::torrent_resumed_alert
*p
);
268 void handleTrackerErrorAlert(const lt::tracker_error_alert
*p
);
269 void handleTrackerReplyAlert(const lt::tracker_reply_alert
*p
);
270 void handleTrackerWarningAlert(const lt::tracker_warning_alert
*p
);
272 bool isMoveInProgress() const;
274 void setAutoManaged(bool enable
);
276 void adjustActualSavePath();
277 void adjustActualSavePath_impl();
278 void move_impl(QString path
, MoveStorageMode mode
);
279 void moveStorage(const QString
&newPath
, MoveStorageMode mode
);
280 void manageIncompleteFiles();
281 void applyFirstLastPiecePriority(bool enabled
, const QVector
<DownloadPriority
> &updatedFilePrio
= {});
283 void prepareResumeData(const lt::add_torrent_params
¶ms
);
284 void endReceivedMetadataHandling(const QString
&savePath
, const QStringList
&fileNames
);
287 Session
*const m_session
;
288 lt::session
*m_nativeSession
;
289 lt::torrent_handle m_nativeHandle
;
290 lt::torrent_status m_nativeStatus
;
291 TorrentState m_state
= TorrentState::Unknown
;
292 TorrentInfo m_torrentInfo
;
293 SpeedMonitor m_speedMonitor
;
297 // m_moveFinishedTriggers is activated only when the following conditions are met:
298 // all file rename jobs complete, all file move jobs complete
299 QQueue
<EventTrigger
> m_moveFinishedTriggers
;
300 int m_renameCount
= 0;
301 bool m_storageIsMoving
= false;
303 MaintenanceJob m_maintenanceJob
= MaintenanceJob::None
;
305 #ifndef QBT_USES_LIBTORRENT2
306 // Until libtorrent provided an "old_name" field in `file_renamed_alert`
307 // we relied on this workaround to remove empty leftover folders
308 QHash
<lt::file_index_t
, QVector
<QString
>> m_oldPath
;
311 QHash
<QString
, QMap
<lt::tcp::endpoint
, int>> m_trackerPeerCounts
;
312 FileErrorInfo m_lastFileError
;
320 int m_seedingTimeLimit
;
321 TorrentOperatingMode m_operatingMode
;
322 TorrentContentLayout m_contentLayout
;
323 bool m_hasSeedStatus
;
324 bool m_fastresumeDataRejected
= false;
325 bool m_hasMissingFiles
= false;
326 bool m_hasFirstLastPiecePriority
= false;
330 bool m_unchecked
= false;
332 lt::add_torrent_params m_ltAddTorrentParams
;