Vladimir Golovnev
5 years ago
committed by
GitHub
19 changed files with 2774 additions and 2547 deletions
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,337 @@
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent. |
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru> |
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org> |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
#pragma once |
||||
|
||||
#include <functional> |
||||
|
||||
#include <libtorrent/fwd.hpp> |
||||
#include <libtorrent/torrent_handle.hpp> |
||||
#include <libtorrent/torrent_status.hpp> |
||||
|
||||
#include <QDateTime> |
||||
#include <QHash> |
||||
#include <QObject> |
||||
#include <QQueue> |
||||
#include <QSet> |
||||
#include <QString> |
||||
#include <QVector> |
||||
|
||||
#include "private/speedmonitor.h" |
||||
#include "infohash.h" |
||||
#include "torrenthandle.h" |
||||
#include "torrentinfo.h" |
||||
|
||||
namespace BitTorrent |
||||
{ |
||||
class Session; |
||||
struct AddTorrentParams; |
||||
|
||||
struct CreateTorrentParams |
||||
{ |
||||
bool restored = false; // is existing torrent job?
|
||||
// for both new and restored torrents
|
||||
QString name; |
||||
QString category; |
||||
QSet<QString> tags; |
||||
QString savePath; |
||||
bool disableTempPath = false; |
||||
bool sequential = false; |
||||
bool firstLastPiecePriority = false; |
||||
bool hasSeedStatus = false; |
||||
bool skipChecking = false; |
||||
bool hasRootFolder = true; |
||||
bool forced = false; |
||||
bool paused = false; |
||||
int uploadLimit = -1; |
||||
int downloadLimit = -1; |
||||
// for new torrents
|
||||
QVector<DownloadPriority> filePriorities; |
||||
QDateTime addedTime; |
||||
// for restored torrents
|
||||
qreal ratioLimit = TorrentHandle::USE_GLOBAL_RATIO; |
||||
int seedingTimeLimit = TorrentHandle::USE_GLOBAL_SEEDING_TIME; |
||||
|
||||
CreateTorrentParams() = default; |
||||
explicit CreateTorrentParams(const AddTorrentParams ¶ms); |
||||
}; |
||||
|
||||
enum class MoveStorageMode |
||||
{ |
||||
KeepExistingFiles, |
||||
Overwrite |
||||
}; |
||||
|
||||
class TorrentHandleImpl final : public QObject, public TorrentHandle |
||||
{ |
||||
Q_DISABLE_COPY(TorrentHandleImpl) |
||||
Q_DECLARE_TR_FUNCTIONS(BitTorrent::TorrentHandleImpl) |
||||
|
||||
public: |
||||
TorrentHandleImpl(Session *session, const lt::torrent_handle &nativeHandle, |
||||
const CreateTorrentParams ¶ms); |
||||
~TorrentHandleImpl() override; |
||||
|
||||
bool isValid() const; |
||||
|
||||
InfoHash hash() const override; |
||||
QString name() const override; |
||||
QDateTime creationDate() const override; |
||||
QString creator() const override; |
||||
QString comment() const override; |
||||
bool isPrivate() const override; |
||||
qlonglong totalSize() const override; |
||||
qlonglong wantedSize() const override; |
||||
qlonglong completedSize() const override; |
||||
qlonglong incompletedSize() const override; |
||||
qlonglong pieceLength() const override; |
||||
qlonglong wastedSize() const override; |
||||
QString currentTracker() const override; |
||||
|
||||
QString savePath(bool actual = false) const override; |
||||
QString rootPath(bool actual = false) const override; |
||||
QString contentPath(bool actual = false) const override; |
||||
|
||||
bool useTempPath() const override; |
||||
|
||||
bool isAutoTMMEnabled() const override; |
||||
void setAutoTMMEnabled(bool enabled) override; |
||||
QString category() const override; |
||||
bool belongsToCategory(const QString &category) const override; |
||||
bool setCategory(const QString &category) override; |
||||
|
||||
QSet<QString> tags() const override; |
||||
bool hasTag(const QString &tag) const override; |
||||
bool addTag(const QString &tag) override; |
||||
bool removeTag(const QString &tag) override; |
||||
void removeAllTags() override; |
||||
|
||||
bool hasRootFolder() const override; |
||||
|
||||
int filesCount() const override; |
||||
int piecesCount() const override; |
||||
int piecesHave() const override; |
||||
qreal progress() const override; |
||||
QDateTime addedTime() const override; |
||||
qreal ratioLimit() const override; |
||||
int seedingTimeLimit() const override; |
||||
|
||||
QString filePath(int index) const override; |
||||
QString fileName(int index) const override; |
||||
qlonglong fileSize(int index) const override; |
||||
QStringList absoluteFilePaths() const override; |
||||
QStringList absoluteFilePathsUnwanted() const override; |
||||
QVector<DownloadPriority> filePriorities() const override; |
||||
|
||||
TorrentInfo info() const override; |
||||
bool isSeed() const override; |
||||
bool isPaused() const override; |
||||
bool isResumed() const override; |
||||
bool isQueued() const override; |
||||
bool isForced() const override; |
||||
bool isChecking() const override; |
||||
bool isDownloading() const override; |
||||
bool isUploading() const override; |
||||
bool isCompleted() const override; |
||||
bool isActive() const override; |
||||
bool isInactive() const override; |
||||
bool isErrored() const override; |
||||
bool isSequentialDownload() const override; |
||||
bool hasFirstLastPiecePriority() const override; |
||||
TorrentState state() const override; |
||||
bool hasMetadata() const override; |
||||
bool hasMissingFiles() const override; |
||||
bool hasError() const override; |
||||
bool hasFilteredPieces() const override; |
||||
int queuePosition() const override; |
||||
QVector<TrackerEntry> trackers() const override; |
||||
QHash<QString, TrackerInfo> trackerInfos() const override; |
||||
QVector<QUrl> urlSeeds() const override; |
||||
QString error() const override; |
||||
qlonglong totalDownload() const override; |
||||
qlonglong totalUpload() const override; |
||||
qlonglong activeTime() const override; |
||||
qlonglong finishedTime() const override; |
||||
qlonglong seedingTime() const override; |
||||
qlonglong eta() const override; |
||||
QVector<qreal> filesProgress() const override; |
||||
int seedsCount() const override; |
||||
int peersCount() const override; |
||||
int leechsCount() const override; |
||||
int totalSeedsCount() const override; |
||||
int totalPeersCount() const override; |
||||
int totalLeechersCount() const override; |
||||
int completeCount() const override; |
||||
int incompleteCount() const override; |
||||
QDateTime lastSeenComplete() const override; |
||||
QDateTime completedTime() const override; |
||||
qlonglong timeSinceUpload() const override; |
||||
qlonglong timeSinceDownload() const override; |
||||
qlonglong timeSinceActivity() const override; |
||||
int downloadLimit() const override; |
||||
int uploadLimit() const override; |
||||
bool superSeeding() const override; |
||||
QVector<PeerInfo> peers() const override; |
||||
QBitArray pieces() const override; |
||||
QBitArray downloadingPieces() const override; |
||||
QVector<int> pieceAvailability() const override; |
||||
qreal distributedCopies() const override; |
||||
qreal maxRatio() const override; |
||||
int maxSeedingTime() const override; |
||||
qreal realRatio() const override; |
||||
int uploadPayloadRate() const override; |
||||
int downloadPayloadRate() const override; |
||||
qlonglong totalPayloadUpload() const override; |
||||
qlonglong totalPayloadDownload() const override; |
||||
int connectionsCount() const override; |
||||
int connectionsLimit() const override; |
||||
qlonglong nextAnnounce() const override; |
||||
QVector<qreal> availableFileFractions() const override; |
||||
|
||||
void setName(const QString &name) override; |
||||
void setSequentialDownload(bool enable) override; |
||||
void setFirstLastPiecePriority(bool enabled) override; |
||||
void pause() override; |
||||
void resume(bool forced = false) override; |
||||
void move(QString path) override; |
||||
void forceReannounce(int index = -1) override; |
||||
void forceDHTAnnounce() override; |
||||
void forceRecheck() override; |
||||
void renameFile(int index, const QString &name) override; |
||||
void prioritizeFiles(const QVector<DownloadPriority> &priorities) override; |
||||
void setRatioLimit(qreal limit) override; |
||||
void setSeedingTimeLimit(int limit) override; |
||||
void setUploadLimit(int limit) override; |
||||
void setDownloadLimit(int limit) override; |
||||
void setSuperSeeding(bool enable) override; |
||||
void flushCache() const override; |
||||
void addTrackers(const QVector<TrackerEntry> &trackers) override; |
||||
void replaceTrackers(const QVector<TrackerEntry> &trackers) override; |
||||
void addUrlSeeds(const QVector<QUrl> &urlSeeds) override; |
||||
void removeUrlSeeds(const QVector<QUrl> &urlSeeds) override; |
||||
bool connectPeer(const PeerAddress &peerAddress) override; |
||||
|
||||
QString createMagnetURI() const override; |
||||
|
||||
bool needSaveResumeData() const; |
||||
|
||||
// Session interface
|
||||
lt::torrent_handle nativeHandle() const; |
||||
|
||||
void handleAlert(const lt::alert *a); |
||||
void handleStateUpdate(const lt::torrent_status &nativeStatus); |
||||
void handleTempPathChanged(); |
||||
void handleCategorySavePathChanged(); |
||||
void handleAppendExtensionToggled(); |
||||
void saveResumeData(); |
||||
void handleStorageMoved(const QString &newPath, const QString &errorMessage); |
||||
|
||||
private: |
||||
typedef std::function<void ()> EventTrigger; |
||||
|
||||
#if (LIBTORRENT_VERSION_NUM < 10200) |
||||
using LTFileIndex = int; |
||||
#else |
||||
using LTFileIndex = lt::file_index_t; |
||||
#endif |
||||
|
||||
void updateStatus(); |
||||
void updateStatus(const lt::torrent_status &nativeStatus); |
||||
void updateState(); |
||||
void updateTorrentInfo(); |
||||
|
||||
void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert *p); |
||||
void handleFileCompletedAlert(const lt::file_completed_alert *p); |
||||
void handleFileRenamedAlert(const lt::file_renamed_alert *p); |
||||
void handleFileRenameFailedAlert(const lt::file_rename_failed_alert *p); |
||||
void handleMetadataReceivedAlert(const lt::metadata_received_alert *p); |
||||
void handlePerformanceAlert(const lt::performance_alert *p) const; |
||||
void handleSaveResumeDataAlert(const lt::save_resume_data_alert *p); |
||||
void handleSaveResumeDataFailedAlert(const lt::save_resume_data_failed_alert *p); |
||||
void handleTorrentCheckedAlert(const lt::torrent_checked_alert *p); |
||||
void handleTorrentFinishedAlert(const lt::torrent_finished_alert *p); |
||||
void handleTorrentPausedAlert(const lt::torrent_paused_alert *p); |
||||
void handleTorrentResumedAlert(const lt::torrent_resumed_alert *p); |
||||
void handleTrackerErrorAlert(const lt::tracker_error_alert *p); |
||||
void handleTrackerReplyAlert(const lt::tracker_reply_alert *p); |
||||
void handleTrackerWarningAlert(const lt::tracker_warning_alert *p); |
||||
|
||||
void resume_impl(bool forced); |
||||
bool isMoveInProgress() const; |
||||
QString actualStorageLocation() const; |
||||
bool isAutoManaged() const; |
||||
void setAutoManaged(bool enable); |
||||
|
||||
void adjustActualSavePath(); |
||||
void adjustActualSavePath_impl(); |
||||
void move_impl(QString path, MoveStorageMode mode); |
||||
void moveStorage(const QString &newPath, MoveStorageMode mode); |
||||
void manageIncompleteFiles(); |
||||
void setFirstLastPiecePriorityImpl(bool enabled, const QVector<DownloadPriority> &updatedFilePrio = {}); |
||||
|
||||
Session *const m_session; |
||||
lt::torrent_handle m_nativeHandle; |
||||
lt::torrent_status m_nativeStatus; |
||||
TorrentState m_state; |
||||
TorrentInfo m_torrentInfo; |
||||
SpeedMonitor m_speedMonitor; |
||||
|
||||
InfoHash m_hash; |
||||
|
||||
bool m_storageIsMoving = false; |
||||
// m_moveFinishedTriggers is activated only when the following conditions are met:
|
||||
// all file rename jobs complete, all file move jobs complete
|
||||
QQueue<EventTrigger> m_moveFinishedTriggers; |
||||
int m_renameCount; |
||||
|
||||
// Until libtorrent provide an "old_name" field in `file_renamed_alert`
|
||||
// we will rely on this workaround to remove empty leftover folders
|
||||
QHash<LTFileIndex, QVector<QString>> m_oldPath; |
||||
|
||||
bool m_useAutoTMM; |
||||
|
||||
// Persistent data
|
||||
QString m_name; |
||||
QString m_savePath; |
||||
QString m_category; |
||||
QSet<QString> m_tags; |
||||
bool m_hasSeedStatus; |
||||
qreal m_ratioLimit; |
||||
int m_seedingTimeLimit; |
||||
bool m_tempPathDisabled; |
||||
bool m_fastresumeDataRejected; |
||||
bool m_hasMissingFiles; |
||||
bool m_hasRootFolder; |
||||
bool m_needsToSetFirstLastPiecePriority; |
||||
|
||||
QHash<QString, TrackerInfo> m_trackerInfos; |
||||
|
||||
bool m_unchecked = false; |
||||
}; |
||||
} |
Loading…
Reference in new issue