Skip to content

Commit

Permalink
Support downloading torrent from previously fetched metadata
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Piccirello <thomas@piccirello.com>
  • Loading branch information
Piccirello committed Dec 14, 2024
1 parent 025b6c6 commit f8f643b
Showing 1 changed file with 57 additions and 5 deletions.
62 changes: 57 additions & 5 deletions src/webui/api/torrentscontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ void TorrentsController::pieceStatesAction()

void TorrentsController::addAction()
{
const QString urls = params()[u"urls"_s];
const QStringList urls = params()[u"urls"_s].split(u'\n', Qt::SkipEmptyParts);

const bool skipChecking = parseBool(params()[u"skip_checking"_s]).value_or(false);
const bool seqDownload = parseBool(params()[u"sequentialDownload"_s]).value_or(false);
Expand Down Expand Up @@ -941,7 +941,31 @@ void TorrentsController::addAction()
? Utils::String::toEnum(contentLayoutParam, BitTorrent::TorrentContentLayout::Original)
: std::optional<BitTorrent::TorrentContentLayout> {});

const BitTorrent::AddTorrentParams addTorrentParams
const DataMap &torrents = data();

QList<BitTorrent::DownloadPriority> filePriorities;
const QStringList filePrioritiesParam = params()[u"filePriorities"_s].split(u',', Qt::SkipEmptyParts);
if ((urls.size() > 1) && !filePrioritiesParam.isEmpty())
throw APIError(APIErrorType::BadParams, tr("You cannot specify filePriorities when adding multiple torrents"));
if (!torrents.isEmpty() && !filePrioritiesParam.isEmpty())
throw APIError(APIErrorType::BadParams, tr("You cannot specify filePriorities when uploading torrent files"));
if (!filePrioritiesParam.isEmpty())
{
filePriorities.reserve(filePrioritiesParam.size());
for (const QString &priorityStr : filePrioritiesParam)
{
bool ok = false;
const auto priority = static_cast<BitTorrent::DownloadPriority>(priorityStr.toInt(&ok));
if (!ok)
throw APIError(APIErrorType::BadParams, tr("Priority must be an integer"));
if (!BitTorrent::isValidDownloadPriority(priority))
throw APIError(APIErrorType::BadParams, tr("Priority is not valid"));

filePriorities << priority;
}
}

BitTorrent::AddTorrentParams addTorrentParams
{
// TODO: Check if destination actually exists
.name = torrentName,
Expand Down Expand Up @@ -975,17 +999,45 @@ void TorrentsController::addAction()
}
};


bool partialSuccess = false;
for (QString url : asConst(urls.split(u'\n')))
for (QString url : urls)
{
url = url.trimmed();
if (!url.isEmpty())
if (url.isEmpty())
continue;

BitTorrent::InfoHash infoHash;
if (const auto sourceTorrentDescr = BitTorrent::TorrentDescriptor::parse(url))
infoHash = sourceTorrentDescr.value().infoHash();
else if (const auto cachedInfoHash = m_torrentSourceCache.get(url))
infoHash = cachedInfoHash.value();

if (const auto torrentDescr = m_torrentMetadataCache.get(infoHash))
{
if (!filePriorities.isEmpty())
{
const BitTorrent::TorrentInfo &info = torrentDescr.value().info().value();
if (filePriorities.size() != info.filesCount())
throw APIError(APIErrorType::BadParams, tr("Length of filePriorities must equal number of files in torrent"));

addTorrentParams.filePriorities = filePriorities;
}

partialSuccess |= BitTorrent::Session::instance()->addTorrent(torrentDescr.value(), addTorrentParams);
}
else
{
if (!filePriorities.isEmpty())
throw APIError(APIErrorType::BadParams, tr("filePriorities may only be specified when metadata has already been fetched"));

partialSuccess |= app()->addTorrentManager()->addTorrent(url, addTorrentParams);
}
m_torrentSourceCache.remove(url);
m_torrentMetadataCache.remove(infoHash);
}

const DataMap &torrents = data();
// process uploaded .torrent files
for (auto it = torrents.constBegin(); it != torrents.constEnd(); ++it)
{
if (const auto loadResult = BitTorrent::TorrentDescriptor::load(it.value()))
Expand Down

0 comments on commit f8f643b

Please sign in to comment.