diff --git a/src/base/bittorrent/torrent.h b/src/base/bittorrent/torrent.h
index 644af158b..f3b62c1c9 100644
--- a/src/base/bittorrent/torrent.h
+++ b/src/base/bittorrent/torrent.h
@@ -282,6 +282,7 @@ namespace BitTorrent
virtual int maxInactiveSeedingTime() const = 0;
virtual qreal realRatio() const = 0;
virtual qreal popularity() const = 0;
+ virtual qreal importance() const = 0;
virtual int uploadPayloadRate() const = 0;
virtual int downloadPayloadRate() const = 0;
virtual qlonglong totalPayloadUpload() const = 0;
diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp
index c3a7c0f2b..a1ecb010b 100644
--- a/src/base/bittorrent/torrentimpl.cpp
+++ b/src/base/bittorrent/torrentimpl.cpp
@@ -1572,6 +1572,25 @@ qreal TorrentImpl::popularity() const
return (activeMonths > 0) ? (realRatio() / activeMonths) : 0;
}
+qreal TorrentImpl::importance() const
+{
+ // Popularity divided by seed count is a much better measure of how important you are as a seed for a torrent than popularity alone
+ const qreal pop = popularity();
+ const int seeds = totalSeedsCount();
+
+ if (seeds > 0)
+ {
+ return pop / seeds;
+ }
+
+ if (pop > 0)
+ {
+ return Torrent::MAX_RATIO;
+ }
+
+ return 0.0;
+}
+
void TorrentImpl::setName(const QString &name)
{
if (m_name != name)
diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h
index 2c1f9af77..e99554f2d 100644
--- a/src/base/bittorrent/torrentimpl.h
+++ b/src/base/bittorrent/torrentimpl.h
@@ -209,6 +209,7 @@ namespace BitTorrent
int maxInactiveSeedingTime() const override;
qreal realRatio() const override;
qreal popularity() const override;
+ qreal importance() const override;
int uploadPayloadRate() const override;
int downloadPayloadRate() const override;
qlonglong totalPayloadUpload() const override;
diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp
index d86f5a074..a2128fa68 100644
--- a/src/gui/properties/propertieswidget.cpp
+++ b/src/gui/properties/propertieswidget.cpp
@@ -227,6 +227,7 @@ void PropertiesWidget::clear()
m_ui->labelReannounceInVal->clear();
m_ui->labelShareRatioVal->clear();
m_ui->labelPopularityVal->clear();
+ m_ui->labelImportanceVal->clear();
m_ui->listWebSeeds->clear();
m_ui->labelETAVal->clear();
m_ui->labelSeedsVal->clear();
@@ -446,6 +447,9 @@ void PropertiesWidget::loadDynamicData()
const qreal popularity = m_torrent->popularity();
m_ui->labelPopularityVal->setText(popularity >= BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(popularity, 2));
+ const qreal importance = m_torrent->importance();
+ m_ui->labelImportanceVal->setText(importance >= BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(importance, 2));
+
m_ui->labelSeedsVal->setText(tr("%1 (%2 total)", "%1 and %2 are numbers, e.g. 3 (10 total)")
.arg(QString::number(m_torrent->seedsCount())
, QString::number(m_torrent->totalSeedsCount())));
diff --git a/src/gui/properties/propertieswidget.ui b/src/gui/properties/propertieswidget.ui
index dd21f6fef..574d256f0 100644
--- a/src/gui/properties/propertieswidget.ui
+++ b/src/gui/properties/propertieswidget.ui
@@ -633,6 +633,41 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Popularity / Total Seeds, shows how important the specific seeder is.
+
+
+ Importance:
+
+
+ Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Popularity / Total Seeds, shows how important the specific seeder is.
+
+
+ Qt::TextFormat::PlainText
+
+
+
diff --git a/src/gui/transferlistmodel.cpp b/src/gui/transferlistmodel.cpp
index 0298db047..d3ed311fe 100644
--- a/src/gui/transferlistmodel.cpp
+++ b/src/gui/transferlistmodel.cpp
@@ -168,6 +168,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
case TR_UPSPEED: return tr("Up Speed", "i.e: Upload speed");
case TR_RATIO: return tr("Ratio", "Share ratio");
case TR_POPULARITY: return tr("Popularity");
+ case TR_IMPORTANCE: return tr("Importance");
case TR_ETA: return tr("ETA", "i.e: Estimated Time of Arrival / Time left");
case TR_CATEGORY: return tr("Category");
case TR_TAGS: return tr("Tags");
@@ -202,6 +203,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
switch (section)
{
case TR_POPULARITY: return tr("Ratio / Time Active (in months), indicates how popular the torrent is");
+ case TR_IMPORTANCE: return tr("Popularity / Total Seeds, shows how important the specific seeder is.");
default: return {};
}
}
@@ -227,6 +229,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
case TR_RATIO_LIMIT:
case TR_RATIO:
case TR_POPULARITY:
+ case TR_IMPORTANCE:
case TR_QUEUE_POSITION:
case TR_LAST_ACTIVITY:
case TR_AVAILABILITY:
@@ -395,6 +398,8 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons
return ratioString(torrent->maxRatio());
case TR_POPULARITY:
return ratioString(torrent->popularity());
+ case TR_IMPORTANCE:
+ return ratioString(torrent->importance());
case TR_CATEGORY:
return torrent->category();
case TR_TAGS:
@@ -476,6 +481,8 @@ QVariant TransferListModel::internalValue(const BitTorrent::Torrent *torrent, co
return torrent->realRatio();
case TR_POPULARITY:
return torrent->popularity();
+ case TR_IMPORTANCE:
+ return torrent->importance();
case TR_CATEGORY:
return torrent->category();
case TR_TAGS:
@@ -588,6 +595,7 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
case TR_RATIO_LIMIT:
case TR_RATIO:
case TR_POPULARITY:
+ case TR_IMPORTANCE:
case TR_QUEUE_POSITION:
case TR_LAST_ACTIVITY:
case TR_AVAILABILITY:
diff --git a/src/gui/transferlistmodel.h b/src/gui/transferlistmodel.h
index 306beee0b..d3f744244 100644
--- a/src/gui/transferlistmodel.h
+++ b/src/gui/transferlistmodel.h
@@ -63,6 +63,7 @@ public:
TR_ETA,
TR_RATIO,
TR_POPULARITY,
+ TR_IMPORTANCE,
TR_CATEGORY,
TR_TAGS,
TR_ADD_DATE,
diff --git a/src/gui/transferlistsortmodel.cpp b/src/gui/transferlistsortmodel.cpp
index 782aead74..2ed0e8eaf 100644
--- a/src/gui/transferlistsortmodel.cpp
+++ b/src/gui/transferlistsortmodel.cpp
@@ -210,6 +210,9 @@ int TransferListSortModel::compare(const QModelIndex &left, const QModelIndex &r
case TransferListModel::TR_POPULARITY:
return customCompare(leftValue.toReal(), rightValue.toReal());
+ case TransferListModel::TR_IMPORTANCE:
+ return customCompare(leftValue.toReal(), rightValue.toReal());
+
case TransferListModel::TR_STATUS:
return threeWayCompare(leftValue.toInt(), rightValue.toInt());
diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp
index 6fb71bfaa..d3f8c3a25 100644
--- a/src/gui/transferlistwidget.cpp
+++ b/src/gui/transferlistwidget.cpp
@@ -187,6 +187,7 @@ TransferListWidget::TransferListWidget(IGUIApplication *app, QWidget *parent)
setColumnHidden(TransferListModel::TR_COMPLETED, true);
setColumnHidden(TransferListModel::TR_RATIO_LIMIT, true);
setColumnHidden(TransferListModel::TR_POPULARITY, true);
+ setColumnHidden(TransferListModel::TR_IMPORTANCE, true);
setColumnHidden(TransferListModel::TR_SEEN_COMPLETE_DATE, true);
setColumnHidden(TransferListModel::TR_LAST_ACTIVITY, true);
setColumnHidden(TransferListModel::TR_TOTAL_SIZE, true);
diff --git a/src/webui/api/serialize/serialize_torrent.cpp b/src/webui/api/serialize/serialize_torrent.cpp
index 94c83a934..4f67ad5d4 100644
--- a/src/webui/api/serialize/serialize_torrent.cpp
+++ b/src/webui/api/serialize/serialize_torrent.cpp
@@ -169,6 +169,7 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent)
{KEY_TORRENT_RATIO, adjustRatio(torrent.realRatio())},
{KEY_TORRENT_RATIO_LIMIT, torrent.ratioLimit()},
{KEY_TORRENT_POPULARITY, torrent.popularity()},
+ {KEY_TORRENT_IMPORTANCE, adjustRatio(torrent.importance())},
{KEY_TORRENT_SEEDING_TIME_LIMIT, torrent.seedingTimeLimit()},
{KEY_TORRENT_INACTIVE_SEEDING_TIME_LIMIT, torrent.inactiveSeedingTimeLimit()},
{KEY_TORRENT_LAST_SEEN_COMPLETE_TIME, Utils::DateTime::toSecsSinceEpoch(torrent.lastSeenComplete())},
diff --git a/src/webui/api/serialize/serialize_torrent.h b/src/webui/api/serialize/serialize_torrent.h
index 438960e7f..2b34c6fda 100644
--- a/src/webui/api/serialize/serialize_torrent.h
+++ b/src/webui/api/serialize/serialize_torrent.h
@@ -55,6 +55,7 @@ inline const QString KEY_TORRENT_LEECHS = u"num_leechs"_s;
inline const QString KEY_TORRENT_NUM_INCOMPLETE = u"num_incomplete"_s;
inline const QString KEY_TORRENT_RATIO = u"ratio"_s;
inline const QString KEY_TORRENT_POPULARITY = u"popularity"_s;
+inline const QString KEY_TORRENT_IMPORTANCE = u"importance"_s;
inline const QString KEY_TORRENT_ETA = u"eta"_s;
inline const QString KEY_TORRENT_STATE = u"state"_s;
inline const QString KEY_TORRENT_SEQUENTIAL_DOWNLOAD = u"seq_dl"_s;
diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp
index 9e9a4ebf6..662e823c3 100644
--- a/src/webui/api/torrentscontroller.cpp
+++ b/src/webui/api/torrentscontroller.cpp
@@ -102,6 +102,7 @@ const QString KEY_PROP_PEERS = u"peers"_s;
const QString KEY_PROP_PEERS_TOTAL = u"peers_total"_s;
const QString KEY_PROP_RATIO = u"share_ratio"_s;
const QString KEY_PROP_POPULARITY = u"popularity"_s;
+const QString KEY_PROP_IMPORTANCE = u"importance"_s;
const QString KEY_PROP_REANNOUNCE = u"reannounce"_s;
const QString KEY_PROP_TOTAL_SIZE = u"total_size"_s;
const QString KEY_PROP_PIECES_NUM = u"pieces_num"_s;
@@ -637,6 +638,7 @@ void TorrentsController::infoAction()
// - "peers_total": Torrent total number of peers
// - "share_ratio": Torrent share ratio
// - "popularity": Torrent popularity
+// - "importance": Torrent importance
// - "reannounce": Torrent next reannounce time
// - "total_size": Torrent total size
// - "pieces_num": Torrent pieces count
@@ -672,6 +674,7 @@ void TorrentsController::propertiesAction()
const int uploadLimit = torrent->uploadLimit();
const qreal ratio = torrent->realRatio();
const qreal popularity = torrent->popularity();
+ const qreal importance = torrent->importance();
const bool hasMetadata = torrent->hasMetadata();
const bool isPrivate = torrent->isPrivate();
@@ -703,6 +706,7 @@ void TorrentsController::propertiesAction()
{KEY_PROP_PEERS_TOTAL, torrent->totalLeechersCount()},
{KEY_PROP_RATIO, ((ratio >= BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio)},
{KEY_PROP_POPULARITY, ((popularity >= BitTorrent::Torrent::MAX_RATIO) ? -1 : popularity)},
+ {KEY_PROP_IMPORTANCE, ((importance >= BitTorrent::Torrent::MAX_RATIO) ? -1 : importance)},
{KEY_PROP_REANNOUNCE, torrent->nextAnnounce()},
{KEY_PROP_TOTAL_SIZE, torrent->totalSize()},
{KEY_PROP_PIECES_NUM, torrent->piecesCount()},
diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js
index 032a79a1e..dbdf8a0c8 100644
--- a/src/webui/www/private/scripts/dynamicTable.js
+++ b/src/webui/www/private/scripts/dynamicTable.js
@@ -1116,6 +1116,7 @@ window.qBittorrent.DynamicTable ??= (() => {
this.newColumn("eta", "", "QBT_TR(ETA)QBT_TR[CONTEXT=TransferListModel]", 100, true);
this.newColumn("ratio", "", "QBT_TR(Ratio)QBT_TR[CONTEXT=TransferListModel]", 100, true);
this.newColumn("popularity", "", "QBT_TR(Popularity)QBT_TR[CONTEXT=TransferListModel]", 100, true);
+ this.newColumn("importance", "", "QBT_TR(Importance)QBT_TR[CONTEXT=TransferListModel]", 100, true);
this.newColumn("category", "", "QBT_TR(Category)QBT_TR[CONTEXT=TransferListModel]", 100, true);
this.newColumn("tags", "", "QBT_TR(Tags)QBT_TR[CONTEXT=TransferListModel]", 100, true);
this.newColumn("added_on", "", "QBT_TR(Added On)QBT_TR[CONTEXT=TransferListModel]", 100, true);
@@ -1419,6 +1420,14 @@ window.qBittorrent.DynamicTable ??= (() => {
td.title = popularity;
};
+ // importance
+ this.columns["importance"].updateId = function(td, row) {
+ const value = this.getRowValue(row);
+ const importance = (value === -1) ? "∞" : window.qBittorrent.Misc.toFixedPointString(value, 2);
+ td.textContent = importance;
+ td.title = importance;
+ };
+
// added on
this.columns["added_on"].updateTd = function(td, row) {
const date = new Date(this.getRowValue(row) * 1000).toLocaleString();
diff --git a/src/webui/www/private/scripts/prop-general.js b/src/webui/www/private/scripts/prop-general.js
index fce3c84a6..5bf45f8be 100644
--- a/src/webui/www/private/scripts/prop-general.js
+++ b/src/webui/www/private/scripts/prop-general.js
@@ -58,6 +58,7 @@ window.qBittorrent.PropGeneral ??= (() => {
document.getElementById("peers").textContent = "";
document.getElementById("share_ratio").textContent = "";
document.getElementById("popularity").textContent = "";
+ document.getElementById("importance").textContent = "";
document.getElementById("reannounce").textContent = "";
document.getElementById("last_seen").textContent = "";
document.getElementById("total_size").textContent = "";
@@ -174,6 +175,8 @@ window.qBittorrent.PropGeneral ??= (() => {
document.getElementById("popularity").textContent = data.popularity.toFixed(2);
+ document.getElementById("importance").textContent = (data.importance === -1) ? "∞" : data.importance.toFixed(2);
+
document.getElementById("reannounce").textContent = window.qBittorrent.Misc.friendlyDuration(data.reannounce);
const lastSeen = (data.last_seen >= 0)
diff --git a/src/webui/www/private/views/properties.html b/src/webui/www/private/views/properties.html
index fbcaa1d53..e4b30f3a7 100644
--- a/src/webui/www/private/views/properties.html
+++ b/src/webui/www/private/views/properties.html
@@ -52,6 +52,9 @@
QBT_TR(Popularity:)QBT_TR[CONTEXT=PropertiesWidget] |
|
+
+ QBT_TR(Importance:)QBT_TR[CONTEXT=PropertiesWidget] |
+ |