/* * Bittorrent Client using Qt and libtorrent. * Copyright (C) 2015 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * In addition, as a special exception, the copyright holders give permission to * link this program with the OpenSSL project's "OpenSSL" library (or with * modified versions of it that use the same license as the "OpenSSL" library), * and distribute the linked executables. You must obey the GNU General Public * License in all respects for all of the code used other than "OpenSSL". If you * modify file(s), you may extend this exception to your version of the file(s), * but you are not obligated to do so. If you do not wish to do so, delete this * exception statement from your version. */ #ifndef BITTORRENT_TORRENTHANDLE_H #define BITTORRENT_TORRENTHANDLE_H #include #include #include #include #include #include #include #include #include #if LIBTORRENT_VERSION_NUM >= 10100 #include #endif #include #include "base/tristatebool.h" #include "private/speedmonitor.h" #include "infohash.h" #include "torrentinfo.h" class QBitArray; class QStringList; template struct QPair; extern const QString QB_EXT; namespace libtorrent { class alert; struct stats_alert; struct torrent_checked_alert; struct torrent_finished_alert; struct torrent_paused_alert; struct torrent_resumed_alert; struct save_resume_data_alert; struct save_resume_data_failed_alert; struct file_renamed_alert; struct file_rename_failed_alert; struct storage_moved_alert; struct storage_moved_failed_alert; struct metadata_received_alert; struct file_completed_alert; struct tracker_error_alert; struct tracker_reply_alert; struct tracker_warning_alert; struct fastresume_rejected_alert; struct torrent_status; } namespace BitTorrent { struct PeerAddress; class Session; class PeerInfo; class TrackerEntry; struct AddTorrentParams; struct AddTorrentData { bool resumed; // for both new and resumed torrents QString name; QString category; QSet tags; QString savePath; bool disableTempPath; bool sequential; bool firstLastPiecePriority; bool hasSeedStatus; bool skipChecking; bool hasRootFolder; bool addForced; bool addPaused; int uploadLimit; int downloadLimit; // for new torrents QVector filePriorities; // for resumed torrents qreal ratioLimit; int seedingTimeLimit; AddTorrentData(); AddTorrentData(const AddTorrentParams ¶ms); }; struct TrackerInfo { QString lastMessage; quint32 numPeers = 0; }; enum class TorrentState { Unknown = -1, ForcedDownloading, Downloading, DownloadingMetadata, Allocating, StalledDownloading, ForcedUploading, Uploading, StalledUploading, #if LIBTORRENT_VERSION_NUM < 10100 QueuedForChecking, #endif CheckingResumeData, QueuedDownloading, QueuedUploading, CheckingUploading, CheckingDownloading, PausedDownloading, PausedUploading, MissingFiles, Error }; class TorrentHandle : public QObject { Q_DISABLE_COPY(TorrentHandle) public: static const qreal USE_GLOBAL_RATIO; static const qreal NO_RATIO_LIMIT; static const int USE_GLOBAL_SEEDING_TIME; static const int NO_SEEDING_TIME_LIMIT; static const qreal MAX_RATIO; static const int MAX_SEEDING_TIME; TorrentHandle(Session *session, const libtorrent::torrent_handle &nativeHandle, const AddTorrentData &data); ~TorrentHandle(); bool isValid() const; InfoHash hash() const; QString name() const; QDateTime creationDate() const; QString creator() const; QString comment() const; bool isPrivate() const; qlonglong totalSize() const; qlonglong wantedSize() const; qlonglong completedSize() const; qlonglong incompletedSize() const; qlonglong pieceLength() const; qlonglong wastedSize() const; QString currentTracker() const; // 1. savePath() - the path where all the files and subfolders of torrent are stored (as always). // 2. rootPath() - absolute path of torrent file tree (save path + first item from 1st torrent file path). // 3. contentPath() - absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents). // // These methods have 'actual' parameter (defaults to false) which allow to get actual or final path variant. // // Examples. // Suppose we have three torrent with following structures and save path `/home/user/torrents`: // // Torrent A (multifile) // // torrentA/ // subdir1/ // subdir2/ // file1 // file2 // file3 // file4 // // // Torrent A* (Torrent A in "strip root folder" mode) // // // Torrent B (singlefile) // // torrentB/ // subdir1/ // file1 // // // Torrent C (singlefile) // // file1 // // // Results: // | | rootPath | contentPath | // |---|------------------------------|--------------------------------------------| // | A | /home/user/torrents/torrentA | /home/user/torrents/torrentA | // | A*| | /home/user/torrents | // | B | /home/user/torrents/torrentB | /home/user/torrents/torrentB/subdir1/file1 | // | C | /home/user/torrents/file1 | /home/user/torrents/file1 | QString savePath(bool actual = false) const; QString rootPath(bool actual = false) const; QString contentPath(bool actual = false) const; bool useTempPath() const; bool isAutoTMMEnabled() const; void setAutoTMMEnabled(bool enabled); QString category() const; bool belongsToCategory(const QString &category) const; bool setCategory(const QString &category); QSet tags() const; bool hasTag(const QString &tag) const; bool addTag(const QString &tag); bool removeTag(const QString &tag); void removeAllTags(); bool hasRootFolder() const; int filesCount() const; int piecesCount() const; int piecesHave() const; qreal progress() const; QDateTime addedTime() const; qreal ratioLimit() const; int seedingTimeLimit() const; QString filePath(int index) const; QString fileName(int index) const; qlonglong fileSize(int index) const; QStringList absoluteFilePaths() const; QStringList absoluteFilePathsUnwanted() const; QVector filePriorities() const; TorrentInfo info() const; bool isSeed() const; bool isPaused() const; bool isResumed() const; bool isQueued() const; bool isForced() const; bool isChecking() const; bool isDownloading() const; bool isUploading() const; bool isCompleted() const; bool isActive() const; bool isInactive() const; bool isErrored() const; bool isSequentialDownload() const; bool hasFirstLastPiecePriority() const; TorrentState state() const; bool hasMetadata() const; bool hasMissingFiles() const; bool hasError() const; bool hasFilteredPieces() const; int queuePosition() const; QList trackers() const; QHash trackerInfos() const; QList urlSeeds() const; QString error() const; qlonglong totalDownload() const; qlonglong totalUpload() const; int activeTime() const; int finishedTime() const; int seedingTime() const; qulonglong eta() const; QVector filesProgress() const; int seedsCount() const; int peersCount() const; int leechsCount() const; int totalSeedsCount() const; int totalPeersCount() const; int totalLeechersCount() const; int completeCount() const; int incompleteCount() const; QDateTime lastSeenComplete() const; QDateTime completedTime() const; int timeSinceUpload() const; int timeSinceDownload() const; int timeSinceActivity() const; int downloadLimit() const; int uploadLimit() const; bool superSeeding() const; QList peers() const; QBitArray pieces() const; QBitArray downloadingPieces() const; QVector pieceAvailability() const; qreal distributedCopies() const; qreal maxRatio() const; int maxSeedingTime() const; qreal realRatio() const; int uploadPayloadRate() const; int downloadPayloadRate() const; qlonglong totalPayloadUpload() const; qlonglong totalPayloadDownload() const; int connectionsCount() const; int connectionsLimit() const; qlonglong nextAnnounce() const; void setName(const QString &name); void setSequentialDownload(bool b); void toggleSequentialDownload(); void setFirstLastPiecePriority(bool b); void toggleFirstLastPiecePriority(); void pause(); void resume(bool forced = false); void move(QString path); void forceReannounce(int index = -1); void forceDHTAnnounce(); void forceRecheck(); #if LIBTORRENT_VERSION_NUM < 10100 void setTrackerLogin(const QString &username, const QString &password); #endif void renameFile(int index, const QString &name); bool saveTorrentFile(const QString &path); void prioritizeFiles(const QVector &priorities); void setFilePriority(int index, int priority); void setRatioLimit(qreal limit); void setSeedingTimeLimit(int limit); void setUploadLimit(int limit); void setDownloadLimit(int limit); void setSuperSeeding(bool enable); void flushCache(); void addTrackers(const QList &trackers); void replaceTrackers(QList trackers); void addUrlSeeds(const QList &urlSeeds); void removeUrlSeeds(const QList &urlSeeds); bool connectPeer(const PeerAddress &peerAddress); QString toMagnetUri() const; bool needSaveResumeData() const; // Session interface libtorrent::torrent_handle nativeHandle() const; void handleAlert(libtorrent::alert *a); void handleStateUpdate(const libtorrent::torrent_status &nativeStatus); void handleTempPathChanged(); void handleCategorySavePathChanged(); void handleAppendExtensionToggled(); void saveResumeData(bool updateStatus = false); /** * @brief fraction of file pieces that are available at least from one peer * * This is not the same as torrrent availability, it is just a fraction of pieces * that can be downloaded right now. It varies between 0 to 1. */ QVector availableFileFractions() const; private: typedef boost::function EventTrigger; void updateStatus(); void updateStatus(const libtorrent::torrent_status &nativeStatus); void updateState(); void updateTorrentInfo(); void handleStorageMovedAlert(libtorrent::storage_moved_alert *p); void handleStorageMovedFailedAlert(libtorrent::storage_moved_failed_alert *p); void handleTrackerReplyAlert(libtorrent::tracker_reply_alert *p); void handleTrackerWarningAlert(libtorrent::tracker_warning_alert *p); void handleTrackerErrorAlert(libtorrent::tracker_error_alert *p); void handleTorrentCheckedAlert(libtorrent::torrent_checked_alert *p); void handleTorrentFinishedAlert(libtorrent::torrent_finished_alert *p); void handleTorrentPausedAlert(libtorrent::torrent_paused_alert *p); void handleTorrentResumedAlert(libtorrent::torrent_resumed_alert *p); void handleSaveResumeDataAlert(libtorrent::save_resume_data_alert *p); void handleSaveResumeDataFailedAlert(libtorrent::save_resume_data_failed_alert *p); void handleFastResumeRejectedAlert(libtorrent::fastresume_rejected_alert *p); void handleFileRenamedAlert(libtorrent::file_renamed_alert *p); void handleFileRenameFailedAlert(libtorrent::file_rename_failed_alert *p); void handleFileCompletedAlert(libtorrent::file_completed_alert *p); void handleMetadataReceivedAlert(libtorrent::metadata_received_alert *p); void handleStatsAlert(libtorrent::stats_alert *p); void resume_impl(bool forced, bool uploadMode); bool isMoveInProgress() const; QString nativeActualSavePath() const; void adjustActualSavePath(); void adjustActualSavePath_impl(); void move_impl(QString path, bool overwrite); void moveStorage(const QString &newPath, bool overwrite); void manageIncompleteFiles(); bool addTracker(const TrackerEntry &tracker); bool addUrlSeed(const QUrl &urlSeed); bool removeUrlSeed(const QUrl &urlSeed); Session *const m_session; libtorrent::torrent_handle m_nativeHandle; libtorrent::torrent_status m_nativeStatus; TorrentState m_state; TorrentInfo m_torrentInfo; SpeedMonitor m_speedMonitor; InfoHash m_hash; struct { QString oldPath; QString newPath; // queuedPath is where files should be moved to, // when current moving is completed QString queuedPath; bool queuedOverwrite = true; } m_moveStorageInfo; // m_moveFinishedTriggers is activated only when the following conditions are met: // all file rename jobs complete, all file move jobs complete QQueue m_moveFinishedTriggers; int m_renameCount; bool m_useAutoTMM; // Persistent data QString m_name; QString m_savePath; QString m_category; QSet m_tags; bool m_hasSeedStatus; qreal m_ratioLimit; int m_seedingTimeLimit; bool m_tempPathDisabled; bool m_hasMissingFiles; bool m_hasRootFolder; bool m_needsToSetFirstLastPiecePriority; bool m_pauseAfterRecheck; bool m_needSaveResumeData; QHash m_trackerInfos; }; } Q_DECLARE_METATYPE(BitTorrent::TorrentState) #endif // BITTORRENT_TORRENTHANDLE_H