This commit is contained in:
VioPaige 2025-08-19 05:20:09 +08:00 committed by GitHub
commit 77538599dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 94 additions and 0 deletions

View file

@ -283,6 +283,7 @@ namespace BitTorrent
virtual int maxInactiveSeedingTime() const = 0; virtual int maxInactiveSeedingTime() const = 0;
virtual qreal realRatio() const = 0; virtual qreal realRatio() const = 0;
virtual qreal popularity() const = 0; virtual qreal popularity() const = 0;
virtual qreal importance() const = 0;
virtual int uploadPayloadRate() const = 0; virtual int uploadPayloadRate() const = 0;
virtual int downloadPayloadRate() const = 0; virtual int downloadPayloadRate() const = 0;
virtual qlonglong totalPayloadUpload() const = 0; virtual qlonglong totalPayloadUpload() const = 0;

View file

@ -1584,6 +1584,25 @@ qreal TorrentImpl::popularity() const
return (activeMonths > 0) ? (realRatio() / activeMonths) : 0; 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) void TorrentImpl::setName(const QString &name)
{ {
if (m_name != name) if (m_name != name)

View file

@ -210,6 +210,7 @@ namespace BitTorrent
int maxInactiveSeedingTime() const override; int maxInactiveSeedingTime() const override;
qreal realRatio() const override; qreal realRatio() const override;
qreal popularity() const override; qreal popularity() const override;
qreal importance() const override;
int uploadPayloadRate() const override; int uploadPayloadRate() const override;
int downloadPayloadRate() const override; int downloadPayloadRate() const override;
qlonglong totalPayloadUpload() const override; qlonglong totalPayloadUpload() const override;

View file

@ -227,6 +227,7 @@ void PropertiesWidget::clear()
m_ui->labelReannounceInVal->clear(); m_ui->labelReannounceInVal->clear();
m_ui->labelShareRatioVal->clear(); m_ui->labelShareRatioVal->clear();
m_ui->labelPopularityVal->clear(); m_ui->labelPopularityVal->clear();
m_ui->labelImportanceVal->clear();
m_ui->listWebSeeds->clear(); m_ui->listWebSeeds->clear();
m_ui->labelETAVal->clear(); m_ui->labelETAVal->clear();
m_ui->labelSeedsVal->clear(); m_ui->labelSeedsVal->clear();
@ -446,6 +447,9 @@ void PropertiesWidget::loadDynamicData()
const qreal popularity = m_torrent->popularity(); const qreal popularity = m_torrent->popularity();
m_ui->labelPopularityVal->setText(popularity >= BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(popularity, 2)); 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)") m_ui->labelSeedsVal->setText(tr("%1 (%2 total)", "%1 and %2 are numbers, e.g. 3 (10 total)")
.arg(QString::number(m_torrent->seedsCount()) .arg(QString::number(m_torrent->seedsCount())
, QString::number(m_torrent->totalSeedsCount()))); , QString::number(m_torrent->totalSeedsCount())));

View file

@ -633,6 +633,41 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0">
<widget class="QLabel" name="labelImportance">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Popularity / Total Seeds, shows how important the specific seeder is.</string>
</property>
<property name="text">
<string>Importance:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="labelImportanceVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Popularity / Total Seeds, shows how important the specific seeder is.</string>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View file

