mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-08-19 21:03:30 -07:00
Add WebAPI for downloading torrent metadata
Signed-off-by: Thomas Piccirello <thomas@piccirello.com>
This commit is contained in:
parent
e45ca3fde7
commit
69bf31f4e9
4 changed files with 50 additions and 2 deletions
|
@ -141,6 +141,22 @@ catch (const lt::system_error &err)
|
||||||
return nonstd::make_unexpected(QString::fromLocal8Bit(err.what()));
|
return nonstd::make_unexpected(QString::fromLocal8Bit(err.what()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nonstd::expected<QByteArray, QString> BitTorrent::TorrentDescriptor::saveToBuffer() const
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const lt::entry torrentEntry = lt::write_torrent_file(m_ltAddTorrentParams);
|
||||||
|
// usually torrent size should be smaller than 1 MB,
|
||||||
|
// however there are >100 MB v2/hybrid torrent files out in the wild
|
||||||
|
QByteArray buffer;
|
||||||
|
buffer.reserve(1024 * 1024);
|
||||||
|
lt::bencode(std::back_inserter(buffer), torrentEntry);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
catch (const lt::system_error &err)
|
||||||
|
{
|
||||||
|
return nonstd::make_unexpected(QString::fromLocal8Bit(err.what()));
|
||||||
|
}
|
||||||
|
|
||||||
BitTorrent::TorrentDescriptor::TorrentDescriptor(lt::add_torrent_params ltAddTorrentParams)
|
BitTorrent::TorrentDescriptor::TorrentDescriptor(lt::add_torrent_params ltAddTorrentParams)
|
||||||
: m_ltAddTorrentParams {std::move(ltAddTorrentParams)}
|
: m_ltAddTorrentParams {std::move(ltAddTorrentParams)}
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace BitTorrent
|
||||||
static nonstd::expected<TorrentDescriptor, QString> loadFromFile(const Path &path) noexcept;
|
static nonstd::expected<TorrentDescriptor, QString> loadFromFile(const Path &path) noexcept;
|
||||||
static nonstd::expected<TorrentDescriptor, QString> parse(const QString &str) noexcept;
|
static nonstd::expected<TorrentDescriptor, QString> parse(const QString &str) noexcept;
|
||||||
nonstd::expected<void, QString> saveToFile(const Path &path) const;
|
nonstd::expected<void, QString> saveToFile(const Path &path) const;
|
||||||
|
nonstd::expected<QByteArray, QString> saveToBuffer() const;
|
||||||
|
|
||||||
const lt::add_torrent_params <AddTorrentParams() const;
|
const lt::add_torrent_params <AddTorrentParams() const;
|
||||||
|
|
||||||
|
|
|
@ -997,9 +997,9 @@ void TorrentsController::addAction()
|
||||||
if (!filePrioritiesParam.isEmpty())
|
if (!filePrioritiesParam.isEmpty())
|
||||||
{
|
{
|
||||||
if (urls.size() > 1)
|
if (urls.size() > 1)
|
||||||
throw APIError(APIErrorType::BadParams, tr("You cannot specify filePriorities when adding multiple torrents"));
|
throw APIError(APIErrorType::BadParams, tr("Cannot specify filePriorities when adding multiple torrents"));
|
||||||
if (!torrents.isEmpty())
|
if (!torrents.isEmpty())
|
||||||
throw APIError(APIErrorType::BadParams, tr("You cannot specify filePriorities when uploading torrent files"));
|
throw APIError(APIErrorType::BadParams, tr("Cannot specify filePriorities when uploading torrent files"));
|
||||||
|
|
||||||
filePriorities.reserve(filePrioritiesParam.size());
|
filePriorities.reserve(filePrioritiesParam.size());
|
||||||
for (const QString &priorityStr : filePrioritiesParam)
|
for (const QString &priorityStr : filePrioritiesParam)
|
||||||
|
@ -2035,6 +2035,36 @@ void TorrentsController::parseMetadataAction()
|
||||||
setResult(result);
|
setResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TorrentsController::saveMetadataAction()
|
||||||
|
{
|
||||||
|
requireParams({u"source"_s});
|
||||||
|
|
||||||
|
const QString sourceParam = params()[u"source"_s].trimmed();
|
||||||
|
if (sourceParam.isEmpty())
|
||||||
|
throw APIError(APIErrorType::BadParams, tr("Must specify URI or hash"));
|
||||||
|
|
||||||
|
const QString source = QUrl::fromPercentEncoding(sourceParam.toLatin1());
|
||||||
|
|
||||||
|
BitTorrent::InfoHash infoHash;
|
||||||
|
if (const auto iter = m_torrentSourceCache.constFind(source); iter != m_torrentSourceCache.constEnd())
|
||||||
|
infoHash = iter.value();
|
||||||
|
else if (const auto sourceTorrentDescr = BitTorrent::TorrentDescriptor::parse(source))
|
||||||
|
infoHash = sourceTorrentDescr.value().infoHash();
|
||||||
|
|
||||||
|
if (!infoHash.isValid())
|
||||||
|
throw APIError(APIErrorType::NotFound);
|
||||||
|
|
||||||
|
const BitTorrent::TorrentDescriptor &torrentDescr = m_torrentMetadataCache.value(infoHash);
|
||||||
|
if (!torrentDescr.info().has_value())
|
||||||
|
throw APIError(APIErrorType::Conflict, tr("Metadata is not yet available"));
|
||||||
|
|
||||||
|
const nonstd::expected<QByteArray, QString> result = torrentDescr.saveToBuffer();
|
||||||
|
if (!result)
|
||||||
|
throw APIError(APIErrorType::Conflict, tr("Unable to export torrent metadata. Error: %1").arg(result.error()));
|
||||||
|
|
||||||
|
setResult(result.value(), u"application/x-bittorrent"_s, (infoHash.toTorrentID().toString() + u".torrent"));
|
||||||
|
}
|
||||||
|
|
||||||
void TorrentsController::onDownloadFinished(const Net::DownloadResult &result)
|
void TorrentsController::onDownloadFinished(const Net::DownloadResult &result)
|
||||||
{
|
{
|
||||||
const QString source = result.url;
|
const QString source = result.url;
|
||||||
|
|
|
@ -112,6 +112,7 @@ private slots:
|
||||||
void setSSLParametersAction();
|
void setSSLParametersAction();
|
||||||
void fetchMetadataAction();
|
void fetchMetadataAction();
|
||||||
void parseMetadataAction();
|
void parseMetadataAction();
|
||||||
|
void saveMetadataAction();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onDownloadFinished(const Net::DownloadResult &result);
|
void onDownloadFinished(const Net::DownloadResult &result);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue