|
|
@ -29,7 +29,6 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
#include "btjson.h" |
|
|
|
#include "btjson.h" |
|
|
|
#include "misc.h" |
|
|
|
|
|
|
|
#include "fs_utils.h" |
|
|
|
#include "fs_utils.h" |
|
|
|
#include "qbtsession.h" |
|
|
|
#include "qbtsession.h" |
|
|
|
#include "torrentpersistentdata.h" |
|
|
|
#include "torrentpersistentdata.h" |
|
|
@ -89,7 +88,9 @@ static const char KEY_TORRENT_DLSPEED[] = "dlspeed"; |
|
|
|
static const char KEY_TORRENT_UPSPEED[] = "upspeed"; |
|
|
|
static const char KEY_TORRENT_UPSPEED[] = "upspeed"; |
|
|
|
static const char KEY_TORRENT_PRIORITY[] = "priority"; |
|
|
|
static const char KEY_TORRENT_PRIORITY[] = "priority"; |
|
|
|
static const char KEY_TORRENT_SEEDS[] = "num_seeds"; |
|
|
|
static const char KEY_TORRENT_SEEDS[] = "num_seeds"; |
|
|
|
|
|
|
|
static const char KEY_TORRENT_NUM_COMPLETE[] = "num_complete"; |
|
|
|
static const char KEY_TORRENT_LEECHS[] = "num_leechs"; |
|
|
|
static const char KEY_TORRENT_LEECHS[] = "num_leechs"; |
|
|
|
|
|
|
|
static const char KEY_TORRENT_NUM_INCOMPLETE[] = "num_incomplete"; |
|
|
|
static const char KEY_TORRENT_RATIO[] = "ratio"; |
|
|
|
static const char KEY_TORRENT_RATIO[] = "ratio"; |
|
|
|
static const char KEY_TORRENT_ETA[] = "eta"; |
|
|
|
static const char KEY_TORRENT_ETA[] = "eta"; |
|
|
|
static const char KEY_TORRENT_STATE[] = "state"; |
|
|
|
static const char KEY_TORRENT_STATE[] = "state"; |
|
|
@ -107,11 +108,15 @@ static const char KEY_PROP_PIECE_SIZE[] = "piece_size"; |
|
|
|
static const char KEY_PROP_COMMENT[] = "comment"; |
|
|
|
static const char KEY_PROP_COMMENT[] = "comment"; |
|
|
|
static const char KEY_PROP_WASTED[] = "total_wasted"; |
|
|
|
static const char KEY_PROP_WASTED[] = "total_wasted"; |
|
|
|
static const char KEY_PROP_UPLOADED[] = "total_uploaded"; |
|
|
|
static const char KEY_PROP_UPLOADED[] = "total_uploaded"; |
|
|
|
|
|
|
|
static const char KEY_PROP_UPLOADED_SESSION[] = "total_uploaded_session"; |
|
|
|
static const char KEY_PROP_DOWNLOADED[] = "total_downloaded"; |
|
|
|
static const char KEY_PROP_DOWNLOADED[] = "total_downloaded"; |
|
|
|
|
|
|
|
static const char KEY_PROP_DOWNLOADED_SESSION[] = "total_downloaded_session"; |
|
|
|
static const char KEY_PROP_UP_LIMIT[] = "up_limit"; |
|
|
|
static const char KEY_PROP_UP_LIMIT[] = "up_limit"; |
|
|
|
static const char KEY_PROP_DL_LIMIT[] = "dl_limit"; |
|
|
|
static const char KEY_PROP_DL_LIMIT[] = "dl_limit"; |
|
|
|
static const char KEY_PROP_TIME_ELAPSED[] = "time_elapsed"; |
|
|
|
static const char KEY_PROP_TIME_ELAPSED[] = "time_elapsed"; |
|
|
|
|
|
|
|
static const char KEY_PROP_SEEDING_TIME[] = "seeding_time"; |
|
|
|
static const char KEY_PROP_CONNECT_COUNT[] = "nb_connections"; |
|
|
|
static const char KEY_PROP_CONNECT_COUNT[] = "nb_connections"; |
|
|
|
|
|
|
|
static const char KEY_PROP_CONNECT_COUNT_LIMIT[] = "nb_connections_limit"; |
|
|
|
static const char KEY_PROP_RATIO[] = "share_ratio"; |
|
|
|
static const char KEY_PROP_RATIO[] = "share_ratio"; |
|
|
|
|
|
|
|
|
|
|
|
// File keys
|
|
|
|
// File keys
|
|
|
@ -122,8 +127,10 @@ static const char KEY_FILE_PRIORITY[] = "priority"; |
|
|
|
static const char KEY_FILE_IS_SEED[] = "is_seed"; |
|
|
|
static const char KEY_FILE_IS_SEED[] = "is_seed"; |
|
|
|
|
|
|
|
|
|
|
|
// TransferInfo keys
|
|
|
|
// TransferInfo keys
|
|
|
|
static const char KEY_TRANSFER_DLSPEED[] = "dl_info"; |
|
|
|
static const char KEY_TRANSFER_DLSPEED[] = "dl_info_speed"; |
|
|
|
static const char KEY_TRANSFER_UPSPEED[] = "up_info"; |
|
|
|
static const char KEY_TRANSFER_DLDATA[] = "dl_info_data"; |
|
|
|
|
|
|
|
static const char KEY_TRANSFER_UPSPEED[] = "up_info_speed"; |
|
|
|
|
|
|
|
static const char KEY_TRANSFER_UPDATA[] = "up_info_data"; |
|
|
|
|
|
|
|
|
|
|
|
static QVariantMap toMap(const QTorrentHandle& h) |
|
|
|
static QVariantMap toMap(const QTorrentHandle& h) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -132,25 +139,21 @@ static QVariantMap toMap(const QTorrentHandle& h) |
|
|
|
QVariantMap ret; |
|
|
|
QVariantMap ret; |
|
|
|
ret[KEY_TORRENT_HASH] = h.hash(); |
|
|
|
ret[KEY_TORRENT_HASH] = h.hash(); |
|
|
|
ret[KEY_TORRENT_NAME] = h.name(); |
|
|
|
ret[KEY_TORRENT_NAME] = h.name(); |
|
|
|
ret[KEY_TORRENT_SIZE] = misc::friendlyUnit(status.total_wanted, false, true); // FIXME: Should pass as Number, not formatted String (for sorting).
|
|
|
|
ret[KEY_TORRENT_SIZE] = static_cast<qlonglong>(status.total_wanted); |
|
|
|
ret[KEY_TORRENT_PROGRESS] = (double)h.progress(status); |
|
|
|
ret[KEY_TORRENT_PROGRESS] = h.progress(status); |
|
|
|
ret[KEY_TORRENT_DLSPEED] = misc::friendlyUnit(status.download_payload_rate, true, true); // FIXME: Should be passed as a Number
|
|
|
|
ret[KEY_TORRENT_DLSPEED] = status.download_payload_rate; |
|
|
|
ret[KEY_TORRENT_UPSPEED] = misc::friendlyUnit(status.upload_payload_rate, true, true); // FIXME: Should be passed as a Number
|
|
|
|
ret[KEY_TORRENT_UPSPEED] = status.upload_payload_rate; |
|
|
|
if (QBtSession::instance()->isQueueingEnabled() && h.queue_position(status) >= 0) |
|
|
|
if (QBtSession::instance()->isQueueingEnabled() && h.queue_position(status) >= 0) |
|
|
|
ret[KEY_TORRENT_PRIORITY] = QString::number(h.queue_position(status)); |
|
|
|
ret[KEY_TORRENT_PRIORITY] = h.queue_position(status); |
|
|
|
else |
|
|
|
else |
|
|
|
ret[KEY_TORRENT_PRIORITY] = "*"; |
|
|
|
ret[KEY_TORRENT_PRIORITY] = -1; |
|
|
|
QString seeds = QString::number(status.num_seeds); |
|
|
|
ret[KEY_TORRENT_SEEDS] = status.num_seeds; |
|
|
|
if (status.num_complete > 0) |
|
|
|
ret[KEY_TORRENT_NUM_COMPLETE] = status.num_complete; |
|
|
|
seeds += " ("+QString::number(status.num_complete)+")"; |
|
|
|
ret[KEY_TORRENT_LEECHS] = status.num_peers - status.num_seeds; |
|
|
|
ret[KEY_TORRENT_SEEDS] = seeds; |
|
|
|
ret[KEY_TORRENT_NUM_INCOMPLETE] = status.num_incomplete; |
|
|
|
QString leechs = QString::number(status.num_peers - status.num_seeds); |
|
|
|
|
|
|
|
if (status.num_incomplete > 0) |
|
|
|
|
|
|
|
leechs += " ("+QString::number(status.num_incomplete)+")"; |
|
|
|
|
|
|
|
ret[KEY_TORRENT_LEECHS] = leechs; |
|
|
|
|
|
|
|
const qreal ratio = QBtSession::instance()->getRealRatio(status); |
|
|
|
const qreal ratio = QBtSession::instance()->getRealRatio(status); |
|
|
|
ret[KEY_TORRENT_RATIO] = (ratio > 100.) ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1, false); |
|
|
|
ret[KEY_TORRENT_RATIO] = (ratio > 100.) ? -1 : ratio; |
|
|
|
QString eta; |
|
|
|
qulonglong eta = 0; |
|
|
|
QString state; |
|
|
|
QString state; |
|
|
|
if (h.is_paused(status)) { |
|
|
|
if (h.is_paused(status)) { |
|
|
|
if (h.has_error(status)) |
|
|
|
if (h.has_error(status)) |
|
|
@ -175,14 +178,14 @@ static QVariantMap toMap(const QTorrentHandle& h) |
|
|
|
case torrent_status::downloading: |
|
|
|
case torrent_status::downloading: |
|
|
|
case torrent_status::downloading_metadata: |
|
|
|
case torrent_status::downloading_metadata: |
|
|
|
state = status.download_payload_rate > 0 ? "downloading" : "stalledDL"; |
|
|
|
state = status.download_payload_rate > 0 ? "downloading" : "stalledDL"; |
|
|
|
eta = misc::userFriendlyDuration(QBtSession::instance()->getETA(h.hash(), status)); |
|
|
|
eta = QBtSession::instance()->getETA(h.hash(), status); |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
qWarning("Unrecognized torrent status, should not happen!!! status was %d", h.state()); |
|
|
|
qWarning("Unrecognized torrent status, should not happen!!! status was %d", h.state()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
ret[KEY_TORRENT_ETA] = eta.isEmpty() ? QString::fromUtf8("∞") : eta; |
|
|
|
ret[KEY_TORRENT_ETA] = eta ? eta : MAX_ETA; |
|
|
|
ret[KEY_TORRENT_STATE] = state; |
|
|
|
ret[KEY_TORRENT_STATE] = state; |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
return ret; |
|
|
@ -199,9 +202,11 @@ static QVariantMap toMap(const QTorrentHandle& h) |
|
|
|
* - "progress: Torrent progress |
|
|
|
* - "progress: Torrent progress |
|
|
|
* - "dlspeed": Torrent download speed |
|
|
|
* - "dlspeed": Torrent download speed |
|
|
|
* - "upspeed": Torrent upload speed |
|
|
|
* - "upspeed": Torrent upload speed |
|
|
|
* - "priority": Torrent priority ('*' if queuing is disabled) |
|
|
|
* - "priority": Torrent priority (-1 if queuing is disabled) |
|
|
|
* - "num_seeds": Torrent seed count |
|
|
|
* - "num_seeds": Torrent seeds connected to |
|
|
|
* - "num_leechs": Torrent leecher count |
|
|
|
* - "num_complete": Torrent seeds in the swarm |
|
|
|
|
|
|
|
* - "num_leechs": Torrent leechers connected to |
|
|
|
|
|
|
|
* - "num_incomplete": Torrent leechers in the swarm |
|
|
|
* - "ratio": Torrent share ratio |
|
|
|
* - "ratio": Torrent share ratio |
|
|
|
* - "eta": Torrent ETA |
|
|
|
* - "eta": Torrent ETA |
|
|
|
* - "state": Torrent state |
|
|
|
* - "state": Torrent state |
|
|
@ -252,7 +257,7 @@ QByteArray btjson::getTrackersForTorrent(const QString& hash) |
|
|
|
status = it->fails > 0 ? tr("Not working") : tr("Not contacted yet"); |
|
|
|
status = it->fails > 0 ? tr("Not working") : tr("Not contacted yet"); |
|
|
|
} |
|
|
|
} |
|
|
|
tracker_dict[KEY_TRACKER_STATUS] = status; |
|
|
|
tracker_dict[KEY_TRACKER_STATUS] = status; |
|
|
|
tracker_dict[KEY_TRACKER_PEERS] = QString::number(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers); |
|
|
|
tracker_dict[KEY_TRACKER_PEERS] = static_cast<qulonglong>(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers); |
|
|
|
tracker_dict[KEY_TRACKER_MSG] = data.last_message.trimmed(); |
|
|
|
tracker_dict[KEY_TRACKER_MSG] = data.last_message.trimmed(); |
|
|
|
|
|
|
|
|
|
|
|
tracker_list.append(tracker_dict); |
|
|
|
tracker_list.append(tracker_dict); |
|
|
@ -276,11 +281,15 @@ QByteArray btjson::getTrackersForTorrent(const QString& hash) |
|
|
|
* - "comment": Torrent comment |
|
|
|
* - "comment": Torrent comment |
|
|
|
* - "total_wasted": Total data wasted for torrent |
|
|
|
* - "total_wasted": Total data wasted for torrent |
|
|
|
* - "total_uploaded": Total data uploaded for torrent |
|
|
|
* - "total_uploaded": Total data uploaded for torrent |
|
|
|
|
|
|
|
* - "total_uploaded_session": Total data uploaded this session |
|
|
|
* - "total_downloaded": Total data uploaded for torrent |
|
|
|
* - "total_downloaded": Total data uploaded for torrent |
|
|
|
|
|
|
|
* - "total_downloaded_session": Total data downloaded this session |
|
|
|
* - "up_limit": Torrent upload limit |
|
|
|
* - "up_limit": Torrent upload limit |
|
|
|
* - "dl_limit": Torrent download limit |
|
|
|
* - "dl_limit": Torrent download limit |
|
|
|
* - "time_elapsed": Torrent elapsed time |
|
|
|
* - "time_elapsed": Torrent elapsed time |
|
|
|
|
|
|
|
* - "seeding_time": Torrent elapsed time while complete |
|
|
|
* - "nb_connections": Torrent connection count |
|
|
|
* - "nb_connections": Torrent connection count |
|
|
|
|
|
|
|
* - "nb_connections_limit": Torrent connection count limit |
|
|
|
* - "share_ratio": Torrent share ratio |
|
|
|
* - "share_ratio": Torrent share ratio |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
QByteArray btjson::getPropertiesForTorrent(const QString& hash) |
|
|
|
QByteArray btjson::getPropertiesForTorrent(const QString& hash) |
|
|
@ -298,21 +307,22 @@ QByteArray btjson::getPropertiesForTorrent(const QString& hash) |
|
|
|
if (save_path.isEmpty()) |
|
|
|
if (save_path.isEmpty()) |
|
|
|
save_path = fsutils::toNativePath(h.save_path()); |
|
|
|
save_path = fsutils::toNativePath(h.save_path()); |
|
|
|
data[KEY_PROP_SAVE_PATH] = save_path; |
|
|
|
data[KEY_PROP_SAVE_PATH] = save_path; |
|
|
|
data[KEY_PROP_CREATION_DATE] = h.creation_date(); |
|
|
|
data[KEY_PROP_CREATION_DATE] = h.creation_date_unix(); |
|
|
|
data[KEY_PROP_PIECE_SIZE] = misc::friendlyUnit(h.piece_length(), false, true); |
|
|
|
data[KEY_PROP_PIECE_SIZE] = static_cast<qlonglong>(h.piece_length()); |
|
|
|
data[KEY_PROP_COMMENT] = h.comment(); |
|
|
|
data[KEY_PROP_COMMENT] = h.comment(); |
|
|
|
data[KEY_PROP_WASTED] = misc::friendlyUnit(status.total_failed_bytes + status.total_redundant_bytes, false, true); |
|
|
|
data[KEY_PROP_WASTED] = static_cast<qlonglong>(status.total_failed_bytes + status.total_redundant_bytes); |
|
|
|
data[KEY_PROP_UPLOADED] = QString(misc::friendlyUnit(status.all_time_upload, false, true) + " (" + misc::friendlyUnit(status.total_payload_upload, false, true) + " " + tr("this session") + ")"); |
|
|
|
data[KEY_PROP_UPLOADED] = static_cast<qlonglong>(status.all_time_upload); |
|
|
|
data[KEY_PROP_DOWNLOADED] = QString(misc::friendlyUnit(status.all_time_download, false, true) + " (" + misc::friendlyUnit(status.total_payload_download, false, true) + " " + tr("this session") + ")"); |
|
|
|
data[KEY_PROP_UPLOADED_SESSION] = static_cast<qlonglong>(status.total_payload_upload); |
|
|
|
data[KEY_PROP_UP_LIMIT] = h.upload_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.upload_limit(), true, true); |
|
|
|
data[KEY_PROP_DOWNLOADED] = static_cast<qlonglong>(status.all_time_download); |
|
|
|
data[KEY_PROP_DL_LIMIT] = h.download_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.download_limit(), true, true); |
|
|
|
data[KEY_PROP_DOWNLOADED_SESSION] = static_cast<qlonglong>(status.total_payload_download); |
|
|
|
QString elapsed_txt = misc::userFriendlyDuration(status.active_time); |
|
|
|
data[KEY_PROP_UP_LIMIT] = h.upload_limit() <= 0 ? -1 : h.upload_limit(); |
|
|
|
if (h.is_seed(status)) |
|
|
|
data[KEY_PROP_DL_LIMIT] = h.download_limit() <= 0 ? -1 : h.download_limit(); |
|
|
|
elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(status.seeding_time))+")"; |
|
|
|
data[KEY_PROP_TIME_ELAPSED] = status.active_time; |
|
|
|
data[KEY_PROP_TIME_ELAPSED] = elapsed_txt; |
|
|
|
data[KEY_PROP_SEEDING_TIME] = status.seeding_time; |
|
|
|
data[KEY_PROP_CONNECT_COUNT] = QString(QString::number(status.num_connections) + " (" + tr("%1 max", "e.g. 10 max").arg(QString::number(status.connections_limit)) + ")"); |
|
|
|
data[KEY_PROP_CONNECT_COUNT] = status.num_connections; |
|
|
|
|
|
|
|
data[KEY_PROP_CONNECT_COUNT_LIMIT] = status.connections_limit; |
|
|
|
const qreal ratio = QBtSession::instance()->getRealRatio(status); |
|
|
|
const qreal ratio = QBtSession::instance()->getRealRatio(status); |
|
|
|
data[KEY_PROP_RATIO] = ratio > 100. ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1, false); |
|
|
|
data[KEY_PROP_RATIO] = ratio > 100. ? -1 : ratio; |
|
|
|
} catch(const std::exception& e) { |
|
|
|
} catch(const std::exception& e) { |
|
|
|
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what()); |
|
|
|
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what()); |
|
|
|
return QByteArray(); |
|
|
|
return QByteArray(); |
|
|
@ -350,7 +360,7 @@ QByteArray btjson::getFilesForTorrent(const QString& hash) |
|
|
|
fileName.chop(4); |
|
|
|
fileName.chop(4); |
|
|
|
file_dict[KEY_FILE_NAME] = fsutils::toNativePath(fileName); |
|
|
|
file_dict[KEY_FILE_NAME] = fsutils::toNativePath(fileName); |
|
|
|
const size_type size = h.filesize_at(i); |
|
|
|
const size_type size = h.filesize_at(i); |
|
|
|
file_dict[KEY_FILE_SIZE] = misc::friendlyUnit(size, false, true); |
|
|
|
file_dict[KEY_FILE_SIZE] = static_cast<qlonglong>(size); |
|
|
|
file_dict[KEY_FILE_PROGRESS] = (size > 0) ? (fp[i] / (double) size) : 1.; |
|
|
|
file_dict[KEY_FILE_PROGRESS] = (size > 0) ? (fp[i] / (double) size) : 1.; |
|
|
|
file_dict[KEY_FILE_PRIORITY] = priorities[i]; |
|
|
|
file_dict[KEY_FILE_PRIORITY] = priorities[i]; |
|
|
|
if (i == 0) |
|
|
|
if (i == 0) |
|
|
@ -371,14 +381,18 @@ QByteArray btjson::getFilesForTorrent(const QString& hash) |
|
|
|
* |
|
|
|
* |
|
|
|
* The return value is a JSON-formatted dictionary. |
|
|
|
* The return value is a JSON-formatted dictionary. |
|
|
|
* The dictionary keys are: |
|
|
|
* The dictionary keys are: |
|
|
|
* - "dl_info": Global download info |
|
|
|
* - "dl_info_speed": Global download rate |
|
|
|
* - "up_info": Global upload info |
|
|
|
* - "dl_info_data": Data downloaded this session |
|
|
|
|
|
|
|
* - "up_info_speed": Global upload rate |
|
|
|
|
|
|
|
* - "up_info_data": Data uploaded this session |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
QByteArray btjson::getTransferInfo() |
|
|
|
QByteArray btjson::getTransferInfo() |
|
|
|
{ |
|
|
|
{ |
|
|
|
CACHED_VARIABLE(QVariantMap, info, CACHE_DURATION_MS); |
|
|
|
CACHED_VARIABLE(QVariantMap, info, CACHE_DURATION_MS); |
|
|
|
session_status sessionStatus = QBtSession::instance()->getSessionStatus(); |
|
|
|
session_status sessionStatus = QBtSession::instance()->getSessionStatus(); |
|
|
|
info[KEY_TRANSFER_DLSPEED] = tr("D: %1/s - T: %2", "Download speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_download_rate, true, true)).arg(misc::friendlyUnit(sessionStatus.total_payload_download, false, true)); |
|
|
|
info[KEY_TRANSFER_DLSPEED] = sessionStatus.payload_download_rate; |
|
|
|
info[KEY_TRANSFER_UPSPEED] = tr("U: %1/s - T: %2", "Upload speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_upload_rate, true, true)).arg(misc::friendlyUnit(sessionStatus.total_payload_upload, false, true)); |
|
|
|
info[KEY_TRANSFER_DLDATA] = static_cast<qlonglong>(sessionStatus.total_payload_download); |
|
|
|
|
|
|
|
info[KEY_TRANSFER_UPSPEED] = sessionStatus.payload_upload_rate; |
|
|
|
|
|
|
|
info[KEY_TRANSFER_UPDATA] = static_cast<qlonglong>(sessionStatus.total_payload_upload); |
|
|
|
return json::toJson(info); |
|
|
|
return json::toJson(info); |
|
|
|
} |
|
|
|
} |
|
|
|