WebUI: fix window can not close regression
[qBittorrent.git] / src / base / bittorrent / torrentimpl.h
blob5c54b2d000a3675efbc726ca07ecc00edd17cb57
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2015-2023 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.
30 #pragma once
32 #include <functional>
33 #include <memory>
35 #include <libtorrent/add_torrent_params.hpp>
36 #include <libtorrent/fwd.hpp>
37 #include <libtorrent/torrent_handle.hpp>
38 #include <libtorrent/torrent_info.hpp>
39 #include <libtorrent/torrent_status.hpp>
41 #include <QBitArray>
42 #include <QDateTime>
43 #include <QHash>
44 #include <QList>
45 #include <QMap>
46 #include <QObject>
47 #include <QQueue>
48 #include <QString>
50 #include "base/path.h"
51 #include "base/tagset.h"
52 #include "infohash.h"
53 #include "speedmonitor.h"
54 #include "sslparameters.h"
55 #include "torrent.h"
56 #include "torrentcontentlayout.h"
57 #include "torrentinfo.h"
58 #include "trackerentrystatus.h"
60 namespace BitTorrent
62 class SessionImpl;
63 struct LoadTorrentParams;
65 enum class MoveStorageMode
67 FailIfExist,
68 KeepExistingFiles,
69 Overwrite
72 enum class MoveStorageContext
74 AdjustCurrentLocation,
75 ChangeSavePath,
76 ChangeDownloadPath
79 enum class MaintenanceJob
81 None,
82 HandleMetadata
85 struct FileErrorInfo
87 lt::error_code error;
88 lt::operation_t operation = lt::operation_t::unknown;
91 class TorrentImpl final : public Torrent
93 Q_OBJECT
94 Q_DISABLE_COPY_MOVE(TorrentImpl)
96 public:
97 TorrentImpl(SessionImpl *session, lt::session *nativeSession
98 , const lt::torrent_handle &nativeHandle, const LoadTorrentParams &params);
99 ~TorrentImpl() override;
101 bool isValid() const;
103 Session *session() const override;
105 InfoHash infoHash() const override;
106 QString name() const override;
107 QDateTime creationDate() const override;
108 QString creator() const override;
109 QString comment() const override;
110 bool isPrivate() const override;
111 qlonglong totalSize() const override;
112 qlonglong wantedSize() const override;
113 qlonglong completedSize() const override;
114 qlonglong pieceLength() const override;
115 qlonglong wastedSize() const override;
116 QString currentTracker() const override;
118 bool isAutoTMMEnabled() const override;
119 void setAutoTMMEnabled(bool enabled) override;
120 Path savePath() const override;
121 void setSavePath(const Path &path) override;
122 Path downloadPath() const override;
123 void setDownloadPath(const Path &path) override;
124 Path actualStorageLocation() const override;
125 Path rootPath() const override;
126 Path contentPath() const override;
127 QString category() const override;
128 bool belongsToCategory(const QString &category) const override;
129 bool setCategory(const QString &category) override;
131 TagSet tags() const override;
132 bool hasTag(const Tag &tag) const override;
133 bool addTag(const Tag &tag) override;
134 bool removeTag(const Tag &tag) override;
135 void removeAllTags() override;
137 int filesCount() const override;
138 int piecesCount() const override;
139 int piecesHave() const override;
140 qreal progress() const override;
142 QDateTime addedTime() const override;
143 QDateTime completedTime() const override;
144 QDateTime lastSeenComplete() const override;
145 qlonglong activeTime() const override;
146 qlonglong finishedTime() const override;
147 qlonglong timeSinceUpload() const override;
148 qlonglong timeSinceDownload() const override;
149 qlonglong timeSinceActivity() const override;
151 qreal ratioLimit() const override;
152 void setRatioLimit(qreal limit) override;
153 int seedingTimeLimit() const override;
154 void setSeedingTimeLimit(int limit) override;
155 int inactiveSeedingTimeLimit() const override;
156 void setInactiveSeedingTimeLimit(int limit) override;
157 ShareLimitAction shareLimitAction() const override;
158 void setShareLimitAction(ShareLimitAction action) override;
160 Path filePath(int index) const override;
161 Path actualFilePath(int index) const override;
162 qlonglong fileSize(int index) const override;
163 PathList filePaths() const override;
164 PathList actualFilePaths() const override;
165 QList<DownloadPriority> filePriorities() const override;
167 TorrentInfo info() const override;
168 bool isFinished() const override;
169 bool isStopped() const override;
170 bool isQueued() const override;
171 bool isForced() const override;
172 bool isChecking() const override;
173 bool isDownloading() const override;
174 bool isMoving() const override;
175 bool isUploading() const override;
176 bool isCompleted() const override;
177 bool isActive() const override;
178 bool isInactive() const override;
179 bool isErrored() const override;
180 bool isSequentialDownload() const override;
181 bool hasFirstLastPiecePriority() const override;
182 TorrentState state() const override;
183 bool hasMetadata() const override;
184 bool hasMissingFiles() const override;
185 bool hasError() const override;
186 int queuePosition() const override;
187 QList<TrackerEntryStatus> trackers() const override;
188 QList<QUrl> urlSeeds() const override;
189 QString error() const override;
190 qlonglong totalDownload() const override;
191 qlonglong totalUpload() const override;
192 qlonglong eta() const override;
193 QList<qreal> filesProgress() const override;
194 int seedsCount() const override;
195 int peersCount() const override;
196 int leechsCount() const override;
197 int totalSeedsCount() const override;
198 int totalPeersCount() const override;
199 int totalLeechersCount() const override;
200 int downloadLimit() const override;
201 int uploadLimit() const override;
202 bool superSeeding() const override;
203 bool isDHTDisabled() const override;
204 bool isPEXDisabled() const override;
205 bool isLSDDisabled() const override;
206 QList<PeerInfo> peers() const override;
207 QBitArray pieces() const override;
208 QBitArray downloadingPieces() const override;
209 QList<int> pieceAvailability() const override;
210 qreal distributedCopies() const override;
211 qreal maxRatio() const override;
212 int maxSeedingTime() const override;
213 int maxInactiveSeedingTime() const override;
214 qreal realRatio() const override;
215 qreal popularity() const override;
216 int uploadPayloadRate() const override;
217 int downloadPayloadRate() const override;
218 qlonglong totalPayloadUpload() const override;
219 qlonglong totalPayloadDownload() const override;
220 int connectionsCount() const override;
221 int connectionsLimit() const override;
222 qlonglong nextAnnounce() const override;
223 QList<qreal> availableFileFractions() const override;
225 void setName(const QString &name) override;
226 void setSequentialDownload(bool enable) override;
227 void setFirstLastPiecePriority(bool enabled) override;
228 void stop() override;
229 void start(TorrentOperatingMode mode = TorrentOperatingMode::AutoManaged) override;
230 void forceReannounce(int index = -1) override;
231 void forceDHTAnnounce() override;
232 void forceRecheck() override;
233 void renameFile(int index, const Path &path) override;
234 void prioritizeFiles(const QList<DownloadPriority> &priorities) override;
235 void setUploadLimit(int limit) override;
236 void setDownloadLimit(int limit) override;
237 void setSuperSeeding(bool enable) override;
238 void setDHTDisabled(bool disable) override;
239 void setPEXDisabled(bool disable) override;
240 void setLSDDisabled(bool disable) override;
241 void flushCache() const override;
242 void addTrackers(QList<TrackerEntry> trackers) override;
243 void removeTrackers(const QStringList &trackers) override;
244 void replaceTrackers(QList<TrackerEntry> trackers) override;
245 void addUrlSeeds(const QList<QUrl> &urlSeeds) override;
246 void removeUrlSeeds(const QList<QUrl> &urlSeeds) override;
247 bool connectPeer(const PeerAddress &peerAddress) override;
248 void clearPeers() override;
249 void setMetadata(const TorrentInfo &torrentInfo) override;
251 StopCondition stopCondition() const override;
252 void setStopCondition(StopCondition stopCondition) override;
253 SSLParameters getSSLParameters() const override;
254 void setSSLParameters(const SSLParameters &sslParams) override;
255 bool applySSLParameters();
257 QString createMagnetURI() const override;
258 nonstd::expected<QByteArray, QString> exportToBuffer() const override;
259 nonstd::expected<void, QString> exportToFile(const Path &path) const override;
261 void fetchPeerInfo(std::function<void (QList<PeerInfo>)> resultHandler) const override;
262 void fetchURLSeeds(std::function<void (QList<QUrl>)> resultHandler) const override;
263 void fetchPieceAvailability(std::function<void (QList<int>)> resultHandler) const override;
264 void fetchDownloadingPieces(std::function<void (QBitArray)> resultHandler) const override;
265 void fetchAvailableFileFractions(std::function<void (QList<qreal>)> resultHandler) const override;
267 bool needSaveResumeData() const;
269 // Session interface
270 lt::torrent_handle nativeHandle() const;
272 void handleAlert(const lt::alert *a);
273 void handleStateUpdate(const lt::torrent_status &nativeStatus);
274 void handleQueueingModeChanged();
275 void handleCategoryOptionsChanged();
276 void handleAppendExtensionToggled();
277 void handleUnwantedFolderToggled();
278 void requestResumeData(lt::resume_data_flags_t flags = {});
279 void deferredRequestResumeData();
280 void handleMoveStorageJobFinished(const Path &path, MoveStorageContext context, bool hasOutstandingJob);
281 void fileSearchFinished(const Path &savePath, const PathList &fileNames);
282 TrackerEntryStatus updateTrackerEntryStatus(const lt::announce_entry &announceEntry, const QHash<lt::tcp::endpoint, QMap<int, int>> &updateInfo);
283 void resetTrackerEntryStatuses();
285 private:
286 using EventTrigger = std::function<void ()>;
288 std::shared_ptr<const lt::torrent_info> nativeTorrentInfo() const;
290 void updateStatus(const lt::torrent_status &nativeStatus);
291 void updateProgress();
292 void updateState();
294 void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert *p);
295 void handleFileCompletedAlert(const lt::file_completed_alert *p);
296 void handleFileErrorAlert(const lt::file_error_alert *p);
297 #ifdef QBT_USES_LIBTORRENT2
298 void handleFilePrioAlert(const lt::file_prio_alert *p);
299 #endif
300 void handleFileRenamedAlert(const lt::file_renamed_alert *p);
301 void handleFileRenameFailedAlert(const lt::file_rename_failed_alert *p);
302 void handleMetadataReceivedAlert(const lt::metadata_received_alert *p);
303 void handlePerformanceAlert(const lt::performance_alert *p) const;
304 void handleSaveResumeDataAlert(const lt::save_resume_data_alert *p);
305 void handleSaveResumeDataFailedAlert(const lt::save_resume_data_failed_alert *p);
306 void handleTorrentCheckedAlert(const lt::torrent_checked_alert *p);
307 void handleTorrentFinishedAlert(const lt::torrent_finished_alert *p);
308 void handleTorrentPausedAlert(const lt::torrent_paused_alert *p);
309 void handleTorrentResumedAlert(const lt::torrent_resumed_alert *p);
311 bool isMoveInProgress() const;
313 void setAutoManaged(bool enable);
315 Path makeActualPath(int index, const Path &path) const;
316 Path makeUserPath(const Path &path) const;
317 void adjustStorageLocation();
318 void doRenameFile(int index, const Path &path);
319 void moveStorage(const Path &newPath, MoveStorageContext context);
320 void manageActualFilePaths();
321 void applyFirstLastPiecePriority(bool enabled);
323 void prepareResumeData(const lt::add_torrent_params &params);
324 void endReceivedMetadataHandling(const Path &savePath, const PathList &fileNames);
325 void reload();
327 nonstd::expected<lt::entry, QString> exportTorrent() const;
329 template <typename Func, typename Callback>
330 void invokeAsync(Func func, Callback resultHandler) const;
332 SessionImpl *const m_session = nullptr;
333 lt::session *m_nativeSession = nullptr;
334 lt::torrent_handle m_nativeHandle;
335 mutable lt::torrent_status m_nativeStatus;
336 TorrentState m_state = TorrentState::Unknown;
337 TorrentInfo m_torrentInfo;
338 PathList m_filePaths;
339 QHash<lt::file_index_t, int> m_indexMap;
340 QList<DownloadPriority> m_filePriorities;
341 QBitArray m_completedFiles;
342 SpeedMonitor m_payloadRateMonitor;
344 InfoHash m_infoHash;
346 QDateTime m_creationDate;
347 QString m_creator;
348 QString m_comment;
350 QDateTime m_addedTime;
351 QDateTime m_completedTime;
352 QDateTime m_lastSeenComplete;
354 // m_moveFinishedTriggers is activated only when the following conditions are met:
355 // all file rename jobs complete, all file move jobs complete
356 QQueue<EventTrigger> m_moveFinishedTriggers;
357 int m_renameCount = 0;
358 bool m_storageIsMoving = false;
360 QQueue<EventTrigger> m_statusUpdatedTriggers;
362 MaintenanceJob m_maintenanceJob = MaintenanceJob::None;
364 QList<TrackerEntryStatus> m_trackerEntryStatuses;
365 QList<QUrl> m_urlSeeds;
366 FileErrorInfo m_lastFileError;
368 // Persistent data
369 QString m_name;
370 Path m_savePath;
371 Path m_downloadPath;
372 QString m_category;
373 TagSet m_tags;
374 qreal m_ratioLimit = 0;
375 int m_seedingTimeLimit = 0;
376 int m_inactiveSeedingTimeLimit = 0;
377 ShareLimitAction m_shareLimitAction = ShareLimitAction::Default;
378 TorrentOperatingMode m_operatingMode = TorrentOperatingMode::AutoManaged;
379 TorrentContentLayout m_contentLayout = TorrentContentLayout::Original;
380 bool m_hasFinishedStatus = false;
381 bool m_hasMissingFiles = false;
382 bool m_hasFirstLastPiecePriority = false;
383 bool m_useAutoTMM = false;
384 bool m_isStopped = false;
385 StopCondition m_stopCondition = StopCondition::None;
386 SSLParameters m_sslParams;
388 bool m_unchecked = false;
390 lt::add_torrent_params m_ltAddTorrentParams;
392 int m_downloadLimit = 0;
393 int m_uploadLimit = 0;
395 QBitArray m_pieces;
396 QList<std::int64_t> m_filesProgress;
398 bool m_deferredRequestResumeDataInvoked = false;