mirror of
https://github.com/transmission/transmission
synced 2024-12-29 02:56:11 +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 <cassert>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
#include <QDateTime>
|
||||
|
@ -28,6 +30,7 @@
|
|||
#include <QTreeWidgetItem>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/announce-list.h>
|
||||
#include <libtransmission/utils.h> // tr_getRatio()
|
||||
|
||||
#include "BaseDialog.h"
|
||||
|
@ -1340,42 +1343,56 @@ void DetailsDialog::onTrackerSelectionChanged()
|
|||
void DetailsDialog::onAddTrackerClicked()
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
QString const text = QInputDialog::getMultiLineText(
|
||||
auto const text_qstr = QInputDialog::getMultiLineText(
|
||||
this,
|
||||
tr("Add URL(s)"),
|
||||
tr("Add tracker announce URLs, one per line:"),
|
||||
{},
|
||||
&ok);
|
||||
|
||||
if (ok)
|
||||
if (!ok)
|
||||
{
|
||||
QSet<QString> urls;
|
||||
torrent_ids_t ids;
|
||||
return;
|
||||
}
|
||||
|
||||
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();
|
||||
if (!line.isEmpty() && QUrl(url).isValid())
|
||||
// make a note if the torrent doesn't already have the URL
|
||||
if (tracker_model_->find(id, announce_url) == -1)
|
||||
{
|
||||
for (auto const& id : ids_)
|
||||
{
|
||||
if (tracker_model_->find(id, url) == -1 && !urls.contains(url))
|
||||
{
|
||||
ids.insert(id);
|
||||
urls.insert(url);
|
||||
}
|
||||
}
|
||||
url_to_ids[announce_url].insert(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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."));
|
||||
}
|
||||
else
|
||||
{
|
||||
torrentSet(ids, TR_KEY_trackerAdd, urls.values());
|
||||
torrentSet(
|
||||
torrent_ids_t{ std::begin(ids), std::end(ids) },
|
||||
TR_KEY_trackerAdd,
|
||||
QList<QString>{ std::begin(urls), std::end(urls) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "RpcClient.h"
|
||||
|
||||
#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)
|
||||
{
|
||||
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);
|
||||
tr_rpc_request_exec_json(session_, json.get(), localSessionCallback, this);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue