mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2026-01-07 16:12:30 -06:00
committed by
GitHub
parent
e4313d6651
commit
dcf3e97291
@@ -116,6 +116,11 @@ std::size_t BitTorrent::qHash(const BitTorrent::TorrentID &key, const std::size_
|
||||
return ::qHash(static_cast<TorrentID::BaseType>(key), seed);
|
||||
}
|
||||
|
||||
std::size_t BitTorrent::qHash(const InfoHash &key, const std::size_t seed)
|
||||
{
|
||||
return qHashMulti(seed, key.v1(), key.v2());
|
||||
}
|
||||
|
||||
bool BitTorrent::operator==(const BitTorrent::InfoHash &left, const BitTorrent::InfoHash &right)
|
||||
{
|
||||
return (static_cast<InfoHash::WrappedType>(left) == static_cast<InfoHash::WrappedType>(right));
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace BitTorrent
|
||||
};
|
||||
|
||||
std::size_t qHash(const TorrentID &key, std::size_t seed = 0);
|
||||
std::size_t qHash(const InfoHash &key, std::size_t seed = 0);
|
||||
|
||||
bool operator==(const InfoHash &left, const InfoHash &right);
|
||||
}
|
||||
|
||||
@@ -440,13 +440,11 @@ namespace BitTorrent
|
||||
virtual void banIP(const QString &ip) = 0;
|
||||
|
||||
virtual bool isKnownTorrent(const InfoHash &infoHash) const = 0;
|
||||
virtual bool addTorrent(const QString &source, const AddTorrentParams ¶ms = {}) = 0;
|
||||
virtual bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) = 0;
|
||||
virtual bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteOption::DeleteTorrent) = 0;
|
||||
virtual bool downloadMetadata(const TorrentDescriptor &torrentDescr) = 0;
|
||||
virtual bool cancelDownloadMetadata(const TorrentID &id) = 0;
|
||||
|
||||
virtual void recursiveTorrentDownload(const TorrentID &id) = 0;
|
||||
virtual void increaseTorrentsQueuePos(const QVector<TorrentID> &ids) = 0;
|
||||
virtual void decreaseTorrentsQueuePos(const QVector<TorrentID> &ids) = 0;
|
||||
virtual void topTorrentsQueuePos(const QVector<TorrentID> &ids) = 0;
|
||||
@@ -454,17 +452,15 @@ namespace BitTorrent
|
||||
|
||||
signals:
|
||||
void startupProgressUpdated(int progress);
|
||||
void addTorrentFailed(const InfoHash &infoHash, const QString &reason);
|
||||
void allTorrentsFinished();
|
||||
void categoryAdded(const QString &categoryName);
|
||||
void categoryRemoved(const QString &categoryName);
|
||||
void categoryOptionsChanged(const QString &categoryName);
|
||||
void downloadFromUrlFailed(const QString &url, const QString &reason);
|
||||
void downloadFromUrlFinished(const QString &url);
|
||||
void fullDiskError(Torrent *torrent, const QString &msg);
|
||||
void IPFilterParsed(bool error, int ruleCount);
|
||||
void loadTorrentFailed(const QString &error);
|
||||
void metadataDownloaded(const TorrentInfo &info);
|
||||
void recursiveTorrentDownloadPossible(Torrent *torrent);
|
||||
void restored();
|
||||
void speedLimitModeChanged(bool alternative);
|
||||
void statsUpdated();
|
||||
|
||||
@@ -77,11 +77,9 @@
|
||||
#include "base/algorithm.h"
|
||||
#include "base/global.h"
|
||||
#include "base/logger.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
#include "base/net/proxyconfigurationmanager.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/profile.h"
|
||||
#include "base/torrentfileguard.h"
|
||||
#include "base/torrentfilter.h"
|
||||
#include "base/unicodestrings.h"
|
||||
#include "base/utils/bytearray.h"
|
||||
@@ -2254,35 +2252,6 @@ void SessionImpl::processShareLimits()
|
||||
}
|
||||
}
|
||||
|
||||
// Add to BitTorrent session the downloaded torrent file
|
||||
void SessionImpl::handleDownloadFinished(const Net::DownloadResult &result)
|
||||
{
|
||||
switch (result.status)
|
||||
{
|
||||
case Net::DownloadStatus::Success:
|
||||
emit downloadFromUrlFinished(result.url);
|
||||
if (const auto loadResult = TorrentDescriptor::load(result.data))
|
||||
addTorrent(loadResult.value(), m_downloadedTorrents.take(result.url));
|
||||
else
|
||||
LogMsg(tr("Failed to load torrent. Reason: \"%1\"").arg(loadResult.error()), Log::WARNING);
|
||||
break;
|
||||
case Net::DownloadStatus::RedirectedToMagnet:
|
||||
emit downloadFromUrlFinished(result.url);
|
||||
if (const auto parseResult = TorrentDescriptor::parse(result.magnetURI))
|
||||
{
|
||||
addTorrent(parseResult.value(), m_downloadedTorrents.take(result.url));
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(tr("Failed to load torrent. The request was redirected to invalid Magnet URI. Reason: \"%1\"")
|
||||
.arg(parseResult.error()), Log::WARNING);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
emit downloadFromUrlFailed(result.url, result.errorString);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionImpl::fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames)
|
||||
{
|
||||
TorrentImpl *torrent = m_torrents.value(id);
|
||||
@@ -2593,40 +2562,6 @@ qsizetype SessionImpl::torrentsCount() const
|
||||
return m_torrents.size();
|
||||
}
|
||||
|
||||
bool SessionImpl::addTorrent(const QString &source, const AddTorrentParams ¶ms)
|
||||
{
|
||||
// `source`: .torrent file path/url or magnet uri
|
||||
|
||||
if (!isRestored())
|
||||
return false;
|
||||
|
||||
if (Net::DownloadManager::hasSupportedScheme(source))
|
||||
{
|
||||
LogMsg(tr("Downloading torrent, please wait... Source: \"%1\"").arg(source));
|
||||
const auto *pref = Preferences::instance();
|
||||
// Launch downloader
|
||||
Net::DownloadManager::instance()->download(Net::DownloadRequest(source).limit(pref->getTorrentFileSizeLimit())
|
||||
, pref->useProxyForGeneralPurposes(), this, &SessionImpl::handleDownloadFinished);
|
||||
m_downloadedTorrents[source] = params;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (const auto parseResult = TorrentDescriptor::parse(source))
|
||||
return addTorrent(parseResult.value(), params);
|
||||
|
||||
const Path path {source};
|
||||
TorrentFileGuard guard {path};
|
||||
const auto loadResult = TorrentDescriptor::loadFromFile(path);
|
||||
if (!loadResult)
|
||||
{
|
||||
LogMsg(tr("Failed to load torrent. Source: \"%1\". Reason: \"%2\"").arg(source, loadResult.error()), Log::WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
guard.markAsAddedToSession();
|
||||
return addTorrent(loadResult.value(), params);
|
||||
}
|
||||
|
||||
bool SessionImpl::addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms)
|
||||
{
|
||||
if (!isRestored())
|
||||
@@ -2713,35 +2648,8 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
|
||||
if (m_loadingTorrents.contains(id) || (infoHash.isHybrid() && m_loadingTorrents.contains(altID)))
|
||||
return false;
|
||||
|
||||
if (Torrent *torrent = findTorrent(infoHash))
|
||||
{
|
||||
// a duplicate torrent is being added
|
||||
if (hasMetadata)
|
||||
{
|
||||
// Trying to set metadata to existing torrent in case if it has none
|
||||
torrent->setMetadata(*source.info());
|
||||
}
|
||||
|
||||
if (!isMergeTrackersEnabled())
|
||||
{
|
||||
LogMsg(tr("Detected an attempt to add a duplicate torrent. Merging of trackers is disabled. Torrent: %1").arg(torrent->name()));
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool isPrivate = torrent->isPrivate() || (hasMetadata && source.info()->isPrivate());
|
||||
if (isPrivate)
|
||||
{
|
||||
LogMsg(tr("Detected an attempt to add a duplicate torrent. Trackers cannot be merged because it is a private torrent. Torrent: %1").arg(torrent->name()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// merge trackers and web seeds
|
||||
torrent->addTrackers(source.trackers());
|
||||
torrent->addUrlSeeds(source.urlSeeds());
|
||||
|
||||
LogMsg(tr("Detected an attempt to add a duplicate torrent. Trackers are merged from new source. Torrent: %1").arg(torrent->name()));
|
||||
if (findTorrent(infoHash))
|
||||
return false;
|
||||
}
|
||||
|
||||
// It looks illogical that we don't just use an existing handle,
|
||||
// but as previous experience has shown, it actually creates unnecessary
|
||||
@@ -4961,16 +4869,6 @@ void SessionImpl::handleTorrentFinished(TorrentImpl *const torrent)
|
||||
if (const Path exportPath = finishedTorrentExportDirectory(); !exportPath.isEmpty())
|
||||
exportTorrentFile(torrent, exportPath);
|
||||
|
||||
// Check whether it contains .torrent files
|
||||
for (const Path &torrentRelpath : asConst(torrent->filePaths()))
|
||||
{
|
||||
if (torrentRelpath.hasExtension(u".torrent"_s))
|
||||
{
|
||||
emit recursiveTorrentDownloadPossible(torrent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const bool hasUnfinishedTorrents = std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent)
|
||||
{
|
||||
return !(torrent->isFinished() || torrent->isPaused() || torrent->isErrored());
|
||||
@@ -5263,37 +5161,6 @@ void SessionImpl::disableIPFilter()
|
||||
m_nativeSession->set_ip_filter(filter);
|
||||
}
|
||||
|
||||
void SessionImpl::recursiveTorrentDownload(const TorrentID &id)
|
||||
{
|
||||
const TorrentImpl *torrent = m_torrents.value(id);
|
||||
if (!torrent)
|
||||
return;
|
||||
|
||||
for (const Path &torrentRelpath : asConst(torrent->filePaths()))
|
||||
{
|
||||
if (torrentRelpath.hasExtension(u".torrent"_s))
|
||||
{
|
||||
const Path torrentFullpath = torrent->savePath() / torrentRelpath;
|
||||
|
||||
LogMsg(tr("Recursive download .torrent file within torrent. Source torrent: \"%1\". File: \"%2\"")
|
||||
.arg(torrent->name(), torrentFullpath.toString()));
|
||||
|
||||
AddTorrentParams params;
|
||||
// Passing the save path along to the sub torrent file
|
||||
params.savePath = torrent->savePath();
|
||||
if (const auto loadResult = TorrentDescriptor::loadFromFile(torrentFullpath))
|
||||
{
|
||||
addTorrent(loadResult.value(), params);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(tr("Failed to load .torrent file within torrent. Source torrent: \"%1\". File: \"%2\". Error: \"%3\"")
|
||||
.arg(torrent->name(), torrentFullpath.toString(), loadResult.error()), Log::WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SessionStatus &SessionImpl::status() const
|
||||
{
|
||||
return m_status;
|
||||
@@ -5406,6 +5273,7 @@ void SessionImpl::handleAddTorrentAlerts(const std::vector<lt::alert *> &alerts)
|
||||
if (const auto loadingTorrentsIter = m_loadingTorrents.find(TorrentID::fromInfoHash(infoHash))
|
||||
; loadingTorrentsIter != m_loadingTorrents.end())
|
||||
{
|
||||
emit addTorrentFailed(infoHash, msg);
|
||||
m_loadingTorrents.erase(loadingTorrentsIter);
|
||||
}
|
||||
else if (const auto downloadedMetadataIter = m_downloadedMetadata.find(TorrentID::fromInfoHash(infoHash))
|
||||
|
||||
@@ -67,11 +67,6 @@ class FileSearcher;
|
||||
class FilterParserThread;
|
||||
class NativeSessionExtension;
|
||||
|
||||
namespace Net
|
||||
{
|
||||
struct DownloadResult;
|
||||
}
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class InfoHash;
|
||||
@@ -414,13 +409,11 @@ namespace BitTorrent
|
||||
void banIP(const QString &ip) override;
|
||||
|
||||
bool isKnownTorrent(const InfoHash &infoHash) const override;
|
||||
bool addTorrent(const QString &source, const AddTorrentParams ¶ms = {}) override;
|
||||
bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) override;
|
||||
bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteTorrent) override;
|
||||
bool downloadMetadata(const TorrentDescriptor &torrentDescr) override;
|
||||
bool cancelDownloadMetadata(const TorrentID &id) override;
|
||||
|
||||
void recursiveTorrentDownload(const TorrentID &id) override;
|
||||
void increaseTorrentsQueuePos(const QVector<TorrentID> &ids) override;
|
||||
void decreaseTorrentsQueuePos(const QVector<TorrentID> &ids) override;
|
||||
void topTorrentsQueuePos(const QVector<TorrentID> &ids) override;
|
||||
@@ -477,7 +470,6 @@ namespace BitTorrent
|
||||
void generateResumeData();
|
||||
void handleIPFilterParsed(int ruleCount);
|
||||
void handleIPFilterError();
|
||||
void handleDownloadFinished(const Net::DownloadResult &result);
|
||||
void fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames);
|
||||
|
||||
private:
|
||||
@@ -746,7 +738,6 @@ namespace BitTorrent
|
||||
QHash<TorrentID, TorrentImpl *> m_torrents;
|
||||
QHash<TorrentID, TorrentImpl *> m_hybridTorrentsByAltID;
|
||||
QHash<TorrentID, LoadTorrentParams> m_loadingTorrents;
|
||||
QHash<QString, AddTorrentParams> m_downloadedTorrents;
|
||||
QHash<TorrentID, RemovingTorrentData> m_removingTorrents;
|
||||
QSet<TorrentID> m_needSaveResumeDataTorrents;
|
||||
QHash<TorrentID, TorrentID> m_changedTorrentIDs;
|
||||
|
||||
Reference in New Issue
Block a user