Merge pull request #12513 from glassez/torrent-impl

Split TorrentHandle interface and implementation
This commit is contained in:
Vladimir Golovnev 2020-04-17 07:40:28 +03:00 committed by GitHub
commit 2681093d27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 2765 additions and 2538 deletions

View file

@ -61,6 +61,7 @@
#endif // Q_OS_MACOS
#endif
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/exceptions.h"

View file

@ -22,6 +22,7 @@ bittorrent/session.h
bittorrent/sessionstatus.h
bittorrent/torrentcreatorthread.h
bittorrent/torrenthandle.h
bittorrent/torrenthandleimpl.h
bittorrent/torrentinfo.h
bittorrent/tracker.h
bittorrent/trackerentry.h
@ -100,6 +101,7 @@ bittorrent/private/statistics.cpp
bittorrent/session.cpp
bittorrent/torrentcreatorthread.cpp
bittorrent/torrenthandle.cpp
bittorrent/torrenthandleimpl.cpp
bittorrent/torrentinfo.cpp
bittorrent/tracker.cpp
bittorrent/trackerentry.cpp

View file

@ -21,6 +21,7 @@ HEADERS += \
$$PWD/bittorrent/sessionstatus.h \
$$PWD/bittorrent/torrentcreatorthread.h \
$$PWD/bittorrent/torrenthandle.h \
$$PWD/bittorrent/torrenthandleimpl.h \
$$PWD/bittorrent/torrentinfo.h \
$$PWD/bittorrent/tracker.h \
$$PWD/bittorrent/trackerentry.h \
@ -99,6 +100,7 @@ SOURCES += \
$$PWD/bittorrent/session.cpp \
$$PWD/bittorrent/torrentcreatorthread.cpp \
$$PWD/bittorrent/torrenthandle.cpp \
$$PWD/bittorrent/torrenthandleimpl.cpp \
$$PWD/bittorrent/torrentinfo.cpp \
$$PWD/bittorrent/tracker.cpp \
$$PWD/bittorrent/trackerentry.cpp \

View file

@ -28,6 +28,8 @@
#include "peerinfo.h"
#include <libtorrent/version.hpp>
#include <QBitArray>
#include "base/bittorrent/torrenthandle.h"

View file

