Browse Source

- Support per-peer rate limiting

adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
47fc4679d4
  1. 1
      Changelog
  2. 4
      src/TransferListWidget.cpp
  3. 71
      src/peerlistwidget.cpp
  4. 3
      src/peerlistwidget.h
  5. 10
      src/qtorrenthandle.cpp
  6. 2
      src/qtorrenthandle.h

1
Changelog

@ -23,6 +23,7 @@
- FEATURE: Seeds and Peers columns are now sortable - FEATURE: Seeds and Peers columns are now sortable
- FEATURE: Torrents can be rechecked from Web UI (Stephanos Antaris) - FEATURE: Torrents can be rechecked from Web UI (Stephanos Antaris)
- FEATURE: New peers can manually be added to the torrents - FEATURE: New peers can manually be added to the torrents
- FEATURE: Support per-peer rate limiting
- COSMETIC: Merged download / upload lists - COSMETIC: Merged download / upload lists
- COSMETIC: Torrents can be filtered based on their status - COSMETIC: Torrents can be filtered based on their status
- COSMETIC: Torrent properties are now displayed in main window - COSMETIC: Torrent properties are now displayed in main window

4
src/TransferListWidget.cpp

@ -709,9 +709,9 @@ void TransferListWidget::displayListMenu(const QPoint&) {
connect(&actionDelete, SIGNAL(triggered()), this, SLOT(deleteSelectedTorrents())); connect(&actionDelete, SIGNAL(triggered()), this, SLOT(deleteSelectedTorrents()));
QAction actionPreview_file(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")), tr("Preview file"), 0); QAction actionPreview_file(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")), tr("Preview file"), 0);
connect(&actionPreview_file, SIGNAL(triggered()), this, SLOT(previewSelectedTorrents())); connect(&actionPreview_file, SIGNAL(triggered()), this, SLOT(previewSelectedTorrents()));
QAction actionSet_upload_limit(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")), tr("Set upload limit"), 0); QAction actionSet_upload_limit(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")), tr("Limit upload rate"), 0);
connect(&actionSet_upload_limit, SIGNAL(triggered()), this, SLOT(setUpLimitSelectedTorrents())); connect(&actionSet_upload_limit, SIGNAL(triggered()), this, SLOT(setUpLimitSelectedTorrents()));
QAction actionSet_download_limit(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")), tr("Set download limit"), 0); QAction actionSet_download_limit(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")), tr("Limit download rate"), 0);
connect(&actionSet_download_limit, SIGNAL(triggered()), this, SLOT(setDlLimitSelectedTorrents())); connect(&actionSet_download_limit, SIGNAL(triggered()), this, SLOT(setDlLimitSelectedTorrents()));
QAction actionDelete_Permanently(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")), tr("Delete Permanently"), 0); QAction actionDelete_Permanently(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")), tr("Delete Permanently"), 0);
connect(&actionDelete_Permanently, SIGNAL(triggered()), this, SLOT(deletePermSelectedTorrents())); connect(&actionDelete_Permanently, SIGNAL(triggered()), this, SLOT(deletePermSelectedTorrents()));

71
src/peerlistwidget.cpp

