2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2015-2022 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.
33 #include <QtContainerFwd>
37 #include "base/3rdparty/expected.hpp"
38 #include "base/pathfwd.h"
39 #include "base/tagset.h"
40 #include "abstractfilestorage.h"
49 enum class DownloadPriority
;
57 // Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
58 // since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
59 // https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
60 inline namespace TorrentOperatingModeNS
64 enum class TorrentOperatingMode
70 Q_ENUM_NS(TorrentOperatingMode
)
73 enum class TorrentState
79 ForcedDownloadingMetadata
,
103 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
104 std::size_t qHash(TorrentState key
, std::size_t seed
= 0);
106 uint
qHash(TorrentState key
, uint seed
= 0);
109 class Torrent
: public QObject
, public AbstractFileStorage
112 Q_DISABLE_COPY_MOVE(Torrent
)
115 enum class StopCondition
118 MetadataReceived
= 1,
121 Q_ENUM(StopCondition
)
123 static const qreal USE_GLOBAL_RATIO
;
124 static const qreal NO_RATIO_LIMIT
;
126 static const int USE_GLOBAL_SEEDING_TIME
;
127 static const int NO_SEEDING_TIME_LIMIT
;
129 static const qreal MAX_RATIO
;
130 static const int MAX_SEEDING_TIME
;
132 using QObject::QObject
;
134 virtual InfoHash
infoHash() const = 0;
135 virtual QString
name() const = 0;
136 virtual QDateTime
creationDate() const = 0;
137 virtual QString
creator() const = 0;
138 virtual QString
comment() const = 0;
139 virtual bool isPrivate() const = 0;
140 virtual qlonglong
totalSize() const = 0;
141 virtual qlonglong
wantedSize() const = 0;
142 virtual qlonglong
completedSize() const = 0;
143 virtual qlonglong
pieceLength() const = 0;
144 virtual qlonglong
wastedSize() const = 0;
145 virtual QString
currentTracker() const = 0;
147 // 1. savePath() - the path where all the files and subfolders of torrent are stored.
148 // 1.1 downloadPath() - the path where all the files and subfolders of torrent are stored until torrent has finished downloading.
149 // 2. rootPath() - absolute path of torrent file tree (first common subfolder of torrent files); empty string if torrent has no root folder.
150 // 3. contentPath() - absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents).
153 // Suppose we have three torrent with following structures and save path `/home/user/torrents`:
155 // Torrent A (multifile)
166 // Torrent A* (Torrent A in "strip root folder" mode)
169 // Torrent B (singlefile)
176 // Torrent C (singlefile)
182 // | | rootPath | contentPath |
183 // |---|------------------------------|--------------------------------------------|
184 // | A | /home/user/torrents/torrentA | /home/user/torrents/torrentA |
185 // | A*| <empty> | /home/user/torrents |
186 // | B | /home/user/torrents/torrentB | /home/user/torrents/torrentB/subdir1/file1 |
187 // | C | <empty> | /home/user/torrents/file1 |
189 virtual bool isAutoTMMEnabled() const = 0;
190 virtual void setAutoTMMEnabled(bool enabled
) = 0;
191 virtual Path
savePath() const = 0;
192 virtual void setSavePath(const Path
&savePath
) = 0;
193 virtual Path
downloadPath() const = 0;
194 virtual void setDownloadPath(const Path
&downloadPath
) = 0;
195 virtual Path
actualStorageLocation() const = 0;
196 virtual Path
rootPath() const = 0;
197 virtual Path
contentPath() const = 0;
198 virtual QString
category() const = 0;
199 virtual bool belongsToCategory(const QString
&category
) const = 0;
200 virtual bool setCategory(const QString
&category
) = 0;
202 virtual TagSet
tags() const = 0;
203 virtual bool hasTag(const QString
&tag
) const = 0;
204 virtual bool addTag(const QString
&tag
) = 0;
205 virtual bool removeTag(const QString
&tag
) = 0;
206 virtual void removeAllTags() = 0;
208 virtual int piecesCount() const = 0;
209 virtual int piecesHave() const = 0;
210 virtual qreal
progress() const = 0;
211 virtual QDateTime
addedTime() const = 0;
212 virtual qreal
ratioLimit() const = 0;
213 virtual int seedingTimeLimit() const = 0;
215 virtual Path
actualFilePath(int index
) const = 0;
216 virtual PathList
filePaths() const = 0;
217 virtual QVector
<DownloadPriority
> filePriorities() const = 0;
219 virtual TorrentInfo
info() const = 0;
220 virtual bool isSeed() const = 0;
221 virtual bool isPaused() const = 0;
222 virtual bool isQueued() const = 0;
223 virtual bool isForced() const = 0;
224 virtual bool isChecking() const = 0;
225 virtual bool isDownloading() const = 0;
226 virtual bool isMoving() const = 0;
227 virtual bool isUploading() const = 0;
228 virtual bool isCompleted() const = 0;
229 virtual bool isActive() const = 0;
230 virtual bool isInactive() const = 0;
231 virtual bool isErrored() const = 0;
232 virtual bool isSequentialDownload() const = 0;
233 virtual bool hasFirstLastPiecePriority() const = 0;
234 virtual TorrentState
state() const = 0;
235 virtual bool hasMetadata() const = 0;
236 virtual bool hasMissingFiles() const = 0;
237 virtual bool hasError() const = 0;
238 virtual int queuePosition() const = 0;
239 virtual QVector
<TrackerEntry
> trackers() const = 0;
240 virtual QVector
<QUrl
> urlSeeds() const = 0;
241 virtual QString
error() const = 0;
242 virtual qlonglong
totalDownload() const = 0;
243 virtual qlonglong
totalUpload() const = 0;
244 virtual qlonglong
activeTime() const = 0;
245 virtual qlonglong
finishedTime() const = 0;
246 virtual qlonglong
eta() const = 0;
247 virtual QVector
<qreal
> filesProgress() const = 0;
248 virtual int seedsCount() const = 0;
249 virtual int peersCount() const = 0;
250 virtual int leechsCount() const = 0;
251 virtual int totalSeedsCount() const = 0;
252 virtual int totalPeersCount() const = 0;
253 virtual int totalLeechersCount() const = 0;
254 virtual QDateTime
lastSeenComplete() const = 0;
255 virtual QDateTime
completedTime() const = 0;
256 virtual qlonglong
timeSinceUpload() const = 0;
257 virtual qlonglong
timeSinceDownload() const = 0;
258 virtual qlonglong
timeSinceActivity() const = 0;
259 virtual int downloadLimit() const = 0;
260 virtual int uploadLimit() const = 0;
261 virtual bool superSeeding() const = 0;
262 virtual bool isDHTDisabled() const = 0;
263 virtual bool isPEXDisabled() const = 0;
264 virtual bool isLSDDisabled() const = 0;
265 virtual QVector
<PeerInfo
> peers() const = 0;
266 virtual QBitArray
pieces() const = 0;
267 virtual QBitArray
downloadingPieces() const = 0;
268 virtual QVector
<int> pieceAvailability() const = 0;
269 virtual qreal
distributedCopies() const = 0;
270 virtual qreal
maxRatio() const = 0;
271 virtual int maxSeedingTime() const = 0;
272 virtual qreal
realRatio() const = 0;
273 virtual int uploadPayloadRate() const = 0;
274 virtual int downloadPayloadRate() const = 0;
275 virtual qlonglong
totalPayloadUpload() const = 0;
276 virtual qlonglong
totalPayloadDownload() const = 0;
277 virtual int connectionsCount() const = 0;
278 virtual int connectionsLimit() const = 0;
279 virtual qlonglong
nextAnnounce() const = 0;
281 * @brief fraction of file pieces that are available at least from one peer
283 * This is not the same as torrrent availability, it is just a fraction of pieces
284 * that can be downloaded right now. It varies between 0 to 1.
286 virtual QVector
<qreal
> availableFileFractions() const = 0;
288 virtual void setName(const QString
&name
) = 0;
289 virtual void setSequentialDownload(bool enable
) = 0;
290 virtual void setFirstLastPiecePriority(bool enabled
) = 0;
291 virtual void pause() = 0;
292 virtual void resume(TorrentOperatingMode mode
= TorrentOperatingMode::AutoManaged
) = 0;
293 virtual void forceReannounce(int index
= -1) = 0;
294 virtual void forceDHTAnnounce() = 0;
295 virtual void forceRecheck() = 0;
296 virtual void prioritizeFiles(const QVector
<DownloadPriority
> &priorities
) = 0;
297 virtual void setRatioLimit(qreal limit
) = 0;
298 virtual void setSeedingTimeLimit(int limit
) = 0;
299 virtual void setUploadLimit(int limit
) = 0;
300 virtual void setDownloadLimit(int limit
) = 0;
301 virtual void setSuperSeeding(bool enable
) = 0;
302 virtual void setDHTDisabled(bool disable
) = 0;
303 virtual void setPEXDisabled(bool disable
) = 0;
304 virtual void setLSDDisabled(bool disable
) = 0;
305 virtual void flushCache() const = 0;
306 virtual void addTrackers(QVector
<TrackerEntry
> trackers
) = 0;
307 virtual void removeTrackers(const QStringList
&trackers
) = 0;
308 virtual void replaceTrackers(QVector
<TrackerEntry
> trackers
) = 0;
309 virtual void addUrlSeeds(const QVector
<QUrl
> &urlSeeds
) = 0;
310 virtual void removeUrlSeeds(const QVector
<QUrl
> &urlSeeds
) = 0;
311 virtual bool connectPeer(const PeerAddress
&peerAddress
) = 0;
312 virtual void clearPeers() = 0;
313 virtual void setMetadata(const TorrentInfo
&torrentInfo
) = 0;
315 virtual StopCondition
stopCondition() const = 0;
316 virtual void setStopCondition(StopCondition stopCondition
) = 0;
318 virtual QString
createMagnetURI() const = 0;
319 virtual nonstd::expected
<QByteArray
, QString
> exportToBuffer() const = 0;
320 virtual nonstd::expected
<void, QString
> exportToFile(const Path
&path
) const = 0;
322 virtual void fetchPeerInfo(std::function
<void (QVector
<PeerInfo
>)> resultHandler
) const = 0;
323 virtual void fetchURLSeeds(std::function
<void (QVector
<QUrl
>)> resultHandler
) const = 0;
324 virtual void fetchFilesProgress(std::function
<void (QVector
<qreal
>)> resultHandler
) const = 0;
325 virtual void fetchPieceAvailability(std::function
<void (QVector
<int>)> resultHandler
) const = 0;
326 virtual void fetchDownloadingPieces(std::function
<void (QBitArray
)> resultHandler
) const = 0;
328 * @brief fraction of file pieces that are available at least from one peer
330 * This is not the same as torrrent availability, it is just a fraction of pieces
331 * that can be downloaded right now. It varies between 0 to 1.
333 virtual void fetchAvailableFileFractions(std::function
<void (QVector
<qreal
>)> resultHandler
) const = 0;
335 TorrentID
id() const;
336 bool isResumed() const;
337 qlonglong
remainingSize() const;
339 void toggleSequentialDownload();
340 void toggleFirstLastPiecePriority();
344 Q_DECLARE_METATYPE(BitTorrent::TorrentState
)