@ -101,7 +101,7 @@
#include "private/portforwarderimpl.h"
#include "private/resumedatasavingmanager.h"
#include "private/statistics.h"
#include "torrenthandle.h"
#include "torrenthandleimpl.h"
#include "tracker.h"
#include "trackerentry.h"
@ -664,7 +664,7 @@ void Session::setTempPathEnabled(const bool enabled)
{
if (enabled != isTempPathEnabled()) {
m_isTempPathEnabled = enabled;
for (TorrentHandle *const torrent : asConst(m_torrents))
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
torrent->handleTempPathChanged();
}
}
@ -678,7 +678,7 @@ void Session::setAppendExtensionEnabled(const bool enabled)
{
if (isAppendExtensionEnabled() != enabled) {
// append or remove .!qB extension for incomplete files
for (TorrentHandle *const torrent : asConst(m_torrents))
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
torrent->handleAppendExtensionToggled();
m_isAppendExtensionEnabled = enabled;
@ -829,12 +829,12 @@ bool Session::editCategory(const QString &name, const QString &savePath)
m_categories[name] = savePath;
m_storedCategories = map_cast(m_categories);
if (isDisableAutoTMMWhenCategorySavePathChanged()) {
for (TorrentHandle *const torrent : asConst(torrents()))
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
if (torrent->category() == name)
torrent->setAutoTMMEnabled(false);
}
else {
for (TorrentHandle *const torrent : asConst(torrents()))
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
if (torrent->category() == name)
torrent->handleCategorySavePathChanged();
}
@ -844,7 +844,7 @@ bool Session::editCategory(const QString &name, const QString &savePath)
bool Session::removeCategory(const QString &name)
{
for (TorrentHandle *const torrent : asConst(torrents()))
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
if (torrent->belongsToCategory(name))
torrent->setCategory("");
@ -931,7 +931,7 @@ bool Session::addTag(const QString &tag)
bool Session::removeTag(const QString &tag)
{
if (m_tags.remove(tag)) {
for (TorrentHandle *const torrent : asConst(torrents()))
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
torrent->removeTag(tag);
m_storedTags = m_tags.values();
emit tagRemoved(tag);
@ -1707,7 +1707,7 @@ void Session::processShareLimits()
{
qDebug("Processing share limits...");
for (TorrentHandle *const torrent : asConst(torrents())) {
for (TorrentHandleImpl *const torrent : asConst(m_torrents)) {
if (torrent->isSeed() && !torrent->isForced()) {
if (torrent->ratioLimit() != TorrentHandle::NO_RATIO_LIMIT) {
const qreal ratio = torrent->realRatio();
@ -1799,7 +1799,7 @@ TorrentHandle *Session::findTorrent(const InfoHash &hash) const
bool Session::hasActiveTorrents() const
{
return std::any_of(m_torrents.begin(), m_torrents.end(), [](TorrentHandle *torrent)
return std::any_of(m_torrents.begin(), m_torrents.end(), [](TorrentHandleImpl *torrent)
{
return TorrentFilter::ActiveTorrent.match(torrent);
});
@ -1807,7 +1807,7 @@ bool Session::hasActiveTorrents() const
bool Session::hasUnfinishedTorrents() const
{
return std::any_of(m_torrents.begin(), m_torrents.end(), [](const TorrentHandle *torrent)
return std::any_of(m_torrents.begin(), m_torrents.end(), [](const TorrentHandleImpl *torrent)
{
return (!torrent->isSeed() && !torrent->isPaused());
});
@ -1815,7 +1815,7 @@ bool Session::hasUnfinishedTorrents() const
bool Session::hasRunningSeed() const
{
return std::any_of(m_torrents.begin(), m_torrents.end(), [](const TorrentHandle *torrent)
return std::any_of(m_torrents.begin(), m_torrents.end(), [](const TorrentHandleImpl *torrent)
{
return (torrent->isSeed() && !torrent->isPaused());
});
@ -1843,7 +1843,7 @@ void Session::banIP(const QString &ip)
// and from the disk, if the corresponding deleteOption is chosen
bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOption)
{
TorrentHandle *const torrent = m_torrents.take(hash);
TorrentHandleImpl *const torrent = m_torrents.take(hash);
if (!torrent) return false;
qDebug("Deleting torrent with hash: %s", qUtf8Printable(torrent->hash()));
@ -1928,21 +1928,21 @@ bool Session::cancelLoadMetadata(const InfoHash &hash)
void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
{
using ElementType = std::pair<int, TorrentHandle *>;
using ElementType = std::pair<int, TorrentHandleImpl *>;
std::priority_queue<ElementType
, std::vector<ElementType>
, std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position
for (const InfoHash &infoHash : hashes) {
TorrentHandle *const torrent = m_torrents.value(infoHash);
TorrentHandleImpl *const torrent = m_torrents.value(infoHash);
if (torrent && !torrent->isSeed())
torrentQueue.emplace(torrent->queuePosition(), torrent);
}
// Increase torrents queue position (starting with the one in the highest queue position)
while (!torrentQueue.empty()) {
const TorrentHandle *torrent = torrentQueue.top().second;
const TorrentHandleImpl *torrent = torrentQueue.top().second;
torrentQueuePositionUp(torrent->nativeHandle());
torrentQueue.pop();
}
@ -1952,19 +1952,19 @@ void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
{
using ElementType = std::pair<int, TorrentHandle *>;
using ElementType = std::pair<int, TorrentHandleImpl *>;
std::priority_queue<ElementType> torrentQueue;
// Sort torrents by queue position
for (const InfoHash &infoHash : hashes) {
TorrentHandle *const torrent = m_torrents.value(infoHash);
TorrentHandleImpl *const torrent = m_torrents.value(infoHash);
if (torrent && !torrent->isSeed())
torrentQueue.emplace(torrent->queuePosition(), torrent);
}
// Decrease torrents queue position (starting with the one in the lowest queue position)
while (!torrentQueue.empty()) {
const TorrentHandle *torrent = torrentQueue.top().second;
const TorrentHandleImpl *torrent = torrentQueue.top().second;
torrentQueuePositionDown(torrent->nativeHandle());
torrentQueue.pop();
}
@ -1977,19 +1977,19 @@ void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
{
using ElementType = std::pair<int, TorrentHandle *>;
using ElementType = std::pair<int, TorrentHandleImpl *>;
std::priority_queue<ElementType> torrentQueue;
// Sort torrents by queue position
for (const InfoHash &infoHash : hashes) {
TorrentHandle *const torrent = m_torrents.value(infoHash);
TorrentHandleImpl *const torrent = m_torrents.value(infoHash);
if (torrent && !torrent->isSeed())
torrentQueue.emplace(torrent->queuePosition(), torrent);
}
// Top torrents queue position (starting with the one in the lowest queue position)
while (!torrentQueue.empty()) {
const TorrentHandle *torrent = torrentQueue.top().second;
const TorrentHandleImpl *torrent = torrentQueue.top().second;
torrentQueuePositionTop(torrent->nativeHandle());
torrentQueue.pop();
}
@ -1999,21 +1999,21 @@ void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
{
using ElementType = std::pair<int, TorrentHandle *>;
using ElementType = std::pair<int, TorrentHandleImpl *>;
std::priority_queue<ElementType
, std::vector<ElementType>
, std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position
for (const InfoHash &infoHash : hashes) {
TorrentHandle *const torrent = m_torrents.value(infoHash);
TorrentHandleImpl *const torrent = m_torrents.value(infoHash);
if (torrent && !torrent->isSeed())
torrentQueue.emplace(torrent->queuePosition(), torrent);
}
// Bottom torrents queue position (starting with the one in the highest queue position)
while (!torrentQueue.empty()) {
const TorrentHandle *torrent = torrentQueue.top().second;
const TorrentHandleImpl *torrent = torrentQueue.top().second;
torrentQueuePositionBottom(torrent->nativeHandle());
torrentQueue.pop();
}
@ -2024,15 +2024,20 @@ void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
saveTorrentsQueue();
}
void Session::handleTorrentSaveResumeDataRequested(const TorrentHandle *torrent)
void Session::handleTorrentSaveResumeDataRequested(const TorrentHandleImpl *torrent)
{
qDebug("Saving resume data is requested for torrent '%s'...", qUtf8Printable(torrent->name()));
++m_numResumeData;
}
QHash<InfoHash, TorrentHandle *> Session::torrents() const
QVector<TorrentHandle *> Session::torrents() const
{
return m_torrents;
QVector<TorrentHandle *> result;
result.reserve(m_torrents.size());
for (TorrentHandleImpl *torrent : asConst(m_torrents))
result << torrent;
return result;
}
bool Session::addTorrent(const QString &source, const AddTorrentParams &params)
@ -2333,7 +2338,7 @@ bool Session::addTorrent_impl(CreateTorrentParams params, const MagnetUri &magne
if (m_addingTorrents.contains(hash) || m_loadedMetadata.contains(hash))
return false;
TorrentHandle *const torrent = m_torrents.value(hash);
TorrentHandleImpl *const torrent = m_torrents.value(hash);
if (torrent) { // a duplicate torrent is added
if (torrent->isPrivate() || (!fromMagnetUri && torrentInfo.isPrivate()))
return false;
@ -2519,7 +2524,7 @@ bool Session::loadMetadata(const MagnetUri &magnetUri)
return true;
}
void Session::exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolder folder)
void Session::exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolder folder)
{
Q_ASSERT(((folder == TorrentExportFolder::Regular) && !torrentExportDirectory().isEmpty()) ||
((folder == TorrentExportFolder::Finished) && !finishedTorrentExportDirectory().isEmpty()));
@ -2545,7 +2550,7 @@ void Session::exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolde
void Session::generateResumeData(const bool final)
{
for (TorrentHandle *const torrent : asConst(m_torrents)) {
for (TorrentHandleImpl *const torrent : asConst(m_torrents)) {
if (!torrent->isValid()) continue;
if (!final && !torrent->needSaveResumeData()) continue;
@ -2592,7 +2597,7 @@ void Session::saveTorrentsQueue()
{
// store hash in textual representation
QMap<int, QString> queue; // Use QMap since it should be ordered by key
for (const TorrentHandle *torrent : asConst(torrents())) {
for (const TorrentHandleImpl *torrent : asConst(m_torrents)) {
// We require actual (non-cached) queue position here!
const int queuePos = LTUnderlyingType<LTQueuePosition> {torrent->nativeHandle().queue_position()};
if (queuePos >= 0)
@ -2633,10 +2638,10 @@ void Session::setDefaultSavePath(QString path)
m_defaultSavePath = path;
if (isDisableAutoTMMWhenDefaultSavePathChanged())
for (TorrentHandle *const torrent : asConst(torrents()))
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
torrent->setAutoTMMEnabled(false);
else
for (TorrentHandle *const torrent : asConst(torrents()))
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
torrent->handleCategorySavePathChanged();
}
@ -2647,7 +2652,7 @@ void Session::setTempPath(QString path)
m_tempPath = path;
for (TorrentHandle *const torrent : asConst(m_torrents))
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
torrent->handleTempPathChanged();
}
@ -3822,48 +3827,48 @@ void Session::updateSeedingLimitTimer()
}
}
void Session::handleTorrentShareLimitChanged(TorrentHandle *const torrent)
void Session::handleTorrentShareLimitChanged(TorrentHandleImpl *const torrent)
{
torrent->saveResumeData();
updateSeedingLimitTimer();
}
void Session::handleTorrentNameChanged(TorrentHandle *const torrent)
void Session::handleTorrentNameChanged(TorrentHandleImpl *const torrent)
{
torrent->saveResumeData();
}
void Session::handleTorrentSavePathChanged(TorrentHandle *const torrent)
void Session::handleTorrentSavePathChanged(TorrentHandleImpl *const torrent)
{
torrent->saveResumeData();
emit torrentSavePathChanged(torrent);
}
void Session::handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory)
void Session::handleTorrentCategoryChanged(TorrentHandleImpl *const torrent, const QString &oldCategory)
{
torrent->saveResumeData();
emit torrentCategoryChanged(torrent, oldCategory);
}
void Session::handleTorrentTagAdded(TorrentHandle *const torrent, const QString &tag)
void Session::handleTorrentTagAdded(TorrentHandleImpl *const torrent, const QString &tag)
{
torrent->saveResumeData();
emit torrentTagAdded(torrent, tag);
}
void Session::handleTorrentTagRemoved(TorrentHandle *const torrent, const QString &tag)
void Session::handleTorrentTagRemoved(TorrentHandleImpl *const torrent, const QString &tag)
{
torrent->saveResumeData();
emit torrentTagRemoved(torrent, tag);
}
void Session::handleTorrentSavingModeChanged(TorrentHandle *const torrent)
void Session::handleTorrentSavingModeChanged(TorrentHandleImpl *const torrent)
{
torrent->saveResumeData();
emit torrentSavingModeChanged(torrent);
}
void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QVector<TrackerEntry> &newTrackers)
void Session::handleTorrentTrackersAdded(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &newTrackers)
{
torrent->saveResumeData();
@ -3875,7 +3880,7 @@ void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QVe
emit trackersChanged(torrent);
}
void Session::handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QVector<TrackerEntry> &deletedTrackers)
void Session::handleTorrentTrackersRemoved(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers)
{
torrent->saveResumeData();
@ -3887,27 +3892,27 @@ void Session::handleTorrentTrackersRemoved(TorrentHandle *const torrent, const Q
emit trackersChanged(torrent);
}
void Session::handleTorrentTrackersChanged(TorrentHandle *const torrent)
void Session::handleTorrentTrackersChanged(TorrentHandleImpl *const torrent)
{
torrent->saveResumeData();
emit trackersChanged(torrent);
}
void Session::handleTorrentUrlSeedsAdded(TorrentHandle *const torrent, const QVector<QUrl> &newUrlSeeds)
void Session::handleTorrentUrlSeedsAdded(TorrentHandleImpl *const torrent, const QVector<QUrl> &newUrlSeeds)
{
torrent->saveResumeData();
for (const QUrl &newUrlSeed : newUrlSeeds)
LogMsg(tr("URL seed '%1' was added to torrent '%2'").arg(newUrlSeed.toString(), torrent->name()));
}
void Session::handleTorrentUrlSeedsRemoved(TorrentHandle *const torrent, const QVector<QUrl> &urlSeeds)
void Session::handleTorrentUrlSeedsRemoved(TorrentHandleImpl *const torrent, const QVector<QUrl> &urlSeeds)
{
torrent->saveResumeData();
for (const QUrl &urlSeed : urlSeeds)
LogMsg(tr("URL seed '%1' was removed from torrent '%2'").arg(urlSeed.toString(), torrent->name()));
}
void Session::handleTorrentMetadataReceived(TorrentHandle *const torrent)
void Session::handleTorrentMetadataReceived(TorrentHandleImpl *const torrent)
{
torrent->saveResumeData();
@ -3928,25 +3933,25 @@ void Session::handleTorrentMetadataReceived(TorrentHandle *const torrent)
emit torrentMetadataLoaded(torrent);
}
void Session::handleTorrentPaused(TorrentHandle *const torrent)
void Session::handleTorrentPaused(TorrentHandleImpl *const torrent)
{
if (!torrent->hasError() && !torrent->hasMissingFiles())
torrent->saveResumeData();
emit torrentPaused(torrent);
}
void Session::handleTorrentResumed(TorrentHandle *const torrent)
void Session::handleTorrentResumed(TorrentHandleImpl *const torrent)
{
torrent->saveResumeData();
emit torrentResumed(torrent);
}
void Session::handleTorrentChecked(TorrentHandle *const torrent)
void Session::handleTorrentChecked(TorrentHandleImpl *const torrent)
{
emit torrentFinishedChecking(torrent);
}
void Session::handleTorrentFinished(TorrentHandle *const torrent)
void Session::handleTorrentFinished(TorrentHandleImpl *const torrent)
{
if (!torrent->hasError() && !torrent->hasMissingFiles())
torrent->saveResumeData();
@ -3981,7 +3986,7 @@ void Session::handleTorrentFinished(TorrentHandle *const torrent)
emit allTorrentsFinished();
}
void Session::handleTorrentResumeDataReady(TorrentHandle *const torrent, const std::shared_ptr<lt::entry> &data)
void Session::handleTorrentResumeDataReady(TorrentHandleImpl *const torrent, const std::shared_ptr<lt::entry> &data)
{
--m_numResumeData;
@ -3998,23 +4003,23 @@ void Session::handleTorrentResumeDataReady(TorrentHandle *const torrent, const s
#endif
}
void Session::handleTorrentResumeDataFailed(TorrentHandle *const torrent)
void Session::handleTorrentResumeDataFailed(TorrentHandleImpl *const torrent)
{
Q_UNUSED(torrent)
--m_numResumeData;
}
void Session::handleTorrentTrackerReply(TorrentHandle *const torrent, const QString &trackerUrl)
void Session::handleTorrentTrackerReply(TorrentHandleImpl *const torrent, const QString &trackerUrl)
{
emit trackerSuccess(torrent, trackerUrl);
}
void Session::handleTorrentTrackerError(TorrentHandle *const torrent, const QString &trackerUrl)
void Session::handleTorrentTrackerError(TorrentHandleImpl *const torrent, const QString &trackerUrl)
{
emit trackerError(torrent, trackerUrl);
}
bool Session::addMoveTorrentStorageJob(TorrentHandle *torrent, const QString &newPath, const MoveStorageMode mode)
bool Session::addMoveTorrentStorageJob(TorrentHandleImpl *torrent, const QString &newPath, const MoveStorageMode mode)
{
Q_ASSERT(torrent);
@ -4087,14 +4092,14 @@ void Session::handleMoveTorrentStorageJobFinished(const QString &errorMessage)
}
}
void Session::handleTorrentTrackerWarning(TorrentHandle *const torrent, const QString &trackerUrl)
void Session::handleTorrentTrackerWarning(TorrentHandleImpl *const torrent, const QString &trackerUrl)
{
emit trackerWarning(torrent, trackerUrl);
}
bool Session::hasPerTorrentRatioLimit() const
{
return std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentHandle *torrent)
return std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentHandleImpl *torrent)
{
return (torrent->ratioLimit() >= 0);
});
@ -4102,7 +4107,7 @@ bool Session::hasPerTorrentRatioLimit() const
bool Session::hasPerTorrentSeedingTimeLimit() const
{
return std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentHandle *torrent)
return std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentHandleImpl *torrent)
{
return (torrent->seedingTimeLimit() >= 0);
});
@ -4176,7 +4181,7 @@ void Session::disableIPFilter()
void Session::recursiveTorrentDownload(const InfoHash &hash)
{
TorrentHandle *const torrent = m_torrents.value(hash);
TorrentHandleImpl *const torrent = m_torrents.value(hash);
if (!torrent) return;
for (int i = 0; i < torrent->filesCount(); ++i) {
@ -4486,7 +4491,7 @@ void Session::handleAlert(const lt::alert *a)
void Session::dispatchTorrentAlert(const lt::alert *a)
{
TorrentHandle *const torrent = m_torrents.value(static_cast<const lt::torrent_alert*>(a)->handle.info_hash());
TorrentHandleImpl *const torrent = m_torrents.value(static_cast<const lt::torrent_alert*>(a)->handle.info_hash());
if (torrent) {
torrent->handleAlert(a);
return;
@ -4506,7 +4511,7 @@ void Session::createTorrentHandle(const lt::torrent_handle &nativeHandle)
const CreateTorrentParams params = m_addingTorrents.take(nativeHandle.info_hash());
TorrentHandle *const torrent = new TorrentHandle(this, nativeHandle, params);
TorrentHandleImpl *const torrent = new TorrentHandleImpl(this, nativeHandle, params);
m_torrents.insert(torrent->hash(), torrent);
const bool fromMagnetUri = !torrent->hasMetadata();
@ -4650,7 +4655,7 @@ void Session::handleMetadataReceivedAlert(const lt::metadata_received_alert *p)
void Session::handleFileErrorAlert(const lt::file_error_alert *p)
{
TorrentHandle *const torrent = m_torrents.value(p->handle.info_hash());
TorrentHandleImpl *const torrent = m_torrents.value(p->handle.info_hash());
if (!torrent)
return;
@ -4744,7 +4749,7 @@ void Session::handlePeerBanAlert(const lt::peer_ban_alert *p)
void Session::handleUrlSeedAlert(const lt::url_seed_alert *p)
{
const TorrentHandle *torrent = m_torrents.value(p->handle.info_hash());
const TorrentHandleImpl *torrent = m_torrents.value(p->handle.info_hash());
if (!torrent)
return;
@ -4975,7 +4980,7 @@ void Session::handleStorageMovedAlert(const lt::storage_moved_alert *p)
{
if (m_moveStorageQueue.isEmpty()) return;
const TorrentHandle *torrent = m_torrents.value(p->handle.info_hash());
const TorrentHandleImpl *torrent = m_torrents.value(p->handle.info_hash());
const MoveStorageJob &currentJob = m_moveStorageQueue.first();
if (currentJob.torrent != torrent) return;
@ -4987,7 +4992,7 @@ void Session::handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert
{
if (m_moveStorageQueue.isEmpty()) return;
const TorrentHandle *torrent = m_torrents.value(p->handle.info_hash());
const TorrentHandleImpl *torrent = m_torrents.value(p->handle.info_hash());
const MoveStorageJob &currentJob = m_moveStorageQueue.first();
if (currentJob.torrent != torrent) return;
@ -5000,7 +5005,7 @@ void Session::handleStateUpdateAlert(const lt::state_update_alert *p)
updatedTorrents.reserve(p->status.size());
for (const lt::torrent_status &status : p->status) {
TorrentHandle *const torrent = m_torrents.value(status.info_hash);
TorrentHandleImpl *const torrent = m_torrents.value(status.info_hash);
if (!torrent)
continue;

View file

@ -93,6 +93,7 @@ namespace BitTorrent
class InfoHash;
class MagnetUri;
class TorrentHandle;
class TorrentHandleImpl;
class Tracker;
class TrackerEntry;
struct CreateTorrentParams;
@ -411,7 +412,7 @@ namespace BitTorrent
void startUpTorrents();
TorrentHandle *findTorrent(const InfoHash &hash) const;
QHash<InfoHash, TorrentHandle *> torrents() const;
QVector<TorrentHandle *> torrents() const;
bool hasActiveTorrents() const;
bool hasUnfinishedTorrents() const;
bool hasRunningSeed() const;
@ -440,31 +441,31 @@ namespace BitTorrent
void bottomTorrentsQueuePos(const QVector<InfoHash> &hashes);
// TorrentHandle interface
void handleTorrentSaveResumeDataRequested(const TorrentHandle *torrent);
void handleTorrentShareLimitChanged(TorrentHandle *const torrent);
void handleTorrentNameChanged(TorrentHandle *const torrent);
void handleTorrentSavePathChanged(TorrentHandle *const torrent);
void handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory);
void handleTorrentTagAdded(TorrentHandle *const torrent, const QString &tag);
void handleTorrentTagRemoved(TorrentHandle *const torrent, const QString &tag);
void handleTorrentSavingModeChanged(TorrentHandle *const torrent);
void handleTorrentMetadataReceived(TorrentHandle *const torrent);
void handleTorrentPaused(TorrentHandle *const torrent);
void handleTorrentResumed(TorrentHandle *const torrent);
void handleTorrentChecked(TorrentHandle *const torrent);
void handleTorrentFinished(TorrentHandle *const torrent);
void handleTorrentTrackersAdded(TorrentHandle *const torrent, const QVector<TrackerEntry> &newTrackers);
void handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QVector<TrackerEntry> &deletedTrackers);
void handleTorrentTrackersChanged(TorrentHandle *const torrent);
void handleTorrentUrlSeedsAdded(TorrentHandle *const torrent, const QVector<QUrl> &newUrlSeeds);
void handleTorrentUrlSeedsRemoved(TorrentHandle *const torrent, const QVector<QUrl> &urlSeeds);
void handleTorrentResumeDataReady(TorrentHandle *const torrent, const std::shared_ptr<lt::entry> &data);
void handleTorrentResumeDataFailed(TorrentHandle *const torrent);
void handleTorrentTrackerReply(TorrentHandle *const torrent, const QString &trackerUrl);
void handleTorrentTrackerWarning(TorrentHandle *const torrent, const QString &trackerUrl);
void handleTorrentTrackerError(TorrentHandle *const torrent, const QString &trackerUrl);
void handleTorrentSaveResumeDataRequested(const TorrentHandleImpl *torrent);
void handleTorrentShareLimitChanged(TorrentHandleImpl *const torrent);
void handleTorrentNameChanged(TorrentHandleImpl *const torrent);
void handleTorrentSavePathChanged(TorrentHandleImpl *const torrent);
void handleTorrentCategoryChanged(TorrentHandleImpl *const torrent, const QString &oldCategory);
void handleTorrentTagAdded(TorrentHandleImpl *const torrent, const QString &tag);
void handleTorrentTagRemoved(TorrentHandleImpl *const torrent, const QString &tag);
void handleTorrentSavingModeChanged(TorrentHandleImpl *const torrent);
void handleTorrentMetadataReceived(TorrentHandleImpl *const torrent);
void handleTorrentPaused(TorrentHandleImpl *const torrent);
void handleTorrentResumed(TorrentHandleImpl *const torrent);
void handleTorrentChecked(TorrentHandleImpl *const torrent);
void handleTorrentFinished(TorrentHandleImpl *const torrent);
void handleTorrentTrackersAdded(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &newTrackers);
void handleTorrentTrackersRemoved(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers);
void handleTorrentTrackersChanged(TorrentHandleImpl *const torrent);
void handleTorrentUrlSeedsAdded(TorrentHandleImpl *const torrent, const QVector<QUrl> &newUrlSeeds);
void handleTorrentUrlSeedsRemoved(TorrentHandleImpl *const torrent, const QVector<QUrl> &urlSeeds);
void handleTorrentResumeDataReady(TorrentHandleImpl *const torrent, const std::shared_ptr<lt::entry> &data);
void handleTorrentResumeDataFailed(TorrentHandleImpl *const torrent);
void handleTorrentTrackerReply(TorrentHandleImpl *const torrent, const QString &trackerUrl);
void handleTorrentTrackerWarning(TorrentHandleImpl *const torrent, const QString &trackerUrl);
void handleTorrentTrackerError(TorrentHandleImpl *const torrent, const QString &trackerUrl);
bool addMoveTorrentStorageJob(TorrentHandle *torrent, const QString &newPath, MoveStorageMode mode);
bool addMoveTorrentStorageJob(TorrentHandleImpl *torrent, const QString &newPath, MoveStorageMode mode);
signals:
void addTorrentFailed(const QString &error);
@ -521,7 +522,7 @@ namespace BitTorrent
private:
struct MoveStorageJob
{
TorrentHandle *torrent;
TorrentHandleImpl *torrent;
QString path;
MoveStorageMode mode;
};
@ -571,7 +572,7 @@ namespace BitTorrent
bool findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const;
void updateSeedingLimitTimer();
void exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
void exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
void handleAlert(const lt::alert *a);
void dispatchTorrentAlert(const lt::alert *a);
@ -733,7 +734,7 @@ namespace BitTorrent
ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
QHash<InfoHash, TorrentInfo> m_loadedMetadata;
QHash<InfoHash, TorrentHandle *> m_torrents;
QHash<InfoHash, TorrentHandleImpl *> m_torrents;
QHash<InfoHash, CreateTorrentParams> m_addingTorrents;
QHash<QString, AddTorrentParams> m_downloadedTorrents;
QHash<InfoHash, RemovingTorrentData> m_removingTorrents;

File diff suppressed because it is too large Load diff

View file

@ -27,84 +27,30 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_TORRENTHANDLE_H
#define BITTORRENT_TORRENTHANDLE_H
#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 <QMetaType>
#include <QSet>
#include <QString>
#include <QVector>
#include "private/speedmonitor.h"
#include "infohash.h"
#include "torrentinfo.h"
extern const QString QB_EXT;
class QBitArray;
class QDateTime;
class QStringList;
class QUrl;
extern const QString QB_EXT;
namespace BitTorrent
{
enum class DownloadPriority;
class InfoHash;
class PeerInfo;
class Session;
class TorrentInfo;
class TrackerEntry;
struct AddTorrentParams;
struct PeerAddress;
struct CreateTorrentParams
{
bool restored; // is existing torrent job?
// for both new and restored torrents
QString name;
QString category;
QSet<QString> tags;
QString savePath;
bool disableTempPath;
bool sequential;
bool firstLastPiecePriority;
bool hasSeedStatus;
bool skipChecking;
bool hasRootFolder;
bool forced;
bool paused;
int uploadLimit;
int downloadLimit;
// for new torrents
QVector<DownloadPriority> filePriorities;
QDateTime addedTime;
// for restored torrents
qreal ratioLimit;
int seedingTimeLimit;
CreateTorrentParams();
explicit CreateTorrentParams(const AddTorrentParams &params);
};
struct TrackerInfo
{
QString lastMessage;
int numPeers = 0;
};
enum class MoveStorageMode
{
KeepExistingFiles,
Overwrite
};
enum class TorrentState
{
Unknown = -1,
@ -135,13 +81,16 @@ namespace BitTorrent
Error
};
struct TrackerInfo
{
QString lastMessage;
int numPeers = 0;
};
uint qHash(TorrentState key, uint seed);
class TorrentHandle : public QObject
class TorrentHandle
{
Q_DISABLE_COPY(TorrentHandle)
Q_DECLARE_TR_FUNCTIONS(BitTorrent::TorrentHandle)
public:
static const qreal USE_GLOBAL_RATIO;
static const qreal NO_RATIO_LIMIT;
@ -152,24 +101,21 @@ namespace BitTorrent
static const qreal MAX_RATIO;
static const int MAX_SEEDING_TIME;
TorrentHandle(Session *session, const lt::torrent_handle &nativeHandle,
const CreateTorrentParams &params);
~TorrentHandle();
virtual ~TorrentHandle() = default;
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;
virtual InfoHash hash() const = 0;
virtual QString name() const = 0;
virtual QDateTime creationDate() const = 0;
virtual QString creator() const = 0;
virtual QString comment() const = 0;
virtual bool isPrivate() const = 0;
virtual qlonglong totalSize() const = 0;
virtual qlonglong wantedSize() const = 0;
virtual qlonglong completedSize() const = 0;
virtual qlonglong incompletedSize() const = 0;
virtual qlonglong pieceLength() const = 0;
virtual qlonglong wastedSize() const = 0;
virtual QString currentTracker() const = 0;
// 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).
@ -214,237 +160,140 @@ namespace BitTorrent
// | 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;
virtual QString savePath(bool actual = false) const = 0;
virtual QString rootPath(bool actual = false) const = 0;
virtual QString contentPath(bool actual = false) const = 0;
bool useTempPath() const;
virtual bool useTempPath() const = 0;
bool isAutoTMMEnabled() const;
void setAutoTMMEnabled(bool enabled);
QString category() const;
bool belongsToCategory(const QString &category) const;
bool setCategory(const QString &category);
virtual bool isAutoTMMEnabled() const = 0;
virtual void setAutoTMMEnabled(bool enabled) = 0;
virtual QString category() const = 0;
virtual bool belongsToCategory(const QString &category) const = 0;
virtual bool setCategory(const QString &category) = 0;
QSet<QString> tags() const;
bool hasTag(const QString &tag) const;
bool addTag(const QString &tag);
bool removeTag(const QString &tag);
void removeAllTags();
virtual QSet<QString> tags() const = 0;
virtual bool hasTag(const QString &tag) const = 0;
virtual bool addTag(const QString &tag) = 0;
virtual bool removeTag(const QString &tag) = 0;
virtual void removeAllTags() = 0;
bool hasRootFolder() const;
virtual bool hasRootFolder() const = 0;
int filesCount() const;
int piecesCount() const;
int piecesHave() const;
qreal progress() const;
QDateTime addedTime() const;
qreal ratioLimit() const;
int seedingTimeLimit() const;
virtual int filesCount() const = 0;
virtual int piecesCount() const = 0;
virtual int piecesHave() const = 0;
virtual qreal progress() const = 0;
virtual QDateTime addedTime() const = 0;
virtual qreal ratioLimit() const = 0;
virtual int seedingTimeLimit() const = 0;
QString filePath(int index) const;
QString fileName(int index) const;
qlonglong fileSize(int index) const;
QStringList absoluteFilePaths() const;
QStringList absoluteFilePathsUnwanted() const;
QVector<DownloadPriority> 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;
QVector<TrackerEntry> trackers() const;
QHash<QString, TrackerInfo> trackerInfos() const;
QVector<QUrl> urlSeeds() const;
QString error() const;
qlonglong totalDownload() const;
qlonglong totalUpload() const;
qlonglong activeTime() const;
qlonglong finishedTime() const;
qlonglong seedingTime() const;
qlonglong eta() const;
QVector<qreal> 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;
qlonglong timeSinceUpload() const;
qlonglong timeSinceDownload() const;
qlonglong timeSinceActivity() const;
int downloadLimit() const;
int uploadLimit() const;
bool superSeeding() const;
QVector<PeerInfo> peers() const;
QBitArray pieces() const;
QBitArray downloadingPieces() const;
QVector<int> 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 enable);
void toggleSequentialDownload();
void setFirstLastPiecePriority(bool enabled);
void toggleFirstLastPiecePriority();
void pause();
void resume(bool forced = false);
void move(QString path);
void forceReannounce(int index = -1);
void forceDHTAnnounce();
void forceRecheck();
void renameFile(int index, const QString &name);
void prioritizeFiles(const QVector<DownloadPriority> &priorities);
void setRatioLimit(qreal limit);
void setSeedingTimeLimit(int limit);
void setUploadLimit(int limit);
void setDownloadLimit(int limit);
void setSuperSeeding(bool enable);
void flushCache() const;
void addTrackers(const QVector<TrackerEntry> &trackers);
void replaceTrackers(const QVector<TrackerEntry> &trackers);
void addUrlSeeds(const QVector<QUrl> &urlSeeds);
void removeUrlSeeds(const QVector<QUrl> &urlSeeds);
bool connectPeer(const PeerAddress &peerAddress);
QString toMagnetUri() const;
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);
virtual QString filePath(int index) const = 0;
virtual QString fileName(int index) const = 0;
virtual qlonglong fileSize(int index) const = 0;
virtual QStringList absoluteFilePaths() const = 0;
virtual QStringList absoluteFilePathsUnwanted() const = 0;
virtual QVector<DownloadPriority> filePriorities() const = 0;
virtual TorrentInfo info() const = 0;
virtual bool isSeed() const = 0;
virtual bool isPaused() const = 0;
virtual bool isResumed() const = 0;
virtual bool isQueued() const = 0;
virtual bool isForced() const = 0;
virtual bool isChecking() const = 0;
virtual bool isDownloading() const = 0;
virtual bool isUploading() const = 0;
virtual bool isCompleted() const = 0;
virtual bool isActive() const = 0;
virtual bool isInactive() const = 0;
virtual bool isErrored() const = 0;
virtual bool isSequentialDownload() const = 0;
virtual bool hasFirstLastPiecePriority() const = 0;
virtual TorrentState state() const = 0;
virtual bool hasMetadata() const = 0;
virtual bool hasMissingFiles() const = 0;
virtual bool hasError() const = 0;
virtual bool hasFilteredPieces() const = 0;
virtual int queuePosition() const = 0;
virtual QVector<TrackerEntry> trackers() const = 0;
virtual QHash<QString, TrackerInfo> trackerInfos() const = 0;
virtual QVector<QUrl> urlSeeds() const = 0;
virtual QString error() const = 0;
virtual qlonglong totalDownload() const = 0;
virtual qlonglong totalUpload() const = 0;
virtual qlonglong activeTime() const = 0;
virtual qlonglong finishedTime() const = 0;
virtual qlonglong seedingTime() const = 0;
virtual qlonglong eta() const = 0;
virtual QVector<qreal> filesProgress() const = 0;
virtual int seedsCount() const = 0;
virtual int peersCount() const = 0;
virtual int leechsCount() const = 0;
virtual int totalSeedsCount() const = 0;
virtual int totalPeersCount() const = 0;
virtual int totalLeechersCount() const = 0;
virtual int completeCount() const = 0;
virtual int incompleteCount() const = 0;
virtual QDateTime lastSeenComplete() const = 0;
virtual QDateTime completedTime() const = 0;
virtual qlonglong timeSinceUpload() const = 0;
virtual qlonglong timeSinceDownload() const = 0;
virtual qlonglong timeSinceActivity() const = 0;
virtual int downloadLimit() const = 0;
virtual int uploadLimit() const = 0;
virtual bool superSeeding() const = 0;
virtual QVector<PeerInfo> peers() const = 0;
virtual QBitArray pieces() const = 0;
virtual QBitArray downloadingPieces() const = 0;
virtual QVector<int> pieceAvailability() const = 0;
virtual qreal distributedCopies() const = 0;
virtual qreal maxRatio() const = 0;
virtual int maxSeedingTime() const = 0;
virtual qreal realRatio() const = 0;
virtual int uploadPayloadRate() const = 0;
virtual int downloadPayloadRate() const = 0;
virtual qlonglong totalPayloadUpload() const = 0;
virtual qlonglong totalPayloadDownload() const = 0;
virtual int connectionsCount() const = 0;
virtual int connectionsLimit() const = 0;
virtual qlonglong nextAnnounce() const = 0;
/**
* @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<qreal> availableFileFractions() const;
virtual QVector<qreal> availableFileFractions() const = 0;
private:
typedef std::function<void ()> EventTrigger;
virtual void setName(const QString &name) = 0;
virtual void setSequentialDownload(bool enable) = 0;
virtual void setFirstLastPiecePriority(bool enabled) = 0;
virtual void pause() = 0;
virtual void resume(bool forced = false) = 0;
virtual void move(QString path) = 0;
virtual void forceReannounce(int index = -1) = 0;
virtual void forceDHTAnnounce() = 0;
virtual void forceRecheck() = 0;
virtual void renameFile(int index, const QString &name) = 0;
virtual void prioritizeFiles(const QVector<DownloadPriority> &priorities) = 0;
virtual void setRatioLimit(qreal limit) = 0;
virtual void setSeedingTimeLimit(int limit) = 0;
virtual void setUploadLimit(int limit) = 0;
virtual void setDownloadLimit(int limit) = 0;
virtual void setSuperSeeding(bool enable) = 0;
virtual void flushCache() const = 0;
virtual void addTrackers(const QVector<TrackerEntry> &trackers) = 0;
virtual void replaceTrackers(const QVector<TrackerEntry> &trackers) = 0;
virtual void addUrlSeeds(const QVector<QUrl> &urlSeeds) = 0;
virtual void removeUrlSeeds(const QVector<QUrl> &urlSeeds) = 0;
virtual bool connectPeer(const PeerAddress &peerAddress) = 0;
#if (LIBTORRENT_VERSION_NUM < 10200)
using LTFileIndex = int;
#else
using LTFileIndex = lt::file_index_t;
#endif
virtual QString createMagnetURI() const = 0;
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;
void toggleSequentialDownload();
void toggleFirstLastPiecePriority();
};
}
Q_DECLARE_METATYPE(BitTorrent::TorrentState)
#endif // BITTORRENT_TORRENTHANDLE_H

File diff suppressed because it is too large Load diff

View file

@ -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 &params);
};
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 &params);
~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;
};
}

View file

@ -28,6 +28,7 @@
#include "torrentfilter.h"
#include "bittorrent/infohash.h"
#include "bittorrent/torrenthandle.h"
const QString TorrentFilter::AnyCategory;

View file

@ -28,6 +28,7 @@
#include "fs.h"
#include <cerrno>
#include <cstring>
#if defined(Q_OS_WIN)

View file

@ -37,7 +37,9 @@
#include <QTextStream>
#include <QToolTip>
#include "base/indexrange.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/bittorrent/torrentinfo.h"
#include "base/utils/misc.h"
namespace

View file

@ -43,6 +43,7 @@
#include <QUrl>
#include "base/bittorrent/downloadpriority.h"
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/preferences.h"

View file

@ -38,6 +38,7 @@
#include <QUrl>
#include <QVBoxLayout>
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/bittorrent/trackerentry.h"
@ -223,7 +224,7 @@ void StatusFilterWidget::updateTorrentNumbers()
int nbStalledDownloading = 0;
int nbErrored = 0;
const QHash<BitTorrent::InfoHash, BitTorrent::TorrentHandle *> torrents = BitTorrent::Session::instance()->torrents();
const QVector<BitTorrent::TorrentHandle *> torrents = BitTorrent::Session::instance()->torrents();
for (const BitTorrent::TorrentHandle *torrent : torrents) {
if (torrent->isDownloading())
++nbDownloading;

View file

@ -31,6 +31,7 @@
#include <QDateTime>
#include <QStringList>
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/global.h"
#include "base/types.h"

View file

@ -652,7 +652,7 @@ void TransferListWidget::copySelectedMagnetURIs() const
{
QStringList magnetUris;
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents()))
magnetUris << torrent->toMagnetUri();
magnetUris << torrent->createMagnetURI();
qApp->clipboard()->setText(magnetUris.join('\n'));
}

View file

@ -30,6 +30,7 @@
#include <QDateTime>
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/utils/fs.h"
@ -85,7 +86,7 @@ QVariantMap serialize(const BitTorrent::TorrentHandle &torrent)
QVariantMap ret = {
{KEY_TORRENT_HASH, QString(torrent.hash())},
{KEY_TORRENT_NAME, torrent.name()},
{KEY_TORRENT_MAGNET_URI, torrent.toMagnetUri()},
{KEY_TORRENT_MAGNET_URI, torrent.createMagnetURI()},
{KEY_TORRENT_SIZE, torrent.wantedSize()},
{KEY_TORRENT_PROGRESS, torrent.progress()},
{KEY_TORRENT_DLSPEED, torrent.downloadPayloadRate()},

View file

@ -34,6 +34,7 @@
#include <QMetaObject>
#include <QThread>
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/peeraddress.h"
#include "base/bittorrent/peerinfo.h"
#include "base/bittorrent/session.h"