@ -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_UPSPEED: return tr("Up Speed", "i.e: Upload speed");
case TR_RATIO: return tr("Ratio", "Share ratio"); case TR_RATIO: return tr("Ratio", "Share ratio");
case TR_POPULARITY: return tr("Popularity"); 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_ETA: return tr("ETA", "i.e: Estimated Time of Arrival / Time left");
case TR_CATEGORY: return tr("Category"); case TR_CATEGORY: return tr("Category");
case TR_TAGS: return tr("Tags"); case TR_TAGS: return tr("Tags");
@ -202,6 +203,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
switch (section) switch (section)
{ {
case TR_POPULARITY: return tr("Ratio / Time Active (in months), indicates how popular the torrent is"); 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 {}; default: return {};
} }
} }
@ -227,6 +229,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
case TR_RATIO_LIMIT: case TR_RATIO_LIMIT:
case TR_RATIO: case TR_RATIO:
case TR_POPULARITY: case TR_POPULARITY:
case TR_IMPORTANCE:
case TR_QUEUE_POSITION: case TR_QUEUE_POSITION:
case TR_LAST_ACTIVITY: case TR_LAST_ACTIVITY:
case TR_AVAILABILITY: case TR_AVAILABILITY:
@ -395,6 +398,8 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons
return ratioString(torrent->maxRatio()); return ratioString(torrent->maxRatio());
case TR_POPULARITY: case TR_POPULARITY:
return ratioString(torrent->popularity()); return ratioString(torrent->popularity());
case TR_IMPORTANCE:
return ratioString(torrent->importance());
case TR_CATEGORY: case TR_CATEGORY:
return torrent->category(); return torrent->category();
case TR_TAGS: case TR_TAGS:
@ -476,6 +481,8 @@ QVariant TransferListModel::internalValue(const BitTorrent::Torrent *torrent, co
return torrent->realRatio(); return torrent->realRatio();
case TR_POPULARITY: case TR_POPULARITY:
return torrent->popularity(); return torrent->popularity();
case TR_IMPORTANCE:
return torrent->importance();
case TR_CATEGORY: case TR_CATEGORY:
return torrent->category(); return torrent->category();
case TR_TAGS: case TR_TAGS:
@ -592,6 +599,7 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
case TR_RATIO_LIMIT: case TR_RATIO_LIMIT:
case TR_RATIO: case TR_RATIO:
case TR_POPULARITY: case TR_POPULARITY:
case TR_IMPORTANCE:
case TR_QUEUE_POSITION: case TR_QUEUE_POSITION:
case TR_LAST_ACTIVITY: case TR_LAST_ACTIVITY:
case TR_AVAILABILITY: case TR_AVAILABILITY:

View file

@ -63,6 +63,7 @@ public:
TR_ETA, TR_ETA,
TR_RATIO, TR_RATIO,
TR_POPULARITY, TR_POPULARITY,
TR_IMPORTANCE,
TR_CATEGORY, TR_CATEGORY,
TR_TAGS, TR_TAGS,
TR_ADD_DATE, TR_ADD_DATE,

View file

@ -210,6 +210,9 @@ int TransferListSortModel::compare(const QModelIndex &left, const QModelIndex &r
case TransferListModel::TR_POPULARITY: case TransferListModel::TR_POPULARITY:
return customCompare(leftValue.toReal(), rightValue.toReal()); return customCompare(leftValue.toReal(), rightValue.toReal());
case TransferListModel::TR_IMPORTANCE:
return customCompare(leftValue.toReal(), rightValue.toReal());
case TransferListModel::TR_STATUS: case TransferListModel::TR_STATUS:
return threeWayCompare(leftValue.toInt(), rightValue.toInt()); return threeWayCompare(leftValue.toInt(), rightValue.toInt());

View file

@ -187,6 +187,7 @@ TransferListWidget::TransferListWidget(IGUIApplication *app, QWidget *parent)
setColumnHidden(TransferListModel::TR_COMPLETED, true); setColumnHidden(TransferListModel::TR_COMPLETED, true);
setColumnHidden(TransferListModel::TR_RATIO_LIMIT, true); setColumnHidden(TransferListModel::TR_RATIO_LIMIT, true);
setColumnHidden(TransferListModel::TR_POPULARITY, true); setColumnHidden(TransferListModel::TR_POPULARITY, true);
setColumnHidden(TransferListModel::TR_IMPORTANCE, true);
setColumnHidden(TransferListModel::TR_SEEN_COMPLETE_DATE, true); setColumnHidden(TransferListModel::TR_SEEN_COMPLETE_DATE, true);
setColumnHidden(TransferListModel::TR_LAST_ACTIVITY, true); setColumnHidden(TransferListModel::TR_LAST_ACTIVITY, true);
setColumnHidden(TransferListModel::TR_TOTAL_SIZE, true); setColumnHidden(TransferListModel::TR_TOTAL_SIZE, true);

View file

@ -169,6 +169,7 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent)
{KEY_TORRENT_RATIO, adjustRatio(torrent.realRatio())}, {KEY_TORRENT_RATIO, adjustRatio(torrent.realRatio())},
{KEY_TORRENT_RATIO_LIMIT, torrent.ratioLimit()}, {KEY_TORRENT_RATIO_LIMIT, torrent.ratioLimit()},
{KEY_TORRENT_POPULARITY, torrent.popularity()}, {KEY_TORRENT_POPULARITY, torrent.popularity()},
{KEY_TORRENT_IMPORTANCE, adjustRatio(torrent.importance())},
{KEY_TORRENT_SEEDING_TIME_LIMIT, torrent.seedingTimeLimit()}, {KEY_TORRENT_SEEDING_TIME_LIMIT, torrent.seedingTimeLimit()},
{KEY_TORRENT_INACTIVE_SEEDING_TIME_LIMIT, torrent.inactiveSeedingTimeLimit()}, {KEY_TORRENT_INACTIVE_SEEDING_TIME_LIMIT, torrent.inactiveSeedingTimeLimit()},
{KEY_TORRENT_SHARE_LIMIT_ACTION, Utils::String::fromEnum(torrent.shareLimitAction())}, {KEY_TORRENT_SHARE_LIMIT_ACTION, Utils::String::fromEnum(torrent.shareLimitAction())},

View file

@ -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_NUM_INCOMPLETE = u"num_incomplete"_s;
inline const QString KEY_TORRENT_RATIO = u"ratio"_s; inline const QString KEY_TORRENT_RATIO = u"ratio"_s;
inline const QString KEY_TORRENT_POPULARITY = u"popularity"_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_ETA = u"eta"_s;
inline const QString KEY_TORRENT_STATE = u"state"_s; inline const QString KEY_TORRENT_STATE = u"state"_s;
inline const QString KEY_TORRENT_SEQUENTIAL_DOWNLOAD = u"seq_dl"_s; inline const QString KEY_TORRENT_SEQUENTIAL_DOWNLOAD = u"seq_dl"_s;

View file

@ -109,6 +109,7 @@ const QString KEY_PROP_PEERS = u"peers"_s;
const QString KEY_PROP_PEERS_TOTAL = u"peers_total"_s; const QString KEY_PROP_PEERS_TOTAL = u"peers_total"_s;
const QString KEY_PROP_RATIO = u"share_ratio"_s; const QString KEY_PROP_RATIO = u"share_ratio"_s;
const QString KEY_PROP_POPULARITY = u"popularity"_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_REANNOUNCE = u"reannounce"_s;
const QString KEY_PROP_TOTAL_SIZE = u"total_size"_s; const QString KEY_PROP_TOTAL_SIZE = u"total_size"_s;
const QString KEY_PROP_PIECES_NUM = u"pieces_num"_s; const QString KEY_PROP_PIECES_NUM = u"pieces_num"_s;
@ -672,6 +673,7 @@ void TorrentsController::infoAction()
// - "peers_total": Torrent total number of peers // - "peers_total": Torrent total number of peers
// - "share_ratio": Torrent share ratio // - "share_ratio": Torrent share ratio
// - "popularity": Torrent popularity // - "popularity": Torrent popularity
// - "importance": Torrent importance
// - "reannounce": Torrent next reannounce time // - "reannounce": Torrent next reannounce time
// - "total_size": Torrent total size // - "total_size": Torrent total size
// - "pieces_num": Torrent pieces count // - "pieces_num": Torrent pieces count
@ -707,6 +709,7 @@ void TorrentsController::propertiesAction()
const int uploadLimit = torrent->uploadLimit(); const int uploadLimit = torrent->uploadLimit();
const qreal ratio = torrent->realRatio(); const qreal ratio = torrent->realRatio();
const qreal popularity = torrent->popularity(); const qreal popularity = torrent->popularity();
const qreal importance = torrent->importance();
const bool hasMetadata = torrent->hasMetadata(); const bool hasMetadata = torrent->hasMetadata();
const bool isPrivate = torrent->isPrivate(); const bool isPrivate = torrent->isPrivate();
@ -738,6 +741,7 @@ void TorrentsController::propertiesAction()
{KEY_PROP_PEERS_TOTAL, torrent->totalLeechersCount()}, {KEY_PROP_PEERS_TOTAL, torrent->totalLeechersCount()},
{KEY_PROP_RATIO, ((ratio >= BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio)}, {KEY_PROP_RATIO, ((ratio >= BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio)},
{KEY_PROP_POPULARITY, ((popularity >= BitTorrent::Torrent::MAX_RATIO) ? -1 : popularity)}, {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_REANNOUNCE, torrent->nextAnnounce()},
{KEY_PROP_TOTAL_SIZE, torrent->totalSize()}, {KEY_PROP_TOTAL_SIZE, torrent->totalSize()},
{KEY_PROP_PIECES_NUM, torrent->piecesCount()}, {KEY_PROP_PIECES_NUM, torrent->piecesCount()},

View file

@ -1120,6 +1120,7 @@ window.qBittorrent.DynamicTable ??= (() => {
this.newColumn("eta", "", "QBT_TR(ETA)QBT_TR[CONTEXT=TransferListModel]", 100, true); 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("ratio", "", "QBT_TR(Ratio)QBT_TR[CONTEXT=TransferListModel]", 100, true);
this.newColumn("popularity", "", "QBT_TR(Popularity)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("category", "", "QBT_TR(Category)QBT_TR[CONTEXT=TransferListModel]", 100, true);
this.newColumn("tags", "", "QBT_TR(Tags)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); this.newColumn("added_on", "", "QBT_TR(Added On)QBT_TR[CONTEXT=TransferListModel]", 100, true);
@ -1423,6 +1424,14 @@ window.qBittorrent.DynamicTable ??= (() => {
td.title = popularity; 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 // added on
this.columns["added_on"].updateTd = function(td, row) { this.columns["added_on"].updateTd = function(td, row) {
const date = new Date(this.getRowValue(row) * 1000).toLocaleString(); const date = new Date(this.getRowValue(row) * 1000).toLocaleString();

View file

@ -58,6 +58,7 @@ window.qBittorrent.PropGeneral ??= (() => {
document.getElementById("peers").textContent = ""; document.getElementById("peers").textContent = "";
document.getElementById("share_ratio").textContent = ""; document.getElementById("share_ratio").textContent = "";
document.getElementById("popularity").textContent = ""; document.getElementById("popularity").textContent = "";
document.getElementById("importance").textContent = "";
document.getElementById("reannounce").textContent = ""; document.getElementById("reannounce").textContent = "";
document.getElementById("last_seen").textContent = ""; document.getElementById("last_seen").textContent = "";
document.getElementById("total_size").textContent = ""; document.getElementById("total_size").textContent = "";
@ -174,6 +175,8 @@ window.qBittorrent.PropGeneral ??= (() => {
document.getElementById("popularity").textContent = data.popularity.toFixed(2); 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); document.getElementById("reannounce").textContent = window.qBittorrent.Misc.friendlyDuration(data.reannounce);
const lastSeen = (data.last_seen >= 0) const lastSeen = (data.last_seen >= 0)

View file

@ -52,6 +52,9 @@
<tr> <tr>
<td class="generalLabel" title="QBT_TR(Ratio / Time Active (in months), indicates how popular the torrent is)QBT_TR[CONTEXT=PropertiesWidget]">QBT_TR(Popularity:)QBT_TR[CONTEXT=PropertiesWidget]</td> <td class="generalLabel" title="QBT_TR(Ratio / Time Active (in months), indicates how popular the torrent is)QBT_TR[CONTEXT=PropertiesWidget]">QBT_TR(Popularity:)QBT_TR[CONTEXT=PropertiesWidget]</td>
<td id="popularity" title="QBT_TR(Ratio / Time Active (in months), indicates how popular the torrent is)QBT_TR[CONTEXT=PropertiesWidget]"></td> <td id="popularity" title="QBT_TR(Ratio / Time Active (in months), indicates how popular the torrent is)QBT_TR[CONTEXT=PropertiesWidget]"></td>
<td class="generalLabel" title="QBT_TR(Popularity / Total Seeds (Higher number implies it is more 'important' to seed the torrent))QBT_TR[CONTEXT=PropertiesWidget]">QBT_TR(Importance:)QBT_TR[CONTEXT=PropertiesWidget]</td>
<td id="importance" title="QBT_TR(Popularity / Total Seeds (Higher number implies it is more 'important' to seed the torrent))QBT_TR[CONTEXT=PropertiesWidget]"></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>