@ -35,6 +35,7 @@
#include "propertieswidget.h" #include "propertieswidget.h"
#include "geoip.h" #include "geoip.h"
#include "peeraddition.h" #include "peeraddition.h"
#include "speedlimitdlg.h"
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QSet> #include <QSet>
@ -113,9 +114,23 @@ void PeerListWidget::showPeerListMenu(QPoint) {
QMenu menu; QMenu menu;
QTorrentHandle h = properties->getCurrentTorrent(); QTorrentHandle h = properties->getCurrentTorrent();
if(!h.is_valid()) return; if(!h.is_valid()) return;
QModelIndexList selectedIndexes = selectionModel()->selectedRows();
QStringList selectedPeerIPs;
foreach(const QModelIndex &index, selectedIndexes) {
QString IP = proxyModel->data(index).toString();
selectedPeerIPs << IP;
}
// Add Peer Action
QAction *addPeerAct = 0; QAction *addPeerAct = 0;
if(!h.is_queued() && !h.is_checking()) { if(!h.is_queued() && !h.is_checking()) {
addPeerAct = menu.addAction(QIcon(":/Icons/oxygen/add_peer.png"), "Add a new peer"); addPeerAct = menu.addAction(QIcon(":/Icons/oxygen/add_peer.png"), tr("Add a new peer"));
}
// Per Peer Speed limiting actions
QAction *upLimitAct = 0;
QAction *dlLimitAct = 0;
if(!selectedPeerIPs.isEmpty()) {
upLimitAct = menu.addAction(QIcon(":/Icons/skin/seeding.png"), tr("Limit upload rate"));
dlLimitAct = menu.addAction(QIcon(":/Icons/skin/downloading.png"), tr("Limit download rate"));
} }
QAction *act = menu.exec(QCursor::pos()); QAction *act = menu.exec(QCursor::pos());
if(act == addPeerAct) { if(act == addPeerAct) {
@ -132,11 +147,63 @@ void PeerListWidget::showPeerListMenu(QPoint) {
} }
return; return;
} }
if(act == upLimitAct) {
limitUpRateSelectedPeers(selectedPeerIPs);
return;
}
if(act == dlLimitAct) {
limitDlRateSelectedPeers(selectedPeerIPs);
return;
}
} }
void PeerListWidget::limitUpRateSelectedPeers(QStringList peer_ips) {
QTorrentHandle h = properties->getCurrentTorrent();
if(!h.is_valid()) return;
bool ok=false;
long limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Upload rate limiting"), -1);
if(!ok) return;
foreach(const QString &ip, peer_ips) {
boost::asio::ip::tcp::endpoint ep = peerEndpoints.value(ip, boost::asio::ip::tcp::endpoint());
if(ep != boost::asio::ip::tcp::endpoint()) {
qDebug("Settings Upload limit of %.1f Kb/s to peer %s", limit/1024., ip.toLocal8Bit().data());
try {
h.set_peer_upload_limit(ep, limit);
}catch(std::exception) {
std::cerr << "Impossible to apply upload limit to peer" << std::endl;
}
} else {
qDebug("The selected peer no longer exists...");
}
}
}
void PeerListWidget::limitDlRateSelectedPeers(QStringList peer_ips) {
QTorrentHandle h = properties->getCurrentTorrent();
if(!h.is_valid()) return;
bool ok=false;
long limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Download rate limiting"), -1);
if(!ok) return;
foreach(const QString &ip, peer_ips) {
boost::asio::ip::tcp::endpoint ep = peerEndpoints.value(ip, boost::asio::ip::tcp::endpoint());
if(ep != boost::asio::ip::tcp::endpoint()) {
qDebug("Settings Download limit of %.1f Kb/s to peer %s", limit/1024., ip.toLocal8Bit().data());
try {
h.set_peer_download_limit(ep, limit);
}catch(std::exception) {
std::cerr << "Impossible to apply download limit to peer" << std::endl;
}
} else {
qDebug("The selected peer no longer exists...");
}
}
}
void PeerListWidget::clear() { void PeerListWidget::clear() {
qDebug("clearing peer list"); qDebug("clearing peer list");
peerItems.clear(); peerItems.clear();
peerEndpoints.clear();
missingFlags.clear(); missingFlags.clear();
int nbrows = listModel->rowCount(); int nbrows = listModel->rowCount();
if(nbrows > 0) { if(nbrows > 0) {
@ -184,6 +251,7 @@ void PeerListWidget::loadPeers(const QTorrentHandle &h, bool force_hostname_reso
} else { } else {
// Add new peer // Add new peer
peerItems[peer_ip] = addPeer(peer_ip, peer); peerItems[peer_ip] = addPeer(peer_ip, peer);
peerEndpoints[peer_ip] = peer.ip;
} }
} }
// Delete peers that are gone // Delete peers that are gone
@ -191,6 +259,7 @@ void PeerListWidget::loadPeers(const QTorrentHandle &h, bool force_hostname_reso
while(it.hasNext()) { while(it.hasNext()) {
QString ip = it.next(); QString ip = it.next();
missingFlags.remove(ip); missingFlags.remove(ip);
peerEndpoints.remove(ip);
QStandardItem *item = peerItems.take(ip); QStandardItem *item = peerItems.take(ip);
listModel->removeRow(item->row()); listModel->removeRow(item->row());
} }

3
src/peerlistwidget.h

@ -53,6 +53,7 @@ private:
PeerListDelegate *listDelegate; PeerListDelegate *listDelegate;
QSortFilterProxyModel * proxyModel; QSortFilterProxyModel * proxyModel;
QHash<QString, QStandardItem*> peerItems; QHash<QString, QStandardItem*> peerItems;
QHash<QString, boost::asio::ip::tcp::endpoint> peerEndpoints;
QSet<QString> missingFlags; QSet<QString> missingFlags;
QPointer<ReverseResolution> resolver; QPointer<ReverseResolution> resolver;
PropertiesWidget* properties; PropertiesWidget* properties;
@ -75,6 +76,8 @@ protected slots:
void loadSettings(); void loadSettings();
void saveSettings() const; void saveSettings() const;
void showPeerListMenu(QPoint); void showPeerListMenu(QPoint);
void limitUpRateSelectedPeers(QStringList peer_ips);
void limitDlRateSelectedPeers(QStringList peer_ips);
}; };
#endif // PEERLISTWIDGET_H #endif // PEERLISTWIDGET_H

10
src/qtorrenthandle.cpp

@ -508,6 +508,16 @@ void QTorrentHandle::connect_peer(asio::ip::tcp::endpoint const& adr, int source
h.connect_peer(adr, source); h.connect_peer(adr, source);
} }
void QTorrentHandle::set_peer_upload_limit(asio::ip::tcp::endpoint ip, int limit) const {
Q_ASSERT(h.is_valid());
h.set_peer_upload_limit(ip, limit);
}
void QTorrentHandle::set_peer_download_limit(asio::ip::tcp::endpoint ip, int limit) const {
Q_ASSERT(h.is_valid());
h.set_peer_download_limit(ip, limit);
}
// //
// Operators // Operators
// //

2
src/qtorrenthandle.h

@ -147,6 +147,8 @@ class QTorrentHandle {
void super_seeding(bool on) const; void super_seeding(bool on) const;
void resolve_countries(bool r); void resolve_countries(bool r);
void connect_peer(asio::ip::tcp::endpoint const& adr, int source = 0) const; void connect_peer(asio::ip::tcp::endpoint const& adr, int source = 0) const;
void set_peer_upload_limit(asio::ip::tcp::endpoint ip, int limit) const;
void set_peer_download_limit(asio::ip::tcp::endpoint ip, int limit) const;
// //
// Operators // Operators

Loading…
Cancel
Save