1 /*
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>
5  *
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.
10  *
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.
15  *
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.
19  *
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.
28  */
29 
30 #pragma once
31 
32 #include <QMetaType>
33 #include <QString>
34 #include <QtContainerFwd>
35 
36 #include "abstractfilestorage.h"
37 
38 class QBitArray;
39 class QDateTime;
40 class QUrl;
41 
42 namespace BitTorrent
43 {
44     enum class DownloadPriority;
45     class InfoHash;
46     class PeerInfo;
47     class TorrentID;
48     class TorrentInfo;
49     struct PeerAddress;
50     struct TrackerEntry;
51 
52     // Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
53     // since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
54     // https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
55     inline namespace TorrentOperatingModeNS
56     {
57         Q_NAMESPACE
58 
59         enum class TorrentOperatingMode
60         {
61             AutoManaged = 0,
62             Forced = 1
63         };
64 
65         Q_ENUM_NS(TorrentOperatingMode)
66     }
67 
68     enum class TorrentState
69     {
70         Unknown = -1,
71 
72         ForcedDownloading,
73         Downloading,
74         DownloadingMetadata,
75         StalledDownloading,
76 
77         ForcedUploading,
78         Uploading,
79         StalledUploading,
80 
81         CheckingResumeData,
82         QueuedDownloading,
83         QueuedUploading,
84 
85         CheckingUploading,
86         CheckingDownloading,
87 
88         PausedDownloading,
89         PausedUploading,
90 
91         Moving,
92 
93         MissingFiles,
94         Error
95     };
96 
97     uint qHash(TorrentState key, uint seed);
98 
99     class Torrent : public AbstractFileStorage
100     {
101     public:
102         static const qreal USE_GLOBAL_RATIO;
103         static const qreal NO_RATIO_LIMIT;
104 
105         static const int USE_GLOBAL_SEEDING_TIME;
106         static const int NO_SEEDING_TIME_LIMIT;
107 
108         static const qreal MAX_RATIO;
109         static const int MAX_SEEDING_TIME;
110 
111         virtual ~Torrent() = default;
112 
113         virtual InfoHash infoHash() const = 0;
114         virtual QString name() const = 0;
115         virtual QDateTime creationDate() const = 0;
116         virtual QString creator() const = 0;
117         virtual QString comment() const = 0;
118         virtual bool isPrivate() const = 0;
119         virtual qlonglong totalSize() const = 0;
120         virtual qlonglong wantedSize() const = 0;
121         virtual qlonglong completedSize() const = 0;
122         virtual qlonglong pieceLength() const = 0;
123         virtual qlonglong wastedSize() const = 0;
124         virtual QString currentTracker() const = 0;
125 
126         // 1. savePath() - the path where all the files and subfolders of torrent are stored (as always).
127         // 2. rootPath() - absolute path of torrent file tree (save path + first item from 1st torrent file path).
128         // 3. contentPath() - absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents).
129         //
130         // These methods have 'actual' parameter (defaults to false) which allow to get actual or final path variant.
131         //
132         // Examples.
133         // Suppose we have three torrent with following structures and save path `/home/user/torrents`:
134         //
135         // Torrent A (multifile)
136         //
137         // torrentA/
138         //    subdir1/
139         //       subdir2/
140         //          file1
141         //          file2
142         //       file3
143         //    file4
144         //
145         //
146         // Torrent A* (Torrent A in "strip root folder" mode)
147         //
148         //
149         // Torrent B (singlefile)
150         //
151         // torrentB/
152         //    subdir1/
153         //           file1
154         //
155         //
156         // Torrent C (singlefile)
157         //
158         // file1
159         //
160         //
161         // Results:
162         // |   |           rootPath           |                contentPath                 |
163         // |---|------------------------------|--------------------------------------------|
164         // | A | /home/user/torrents/torrentA | /home/user/torrents/torrentA               |
165         // | A*|           <empty>            | /home/user/torrents                        |
166         // | B | /home/user/torrents/torrentB | /home/user/torrents/torrentB/subdir1/file1 |
167         // | C | /home/user/torrents/file1    | /home/user/torrents/file1                  |
168 
169         virtual QString savePath(bool actual = false) const = 0;
170         virtual QString rootPath(bool actual = false) const = 0;
171         virtual QString contentPath(bool actual = false) const = 0;
172 
173         virtual bool useTempPath() const = 0;
174 
175         virtual bool isAutoTMMEnabled() const = 0;
176         virtual void setAutoTMMEnabled(bool enabled) = 0;
177         virtual QString category() const = 0;
178         virtual bool belongsToCategory(const QString &category) const = 0;
179         virtual bool setCategory(const QString &category) = 0;
180 
181         virtual QSet<QString> tags() const = 0;
182         virtual bool hasTag(const QString &tag) const = 0;
183         virtual bool addTag(const QString &tag) = 0;
184         virtual bool removeTag(const QString &tag) = 0;
185         virtual void removeAllTags() = 0;
186 
187         virtual int piecesCount() const = 0;
188         virtual int piecesHave() const = 0;
189         virtual qreal progress() const = 0;
190         virtual QDateTime addedTime() const = 0;
191         virtual qreal ratioLimit() const = 0;
192         virtual int seedingTimeLimit() const = 0;
193 
194         virtual QStringList absoluteFilePaths() const = 0;
195         virtual QVector<DownloadPriority> filePriorities() const = 0;
196 
197         virtual TorrentInfo info() const = 0;
198         virtual bool isSeed() const = 0;
199         virtual bool isPaused() const = 0;
200         virtual bool isQueued() const = 0;
201         virtual bool isForced() const = 0;
202         virtual bool isChecking() const = 0;
203         virtual bool isDownloading() const = 0;
204         virtual bool isUploading() const = 0;
205         virtual bool isCompleted() const = 0;
206         virtual bool isActive() const = 0;
207         virtual bool isInactive() const = 0;
208         virtual bool isErrored() const = 0;
209         virtual bool isSequentialDownload() const = 0;
210         virtual bool hasFirstLastPiecePriority() const = 0;
211         virtual TorrentState state() const = 0;
212         virtual bool hasMetadata() const = 0;
213         virtual bool hasMissingFiles() const = 0;
214         virtual bool hasError() const = 0;
215         virtual bool hasFilteredPieces() const = 0;
216         virtual int queuePosition() const = 0;
217         virtual QVector<TrackerEntry> trackers() const = 0;
218         virtual QVector<QUrl> urlSeeds() const = 0;
219         virtual QString error() const = 0;
220         virtual qlonglong totalDownload() const = 0;
221         virtual qlonglong totalUpload() const = 0;
222         virtual qlonglong activeTime() const = 0;
223         virtual qlonglong finishedTime() const = 0;
224         virtual qlonglong seedingTime() const = 0;
225         virtual qlonglong eta() const = 0;
226         virtual QVector<qreal> filesProgress() const = 0;
227         virtual int seedsCount() const = 0;
228         virtual int peersCount() const = 0;
229         virtual int leechsCount() const = 0;
230         virtual int totalSeedsCount() const = 0;
231         virtual int totalPeersCount() const = 0;
232         virtual int totalLeechersCount() const = 0;
233         virtual int completeCount() const = 0;
234         virtual int incompleteCount() const = 0;
235         virtual QDateTime lastSeenComplete() const = 0;
236         virtual QDateTime completedTime() const = 0;
237         virtual qlonglong timeSinceUpload() const = 0;
238         virtual qlonglong timeSinceDownload() const = 0;
239         virtual qlonglong timeSinceActivity() const = 0;
240         virtual int downloadLimit() const = 0;
241         virtual int uploadLimit() const = 0;
242         virtual bool superSeeding() const = 0;
243         virtual bool isDHTDisabled() const = 0;
244         virtual bool isPEXDisabled() const = 0;
245         virtual bool isLSDDisabled() const = 0;
246         virtual QVector<PeerInfo> peers() const = 0;
247         virtual QBitArray pieces() const = 0;
248         virtual QBitArray downloadingPieces() const = 0;
249         virtual QVector<int> pieceAvailability() const = 0;
250         virtual qreal distributedCopies() const = 0;
251         virtual qreal maxRatio() const = 0;
252         virtual int maxSeedingTime() const = 0;
253         virtual qreal realRatio() const = 0;
254         virtual int uploadPayloadRate() const = 0;
255         virtual int downloadPayloadRate() const = 0;
256         virtual qlonglong totalPayloadUpload() const = 0;
257         virtual qlonglong totalPayloadDownload() const = 0;
258         virtual int connectionsCount() const = 0;
259         virtual int connectionsLimit() const = 0;
260         virtual qlonglong nextAnnounce() const = 0;
261         /**
262          * @brief fraction of file pieces that are available at least from one peer
263          *
264          * This is not the same as torrrent availability, it is just a fraction of pieces
265          * that can be downloaded right now. It varies between 0 to 1.
266          */
267         virtual QVector<qreal> availableFileFractions() const = 0;
268 
269         virtual void setName(const QString &name) = 0;
270         virtual void setSequentialDownload(bool enable) = 0;
271         virtual void setFirstLastPiecePriority(bool enabled) = 0;
272         virtual void pause() = 0;
273         virtual void resume(TorrentOperatingMode mode = TorrentOperatingMode::AutoManaged) = 0;
274         virtual void move(QString path) = 0;
275         virtual void forceReannounce(int index = -1) = 0;
276         virtual void forceDHTAnnounce() = 0;
277         virtual void forceRecheck() = 0;
278         virtual void prioritizeFiles(const QVector<DownloadPriority> &priorities) = 0;
279         virtual void setRatioLimit(qreal limit) = 0;
280         virtual void setSeedingTimeLimit(int limit) = 0;
281         virtual void setUploadLimit(int limit) = 0;
282         virtual void setDownloadLimit(int limit) = 0;
283         virtual void setSuperSeeding(bool enable) = 0;
284         virtual void setDHTDisabled(bool disable) = 0;
285         virtual void setPEXDisabled(bool disable) = 0;
286         virtual void setLSDDisabled(bool disable) = 0;
287         virtual void flushCache() const = 0;
288         virtual void addTrackers(const QVector<TrackerEntry> &trackers) = 0;
289         virtual void replaceTrackers(const QVector<TrackerEntry> &trackers) = 0;
290         virtual void addUrlSeeds(const QVector<QUrl> &urlSeeds) = 0;
291         virtual void removeUrlSeeds(const QVector<QUrl> &urlSeeds) = 0;
292         virtual bool connectPeer(const PeerAddress &peerAddress) = 0;
293         virtual void clearPeers() = 0;
294 
295         virtual QString createMagnetURI() const = 0;
296 
297         TorrentID id() const;
298         bool isResumed() const;
299         qlonglong remainingSize() const;
300 
301         void toggleSequentialDownload();
302         void toggleFirstLastPiecePriority();
303     };
304 }
305 
306 Q_DECLARE_METATYPE(BitTorrent::TorrentState)
307