mirror of
https://github.com/transmission/transmission
synced 2024-12-30 19:46:56 +00:00
fix: correctly handle batch-adding trackers to multiple torrents (#5122)
This commit is contained in:
parent
d3273504bd
commit
8fc904617b
2 changed files with 47 additions and 23 deletions
|
@ -6,6 +6,8 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
@ -28,6 +30,7 @@
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
|
|
||||||
#include <libtransmission/transmission.h>
|
#include <libtransmission/transmission.h>
|
||||||
|
#include <libtransmission/announce-list.h>
|
||||||
#include <libtransmission/utils.h> // tr_getRatio()
|
#include <libtransmission/utils.h> // tr_getRatio()
|
||||||
|
|
||||||
#include "BaseDialog.h"
|
#include "BaseDialog.h"
|
||||||
|
@ -1340,42 +1343,56 @@ void DetailsDialog::onTrackerSelectionChanged()
|
||||||
void DetailsDialog::onAddTrackerClicked()
|
void DetailsDialog::onAddTrackerClicked()
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
auto const text_qstr = QInputDialog::getMultiLineText(
|
||||||
QString const text = QInputDialog::getMultiLineText(
|
|
||||||
this,
|
this,
|
||||||
tr("Add URL(s)"),
|
tr("Add URL(s)"),
|
||||||
tr("Add tracker announce URLs, one per line:"),
|
tr("Add tracker announce URLs, one per line:"),
|
||||||
{},
|
{},
|
||||||
&ok);
|
&ok);
|
||||||
|
if (!ok)
|
||||||
if (ok)
|
|
||||||
{
|
{
|
||||||
QSet<QString> urls;
|
return;
|
||||||
torrent_ids_t ids;
|
}
|
||||||
|
|
||||||
for (auto const& line : text.split(QRegularExpression(QStringLiteral("[\r\n]+"))))
|
// for each URL entered by the user...
|
||||||
|
auto announce_list = tr_announce_list{};
|
||||||
|
announce_list.parse(text_qstr.toStdString());
|
||||||
|
auto url_to_ids = std::map<QString, std::set<tr_torrent_id_t>>{};
|
||||||
|
for (auto const& info : announce_list)
|
||||||
|
{
|
||||||
|
// for each selected torrent...
|
||||||
|
auto sv = info.announce.sv();
|
||||||
|
auto const announce_url = QString::fromUtf8(std::data(sv), std::size(sv));
|
||||||
|
for (auto const& id : ids_)
|
||||||
{
|
{
|
||||||
QString const url = line.trimmed();
|
// make a note if the torrent doesn't already have the URL
|
||||||
if (!line.isEmpty() && QUrl(url).isValid())
|
if (tracker_model_->find(id, announce_url) == -1)
|
||||||
{
|
{
|
||||||
for (auto const& id : ids_)
|
url_to_ids[announce_url].insert(id);
|
||||||
{
|
|
||||||
if (tracker_model_->find(id, url) == -1 && !urls.contains(url))
|
|
||||||
{
|
|
||||||
ids.insert(id);
|
|
||||||
urls.insert(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (urls.isEmpty())
|
// now reverse the map so that if we're adding identical trackers
|
||||||
|
// to more than one torrent, that can be batched into a single call
|
||||||
|
auto ids_to_urls = std::map<std::set<tr_torrent_id_t>, std::set<QString>>{};
|
||||||
|
for (auto& [announce_url, ids] : url_to_ids)
|
||||||
|
{
|
||||||
|
ids_to_urls[ids].insert(announce_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::empty(ids_to_urls))
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Error"), tr("No new URLs found."));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto const& [ids, urls] : ids_to_urls)
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, tr("Error"), tr("No new URLs found."));
|
torrentSet(
|
||||||
}
|
torrent_ids_t{ std::begin(ids), std::end(ids) },
|
||||||
else
|
TR_KEY_trackerAdd,
|
||||||
{
|
QList<QString>{ std::begin(urls), std::end(urls) });
|
||||||
torrentSet(ids, TR_KEY_trackerAdd, urls.values());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "RpcClient.h"
|
#include "RpcClient.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
@ -160,6 +162,11 @@ void RpcClient::sendNetworkRequest(TrVariantPtr json, QFutureInterface<RpcRespon
|
||||||
|
|
||||||
void RpcClient::sendLocalRequest(TrVariantPtr json, QFutureInterface<RpcResponse> const& promise, int64_t tag)
|
void RpcClient::sendLocalRequest(TrVariantPtr json, QFutureInterface<RpcResponse> const& promise, int64_t tag)
|
||||||
{
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
fmt::print("{:s}:{:d} sending req:\n{:s}\n", __FILE__, __LINE__, tr_variantToStr(json.get(), TR_VARIANT_FMT_JSON));
|
||||||
|
}
|
||||||
|
|
||||||
local_requests_.insert(tag, promise);
|
local_requests_.insert(tag, promise);
|
||||||
tr_rpc_request_exec_json(session_, json.get(), localSessionCallback, this);
|
tr_rpc_request_exec_json(session_, json.get(), localSessionCallback, this);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue