Merge pull request #10158 from Piccirello/webui-peers-table

Add ability to add and ban a peer from the Web UI
This commit is contained in:
Mike Tzou 2019-08-06 10:16:09 +08:00 committed by GitHub
commit 7d598b18ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 197 additions and 1 deletions

View File

@ -40,6 +40,7 @@
#include <QUrl>
#include "base/bittorrent/downloadpriority.h"
#include "base/bittorrent/peeraddress.h"
#include "base/bittorrent/peerinfo.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrenthandle.h"
@ -681,6 +682,42 @@ void TorrentsController::removeTrackersAction()
torrent->forceReannounce();
}
void TorrentsController::addPeersAction()
{
checkParams({"hashes", "peers"});
const QStringList hashes = params()["hashes"].split('|');
const QStringList peers = params()["peers"].split('|');
QVector<BitTorrent::PeerAddress> peerList;
peerList.reserve(peers.size());
for (const QString &peer : peers) {
const BitTorrent::PeerAddress addr = BitTorrent::PeerAddress::parse(peer.trimmed());
if (!addr.ip.isNull())
peerList.append(addr);
}
if (peerList.isEmpty())
throw APIError(APIErrorType::BadParams, "No valid peers were specified");
QJsonObject results;
applyToTorrents(hashes, [peers, peerList, &results](BitTorrent::TorrentHandle *const torrent)
{
const int peersAdded = std::count_if(peerList.cbegin(), peerList.cend(), [torrent](const BitTorrent::PeerAddress &peer)
{
return torrent->connectPeer(peer);
});
results[torrent->hash()] = QJsonObject {
{"added", peersAdded},
{"failed", (peers.size() - peersAdded)}
};
});
setResult(results);
}
void TorrentsController::pauseAction()
{
checkParams({"hashes"});

View File

@ -66,6 +66,7 @@ private slots:
void addTrackersAction();
void editTrackerAction();
void removeTrackersAction();
void addPeersAction();
void filePrioAction();
void uploadLimitAction();
void downloadLimitAction();

View File

@ -29,8 +29,13 @@
#include "transfercontroller.h"
#include <QJsonObject>
#include <QVector>
#include "base/bittorrent/peeraddress.h"
#include "base/bittorrent/peerinfo.h"
#include "base/bittorrent/session.h"
#include "base/global.h"
#include "apierror.h"
const char KEY_TRANSFER_DLSPEED[] = "dl_info_speed";
const char KEY_TRANSFER_DLDATA[] = "dl_info_data";
@ -111,3 +116,15 @@ void TransferController::speedLimitsModeAction()
{
setResult(QString::number(BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled()));
}
void TransferController::banPeersAction()
{
checkParams({"peers"});
const QStringList peers = params()["peers"].split('|');
for (const QString &peer : peers) {
const BitTorrent::PeerAddress addr = BitTorrent::PeerAddress::parse(peer.trimmed());
if (!addr.ip.isNull())
BitTorrent::Session::instance()->banIP(addr.ip.toString());
}
}

View File

@ -46,4 +46,5 @@ private slots:
void downloadLimitAction();
void setUploadLimitAction();
void setDownloadLimitAction();
void banPeersAction();
};

View File

@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="${LANG}">
<head>
<meta charset="UTF-8" />
<title>QBT_TR(Add Peers)QBT_TR[CONTEXT=PeersAdditionDialog]</title>
<link rel="stylesheet" href="css/style.css?v=${CACHEID}" type="text/css" />
<script src="scripts/lib/mootools-1.2-core-yc.js"></script>
<script src="scripts/lib/mootools-1.2-more.js"></script>
<script>
'use strict';
new Keyboard({
defaultEventType: 'keydown',
events: {
'Escape': function(event) {
window.parent.closeWindows();
event.preventDefault();
},
'Esc': function(event) {
window.parent.closeWindows();
event.preventDefault();
}
}
}).activate();
window.addEvent('domready', function() {
const hash = new URI().getData('hash');
if (!hash)
return false;
$('peers').focus();
$('addPeersOk').addEvent('click', function(e) {
new Event(e).stop();
const peers = $('peers').get('value').trim().split(/[\r\n]+/);
if (peers.length === 0)
return
new Request({
url: 'api/v2/torrents/addPeers',
method: 'post',
data: {
hashes: hash,
peers: peers.join(';')
},
onFailure: function() {
alert("QBT_TR(Unable to add peers. Please ensure you are adhering to the IP:port format.)QBT_TR[CONTEXT=HttpServer]");
},
onSuccess: function() {
window.parent.closeWindows();
}
}).send();
});
});
</script>
</head>
<body>
<div style="padding: 10px 10px 0px 10px;">
<p>QBT_TR(List of peers to add (one IP per line):)QBT_TR[CONTEXT=PeersAdditionDialog]</p>
<textarea id="peers" rows="10" style="width: 100%;" placeholder="QBT_TR(Format: IPv4:port / [IPv6]:port)QBT_TR[CONTEXT=PeersAdditionDialog]"></textarea>
<div style="margin-top: 10px; text-align: center;">
<button onclick="window.parent.closeWindows();">QBT_TR(Cancel)QBT_TR[CONTEXT=PeersAdditionDialog]</button>
<button id="addPeersOk">QBT_TR(Ok)QBT_TR[CONTEXT=PeersAdditionDialog]</button>
</div>
</div>
</body>
</html>

