mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-25 18:56:34 +03:00
parent
8e6515be2c
commit
f37d0c486c
15 changed files with 93 additions and 0 deletions
|
@ -282,6 +282,7 @@ namespace BitTorrent
|
|||
virtual int maxSeedingTime() const = 0;
|
||||
virtual int maxInactiveSeedingTime() const = 0;
|
||||
virtual qreal realRatio() const = 0;
|
||||
virtual qreal popularity() const = 0;
|
||||
virtual int uploadPayloadRate() const = 0;
|
||||
virtual int downloadPayloadRate() const = 0;
|
||||
virtual qlonglong totalPayloadUpload() const = 0;
|
||||
|
|
|
@ -1545,6 +1545,15 @@ qlonglong TorrentImpl::nextAnnounce() const
|
|||
return lt::total_seconds(m_nativeStatus.next_announce);
|
||||
}
|
||||
|
||||
qreal TorrentImpl::popularity() const
|
||||
{
|
||||
// in order to produce floating-point numbers using `std::chrono::duration_cast`,
|
||||
// we should use `qreal` as `Rep` to define the `months` duration
|
||||
using months = std::chrono::duration<qreal, std::chrono::months::period>;
|
||||
const auto activeMonths = std::chrono::duration_cast<months>(m_nativeStatus.active_duration).count();
|
||||
return (activeMonths > 0) ? (realRatio() / activeMonths) : 0;
|
||||
}
|
||||
|
||||
void TorrentImpl::setName(const QString &name)
|
||||
{
|
||||
if (m_name != name)
|
||||
|
|
|
@ -210,6 +210,7 @@ namespace BitTorrent
|
|||
int maxSeedingTime() const override;
|
||||
int maxInactiveSeedingTime() const override;
|
||||
qreal realRatio() const override;
|
||||
qreal popularity() const override;
|
||||
int uploadPayloadRate() const override;
|
||||
int downloadPayloadRate() const override;
|
||||
qlonglong totalPayloadUpload() const override;
|
||||
|
|
|
@ -220,6 +220,7 @@ void PropertiesWidget::clear()
|
|||
m_ui->labelConnectionsVal->clear();
|
||||
m_ui->labelReannounceInVal->clear();
|
||||
m_ui->labelShareRatioVal->clear();
|
||||
m_ui->labelPopularityVal->clear();
|
||||
m_ui->listWebSeeds->clear();
|
||||
m_ui->labelETAVal->clear();
|
||||
m_ui->labelSeedsVal->clear();
|
||||
|
@ -407,6 +408,9 @@ void PropertiesWidget::loadDynamicData()
|
|||
const qreal ratio = m_torrent->realRatio();
|
||||
m_ui->labelShareRatioVal->setText(ratio > BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(ratio, 2));
|
||||
|
||||
const qreal popularity = m_torrent->popularity();
|
||||
m_ui->labelPopularityVal->setText(popularity > BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(popularity, 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())));
|
||||
|
|
|
@ -295,6 +295,25 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="labelPopularity">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Ratio / Time Active (in months), indicates how popular the torrent is</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Popularity:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="labelConnectionsVal">
|
||||
<property name="sizePolicy">
|
||||
|
@ -495,6 +514,22 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="labelPopularityVal">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Ratio / Time Active (in months), indicates how popular the torrent is</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="labelUploaded">
|
||||
<property name="sizePolicy">
|
||||
|
|
|
@ -167,6 +167,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
|
|||
case TR_DLSPEED: return tr("Down Speed", "i.e: Download speed");
|
||||
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_ETA: return tr("ETA", "i.e: Estimated Time of Arrival / Time left");
|
||||
case TR_CATEGORY: return tr("Category");
|
||||
case TR_TAGS: return tr("Tags");
|
||||
|
@ -195,6 +196,14 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
|
|||
default: return {};
|
||||
}
|
||||
}
|
||||
else if (role == Qt::ToolTipRole)
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case TR_POPULARITY: return tr("Ratio / Time Active (in months), indicates how popular the torrent is");
|
||||
default: return {};
|
||||
}
|
||||
}
|
||||
else if (role == Qt::TextAlignmentRole)
|
||||
{
|
||||
switch (section)
|
||||
|
@ -216,6 +225,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
|
|||
case TR_DLLIMIT:
|
||||
case TR_RATIO_LIMIT:
|
||||
case TR_RATIO:
|
||||
case TR_POPULARITY:
|
||||
case TR_QUEUE_POSITION:
|
||||
case TR_LAST_ACTIVITY:
|
||||
case TR_AVAILABILITY:
|
||||
|
@ -373,6 +383,8 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons
|
|||
return ratioString(torrent->realRatio());
|
||||
case TR_RATIO_LIMIT:
|
||||
return ratioString(torrent->maxRatio());
|
||||
case TR_POPULARITY:
|
||||
return ratioString(torrent->popularity());
|
||||
case TR_CATEGORY:
|
||||
return torrent->category();
|
||||
case TR_TAGS:
|
||||
|
@ -450,6 +462,8 @@ QVariant TransferListModel::internalValue(const BitTorrent::Torrent *torrent, co
|
|||
return torrent->eta();
|
||||
case TR_RATIO:
|
||||
return torrent->realRatio();
|
||||
case TR_POPULARITY:
|
||||
return torrent->popularity();
|
||||
case TR_CATEGORY:
|
||||
return torrent->category();
|
||||
case TR_TAGS:
|
||||
|
@ -559,6 +573,7 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
|
|||
case TR_DLLIMIT:
|
||||
case TR_RATIO_LIMIT:
|
||||
case TR_RATIO:
|
||||
case TR_POPULARITY:
|
||||
case TR_QUEUE_POSITION:
|
||||
case TR_LAST_ACTIVITY:
|
||||
case TR_AVAILABILITY:
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
TR_UPSPEED,
|
||||
TR_ETA,
|
||||
TR_RATIO,
|
||||
TR_POPULARITY,
|
||||
TR_CATEGORY,
|
||||
TR_TAGS,
|
||||
TR_ADD_DATE,
|
||||
|
|
|
@ -196,6 +196,7 @@ int TransferListSortModel::compare(const QModelIndex &left, const QModelIndex &r
|
|||
case TransferListModel::TR_PROGRESS:
|
||||
case TransferListModel::TR_RATIO:
|
||||
case TransferListModel::TR_RATIO_LIMIT:
|
||||
case TransferListModel::TR_POPULARITY:
|
||||
return customCompare(leftValue.toReal(), rightValue.toReal());
|
||||
|
||||
case TransferListModel::TR_STATUS:
|
||||
|
|
|
@ -178,6 +178,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow)
|
|||
setColumnHidden(TransferListModel::TR_INFOHASH_V2, true);
|
||||
setColumnHidden(TransferListModel::TR_COMPLETED, true);
|
||||
setColumnHidden(TransferListModel::TR_RATIO_LIMIT, true);
|
||||
setColumnHidden(TransferListModel::TR_POPULARITY, true);
|
||||
setColumnHidden(TransferListModel::TR_SEEN_COMPLETE_DATE, true);
|
||||
setColumnHidden(TransferListModel::TR_LAST_ACTIVITY, true);
|
||||
setColumnHidden(TransferListModel::TR_TOTAL_SIZE, true);
|
||||
|
@ -696,6 +697,7 @@ void TransferListWidget::displayColumnHeaderMenu()
|
|||
continue;
|
||||
|
||||
const auto columnName = m_listModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
const QVariant columnToolTip = m_listModel->headerData(i, Qt::Horizontal, Qt::ToolTipRole);
|
||||
QAction *action = menu->addAction(columnName, this, [this, i](const bool checked)
|
||||
{
|
||||
if (!checked && (visibleColumnsCount() <= 1))
|
||||
|
@ -710,6 +712,8 @@ void TransferListWidget::displayColumnHeaderMenu()
|
|||
});
|
||||
action->setCheckable(true);
|
||||
action->setChecked(!isColumnHidden(i));
|
||||
if (!columnToolTip.isNull())
|
||||
action->setToolTip(columnToolTip.toString());
|
||||
}
|
||||
|
||||
menu->addSeparator();
|
||||
|
|
|
@ -152,6 +152,7 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent)
|
|||
{KEY_TORRENT_MAX_INACTIVE_SEEDING_TIME, torrent.maxInactiveSeedingTime()},
|
||||
{KEY_TORRENT_RATIO, adjustRatio(torrent.realRatio())},
|
||||
{KEY_TORRENT_RATIO_LIMIT, torrent.ratioLimit()},
|
||||
{KEY_TORRENT_POPULARITY, torrent.popularity()},
|
||||
{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())},
|
||||
|
|
|
@ -54,6 +54,7 @@ inline const QString KEY_TORRENT_NUM_COMPLETE = u"num_complete"_s;
|
|||
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_ETA = u"eta"_s;
|
||||
inline const QString KEY_TORRENT_STATE = u"state"_s;
|
||||
inline const QString KEY_TORRENT_SEQUENTIAL_DOWNLOAD = u"seq_dl"_s;
|
||||
|
|
|
@ -97,6 +97,7 @@ const QString KEY_PROP_SEEDS_TOTAL = u"seeds_total"_s;
|
|||
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_REANNOUNCE = u"reannounce"_s;
|
||||
const QString KEY_PROP_TOTAL_SIZE = u"total_size"_s;
|
||||
const QString KEY_PROP_PIECES_NUM = u"pieces_num"_s;
|
||||
|
@ -398,6 +399,7 @@ void TorrentsController::infoAction()
|
|||
// - "peers": Torrent connected peers
|
||||
// - "peers_total": Torrent total number of peers
|
||||
// - "share_ratio": Torrent share ratio
|
||||
// - "popularity": Torrent popularity
|
||||
// - "reannounce": Torrent next reannounce time
|
||||
// - "total_size": Torrent total size
|
||||
// - "pieces_num": Torrent pieces count
|
||||
|
@ -432,6 +434,7 @@ void TorrentsController::propertiesAction()
|
|||
const int downloadLimit = torrent->downloadLimit();
|
||||
const int uploadLimit = torrent->uploadLimit();
|
||||
const qreal ratio = torrent->realRatio();
|
||||
const qreal popularity = torrent->popularity();
|
||||
|
||||
const QJsonObject ret
|
||||
{
|
||||
|
@ -460,6 +463,7 @@ void TorrentsController::propertiesAction()
|
|||
{KEY_PROP_PEERS, torrent->leechsCount()},
|
||||
{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_REANNOUNCE, torrent->nextAnnounce()},
|
||||
{KEY_PROP_TOTAL_SIZE, torrent->totalSize()},
|
||||
{KEY_PROP_PIECES_NUM, torrent->piecesCount()},
|
||||
|
|
|
@ -926,6 +926,7 @@ window.qBittorrent.DynamicTable = (function() {
|
|||
this.newColumn('upspeed', '', 'QBT_TR(Up Speed)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('popularity', '', 'QBT_TR(Popularity)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);
|
||||
|
@ -1228,6 +1229,14 @@ window.qBittorrent.DynamicTable = (function() {
|
|||
td.set('title', string);
|
||||
};
|
||||
|
||||
// popularity
|
||||
this.columns['popularity'].updateTd = function(td, row) {
|
||||
const value = this.getRowValue(row);
|
||||
const popularity = (value === -1) ? '∞' : window.qBittorrent.Misc.toFixedPointString(value, 2);
|
||||
td.set('text', popularity);
|
||||
td.set('title', popularity);
|
||||
};
|
||||
|
||||
// added on
|
||||
this.columns['added_on'].updateTd = function(td, row) {
|
||||
const date = new Date(this.getRowValue(row) * 1000).toLocaleString();
|
||||
|
|
|
@ -58,6 +58,7 @@ window.qBittorrent.PropGeneral = (function() {
|
|||
$('seeds').set('html', '');
|
||||
$('peers').set('html', '');
|
||||
$('share_ratio').set('html', '');
|
||||
$('popularity').set('html', '');
|
||||
$('reannounce').set('html', '');
|
||||
$('last_seen').set('html', '');
|
||||
$('total_size').set('html', '');
|
||||
|
@ -160,6 +161,8 @@ window.qBittorrent.PropGeneral = (function() {
|
|||
|
||||
$('share_ratio').set('html', data.share_ratio.toFixed(2));
|
||||
|
||||
$('popularity').set('html', data.popularity.toFixed(2));
|
||||
|
||||
$('reannounce').set('html', window.qBittorrent.Misc.friendlyDuration(data.reannounce));
|
||||
|
||||
const lastSeen = (data.last_seen >= 0)
|
||||
|
|
|
@ -49,6 +49,10 @@
|
|||
<td class="generalLabel">QBT_TR(Last Seen Complete:)QBT_TR[CONTEXT=PropertiesWidget]</td>
|
||||
<td id="last_seen"></td>
|
||||
</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 id="popularity" title="QBT_TR(Ratio / Time Active (in months), indicates how popular the torrent is)QBT_TR[CONTEXT=PropertiesWidget]"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
|
|
Loading…
Reference in a new issue