cache torrent_status

This commit is contained in:
Ivan Sorokin 2014-05-14 02:09:45 +04:00
parent 5af778bc93
commit 329b754197
10 changed files with 176 additions and 252 deletions

View file

@ -316,28 +316,31 @@ void PropertiesWidget::loadDynamicData() {
// Refresh only if the torrent handle is valid and if visible
if (!h.is_valid() || main_window->getCurrentTabWidget() != transferList || state != VISIBLE) return;
try {
libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters
| torrent_handle::query_distributed_copies
| torrent_handle::query_pieces);
// Transfer infos
if (stackedProperties->currentIndex() == PropTabBar::MAIN_TAB) {
wasted->setText(misc::friendlyUnit(h.total_failed_bytes()+h.total_redundant_bytes()));
upTotal->setText(misc::friendlyUnit(h.all_time_upload()) + " ("+misc::friendlyUnit(h.total_payload_upload())+" "+tr("this session")+")");
dlTotal->setText(misc::friendlyUnit(h.all_time_download()) + " ("+misc::friendlyUnit(h.total_payload_download())+" "+tr("this session")+")");
wasted->setText(misc::friendlyUnit(status.total_failed_bytes+status.total_redundant_bytes));
upTotal->setText(misc::friendlyUnit(status.all_time_upload) + " ("+misc::friendlyUnit(status.total_payload_upload)+" "+tr("this session")+")");
dlTotal->setText(misc::friendlyUnit(status.all_time_download) + " ("+misc::friendlyUnit(status.total_payload_download)+" "+tr("this session")+")");
lbl_uplimit->setText(h.upload_limit() <= 0 ? QString::fromUtf8("") : misc::friendlyUnit(h.upload_limit())+tr("/s", "/second (i.e. per second)"));
lbl_dllimit->setText(h.download_limit() <= 0 ? QString::fromUtf8("") : misc::friendlyUnit(h.download_limit())+tr("/s", "/second (i.e. per second)"));
QString elapsed_txt = misc::userFriendlyDuration(h.active_time());
if (h.is_seed()) {
elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(h.seeding_time()))+")";
QString elapsed_txt = misc::userFriendlyDuration(status.active_time);
if (h.is_seed(status)) {
elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(status.seeding_time))+")";
}
lbl_elapsed->setText(elapsed_txt);
if (h.connections_limit() > 0)
lbl_connections->setText(QString::number(h.num_connections())+" ("+tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit()))+")");
if (status.connections_limit > 0)
lbl_connections->setText(QString::number(status.num_connections)+" ("+tr("%1 max", "e.g. 10 max").arg(QString::number(status.connections_limit))+")");
else
lbl_connections->setText(QString::number(h.num_connections()));
lbl_connections->setText(QString::number(status.num_connections));
// Update next announce time
reannounce_lbl->setText(h.next_announce());
reannounce_lbl->setText(misc::userFriendlyDuration(status.next_announce.total_seconds()));
// Update ratio info
const qreal ratio = QBtSession::instance()->getRealRatio(h);
const qreal ratio = QBtSession::instance()->getRealRatio(status);
shareRatio->setText(ratio > QBtSession::MAX_RATIO ? QString::fromUtf8("") : misc::accurateDoubleToString(ratio, 2));
if (!h.is_seed() && h.has_metadata()) {
if (!h.is_seed(status) && status.has_metadata) {
showPiecesDownloaded(true);
// Downloaded pieces
#if LIBTORRENT_VERSION_NUM < 10000
@ -346,19 +349,19 @@ void PropertiesWidget::loadDynamicData() {
bitfield bf(h.torrent_file()->num_pieces(), 0);
#endif
h.downloading_pieces(bf);
downloaded_pieces->setProgress(h.pieces(), bf);
downloaded_pieces->setProgress(status.pieces, bf);
// Pieces availability
if (!h.is_paused() && !h.is_queued() && !h.is_checking()) {
if (!h.is_paused(status) && !h.is_queued(status) && !h.is_checking(status)) {
showPiecesAvailability(true);
std::vector<int> avail;
h.piece_availability(avail);
pieces_availability->setAvailability(avail);
avail_average_lbl->setText(misc::accurateDoubleToString(h.distributed_copies(), 3));
avail_average_lbl->setText(misc::accurateDoubleToString(status.distributed_copies, 3));
} else {
showPiecesAvailability(false);
}
// Progress
qreal progress = h.progress()*100.;
qreal progress = h.progress(status)*100.;
progress_lbl->setText(misc::accurateDoubleToString(progress, 1)+"%");
} else {
showPiecesAvailability(false);
@ -378,7 +381,7 @@ void PropertiesWidget::loadDynamicData() {
}
if (stackedProperties->currentIndex() == PropTabBar::FILES_TAB) {
// Files progress
if (h.is_valid() && h.has_metadata()) {
if (h.is_valid() && status.has_metadata) {
qDebug("Updating priorities in files tab");
filesList->setUpdatesEnabled(false);
std::vector<size_type> fp;

View file

@ -220,7 +220,7 @@ void QBtSession::processBigRatios() {
if (!h.is_valid()) continue;
if (h.is_seed()) {
const QString hash = h.hash();
const qreal ratio = getRealRatio(h);
const qreal ratio = getRealRatio(h.status(torrent_handle::query_accurate_download_counters));
qreal ratio_limit = TorrentPersistentData::getRatioLimit(hash);
if (ratio_limit == TorrentPersistentData::USE_GLOBAL_RATIO)
ratio_limit = global_ratio_limit;
@ -1556,14 +1556,11 @@ bool QBtSession::enableDHT(bool b) {
return true;
}
qreal QBtSession::getRealRatio(QTorrentHandle h) const {
if (!h.is_valid()) {
return 0.;
}
qreal QBtSession::getRealRatio(const libtorrent::torrent_status &status) const {
libtorrent::size_type all_time_upload = status.all_time_upload;
libtorrent::size_type all_time_download = status.all_time_download;
libtorrent::size_type total_done = status.total_done;
libtorrent::size_type all_time_upload = h.all_time_upload();
libtorrent::size_type all_time_download = h.all_time_download();
libtorrent::size_type total_done = h.total_done();
if (all_time_download < total_done) {
// We have more data on disk than we downloaded
// either because the user imported the file
@ -1576,7 +1573,7 @@ qreal QBtSession::getRealRatio(QTorrentHandle h) const {
if (all_time_download == 0) {
if (all_time_upload == 0)
return 0;
return 0.0;
return MAX_RATIO+1;
}
@ -2106,11 +2103,12 @@ void QBtSession::autoRunExternalProgram(const QTorrentHandle &h) {
}
void QBtSession::sendNotificationEmail(const QTorrentHandle &h) {
libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters);
// Prepare mail content
QString content = tr("Torrent name: %1").arg(h.name()) + "\n";
content += tr("Torrent size: %1").arg(misc::friendlyUnit(h.actual_size())) + "\n";
content += tr("Torrent size: %1").arg(misc::friendlyUnit(status.total_wanted)) + "\n";
content += tr("Save path: %1").arg(TorrentPersistentData::getSavePath(h.hash())) + "\n\n";
content += tr("The torrent was downloaded in %1.", "The torrent was downloaded in 1 hour and 20 seconds").arg(misc::userFriendlyDuration(h.active_time())) + "\n\n\n";
content += tr("The torrent was downloaded in %1.", "The torrent was downloaded in 1 hour and 20 seconds").arg(misc::userFriendlyDuration(status.active_time)) + "\n\n\n";
content += tr("Thank you for using qBittorrent.") + "\n";
// Send the notification email
Smtp *sender = new Smtp(this);
@ -2803,9 +2801,9 @@ void QBtSession::drop()
}
}
qlonglong QBtSession::getETA(const QString &hash) const
qlonglong QBtSession::getETA(const QString &hash, const libtorrent::torrent_status &status) const
{
return m_speedMonitor->getETA(hash);
return m_speedMonitor->getETA(hash, status);
}
quint64 QBtSession::getAlltimeDL() const {

View file

@ -92,7 +92,7 @@ public:
qreal getPayloadUploadRate() const;
libtorrent::session_status getSessionStatus() const;
int getListenPort() const;
qreal getRealRatio(QTorrentHandle h) const;
qreal getRealRatio(const libtorrent::torrent_status &status) const;
QHash<QString, TrackerInfos> getTrackersInfo(const QString &hash) const;
bool hasActiveTorrents() const;
bool hasDownloadingTorrents() const;
@ -121,7 +121,7 @@ public slots:
void startUpTorrents();
void recheckTorrent(const QString &hash);
void useAlternativeSpeedsLimit(bool alternative);
qlonglong getETA(const QString& hash) const;
qlonglong getETA(const QString& hash, const libtorrent::torrent_status &status) const;
/* Needed by Web UI */
void pauseAllTorrents();
void pauseTorrent(const QString &hash);

View file

@ -33,6 +33,7 @@
#include <QFile>
#include <QDir>
#include <QByteArray>
#include <QDateTime>
#include <math.h>
#include "fs_utils.h"
#include "misc.h"
@ -87,7 +88,7 @@ QString QTorrentHandle::name() const {
#if LIBTORRENT_VERSION_NUM < 10000
name = misc::toQStringU(torrent_handle::name());
#else
name = misc::toQStringU(torrent_handle::status(torrent_handle::query_name).name);
name = misc::toQStringU(status(query_name).name);
#endif
}
return name;
@ -102,41 +103,16 @@ QString QTorrentHandle::creation_date() const {
return t ? misc::toQString(*t) : "";
}
QString QTorrentHandle::next_announce() const {
return misc::userFriendlyDuration(torrent_handle::status(0x0).next_announce.total_seconds());
}
qlonglong QTorrentHandle::next_announce_s() const {
return torrent_handle::status(0x0).next_announce.total_seconds();
}
float QTorrentHandle::progress() const {
torrent_status st = torrent_handle::status(query_accurate_download_counters);
if (!st.total_wanted)
return 0.;
if (st.total_wanted_done == st.total_wanted)
return 1.;
float progress = (float) st.total_wanted_done / (float) st.total_wanted;
Q_ASSERT(progress >= 0. && progress <= 1.);
return progress;
}
bitfield QTorrentHandle::pieces() const {
return torrent_handle::status(torrent_handle::query_pieces).pieces;
}
QString QTorrentHandle::current_tracker() const {
return misc::toQString(torrent_handle::status(0x0).current_tracker);
return misc::toQString(status(0x0).current_tracker);
}
bool QTorrentHandle::is_paused() const {
torrent_status st = torrent_handle::status(0x0);
return st.paused && !st.auto_managed;
return is_paused(status(0x0));
}
bool QTorrentHandle::is_queued() const {
torrent_status st = torrent_handle::status(0x0);
return st.paused && st.auto_managed;
return is_queued(status(0x0));
}
size_type QTorrentHandle::total_size() const {
@ -189,38 +165,6 @@ bool QTorrentHandle::first_last_piece_first() const {
&& (torrent_handle::piece_priority(extremities.second) == 7);
}
size_type QTorrentHandle::total_wanted_done() const {
return torrent_handle::status(query_accurate_download_counters).total_wanted_done;
}
size_type QTorrentHandle::total_wanted() const {
return torrent_handle::status(0x0).total_wanted;
}
qreal QTorrentHandle::download_payload_rate() const {
return torrent_handle::status(0x0).download_payload_rate;
}
qreal QTorrentHandle::upload_payload_rate() const {
return torrent_handle::status(0x0).upload_payload_rate;
}
int QTorrentHandle::num_peers() const {
return torrent_handle::status(0x0).num_peers;
}
int QTorrentHandle::num_seeds() const {
return torrent_handle::status(0x0).num_seeds;
}
int QTorrentHandle::num_complete() const {
return torrent_handle::status(0x0).num_complete;
}
int QTorrentHandle::num_incomplete() const {
return torrent_handle::status(0x0).num_incomplete;
}
QString QTorrentHandle::save_path() const {
#if LIBTORRENT_VERSION_NUM < 10000
return fsutils::fromNativePath(misc::toQStringU(torrent_handle::save_path()));
@ -260,7 +204,7 @@ QStringList QTorrentHandle::url_seeds() const {
// get the size of the torrent without the filtered files
size_type QTorrentHandle::actual_size() const {
return torrent_handle::status(query_accurate_download_counters).total_wanted;
return status(query_accurate_download_counters).total_wanted;
}
bool QTorrentHandle::has_filtered_pieces() const {
@ -317,7 +261,7 @@ QString QTorrentHandle::orig_filepath_at(unsigned int index) const {
}
torrent_status::state_t QTorrentHandle::state() const {
return torrent_handle::status(0x0).state;
return status(0x0).state;
}
QString QTorrentHandle::creator() const {
@ -336,37 +280,8 @@ QString QTorrentHandle::comment() const {
#endif
}
size_type QTorrentHandle::total_failed_bytes() const {
return torrent_handle::status(0x0).total_failed_bytes;
}
size_type QTorrentHandle::total_redundant_bytes() const {
return torrent_handle::status(0x0).total_redundant_bytes;
}
bool QTorrentHandle::is_checking() const {
torrent_status st = torrent_handle::status(0x0);
return st.state == torrent_status::checking_files || st.state == torrent_status::checking_resume_data;
}
size_type QTorrentHandle::total_done() const {
return torrent_handle::status(query_accurate_download_counters).total_done;
}
size_type QTorrentHandle::all_time_download() const {
return torrent_handle::status(0x0).all_time_download;
}
size_type QTorrentHandle::all_time_upload() const {
return torrent_handle::status(0x0).all_time_upload;
}
size_type QTorrentHandle::total_payload_download() const {
return torrent_handle::status(0x0).total_payload_download;
}
size_type QTorrentHandle::total_payload_upload() const {
return torrent_handle::status(0x0).total_payload_upload;
return is_checking(status(0x0));
}
// Return a list of absolute paths corresponding
@ -408,44 +323,17 @@ int QTorrentHandle::queue_position() const {
return torrent_handle::queue_position()+1;
}
int QTorrentHandle::num_uploads() const {
return torrent_handle::status(0x0).num_uploads;
}
bool QTorrentHandle::is_seed() const {
// Affected by bug http://code.rasterbar.com/libtorrent/ticket/402
//return torrent_handle::is_seed();
// May suffer from approximation problems
//return (progress() == 1.);
// This looks safe
torrent_status::state_t st = state();
return (st == torrent_status::finished || st == torrent_status::seeding);
}
bool QTorrentHandle::is_auto_managed() const {
torrent_status status = torrent_handle::status(0x0);
return status.auto_managed;
return is_seed(status(0x0));
}
bool QTorrentHandle::is_sequential_download() const {
torrent_status status = torrent_handle::status(0x0);
return status.sequential_download;
}
qlonglong QTorrentHandle::active_time() const {
return torrent_handle::status(0x0).active_time;
}
qlonglong QTorrentHandle::seeding_time() const {
return torrent_handle::status(0x0).seeding_time;
}
int QTorrentHandle::num_connections() const {
return torrent_handle::status(0x0).num_connections;
}
int QTorrentHandle::connections_limit() const {
return torrent_handle::status(0x0).connections_limit;
return status(0x0).sequential_download;
}
bool QTorrentHandle::priv() const {
@ -482,12 +370,11 @@ QString QTorrentHandle::root_path() const
}
bool QTorrentHandle::has_error() const {
torrent_status st = torrent_handle::status(0x0);
return st.paused && !st.error.empty();
return has_error(status(0x0));
}
QString QTorrentHandle::error() const {
return misc::toQString(torrent_handle::status(0x0).error);
return misc::toQString(status(0x0).error);
}
void QTorrentHandle::downloading_pieces(bitfield &bf) const {
@ -503,11 +390,7 @@ void QTorrentHandle::downloading_pieces(bitfield &bf) const {
}
bool QTorrentHandle::has_metadata() const {
return torrent_handle::status(0x0).has_metadata;
}
float QTorrentHandle::distributed_copies() const {
return torrent_handle::status(query_distributed_copies).distributed_copies;
return status(0x0).has_metadata;
}
void QTorrentHandle::file_progress(std::vector<size_type>& fp) const {
@ -732,3 +615,41 @@ void QTorrentHandle::rename_file(int index, const QString& name) const {
bool QTorrentHandle::operator ==(const QTorrentHandle& new_h) const {
return info_hash() == new_h.info_hash();
}
bool QTorrentHandle::is_paused(const libtorrent::torrent_status &status)
{
return status.paused && !status.auto_managed;
}
bool QTorrentHandle::is_queued(const libtorrent::torrent_status &status)
{
return status.paused && status.auto_managed;
}
bool QTorrentHandle::is_seed(const libtorrent::torrent_status &status)
{
return status.state == torrent_status::finished
|| status.state == torrent_status::seeding;
}
bool QTorrentHandle::is_checking(const libtorrent::torrent_status &status)
{
return status.state == torrent_status::checking_files
|| status.state == torrent_status::checking_resume_data;
}
bool QTorrentHandle::has_error(const libtorrent::torrent_status &status)
{
return status.paused && !status.error.empty();
}
float QTorrentHandle::progress(const libtorrent::torrent_status &status)
{
if (!status.total_wanted)
return 0.;
if (status.total_wanted_done == status.total_wanted)
return 1.;
float progress = (float) status.total_wanted_done / (float) status.total_wanted;
Q_ASSERT(progress >= 0.f && progress <= 1.f);
return progress;
}

View file

@ -59,24 +59,12 @@ public:
//
QString hash() const;
QString name() const;
float progress() const;
libtorrent::bitfield pieces() const;
QString current_tracker() const;
bool is_paused() const;
bool has_filtered_pieces() const;
libtorrent::size_type total_size() const;
libtorrent::size_type piece_length() const;
int num_pieces() const;
libtorrent::size_type total_wanted_done() const;
libtorrent::size_type total_wanted() const;
qreal download_payload_rate() const;
qreal upload_payload_rate() const;
int num_connections() const;
int connections_limit() const;
int num_peers() const;
int num_seeds() const;
int num_complete() const;
int num_incomplete() const;
QString save_path() const;
QString save_path_parsed() const;
QStringList url_seeds() const;
@ -91,26 +79,13 @@ public:
libtorrent::torrent_status::state_t state() const;
QString creator() const;
QString comment() const;
libtorrent::size_type total_failed_bytes() const;
libtorrent::size_type total_redundant_bytes() const;
libtorrent::size_type total_payload_download() const;
libtorrent::size_type total_payload_upload() const;
libtorrent::size_type all_time_upload() const;
libtorrent::size_type all_time_download() const;
libtorrent::size_type total_done() const;
QStringList absolute_files_path() const;
QStringList absolute_files_path_uneeded() const;
bool has_missing_files() const;
int num_uploads() const;
bool is_seed() const;
bool is_checking() const;
bool is_auto_managed() const;
bool is_sequential_download() const;
qlonglong active_time() const;
qlonglong seeding_time() const;
QString creation_date() const;
QString next_announce() const;
qlonglong next_announce_s() const;
bool priv() const;
bool first_last_piece_first() const;
QString root_path() const;
@ -119,7 +94,6 @@ public:
QString error() const;
void downloading_pieces(libtorrent::bitfield& bf) const;
bool has_metadata() const;
float distributed_copies() const;
void file_progress(std::vector<libtorrent::size_type>& fp) const;
//
@ -142,6 +116,13 @@ public:
//
bool operator ==(const QTorrentHandle& new_h) const;
static bool is_paused(const libtorrent::torrent_status &status);
static bool is_queued(const libtorrent::torrent_status &status);
static bool is_seed(const libtorrent::torrent_status &status);
static bool is_checking(const libtorrent::torrent_status &status);
static bool has_error(const libtorrent::torrent_status &status);
static float progress(const libtorrent::torrent_status &status);
private:
void prioritize_first_last_piece(int file_index, bool b) const;

View file

@ -90,6 +90,7 @@ namespace
TorrentModelItem::TorrentModelItem(const QTorrentHandle &h)
: m_torrent(h)
, m_lastStatus(h.status(torrent_handle::query_accurate_download_counters))
, m_addedTime(TorrentPersistentData::getAddedDate(h.hash()))
, m_seedTime(TorrentPersistentData::getSeedDate(h.hash()))
, m_label(TorrentPersistentData::getLabel(h.hash()))
@ -100,26 +101,33 @@ TorrentModelItem::TorrentModelItem(const QTorrentHandle &h)
m_name = h.name();
}
void TorrentModelItem::refreshStatus()
{
try {
m_lastStatus = m_torrent.status();
} catch(invalid_handle&) {}
}
TorrentModelItem::State TorrentModelItem::state() const
{
try {
// Pause or Queued
if (m_torrent.is_paused()) {
if (m_torrent.is_paused(m_lastStatus)) {
m_icon = get_paused_icon();
m_fgColor = QColor("red");
return m_torrent.is_seed() ? STATE_PAUSED_UP : STATE_PAUSED_DL;
return m_torrent.is_seed(m_lastStatus) ? STATE_PAUSED_UP : STATE_PAUSED_DL;
}
if (m_torrent.is_queued()) {
if (m_torrent.state() != torrent_status::queued_for_checking
&& m_torrent.state() != torrent_status::checking_resume_data
&& m_torrent.state() != torrent_status::checking_files) {
if (m_torrent.is_queued(m_lastStatus)) {
if (m_lastStatus.state != torrent_status::queued_for_checking
&& m_lastStatus.state != torrent_status::checking_resume_data
&& m_lastStatus.state != torrent_status::checking_files) {
m_icon = get_queued_icon();
m_fgColor = QColor("grey");
return m_torrent.is_seed() ? STATE_QUEUED_UP : STATE_QUEUED_DL;
return m_torrent.is_seed(m_lastStatus) ? STATE_QUEUED_UP : STATE_QUEUED_DL;
}
}
// Other states
switch(m_torrent.state()) {
switch(m_lastStatus.state) {
case torrent_status::allocating:
m_icon = get_stalled_downloading_icon();
m_fgColor = QColor("grey");
@ -129,7 +137,7 @@ TorrentModelItem::State TorrentModelItem::state() const
m_fgColor = QColor("green");
return STATE_DOWNLOADING_META;
case torrent_status::downloading: {
if (m_torrent.download_payload_rate() > 0) {
if (m_lastStatus.download_payload_rate > 0) {
m_icon = get_downloading_icon();
m_fgColor = QColor("green");
return STATE_DOWNLOADING;
@ -141,7 +149,7 @@ TorrentModelItem::State TorrentModelItem::state() const
}
case torrent_status::finished:
case torrent_status::seeding:
if (m_torrent.upload_payload_rate() > 0) {
if (m_lastStatus.upload_payload_rate > 0) {
m_icon = get_uploading_icon();
m_fgColor = QColor("orange");
return STATE_SEEDING;
@ -161,7 +169,7 @@ TorrentModelItem::State TorrentModelItem::state() const
case torrent_status::checking_files:
m_icon = get_checking_icon();
m_fgColor = QColor("grey");
return m_torrent.is_seed() ? STATE_CHECKING_UP : STATE_CHECKING_DL;
return m_torrent.is_seed(m_lastStatus) ? STATE_CHECKING_UP : STATE_CHECKING_DL;
default:
m_icon = get_error_icon();
m_fgColor = QColor("red");
@ -224,28 +232,28 @@ QVariant TorrentModelItem::data(int column, int role) const
return pos;
}
case TR_SIZE:
return m_torrent.has_metadata() ? static_cast<qlonglong>(m_torrent.actual_size()) : -1;
return m_lastStatus.has_metadata ? static_cast<qlonglong>(m_lastStatus.total_wanted) : -1;
case TR_PROGRESS:
return m_torrent.progress();
return m_torrent.progress(m_lastStatus);
case TR_STATUS:
return state();
case TR_SEEDS: {
return (role == Qt::DisplayRole) ? m_torrent.num_seeds() : m_torrent.num_complete();
return (role == Qt::DisplayRole) ? m_lastStatus.num_seeds : m_lastStatus.num_complete;
}
case TR_PEERS: {
return (role == Qt::DisplayRole) ? (m_torrent.num_peers()-m_torrent.num_seeds()) : m_torrent.num_incomplete();
return (role == Qt::DisplayRole) ? (m_lastStatus.num_peers-m_lastStatus.num_seeds) : m_lastStatus.num_incomplete;
}
case TR_DLSPEED:
return m_torrent.download_payload_rate();
return m_lastStatus.download_payload_rate;
case TR_UPSPEED:
return m_torrent.upload_payload_rate();
return m_lastStatus.upload_payload_rate;
case TR_ETA: {
// XXX: Is this correct?
if (m_torrent.is_paused() || m_torrent.is_queued()) return MAX_ETA;
return QBtSession::instance()->getETA(m_hash);
if (m_torrent.is_paused(m_lastStatus) || m_torrent.is_queued(m_lastStatus)) return MAX_ETA;
return QBtSession::instance()->getETA(m_hash, m_lastStatus);
}
case TR_RATIO:
return QBtSession::instance()->getRealRatio(m_torrent);
return QBtSession::instance()->getRealRatio(m_lastStatus);
case TR_LABEL:
return m_label;
case TR_ADD_DATE:
@ -253,19 +261,19 @@ QVariant TorrentModelItem::data(int column, int role) const
case TR_SEED_DATE:
return m_seedTime;
case TR_TRACKER:
return m_torrent.current_tracker();
return misc::toQString(m_lastStatus.current_tracker);
case TR_DLLIMIT:
return m_torrent.download_limit();
case TR_UPLIMIT:
return m_torrent.upload_limit();
case TR_AMOUNT_DOWNLOADED:
return static_cast<qlonglong>(m_torrent.all_time_download());
return static_cast<qlonglong>(m_lastStatus.all_time_download);
case TR_AMOUNT_UPLOADED:
return static_cast<qlonglong>(m_torrent.all_time_upload());
return static_cast<qlonglong>(m_lastStatus.all_time_upload);
case TR_AMOUNT_LEFT:
return static_cast<qlonglong>(m_torrent.total_wanted() - m_torrent.total_wanted_done());
return static_cast<qlonglong>(m_lastStatus.total_wanted - m_lastStatus.total_wanted_done);
case TR_TIME_ELAPSED:
return (role == Qt::DisplayRole) ? m_torrent.active_time() : m_torrent.seeding_time();
return (role == Qt::DisplayRole) ? m_lastStatus.active_time : m_lastStatus.seeding_time;
case TR_SAVE_PATH:
return fsutils::toNativePath(m_torrent.save_path_parsed());
default:
@ -464,6 +472,13 @@ void TorrentModel::setRefreshInterval(int refreshInterval)
void TorrentModel::forceModelRefresh()
{
QList<TorrentModelItem*>::const_iterator it = m_torrents.constBegin();
QList<TorrentModelItem*>::const_iterator itend = m_torrents.constEnd();
for ( ; it != itend; ++it) {
TorrentModelItem* item = *it;
item->refreshStatus();
}
emit dataChanged(index(0, 0), index(rowCount()-1, columnCount()-1));
}

View file

@ -53,6 +53,7 @@ public:
public:
TorrentModelItem(const QTorrentHandle& h);
void refreshStatus();
inline int columnCount() const { return NB_COLUMNS; }
QVariant data(int column, int role = Qt::DisplayRole) const;
bool setData(int column, const QVariant &value, int role = Qt::DisplayRole);
@ -66,6 +67,7 @@ private:
private:
QTorrentHandle m_torrent;
libtorrent::torrent_status m_lastStatus;
QDateTime m_addedTime;
QDateTime m_seedTime;
QString m_label;

View file

@ -130,16 +130,16 @@ void TorrentSpeedMonitor::removeSamples(const QTorrentHandle& h) {
} catch(invalid_handle&) {}
}
qlonglong TorrentSpeedMonitor::getETA(const QString &hash) const
qlonglong TorrentSpeedMonitor::getETA(const QString &hash, const libtorrent::torrent_status &status) const
{
QMutexLocker locker(&m_mutex);
QTorrentHandle h = m_session->getTorrentHandle(hash);
if (h.is_paused() || !m_samples.contains(hash))
if (QTorrentHandle::is_paused(status) || !m_samples.contains(hash))
return MAX_ETA;
const Sample<qreal> speed_average = m_samples[hash].average();
if (h.is_seed()) {
if (QTorrentHandle::is_seed(status)) {
if (!speed_average.upload)
return MAX_ETA;
@ -148,17 +148,17 @@ qlonglong TorrentSpeedMonitor::getETA(const QString &hash) const
if (max_ratio < 0)
return MAX_ETA;
libtorrent::size_type realDL = h.all_time_download();
libtorrent::size_type realDL = status.all_time_download;
if (realDL <= 0)
realDL = h.total_wanted();
realDL = status.total_wanted;
return (realDL * max_ratio - h.all_time_upload()) / speed_average.upload;
return (realDL * max_ratio - status.all_time_upload) / speed_average.upload;
}
if (!speed_average.download)
return MAX_ETA;
return (h.total_wanted() - h.total_wanted_done()) / speed_average.download;
return (status.total_wanted - status.total_wanted_done) / speed_average.download;
}
quint64 TorrentSpeedMonitor::getAlltimeDL() const {

View file

@ -48,7 +48,7 @@ class TorrentSpeedMonitor : public QThread
public:
explicit TorrentSpeedMonitor(QBtSession* session);
~TorrentSpeedMonitor();
qlonglong getETA(const QString &hash) const;
qlonglong getETA(const QString &hash, const libtorrent::torrent_status &status) const;
quint64 getAlltimeDL() const;
quint64 getAlltimeUL() const;

View file

@ -124,53 +124,55 @@ static const char KEY_TRANSFER_UPSPEED[] = "up_info";
static JsonDict toJson(const QTorrentHandle& h)
{
libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters);
JsonDict ret;
ret.add(KEY_TORRENT_HASH, h.hash());
ret.add(KEY_TORRENT_NAME, h.name());
ret.add(KEY_TORRENT_SIZE, misc::friendlyUnit(h.actual_size())); // FIXME: Should pass as Number, not formatted String (for sorting).
ret.add(KEY_TORRENT_PROGRESS, (double)h.progress());
ret.add(KEY_TORRENT_DLSPEED, misc::friendlyUnit(h.download_payload_rate(), true)); // FIXME: Should be passed as a Number
ret.add(KEY_TORRENT_UPSPEED, misc::friendlyUnit(h.upload_payload_rate(), true)); // FIXME: Should be passed as a Number
ret.add(KEY_TORRENT_SIZE, misc::friendlyUnit(status.total_wanted)); // FIXME: Should pass as Number, not formatted String (for sorting).
ret.add(KEY_TORRENT_PROGRESS, (double)h.progress(status));
ret.add(KEY_TORRENT_DLSPEED, misc::friendlyUnit(status.download_payload_rate, true)); // FIXME: Should be passed as a Number
ret.add(KEY_TORRENT_UPSPEED, misc::friendlyUnit(status.upload_payload_rate, true)); // FIXME: Should be passed as a Number
if (QBtSession::instance()->isQueueingEnabled() && h.queue_position() >= 0)
ret.add(KEY_TORRENT_PRIORITY, QString::number(h.queue_position()));
else
ret.add(KEY_TORRENT_PRIORITY, "*");
QString seeds = QString::number(h.num_seeds());
if (h.num_complete() > 0)
seeds += " ("+QString::number(h.num_complete())+")";
QString seeds = QString::number(status.num_seeds);
if (status.num_complete > 0)
seeds += " ("+QString::number(status.num_complete)+")";
ret.add(KEY_TORRENT_SEEDS, seeds);
QString leechs = QString::number(h.num_peers() - h.num_seeds());
if (h.num_incomplete() > 0)
leechs += " ("+QString::number(h.num_incomplete())+")";
QString leechs = QString::number(status.num_peers - status.num_seeds);
if (status.num_incomplete > 0)
leechs += " ("+QString::number(status.num_incomplete)+")";
ret.add(KEY_TORRENT_LEECHS, leechs);
const qreal ratio = QBtSession::instance()->getRealRatio(h);
const qreal ratio = QBtSession::instance()->getRealRatio(status);
ret.add(KEY_TORRENT_RATIO, (ratio > 100.) ? QString::fromUtf8("") : misc::accurateDoubleToString(ratio, 1));
QString eta;
QString state;
if (h.is_paused()) {
if (h.has_error())
if (h.is_paused(status)) {
if (h.has_error(status))
state = "error";
else
state = h.is_seed() ? "pausedUP" : "pausedDL";
state = h.is_seed(status) ? "pausedUP" : "pausedDL";
} else {
if (QBtSession::instance()->isQueueingEnabled() && h.is_queued())
state = h.is_seed() ? "queuedUP" : "queuedDL";
if (QBtSession::instance()->isQueueingEnabled() && h.is_queued(status))
state = h.is_seed(status) ? "queuedUP" : "queuedDL";
else {
switch (h.state()) {
switch (status.state) {
case torrent_status::finished:
case torrent_status::seeding:
state = h.upload_payload_rate() > 0 ? "uploading" : "stalledUP";
state = status.upload_payload_rate > 0 ? "uploading" : "stalledUP";
break;
case torrent_status::allocating:
case torrent_status::checking_files:
case torrent_status::queued_for_checking:
case torrent_status::checking_resume_data:
state = h.is_seed() ? "checkingUP" : "checkingDL";
state = h.is_seed(status) ? "checkingUP" : "checkingDL";
break;
case torrent_status::downloading:
case torrent_status::downloading_metadata:
state = h.download_payload_rate() > 0 ? "downloading" : "stalledDL";
eta = misc::userFriendlyDuration(QBtSession::instance()->getETA(h.hash()));
state = status.download_payload_rate > 0 ? "downloading" : "stalledDL";
eta = misc::userFriendlyDuration(QBtSession::instance()->getETA(h.hash(), status));
break;
default:
qWarning("Unrecognized torrent status, should not happen!!! status was %d", h.state());
@ -284,7 +286,9 @@ QString btjson::getPropertiesForTorrent(const QString& hash)
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if (!h.has_metadata())
libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters);
if (!status.has_metadata)
return QString();
// Save path
@ -295,17 +299,17 @@ QString btjson::getPropertiesForTorrent(const QString& hash)
data.add(KEY_PROP_CREATION_DATE, h.creation_date());
data.add(KEY_PROP_PIECE_SIZE, misc::friendlyUnit(h.piece_length()));
data.add(KEY_PROP_COMMENT, h.comment());
data.add(KEY_PROP_WASTED, misc::friendlyUnit(h.total_failed_bytes() + h.total_redundant_bytes()));
data.add(KEY_PROP_UPLOADED, QString(misc::friendlyUnit(h.all_time_upload()) + " (" + misc::friendlyUnit(h.total_payload_upload()) + " " + tr("this session") + ")"));
data.add(KEY_PROP_DOWNLOADED, QString(misc::friendlyUnit(h.all_time_download()) + " (" + misc::friendlyUnit(h.total_payload_download()) + " " + tr("this session") + ")"));
data.add(KEY_PROP_WASTED, misc::friendlyUnit(status.total_failed_bytes + status.total_redundant_bytes));
data.add(KEY_PROP_UPLOADED, QString(misc::friendlyUnit(status.all_time_upload) + " (" + misc::friendlyUnit(status.total_payload_upload) + " " + tr("this session") + ")"));
data.add(KEY_PROP_DOWNLOADED, QString(misc::friendlyUnit(status.all_time_download) + " (" + misc::friendlyUnit(status.total_payload_download) + " " + tr("this session") + ")"));
data.add(KEY_PROP_UP_LIMIT, h.upload_limit() <= 0 ? QString::fromUtf8("") : misc::friendlyUnit(h.upload_limit(), true));
data.add(KEY_PROP_DL_LIMIT, h.download_limit() <= 0 ? QString::fromUtf8("") : misc::friendlyUnit(h.download_limit(), true));
QString elapsed_txt = misc::userFriendlyDuration(h.active_time());
if (h.is_seed())
elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(h.seeding_time()))+")";
QString elapsed_txt = misc::userFriendlyDuration(status.active_time);
if (h.is_seed(status))
elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(status.seeding_time))+")";
data.add(KEY_PROP_TIME_ELAPSED, elapsed_txt);
data.add(KEY_PROP_CONNECT_COUNT, QString(QString::number(h.num_connections()) + " (" + tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit())) + ")"));
const qreal ratio = QBtSession::instance()->getRealRatio(h);
data.add(KEY_PROP_CONNECT_COUNT, QString(QString::number(status.num_connections) + " (" + tr("%1 max", "e.g. 10 max").arg(QString::number(status.connections_limit)) + ")"));
const qreal ratio = QBtSession::instance()->getRealRatio(status);
data.add(KEY_PROP_RATIO, ratio > 100. ? QString::fromUtf8("") : misc::accurateDoubleToString(ratio, 1));
} catch(const std::exception& e) {
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what();