View File

@ -190,6 +190,11 @@
<li><a href="#RemoveTracker"><img src="images/qbt-theme/list-remove.svg" alt="QBT_TR(Remove tracker)QBT_TR[CONTEXT=TrackerListWidget]"/> QBT_TR(Remove tracker)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
<li><a href="#CopyTrackerUrl" id="CopyTrackerUrl"><img src="images/qbt-theme/edit-copy.svg" alt="QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]"/> QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
</ul>
<ul id="torrentPeersMenu" class="contextMenu">
<li><a href="#addPeer"><img src="images/qbt-theme/list-add.svg" alt="QBT_TR(Add a new peer...)QBT_TR[CONTEXT=PeerListWidget]"/> QBT_TR(Add a new peer...)QBT_TR[CONTEXT=PeerListWidget]</a></li>
<li><a href="#copyPeer" id="CopyPeerInfo"><img src="images/qbt-theme/edit-copy.svg" alt="QBT_TR(Copy IP:port)QBT_TR[CONTEXT=PeerListWidget]"/> QBT_TR(Copy IP:port)QBT_TR[CONTEXT=PeerListWidget]</a></li>
<li class="separator"><a href="#banPeer"><img src="images/qbt-theme/user-group-delete.svg" alt="QBT_TR(Ban peer permanently)QBT_TR[CONTEXT=PeerListWidget]"/> QBT_TR(Ban peer permanently)QBT_TR[CONTEXT=PeerListWidget]</a></li>
</ul>
<ul id="torrentFilesMenu" class="contextMenu">
<li>
<a href="#FilePrio" class="arrow-right"><span style="display: inline-block; width: 16px;"></span> QBT_TR(Priority)QBT_TR[CONTEXT=PropertiesWidget]</a>

View File

@ -103,4 +103,69 @@ updateTorrentPeersData = function() {
loadTorrentPeersData();
};
torrentPeersTable.setup('torrentPeersTableDiv', 'torrentPeersTableFixedHeaderDiv', null);
const torrentPeersContextMenu = new ContextMenu({
targets: '#torrentPeersTableDiv',
menu: 'torrentPeersMenu',
actions: {
addPeer: function(element, ref) {
const hash = torrentsTable.getCurrentTorrentHash();
if (!hash)
return;
new MochaUI.Window({
id: 'addPeersPage',
title: "QBT_TR(Add Peers)QBT_TR[CONTEXT=PeersAdditionDialog]",
loadMethod: 'iframe',
contentURL: 'addpeers.html?hash=' + hash,
scrollbars: false,
resizable: false,
maximizable: false,
paddingVertical: 0,
paddingHorizontal: 0,
width: 350,
height: 240
});
},
banPeer: function(element, ref) {
const selectedPeers = torrentPeersTable.selectedRowsIds();
if (selectedPeers.length === 0)
return;
if (confirm('QBT_TR(Are you sure you want to permanently ban the selected peers?)QBT_TR[CONTEXT=PeerListWidget]')) {
new Request({
url: 'api/v2/torrents/banPeers',
noCache: true,
method: 'post',
data: {
hash: torrentsTable.getCurrentTorrentHash(),
peers: selectedPeers.join('|')
}
}).send();
}
}
},
offsets: {
x: -15,
y: 2
},
onShow: function() {
const selectedPeers = torrentPeersTable.selectedRowsIds();
if (selectedPeers.length >= 1) {
this.showItem('copyPeer');
this.showItem('banPeer');
}
else {
this.hideItem('copyPeer');
this.hideItem('banPeer');
}
}
});
new ClipboardJS('#CopyPeerInfo', {
text: function(trigger) {
return torrentPeersTable.selectedRowsIds().join("\n");
}
});
torrentPeersTable.setup('torrentPeersTableDiv', 'torrentPeersTableFixedHeaderDiv', torrentPeersContextMenu);

View File

@ -2,6 +2,7 @@
<qresource prefix="/www">
<file>private/about.html</file>
<file>private/aboutToolbar.html</file>
<file>private/addpeers.html</file>
<file>private/addtrackers.html</file>
<file>private/confirmdeletion.html</file>
<file>private/css/Core.css</file>