mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-07 13:41:26 -07:00
Add unified class to represent parsed torrent metadata
* Add unified class to represent parsed torrent metadata * Unify startup logic of "Add new torrent dialog" PR #19301.
This commit is contained in:
parent
d554f4d44a
commit
f27f2c20e0
18 changed files with 498 additions and 439 deletions
|
@ -101,10 +101,10 @@
|
|||
#include "filterparserthread.h"
|
||||
#include "loadtorrentparams.h"
|
||||
#include "lttypecast.h"
|
||||
#include "magneturi.h"
|
||||
#include "nativesessionextension.h"
|
||||
#include "portforwarderimpl.h"
|
||||
#include "resumedatastorage.h"
|
||||
#include "torrentdescriptor.h"
|
||||
#include "torrentimpl.h"
|
||||
#include "tracker.h"
|
||||
|
||||
|
@ -2250,14 +2250,22 @@ void SessionImpl::handleDownloadFinished(const Net::DownloadResult &result)
|
|||
{
|
||||
case Net::DownloadStatus::Success:
|
||||
emit downloadFromUrlFinished(result.url);
|
||||
if (const nonstd::expected<TorrentInfo, QString> loadResult = TorrentInfo::load(result.data); loadResult)
|
||||
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);
|
||||
addTorrent(MagnetUri(result.magnet), m_downloadedTorrents.take(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);
|
||||
|
@ -2592,13 +2600,12 @@ bool SessionImpl::addTorrent(const QString &source, const AddTorrentParams ¶
|
|||
return true;
|
||||
}
|
||||
|
||||
const MagnetUri magnetUri {source};
|
||||
if (magnetUri.isValid())
|
||||
return addTorrent(magnetUri, params);
|
||||
if (const auto parseResult = TorrentDescriptor::parse(source))
|
||||
return addTorrent(parseResult.value(), params);
|
||||
|
||||
const Path path {source};
|
||||
TorrentFileGuard guard {path};
|
||||
const nonstd::expected<TorrentInfo, QString> loadResult = TorrentInfo::loadFromFile(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);
|
||||
|
@ -2609,23 +2616,12 @@ bool SessionImpl::addTorrent(const QString &source, const AddTorrentParams ¶
|
|||
return addTorrent(loadResult.value(), params);
|
||||
}
|
||||
|
||||
bool SessionImpl::addTorrent(const MagnetUri &magnetUri, const AddTorrentParams ¶ms)
|
||||
bool SessionImpl::addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms)
|
||||
{
|
||||
if (!isRestored())
|
||||
return false;
|
||||
|
||||
if (!magnetUri.isValid())
|
||||
return false;
|
||||
|
||||
return addTorrent_impl(magnetUri, params);
|
||||
}
|
||||
|
||||
bool SessionImpl::addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms)
|
||||
{
|
||||
if (!isRestored())
|
||||
return false;
|
||||
|
||||
return addTorrent_impl(torrentInfo, params);
|
||||
return addTorrent_impl(torrentDescr, params);
|
||||
}
|
||||
|
||||
LoadTorrentParams SessionImpl::initLoadTorrentParams(const AddTorrentParams &addTorrentParams)
|
||||
|
@ -2690,12 +2686,12 @@ LoadTorrentParams SessionImpl::initLoadTorrentParams(const AddTorrentParams &add
|
|||
}
|
||||
|
||||
// Add a torrent to the BitTorrent session
|
||||
bool SessionImpl::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source, const AddTorrentParams &addTorrentParams)
|
||||
bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorrentParams &addTorrentParams)
|
||||
{
|
||||
Q_ASSERT(isRestored());
|
||||
|
||||
const bool hasMetadata = std::holds_alternative<TorrentInfo>(source);
|
||||
const auto infoHash = (hasMetadata ? std::get<TorrentInfo>(source).infoHash() : std::get<MagnetUri>(source).infoHash());
|
||||
const bool hasMetadata = (source.info().has_value());
|
||||
const auto infoHash = source.infoHash();
|
||||
const auto id = TorrentID::fromInfoHash(infoHash);
|
||||
|
||||
// alternative ID can be useful to find existing torrent in case if hybrid torrent was added by v1 info hash
|
||||
|
@ -2712,7 +2708,7 @@ bool SessionImpl::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &so
|
|||
if (hasMetadata)
|
||||
{
|
||||
// Trying to set metadata to existing torrent in case if it has none
|
||||
torrent->setMetadata(std::get<TorrentInfo>(source));
|
||||
torrent->setMetadata(*source.info());
|
||||
}
|
||||
|
||||
if (!isMergeTrackersEnabled())
|
||||
|
@ -2721,29 +2717,16 @@ bool SessionImpl::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &so
|
|||
return false;
|
||||
}
|
||||
|
||||
const bool isPrivate = torrent->isPrivate() || (hasMetadata && std::get<TorrentInfo>(source).isPrivate());
|
||||
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;
|
||||
}
|
||||
|
||||
if (hasMetadata)
|
||||
{
|
||||
const TorrentInfo &torrentInfo = std::get<TorrentInfo>(source);
|
||||
|
||||
// merge trackers and web seeds
|
||||
torrent->addTrackers(torrentInfo.trackers());
|
||||
torrent->addUrlSeeds(torrentInfo.urlSeeds());
|
||||
}
|
||||
else
|
||||
{
|
||||
const MagnetUri &magnetUri = std::get<MagnetUri>(source);
|
||||
|
||||
// merge trackers and web seeds
|
||||
torrent->addTrackers(magnetUri.trackers());
|
||||
torrent->addUrlSeeds(magnetUri.urlSeeds());
|
||||
}
|
||||
// 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()));
|
||||
return false;
|
||||
|
@ -2759,6 +2742,7 @@ bool SessionImpl::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &so
|
|||
|
||||
LoadTorrentParams loadTorrentParams = initLoadTorrentParams(addTorrentParams);
|
||||
lt::add_torrent_params &p = loadTorrentParams.ltAddTorrentParams;
|
||||
p = source.ltAddTorrentParams();
|
||||
|
||||
bool isFindingIncompleteFiles = false;
|
||||
|
||||
|
@ -2767,7 +2751,7 @@ bool SessionImpl::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &so
|
|||
|
||||
if (hasMetadata)
|
||||
{
|
||||
const TorrentInfo &torrentInfo = std::get<TorrentInfo>(source);
|
||||
const TorrentInfo &torrentInfo = *source.info();
|
||||
|
||||
Q_ASSERT(addTorrentParams.filePaths.isEmpty() || (addTorrentParams.filePaths.size() == torrentInfo.filesCount()));
|
||||
|
||||
|
@ -2779,8 +2763,7 @@ bool SessionImpl::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &so
|
|||
{
|
||||
const Path originalRootFolder = Path::findRootFolder(filePaths);
|
||||
const auto originalContentLayout = (originalRootFolder.isEmpty()
|
||||
? TorrentContentLayout::NoSubfolder
|
||||
: TorrentContentLayout::Subfolder);
|
||||
? TorrentContentLayout::NoSubfolder : TorrentContentLayout::Subfolder);
|
||||
if (loadTorrentParams.contentLayout != originalContentLayout)
|
||||
{
|
||||
if (loadTorrentParams.contentLayout == TorrentContentLayout::NoSubfolder)
|
||||
|
@ -2843,13 +2826,10 @@ bool SessionImpl::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &so
|
|||
p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(addTorrentParams.filePriorities[i]);
|
||||
}
|
||||
|
||||
p.ti = torrentInfo.nativeInfo();
|
||||
Q_ASSERT(p.ti);
|
||||
}
|
||||
else
|
||||
{
|
||||
const MagnetUri &magnetUri = std::get<MagnetUri>(source);
|
||||
p = magnetUri.addTorrentParams();
|
||||
|
||||
if (loadTorrentParams.name.isEmpty() && !p.name.empty())
|
||||
loadTorrentParams.name = QString::fromStdString(p.name);
|
||||
}
|
||||
|
@ -3009,19 +2989,20 @@ void SessionImpl::invokeAsync(std::function<void ()> func)
|
|||
|
||||
// Add a torrent to libtorrent session in hidden mode
|
||||
// and force it to download its metadata
|
||||
bool SessionImpl::downloadMetadata(const MagnetUri &magnetUri)
|
||||
bool SessionImpl::downloadMetadata(const TorrentDescriptor &torrentDescr)
|
||||
{
|
||||
if (!magnetUri.isValid())
|
||||
Q_ASSERT(!torrentDescr.info().has_value());
|
||||
if (Q_UNLIKELY(torrentDescr.info().has_value()))
|
||||
return false;
|
||||
|
||||
const InfoHash infoHash = magnetUri.infoHash();
|
||||
const InfoHash infoHash = torrentDescr.infoHash();
|
||||
|
||||
// We should not add torrent if it's already
|
||||
// processed or adding to session
|
||||
if (isKnownTorrent(infoHash))
|
||||
return false;
|
||||
|
||||
lt::add_torrent_params p = magnetUri.addTorrentParams();
|
||||
lt::add_torrent_params p = torrentDescr.ltAddTorrentParams();
|
||||
|
||||
if (isAddTrackersEnabled())
|
||||
{
|
||||
|
@ -5281,8 +5262,7 @@ void SessionImpl::recursiveTorrentDownload(const TorrentID &id)
|
|||
AddTorrentParams params;
|
||||
// Passing the save path along to the sub torrent file
|
||||
params.savePath = torrent->savePath();
|
||||
const nonstd::expected<TorrentInfo, QString> loadResult = TorrentInfo::loadFromFile(torrentFullpath);
|
||||
if (loadResult)
|
||||
if (const auto loadResult = TorrentDescriptor::loadFromFile(torrentFullpath))
|
||||
{
|
||||
addTorrent(loadResult.value(), params);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue