Browse Source

Merge pull request #11000 from Chocobo1/sync

Clean up WebAPI code
adaptive-webui-19844
Mike Tzou 5 years ago committed by GitHub
parent
commit
6cc7c700b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 26
      src/webui/api/appcontroller.cpp
  2. 36
      src/webui/api/logcontroller.cpp
  3. 93
      src/webui/api/serialize/serialize_torrent.cpp
  4. 155
      src/webui/api/synccontroller.cpp
  5. 85
      src/webui/api/torrentscontroller.cpp

26
src/webui/api/appcontroller.cpp

@ -95,7 +95,7 @@ void AppController::preferencesAction()
{ {
const Preferences *const pref = Preferences::instance(); const Preferences *const pref = Preferences::instance();
const auto *session = BitTorrent::Session::instance(); const auto *session = BitTorrent::Session::instance();
QVariantMap data; QJsonObject data;
// Downloads // Downloads
// When adding a torrent // When adding a torrent
@ -116,7 +116,7 @@ void AppController::preferencesAction()
data["export_dir_fin"] = Utils::Fs::toNativePath(session->finishedTorrentExportDirectory()); data["export_dir_fin"] = Utils::Fs::toNativePath(session->finishedTorrentExportDirectory());
// Automatically add torrents from // Automatically add torrents from
const QVariantHash dirs = pref->getScanDirs(); const QVariantHash dirs = pref->getScanDirs();
QVariantMap nativeDirs; QJsonObject nativeDirs;
for (auto i = dirs.cbegin(); i != dirs.cend(); ++i) { for (auto i = dirs.cbegin(); i != dirs.cend(); ++i) {
if (i.value().type() == QVariant::Int) if (i.value().type() == QVariant::Int)
nativeDirs.insert(Utils::Fs::toNativePath(i.key()), i.value().toInt()); nativeDirs.insert(Utils::Fs::toNativePath(i.key()), i.value().toInt());
@ -248,7 +248,7 @@ void AppController::preferencesAction()
data["dyndns_domain"] = pref->getDynDomainName(); data["dyndns_domain"] = pref->getDynDomainName();
// RSS settings // RSS settings
data["rss_refresh_interval"] = RSS::Session::instance()->refreshInterval(); data["rss_refresh_interval"] = static_cast<double>(RSS::Session::instance()->refreshInterval());
data["rss_max_articles_per_feed"] = RSS::Session::instance()->maxArticlesPerFeed(); data["rss_max_articles_per_feed"] = RSS::Session::instance()->maxArticlesPerFeed();
data["rss_processing_enabled"] = RSS::Session::instance()->isProcessingEnabled(); data["rss_processing_enabled"] = RSS::Session::instance()->isProcessingEnabled();
data["rss_auto_downloading_enabled"] = RSS::AutoDownloader::instance()->isProcessingEnabled(); data["rss_auto_downloading_enabled"] = RSS::AutoDownloader::instance()->isProcessingEnabled();
@ -262,7 +262,7 @@ void AppController::preferencesAction()
// Listen on IPv6 address // Listen on IPv6 address
data["listen_on_ipv6_address"] = session->isIPv6Enabled(); data["listen_on_ipv6_address"] = session->isIPv6Enabled();
// Save resume data interval // Save resume data interval
data["save_resume_data_interval"] = session->saveResumeDataInterval(); data["save_resume_data_interval"] = static_cast<double>(session->saveResumeDataInterval());
// Recheck completed torrents // Recheck completed torrents
data["recheck_completed_torrents"] = pref->recheckTorrentsOnCompletion(); data["recheck_completed_torrents"] = pref->recheckTorrentsOnCompletion();
// Resolve peer countries // Resolve peer countries
@ -311,7 +311,7 @@ void AppController::preferencesAction()
data["announce_to_all_tiers"] = session->announceToAllTiers(); data["announce_to_all_tiers"] = session->announceToAllTiers();
data["announce_ip"] = session->announceIP(); data["announce_ip"] = session->announceIP();
setResult(QJsonObject::fromVariantMap(data)); setResult(data);
} }
void AppController::setPreferencesAction() void AppController::setPreferencesAction()
@ -320,9 +320,9 @@ void AppController::setPreferencesAction()
Preferences *const pref = Preferences::instance(); Preferences *const pref = Preferences::instance();
auto session = BitTorrent::Session::instance(); auto session = BitTorrent::Session::instance();
const QVariantMap m = QJsonDocument::fromJson(params()["json"].toUtf8()).toVariant().toMap(); const QVariantHash m = QJsonDocument::fromJson(params()["json"].toUtf8()).toVariant().toHash();
QVariantMap::ConstIterator it; QVariantHash::ConstIterator it;
const auto hasKey = [&it, &m](const char *key) -> bool const auto hasKey = [&it, &m](const char *key) -> bool
{ {
it = m.find(QLatin1String(key)); it = m.find(QLatin1String(key));
@ -364,7 +364,7 @@ void AppController::setPreferencesAction()
session->setFinishedTorrentExportDirectory(it.value().toString()); session->setFinishedTorrentExportDirectory(it.value().toString());
// Automatically add torrents from // Automatically add torrents from
if (hasKey("scan_dirs")) { if (hasKey("scan_dirs")) {
const QVariantMap nativeDirs = it.value().toMap(); const QVariantHash nativeDirs = it.value().toHash();
QVariantHash oldScanDirs = pref->getScanDirs(); QVariantHash oldScanDirs = pref->getScanDirs();
QVariantHash scanDirs; QVariantHash scanDirs;
ScanFoldersModel *model = ScanFoldersModel::instance(); ScanFoldersModel *model = ScanFoldersModel::instance();
@ -747,17 +747,17 @@ void AppController::defaultSavePathAction()
void AppController::networkInterfaceListAction() void AppController::networkInterfaceListAction()
{ {
QVariantList ifaceList; QJsonArray ifaceList;
for (const QNetworkInterface &iface : asConst(QNetworkInterface::allInterfaces())) { for (const QNetworkInterface &iface : asConst(QNetworkInterface::allInterfaces())) {
if (!iface.addressEntries().isEmpty()) { if (!iface.addressEntries().isEmpty()) {
ifaceList.append(QVariantMap { ifaceList.append(QJsonObject {
{"name", iface.humanReadableName()}, {"name", iface.humanReadableName()},
{"value", iface.name()} {"value", iface.name()}
}); });
} }
} }
setResult(QJsonArray::fromVariantList(ifaceList)); setResult(ifaceList);
} }
void AppController::networkInterfaceAddressListAction() void AppController::networkInterfaceAddressListAction()
@ -765,7 +765,7 @@ void AppController::networkInterfaceAddressListAction()
checkParams({"iface"}); checkParams({"iface"});
const QString ifaceName = params().value("iface"); const QString ifaceName = params().value("iface");
QVariantList addressList; QJsonArray addressList;
if (ifaceName.isEmpty()) { if (ifaceName.isEmpty()) {
for (const QHostAddress &ip : asConst(QNetworkInterface::allAddresses())) for (const QHostAddress &ip : asConst(QNetworkInterface::allAddresses()))
@ -777,5 +777,5 @@ void AppController::networkInterfaceAddressListAction()
addressList.append(entry.ip().toString()); addressList.append(entry.ip().toString());
} }
setResult(QJsonArray::fromVariantList(addressList)); setResult(addressList);
} }

36
src/webui/api/logcontroller.cpp

@ -29,6 +29,7 @@
#include "logcontroller.h" #include "logcontroller.h"
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject>
#include "base/global.h" #include "base/global.h"
#include "base/logger.h" #include "base/logger.h"
@ -70,7 +71,7 @@ void LogController::mainAction()
lastKnownId = -1; lastKnownId = -1;
Logger *const logger = Logger::instance(); Logger *const logger = Logger::instance();
QVariantList msgList; QJsonArray msgList;
for (const Log::Msg &msg : asConst(logger->getMessages(lastKnownId))) { for (const Log::Msg &msg : asConst(logger->getMessages(lastKnownId))) {
if (!((msg.type == Log::NORMAL && isNormal) if (!((msg.type == Log::NORMAL && isNormal)
@ -78,15 +79,16 @@ void LogController::mainAction()
|| (msg.type == Log::WARNING && isWarning) || (msg.type == Log::WARNING && isWarning)
|| (msg.type == Log::CRITICAL && isCritical))) || (msg.type == Log::CRITICAL && isCritical)))
continue; continue;
QVariantMap map;
map[KEY_LOG_ID] = msg.id; msgList.append(QJsonObject {
map[KEY_LOG_TIMESTAMP] = msg.timestamp; {KEY_LOG_ID, msg.id},
map[KEY_LOG_MSG_TYPE] = msg.type; {KEY_LOG_TIMESTAMP, msg.timestamp},
map[KEY_LOG_MSG_MESSAGE] = msg.message; {KEY_LOG_MSG_TYPE, msg.type},
msgList.append(map); {KEY_LOG_MSG_MESSAGE, msg.message}
});
} }
setResult(QJsonArray::fromVariantList(msgList)); setResult(msgList);
} }
// Returns the peer log in JSON format. // Returns the peer log in JSON format.
@ -109,17 +111,17 @@ void LogController::peersAction()
lastKnownId = -1; lastKnownId = -1;
Logger *const logger = Logger::instance(); Logger *const logger = Logger::instance();
QVariantList peerList; QJsonArray peerList;
for (const Log::Peer &peer : asConst(logger->getPeers(lastKnownId))) { for (const Log::Peer &peer : asConst(logger->getPeers(lastKnownId))) {
QVariantMap map; peerList.append(QJsonObject {
map[KEY_LOG_ID] = peer.id; {KEY_LOG_ID, peer.id},
map[KEY_LOG_TIMESTAMP] = peer.timestamp; {KEY_LOG_TIMESTAMP, peer.timestamp},
map[KEY_LOG_PEER_IP] = peer.ip; {KEY_LOG_PEER_IP, peer.ip},
map[KEY_LOG_PEER_BLOCKED] = peer.blocked; {KEY_LOG_PEER_BLOCKED, peer.blocked},
map[KEY_LOG_PEER_REASON] = peer.reason; {KEY_LOG_PEER_REASON, peer.reason}
peerList.append(map); });
} }
setResult(QJsonArray::fromVariantList(peerList)); setResult(peerList);
} }

93
src/webui/api/serialize/serialize_torrent.cpp

@ -82,50 +82,55 @@ namespace
QVariantMap serialize(const BitTorrent::TorrentHandle &torrent) QVariantMap serialize(const BitTorrent::TorrentHandle &torrent)
{ {
QVariantMap ret; QVariantMap ret = {
ret[KEY_TORRENT_HASH] = QString(torrent.hash()); {KEY_TORRENT_HASH, QString(torrent.hash())},
ret[KEY_TORRENT_NAME] = torrent.name(); {KEY_TORRENT_NAME, torrent.name()},
ret[KEY_TORRENT_MAGNET_URI] = torrent.toMagnetUri(); {KEY_TORRENT_MAGNET_URI, torrent.toMagnetUri()},
ret[KEY_TORRENT_SIZE] = torrent.wantedSize(); {KEY_TORRENT_SIZE, torrent.wantedSize()},
ret[KEY_TORRENT_PROGRESS] = torrent.progress(); {KEY_TORRENT_PROGRESS, torrent.progress()},
ret[KEY_TORRENT_DLSPEED] = torrent.downloadPayloadRate(); {KEY_TORRENT_DLSPEED, torrent.downloadPayloadRate()},
ret[KEY_TORRENT_UPSPEED] = torrent.uploadPayloadRate(); {KEY_TORRENT_UPSPEED, torrent.uploadPayloadRate()},
ret[KEY_TORRENT_QUEUE_POSITION] = static_cast<int>(torrent.queuePosition()); {KEY_TORRENT_QUEUE_POSITION, torrent.queuePosition()},
ret[KEY_TORRENT_SEEDS] = torrent.seedsCount(); {KEY_TORRENT_SEEDS, torrent.seedsCount()},
ret[KEY_TORRENT_NUM_COMPLETE] = torrent.totalSeedsCount(); {KEY_TORRENT_NUM_COMPLETE, torrent.totalSeedsCount()},
ret[KEY_TORRENT_LEECHS] = torrent.leechsCount(); {KEY_TORRENT_LEECHS, torrent.leechsCount()},
ret[KEY_TORRENT_NUM_INCOMPLETE] = torrent.totalLeechersCount(); {KEY_TORRENT_NUM_INCOMPLETE, torrent.totalLeechersCount()},
{KEY_TORRENT_STATE, torrentStateToString(torrent.state())},
{KEY_TORRENT_ETA, torrent.eta()},
{KEY_TORRENT_SEQUENTIAL_DOWNLOAD, torrent.isSequentialDownload()},
{KEY_TORRENT_FIRST_LAST_PIECE_PRIO, torrent.hasFirstLastPiecePriority()},
{KEY_TORRENT_CATEGORY, torrent.category()},
{KEY_TORRENT_TAGS, torrent.tags().toList().join(", ")},
{KEY_TORRENT_SUPER_SEEDING, torrent.superSeeding()},
{KEY_TORRENT_FORCE_START, torrent.isForced()},
{KEY_TORRENT_SAVE_PATH, Utils::Fs::toNativePath(torrent.savePath())},
{KEY_TORRENT_ADDED_ON, torrent.addedTime().toSecsSinceEpoch()},
{KEY_TORRENT_COMPLETION_ON, torrent.completedTime().toSecsSinceEpoch()},
{KEY_TORRENT_TRACKER, torrent.currentTracker()},
{KEY_TORRENT_DL_LIMIT, torrent.downloadLimit()},
{KEY_TORRENT_UP_LIMIT, torrent.uploadLimit()},
{KEY_TORRENT_AMOUNT_DOWNLOADED, torrent.totalDownload()},
{KEY_TORRENT_AMOUNT_UPLOADED, torrent.totalUpload()},
{KEY_TORRENT_AMOUNT_DOWNLOADED_SESSION, torrent.totalPayloadDownload()},
{KEY_TORRENT_AMOUNT_UPLOADED_SESSION, torrent.totalPayloadUpload()},
{KEY_TORRENT_AMOUNT_LEFT, torrent.incompletedSize()},
{KEY_TORRENT_AMOUNT_COMPLETED, torrent.completedSize()},
{KEY_TORRENT_MAX_RATIO, torrent.maxRatio()},
{KEY_TORRENT_MAX_SEEDING_TIME, torrent.maxSeedingTime()},
{KEY_TORRENT_RATIO_LIMIT, torrent.ratioLimit()},
{KEY_TORRENT_SEEDING_TIME_LIMIT, torrent.seedingTimeLimit()},
{KEY_TORRENT_LAST_SEEN_COMPLETE_TIME, torrent.lastSeenComplete().toSecsSinceEpoch()},
{KEY_TORRENT_AUTO_TORRENT_MANAGEMENT, torrent.isAutoTMMEnabled()},
{KEY_TORRENT_TIME_ACTIVE, torrent.activeTime()},
{KEY_TORRENT_AVAILABILITY, torrent.distributedCopies()},
{KEY_TORRENT_TOTAL_SIZE, torrent.totalSize()}
};
const qreal ratio = torrent.realRatio(); const qreal ratio = torrent.realRatio();
ret[KEY_TORRENT_RATIO] = (ratio > BitTorrent::TorrentHandle::MAX_RATIO) ? -1 : ratio; ret[KEY_TORRENT_RATIO] = (ratio > BitTorrent::TorrentHandle::MAX_RATIO) ? -1 : ratio;
ret[KEY_TORRENT_STATE] = torrentStateToString(torrent.state());
ret[KEY_TORRENT_ETA] = torrent.eta();
ret[KEY_TORRENT_SEQUENTIAL_DOWNLOAD] = torrent.isSequentialDownload();
if (torrent.hasMetadata())
ret[KEY_TORRENT_FIRST_LAST_PIECE_PRIO] = torrent.hasFirstLastPiecePriority();
ret[KEY_TORRENT_CATEGORY] = torrent.category();
ret[KEY_TORRENT_TAGS] = torrent.tags().toList().join(", ");
ret[KEY_TORRENT_SUPER_SEEDING] = torrent.superSeeding();
ret[KEY_TORRENT_FORCE_START] = torrent.isForced();
ret[KEY_TORRENT_SAVE_PATH] = Utils::Fs::toNativePath(torrent.savePath());
ret[KEY_TORRENT_ADDED_ON] = torrent.addedTime().toTime_t();
ret[KEY_TORRENT_COMPLETION_ON] = torrent.completedTime().toTime_t();
ret[KEY_TORRENT_TRACKER] = torrent.currentTracker();
ret[KEY_TORRENT_DL_LIMIT] = torrent.downloadLimit();
ret[KEY_TORRENT_UP_LIMIT] = torrent.uploadLimit();
ret[KEY_TORRENT_AMOUNT_DOWNLOADED] = torrent.totalDownload();
ret[KEY_TORRENT_AMOUNT_UPLOADED] = torrent.totalUpload();
ret[KEY_TORRENT_AMOUNT_DOWNLOADED_SESSION] = torrent.totalPayloadDownload();
ret[KEY_TORRENT_AMOUNT_UPLOADED_SESSION] = torrent.totalPayloadUpload();
ret[KEY_TORRENT_AMOUNT_LEFT] = torrent.incompletedSize();
ret[KEY_TORRENT_AMOUNT_COMPLETED] = torrent.completedSize();
ret[KEY_TORRENT_MAX_RATIO] = torrent.maxRatio();
ret[KEY_TORRENT_MAX_SEEDING_TIME] = torrent.maxSeedingTime();
ret[KEY_TORRENT_RATIO_LIMIT] = torrent.ratioLimit();
ret[KEY_TORRENT_SEEDING_TIME_LIMIT] = torrent.seedingTimeLimit();
ret[KEY_TORRENT_LAST_SEEN_COMPLETE_TIME] = torrent.lastSeenComplete().toTime_t();
ret[KEY_TORRENT_AUTO_TORRENT_MANAGEMENT] = torrent.isAutoTMMEnabled();
ret[KEY_TORRENT_TIME_ACTIVE] = torrent.activeTime();
ret[KEY_TORRENT_AVAILABILITY] = torrent.distributedCopies();
if (torrent.isPaused() || torrent.isChecking()) { if (torrent.isPaused() || torrent.isChecking()) {
ret[KEY_TORRENT_LAST_ACTIVITY_TIME] = 0; ret[KEY_TORRENT_LAST_ACTIVITY_TIME] = 0;
@ -133,10 +138,8 @@ QVariantMap serialize(const BitTorrent::TorrentHandle &torrent)
else { else {
QDateTime dt = QDateTime::currentDateTime(); QDateTime dt = QDateTime::currentDateTime();
dt = dt.addSecs(-torrent.timeSinceActivity()); dt = dt.addSecs(-torrent.timeSinceActivity());
ret[KEY_TORRENT_LAST_ACTIVITY_TIME] = dt.toTime_t(); ret[KEY_TORRENT_LAST_ACTIVITY_TIME] = dt.toSecsSinceEpoch();
} }
ret[KEY_TORRENT_TOTAL_SIZE] = torrent.totalSize();
return ret; return ret;
} }

155
src/webui/api/synccontroller.cpp

@ -47,64 +47,64 @@
#include "isessionmanager.h" #include "isessionmanager.h"
#include "serialize/serialize_torrent.h" #include "serialize/serialize_torrent.h"
namespace
{
const int FREEDISKSPACE_CHECK_TIMEOUT = 30000;
// Sync main data keys // Sync main data keys
const char KEY_SYNC_MAINDATA_QUEUEING[] = "queueing"; const char KEY_SYNC_MAINDATA_QUEUEING[] = "queueing";
const char KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS[] = "use_alt_speed_limits";
const char KEY_SYNC_MAINDATA_REFRESH_INTERVAL[] = "refresh_interval"; const char KEY_SYNC_MAINDATA_REFRESH_INTERVAL[] = "refresh_interval";
const char KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS[] = "use_alt_speed_limits";
// Sync torrent peers keys // Sync torrent peers keys
const char KEY_SYNC_TORRENT_PEERS_SHOW_FLAGS[] = "show_flags"; const char KEY_SYNC_TORRENT_PEERS_SHOW_FLAGS[] = "show_flags";
// Peer keys // Peer keys
const char KEY_PEER_IP[] = "ip";
const char KEY_PEER_PORT[] = "port";
const char KEY_PEER_COUNTRY_CODE[] = "country_code";
const char KEY_PEER_COUNTRY[] = "country";
const char KEY_PEER_CLIENT[] = "client"; const char KEY_PEER_CLIENT[] = "client";
const char KEY_PEER_PROGRESS[] = "progress";
const char KEY_PEER_DOWN_SPEED[] = "dl_speed";
const char KEY_PEER_UP_SPEED[] = "up_speed";
const char KEY_PEER_TOT_DOWN[] = "downloaded";
const char KEY_PEER_TOT_UP[] = "uploaded";
const char KEY_PEER_CONNECTION_TYPE[] = "connection"; const char KEY_PEER_CONNECTION_TYPE[] = "connection";
const char KEY_PEER_COUNTRY[] = "country";
const char KEY_PEER_COUNTRY_CODE[] = "country_code";
const char KEY_PEER_DOWN_SPEED[] = "dl_speed";
const char KEY_PEER_FILES[] = "files";
const char KEY_PEER_FLAGS[] = "flags"; const char KEY_PEER_FLAGS[] = "flags";
const char KEY_PEER_FLAGS_DESCRIPTION[] = "flags_desc"; const char KEY_PEER_FLAGS_DESCRIPTION[] = "flags_desc";
const char KEY_PEER_IP[] = "ip";
const char KEY_PEER_PORT[] = "port";
const char KEY_PEER_PROGRESS[] = "progress";
const char KEY_PEER_RELEVANCE[] = "relevance"; const char KEY_PEER_RELEVANCE[] = "relevance";
const char KEY_PEER_FILES[] = "files"; const char KEY_PEER_TOT_DOWN[] = "downloaded";
const char KEY_PEER_TOT_UP[] = "uploaded";
const char KEY_PEER_UP_SPEED[] = "up_speed";
// TransferInfo keys // TransferInfo keys
const char KEY_TRANSFER_DLSPEED[] = "dl_info_speed"; const char KEY_TRANSFER_CONNECTION_STATUS[] = "connection_status";
const char KEY_TRANSFER_DHT_NODES[] = "dht_nodes";
const char KEY_TRANSFER_DLDATA[] = "dl_info_data"; const char KEY_TRANSFER_DLDATA[] = "dl_info_data";
const char KEY_TRANSFER_DLRATELIMIT[] = "dl_rate_limit"; const char KEY_TRANSFER_DLRATELIMIT[] = "dl_rate_limit";
const char KEY_TRANSFER_UPSPEED[] = "up_info_speed"; const char KEY_TRANSFER_DLSPEED[] = "dl_info_speed";
const char KEY_TRANSFER_FREESPACEONDISK[] = "free_space_on_disk";
const char KEY_TRANSFER_UPDATA[] = "up_info_data"; const char KEY_TRANSFER_UPDATA[] = "up_info_data";
const char KEY_TRANSFER_UPRATELIMIT[] = "up_rate_limit"; const char KEY_TRANSFER_UPRATELIMIT[] = "up_rate_limit";
const char KEY_TRANSFER_DHT_NODES[] = "dht_nodes"; const char KEY_TRANSFER_UPSPEED[] = "up_info_speed";
const char KEY_TRANSFER_CONNECTION_STATUS[] = "connection_status";
const char KEY_TRANSFER_FREESPACEONDISK[] = "free_space_on_disk";
// Statistics keys // Statistics keys
const char KEY_TRANSFER_ALLTIME_DL[] = "alltime_dl"; const char KEY_TRANSFER_ALLTIME_DL[] = "alltime_dl";
const char KEY_TRANSFER_ALLTIME_UL[] = "alltime_ul"; const char KEY_TRANSFER_ALLTIME_UL[] = "alltime_ul";
const char KEY_TRANSFER_TOTAL_WASTE_SESSION[] = "total_wasted_session"; const char KEY_TRANSFER_AVERAGE_TIME_QUEUE[] = "average_time_queue";
const char KEY_TRANSFER_GLOBAL_RATIO[] = "global_ratio"; const char KEY_TRANSFER_GLOBAL_RATIO[] = "global_ratio";
const char KEY_TRANSFER_TOTAL_PEER_CONNECTIONS[] = "total_peer_connections"; const char KEY_TRANSFER_QUEUED_IO_JOBS[] = "queued_io_jobs";
const char KEY_TRANSFER_READ_CACHE_HITS[] = "read_cache_hits"; const char KEY_TRANSFER_READ_CACHE_HITS[] = "read_cache_hits";
const char KEY_TRANSFER_TOTAL_BUFFERS_SIZE[] = "total_buffers_size";
const char KEY_TRANSFER_WRITE_CACHE_OVERLOAD[] = "write_cache_overload";
const char KEY_TRANSFER_READ_CACHE_OVERLOAD[] = "read_cache_overload"; const char KEY_TRANSFER_READ_CACHE_OVERLOAD[] = "read_cache_overload";
const char KEY_TRANSFER_QUEUED_IO_JOBS[] = "queued_io_jobs"; const char KEY_TRANSFER_TOTAL_BUFFERS_SIZE[] = "total_buffers_size";
const char KEY_TRANSFER_AVERAGE_TIME_QUEUE[] = "average_time_queue"; const char KEY_TRANSFER_TOTAL_PEER_CONNECTIONS[] = "total_peer_connections";
const char KEY_TRANSFER_TOTAL_QUEUED_SIZE[] = "total_queued_size"; const char KEY_TRANSFER_TOTAL_QUEUED_SIZE[] = "total_queued_size";
const char KEY_TRANSFER_TOTAL_WASTE_SESSION[] = "total_wasted_session";
const char KEY_TRANSFER_WRITE_CACHE_OVERLOAD[] = "write_cache_overload";
const char KEY_FULL_UPDATE[] = "full_update"; const char KEY_FULL_UPDATE[] = "full_update";
const char KEY_RESPONSE_ID[] = "rid"; const char KEY_RESPONSE_ID[] = "rid";
const char KEY_SUFFIX_REMOVED[] = "_removed"; const char KEY_SUFFIX_REMOVED[] = "_removed";
const int FREEDISKSPACE_CHECK_TIMEOUT = 30000;
namespace
{
void processMap(const QVariantMap &prevData, const QVariantMap &data, QVariantMap &syncData); void processMap(const QVariantMap &prevData, const QVariantMap &data, QVariantMap &syncData);
void processHash(QVariantHash prevData, const QVariantHash &data, QVariantMap &syncData, QVariantList &removedItems); void processHash(QVariantHash prevData, const QVariantHash &data, QVariantMap &syncData, QVariantList &removedItems);
void processList(QVariantList prevData, const QVariantList &data, QVariantList &syncData, QVariantList &removedItems); void processList(QVariantList prevData, const QVariantList &data, QVariantList &syncData, QVariantList &removedItems);
@ -113,29 +113,31 @@ namespace
QVariantMap getTranserInfo() QVariantMap getTranserInfo()
{ {
QVariantMap map; QVariantMap map;
const BitTorrent::SessionStatus &sessionStatus = BitTorrent::Session::instance()->status(); const auto *session = BitTorrent::Session::instance();
const BitTorrent::CacheStatus &cacheStatus = BitTorrent::Session::instance()->cacheStatus();
const BitTorrent::SessionStatus &sessionStatus = session->status();
const BitTorrent::CacheStatus &cacheStatus = session->cacheStatus();
map[KEY_TRANSFER_DLSPEED] = sessionStatus.payloadDownloadRate; map[KEY_TRANSFER_DLSPEED] = sessionStatus.payloadDownloadRate;
map[KEY_TRANSFER_DLDATA] = sessionStatus.totalPayloadDownload; map[KEY_TRANSFER_DLDATA] = sessionStatus.totalPayloadDownload;
map[KEY_TRANSFER_UPSPEED] = sessionStatus.payloadUploadRate; map[KEY_TRANSFER_UPSPEED] = sessionStatus.payloadUploadRate;
map[KEY_TRANSFER_UPDATA] = sessionStatus.totalPayloadUpload; map[KEY_TRANSFER_UPDATA] = sessionStatus.totalPayloadUpload;
map[KEY_TRANSFER_DLRATELIMIT] = BitTorrent::Session::instance()->downloadSpeedLimit(); map[KEY_TRANSFER_DLRATELIMIT] = session->downloadSpeedLimit();
map[KEY_TRANSFER_UPRATELIMIT] = BitTorrent::Session::instance()->uploadSpeedLimit(); map[KEY_TRANSFER_UPRATELIMIT] = session->uploadSpeedLimit();
quint64 atd = BitTorrent::Session::instance()->getAlltimeDL(); const quint64 atd = session->getAlltimeDL();
quint64 atu = BitTorrent::Session::instance()->getAlltimeUL(); const quint64 atu = session->getAlltimeUL();
map[KEY_TRANSFER_ALLTIME_DL] = atd; map[KEY_TRANSFER_ALLTIME_DL] = atd;
map[KEY_TRANSFER_ALLTIME_UL] = atu; map[KEY_TRANSFER_ALLTIME_UL] = atu;
map[KEY_TRANSFER_TOTAL_WASTE_SESSION] = sessionStatus.totalWasted; map[KEY_TRANSFER_TOTAL_WASTE_SESSION] = sessionStatus.totalWasted;
map[KEY_TRANSFER_GLOBAL_RATIO] = ((atd > 0) && (atu > 0)) ? Utils::String::fromDouble(static_cast<qreal>(atu) / atd, 2) : "-"; map[KEY_TRANSFER_GLOBAL_RATIO] = ((atd > 0) && (atu > 0)) ? Utils::String::fromDouble(static_cast<qreal>(atu) / atd, 2) : "-";
map[KEY_TRANSFER_TOTAL_PEER_CONNECTIONS] = sessionStatus.peersCount; map[KEY_TRANSFER_TOTAL_PEER_CONNECTIONS] = sessionStatus.peersCount;
qreal readRatio = cacheStatus.readRatio; const qreal readRatio = cacheStatus.readRatio;
map[KEY_TRANSFER_READ_CACHE_HITS] = (readRatio > 0) ? Utils::String::fromDouble(100 * readRatio, 2) : "0"; map[KEY_TRANSFER_READ_CACHE_HITS] = (readRatio > 0) ? Utils::String::fromDouble(100 * readRatio, 2) : "0";
map[KEY_TRANSFER_TOTAL_BUFFERS_SIZE] = cacheStatus.totalUsedBuffers * 16 * 1024; map[KEY_TRANSFER_TOTAL_BUFFERS_SIZE] = cacheStatus.totalUsedBuffers * 16 * 1024;
// num_peers is not reliable (adds up peers, which didn't even overcome tcp handshake) // num_peers is not reliable (adds up peers, which didn't even overcome tcp handshake)
const auto torrents = BitTorrent::Session::instance()->torrents(); const auto torrents = session->torrents();
const quint32 peers = std::accumulate(torrents.cbegin(), torrents.cend(), 0, [](const quint32 acc, const BitTorrent::TorrentHandle *torrent) const quint32 peers = std::accumulate(torrents.cbegin(), torrents.cend(), 0, [](const quint32 acc, const BitTorrent::TorrentHandle *torrent)
{ {
return (acc + torrent->peersCount()); return (acc + torrent->peersCount());
@ -149,10 +151,10 @@ namespace
map[KEY_TRANSFER_TOTAL_QUEUED_SIZE] = cacheStatus.queuedBytes; map[KEY_TRANSFER_TOTAL_QUEUED_SIZE] = cacheStatus.queuedBytes;
map[KEY_TRANSFER_DHT_NODES] = sessionStatus.dhtNodes; map[KEY_TRANSFER_DHT_NODES] = sessionStatus.dhtNodes;
if (!BitTorrent::Session::instance()->isListening()) map[KEY_TRANSFER_CONNECTION_STATUS] = session->isListening()
map[KEY_TRANSFER_CONNECTION_STATUS] = "disconnected"; ? (sessionStatus.hasIncomingConnections ? "connected" : "firewalled")
else : "disconnected";
map[KEY_TRANSFER_CONNECTION_STATUS] = sessionStatus.hasIncomingConnections ? "connected" : "firewalled";
return map; return map;
} }
@ -163,11 +165,10 @@ namespace
// initialize output variable // initialize output variable
syncData.clear(); syncData.clear();
QVariantList removedItems;
for (auto i = data.cbegin(); i != data.cend(); ++i) { for (auto i = data.cbegin(); i != data.cend(); ++i) {
const QString &key = i.key(); const QString &key = i.key();
const QVariant &value = i.value(); const QVariant &value = i.value();
removedItems.clear(); QVariantList removedItems;
switch (static_cast<QMetaType::Type>(value.type())) { switch (static_cast<QMetaType::Type>(value.type())) {
case QMetaType::QVariantMap: { case QMetaType::QVariantMap: {
@ -315,7 +316,7 @@ namespace
syncData[KEY_FULL_UPDATE] = true; syncData[KEY_FULL_UPDATE] = true;
} }
lastResponseId = lastResponseId % 1000000 + 1; // cycle between 1 and 1000000 lastResponseId = (lastResponseId % 1000000) + 1; // cycle between 1 and 1000000
lastData = data; lastData = data;
lastData[KEY_RESPONSE_ID] = lastResponseId; lastData[KEY_RESPONSE_ID] = lastResponseId;
syncData[KEY_RESPONSE_ID] = lastResponseId; syncData[KEY_RESPONSE_ID] = lastResponseId;
@ -407,48 +408,57 @@ SyncController::~SyncController()
// - rid (int): last response id // - rid (int): last response id
void SyncController::maindataAction() void SyncController::maindataAction()
{ {
auto lastResponse = sessionManager()->session()->getData(QLatin1String("syncMainDataLastResponse")).toMap(); const auto *session = BitTorrent::Session::instance();
auto lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncMainDataLastAcceptedResponse")).toMap();
QVariantMap data; QVariantMap data;
QVariantHash torrents;
BitTorrent::Session *const session = BitTorrent::Session::instance(); QVariantMap lastResponse = sessionManager()->session()->getData(QLatin1String("syncMainDataLastResponse")).toMap();
QVariantMap lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncMainDataLastAcceptedResponse")).toMap();
QVariantHash torrents;
for (const BitTorrent::TorrentHandle *torrent : asConst(session->torrents())) {
const BitTorrent::InfoHash torrentHash = torrent->hash();
for (BitTorrent::TorrentHandle *const torrent : asConst(session->torrents())) {
QVariantMap map = serialize(*torrent); QVariantMap map = serialize(*torrent);
map.remove(KEY_TORRENT_HASH); map.remove(KEY_TORRENT_HASH);
// Calculated last activity time can differ from actual value by up to 10 seconds (this is a libtorrent issue). // Calculated last activity time can differ from actual value by up to 10 seconds (this is a libtorrent issue).
// So we don't need unnecessary updates of last activity time in response. // So we don't need unnecessary updates of last activity time in response.
if (lastResponse.contains("torrents") && lastResponse["torrents"].toHash().contains(torrent->hash()) && const auto iterTorrents = lastResponse.find("torrents");
lastResponse["torrents"].toHash()[torrent->hash()].toMap().contains(KEY_TORRENT_LAST_ACTIVITY_TIME)) { if (iterTorrents != lastResponse.end()) {
uint lastValue = lastResponse["torrents"].toHash()[torrent->hash()].toMap()[KEY_TORRENT_LAST_ACTIVITY_TIME].toUInt(); const QVariantHash lastResponseTorrents = iterTorrents->toHash();
if (qAbs(static_cast<int>(lastValue - map[KEY_TORRENT_LAST_ACTIVITY_TIME].toUInt())) < 15) const auto iterHash = lastResponseTorrents.find(torrentHash);
if (iterHash != lastResponseTorrents.end()) {
const QVariantMap torrentData = iterHash->toMap();
const auto iterLastActivity = torrentData.find(KEY_TORRENT_LAST_ACTIVITY_TIME);
if (iterLastActivity != torrentData.end()) {
const int lastValue = iterLastActivity->toInt();
if (qAbs(lastValue - map[KEY_TORRENT_LAST_ACTIVITY_TIME].toInt()) < 15)
map[KEY_TORRENT_LAST_ACTIVITY_TIME] = lastValue; map[KEY_TORRENT_LAST_ACTIVITY_TIME] = lastValue;
} }
}
torrents[torrent->hash()] = map;
} }
torrents[torrentHash] = map;
}
data["torrents"] = torrents; data["torrents"] = torrents;
QVariantHash categories; QVariantHash categories;
const auto &categoriesList = session->categories(); const auto &categoriesList = session->categories();
for (auto it = categoriesList.cbegin(); it != categoriesList.cend(); ++it) { for (auto it = categoriesList.cbegin(); it != categoriesList.cend(); ++it) {
const auto &key = it.key(); const QString &key = it.key();
categories[key] = QVariantMap { categories[key] = QVariantMap {
{"name", key}, {"name", key},
{"savePath", it.value()} {"savePath", it.value()}
}; };
} }
data["categories"] = categories; data["categories"] = categories;
QVariantList tags; QVariantList tags;
for (const QString &tag : asConst(session->tags())) for (const QString &tag : asConst(session->tags()))
tags << tag; tags << tag;
data["tags"] = tags; data["tags"] = tags;
QVariantMap serverState = getTranserInfo(); QVariantMap serverState = getTranserInfo();
@ -474,13 +484,14 @@ void SyncController::torrentPeersAction()
auto lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastAcceptedResponse")).toMap(); auto lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastAcceptedResponse")).toMap();
const QString hash {params()["hash"]}; const QString hash {params()["hash"]};
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); const BitTorrent::TorrentHandle *torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
QVariantMap data; QVariantMap data;
QVariantHash peers; QVariantHash peers;
const QList<BitTorrent::PeerInfo> peersList = torrent->peers(); const QList<BitTorrent::PeerInfo> peersList = torrent->peers();
#ifndef DISABLE_COUNTRIES_RESOLUTION #ifndef DISABLE_COUNTRIES_RESOLUTION
bool resolvePeerCountries = Preferences::instance()->resolvePeerCountries(); bool resolvePeerCountries = Preferences::instance()->resolvePeerCountries();
#else #else
@ -491,30 +502,32 @@ void SyncController::torrentPeersAction()
for (const BitTorrent::PeerInfo &pi : peersList) { for (const BitTorrent::PeerInfo &pi : peersList) {
if (pi.address().ip.isNull()) continue; if (pi.address().ip.isNull()) continue;
QVariantMap peer;
QVariantMap peer = {
{KEY_PEER_IP, pi.address().ip.toString()},
{KEY_PEER_PORT, pi.address().port},
{KEY_PEER_CLIENT, pi.client()},
{KEY_PEER_PROGRESS, pi.progress()},
{KEY_PEER_DOWN_SPEED, pi.payloadDownSpeed()},
{KEY_PEER_UP_SPEED, pi.payloadUpSpeed()},
{KEY_PEER_TOT_DOWN, pi.totalDownload()},
{KEY_PEER_TOT_UP, pi.totalUpload()},
{KEY_PEER_CONNECTION_TYPE, pi.connectionType()},
{KEY_PEER_FLAGS, pi.flags()},
{KEY_PEER_FLAGS_DESCRIPTION, pi.flagsDescription()},
{KEY_PEER_RELEVANCE, pi.relevance()},
{KEY_PEER_FILES, torrent->info().filesForPiece(pi.downloadingPieceIndex()).join('\n')}
};
#ifndef DISABLE_COUNTRIES_RESOLUTION #ifndef DISABLE_COUNTRIES_RESOLUTION
if (resolvePeerCountries) { if (resolvePeerCountries) {
peer[KEY_PEER_COUNTRY_CODE] = pi.country().toLower(); peer[KEY_PEER_COUNTRY_CODE] = pi.country().toLower();
peer[KEY_PEER_COUNTRY] = Net::GeoIPManager::CountryName(pi.country()); peer[KEY_PEER_COUNTRY] = Net::GeoIPManager::CountryName(pi.country());
} }
#endif #endif
peer[KEY_PEER_IP] = pi.address().ip.toString();
peer[KEY_PEER_PORT] = pi.address().port;
peer[KEY_PEER_CLIENT] = pi.client();
peer[KEY_PEER_PROGRESS] = pi.progress();
peer[KEY_PEER_DOWN_SPEED] = pi.payloadDownSpeed();
peer[KEY_PEER_UP_SPEED] = pi.payloadUpSpeed();
peer[KEY_PEER_TOT_DOWN] = pi.totalDownload();
peer[KEY_PEER_TOT_UP] = pi.totalUpload();
peer[KEY_PEER_CONNECTION_TYPE] = pi.connectionType();
peer[KEY_PEER_FLAGS] = pi.flags();
peer[KEY_PEER_FLAGS_DESCRIPTION] = pi.flagsDescription();
peer[KEY_PEER_RELEVANCE] = pi.relevance();
peer[KEY_PEER_FILES] = torrent->info().filesForPiece(pi.downloadingPieceIndex()).join(QLatin1String("\n"));
peers[pi.address().ip.toString() + ':' + QString::number(pi.address().port)] = peer; peers[pi.address().ip.toString() + ':' + QString::number(pi.address().port)] = peer;
} }
data["peers"] = peers; data["peers"] = peers;
const int acceptedResponseId {params()["rid"].toInt()}; const int acceptedResponseId {params()["rid"].toInt()};

85
src/webui/api/torrentscontroller.cpp

@ -131,9 +131,9 @@ namespace
} }
} }
QVariantList getStickyTrackers(const BitTorrent::TorrentHandle *const torrent) QJsonArray getStickyTrackers(const BitTorrent::TorrentHandle *const torrent)
{ {
uint seedsDHT = 0, seedsPeX = 0, seedsLSD = 0, leechesDHT = 0, leechesPeX = 0, leechesLSD = 0; int seedsDHT = 0, seedsPeX = 0, seedsLSD = 0, leechesDHT = 0, leechesPeX = 0, leechesLSD = 0;
for (const BitTorrent::PeerInfo &peer : asConst(torrent->peers())) { for (const BitTorrent::PeerInfo &peer : asConst(torrent->peers())) {
if (peer.isConnecting()) continue; if (peer.isConnecting()) continue;
@ -161,7 +161,7 @@ namespace
const QString privateMsg {QCoreApplication::translate("TrackerListWidget", "This torrent is private")}; const QString privateMsg {QCoreApplication::translate("TrackerListWidget", "This torrent is private")};
const bool isTorrentPrivate = torrent->isPrivate(); const bool isTorrentPrivate = torrent->isPrivate();
const QVariantMap dht { const QJsonObject dht {
{KEY_TRACKER_URL, "** [DHT] **"}, {KEY_TRACKER_URL, "** [DHT] **"},
{KEY_TRACKER_TIER, ""}, {KEY_TRACKER_TIER, ""},
{KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : "")}, {KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : "")},
@ -172,7 +172,7 @@ namespace
{KEY_TRACKER_LEECHES_COUNT, leechesDHT} {KEY_TRACKER_LEECHES_COUNT, leechesDHT}
}; };
const QVariantMap pex { const QJsonObject pex {
{KEY_TRACKER_URL, "** [PeX] **"}, {KEY_TRACKER_URL, "** [PeX] **"},
{KEY_TRACKER_TIER, ""}, {KEY_TRACKER_TIER, ""},
{KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : "")}, {KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : "")},
@ -183,7 +183,7 @@ namespace
{KEY_TRACKER_LEECHES_COUNT, leechesPeX} {KEY_TRACKER_LEECHES_COUNT, leechesPeX}
}; };
const QVariantMap lsd { const QJsonObject lsd {
{KEY_TRACKER_URL, "** [LSD] **"}, {KEY_TRACKER_URL, "** [LSD] **"},
{KEY_TRACKER_TIER, ""}, {KEY_TRACKER_TIER, ""},
{KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : "")}, {KEY_TRACKER_MSG, (isTorrentPrivate ? privateMsg : "")},
@ -194,7 +194,7 @@ namespace
{KEY_TRACKER_LEECHES_COUNT, leechesLSD} {KEY_TRACKER_LEECHES_COUNT, leechesLSD}
}; };
return QVariantList {dht, pex, lsd}; return {dht, pex, lsd};
} }
} }
@ -309,14 +309,14 @@ void TorrentsController::propertiesAction()
checkParams({"hash"}); checkParams({"hash"});
const QString hash {params()["hash"]}; const QString hash {params()["hash"]};
QVariantMap dataDict; QJsonObject dataDict;
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
dataDict[KEY_PROP_TIME_ELAPSED] = torrent->activeTime(); dataDict[KEY_PROP_TIME_ELAPSED] = torrent->activeTime();
dataDict[KEY_PROP_SEEDING_TIME] = torrent->seedingTime(); dataDict[KEY_PROP_SEEDING_TIME] = torrent->seedingTime();
dataDict[KEY_PROP_ETA] = torrent->eta(); dataDict[KEY_PROP_ETA] = static_cast<double>(torrent->eta());
dataDict[KEY_PROP_CONNECT_COUNT] = torrent->connectionsCount(); dataDict[KEY_PROP_CONNECT_COUNT] = torrent->connectionsCount();
dataDict[KEY_PROP_CONNECT_COUNT_LIMIT] = torrent->connectionsLimit(); dataDict[KEY_PROP_CONNECT_COUNT_LIMIT] = torrent->connectionsLimit();
dataDict[KEY_PROP_DOWNLOADED] = torrent->totalDownload(); dataDict[KEY_PROP_DOWNLOADED] = torrent->totalDownload();
@ -344,11 +344,11 @@ void TorrentsController::propertiesAction()
dataDict[KEY_PROP_PIECE_SIZE] = torrent->pieceLength(); dataDict[KEY_PROP_PIECE_SIZE] = torrent->pieceLength();
dataDict[KEY_PROP_PIECES_HAVE] = torrent->piecesHave(); dataDict[KEY_PROP_PIECES_HAVE] = torrent->piecesHave();
dataDict[KEY_PROP_CREATED_BY] = torrent->creator(); dataDict[KEY_PROP_CREATED_BY] = torrent->creator();
dataDict[KEY_PROP_ADDITION_DATE] = torrent->addedTime().toTime_t(); dataDict[KEY_PROP_ADDITION_DATE] = static_cast<double>(torrent->addedTime().toSecsSinceEpoch());
if (torrent->hasMetadata()) { if (torrent->hasMetadata()) {
dataDict[KEY_PROP_LAST_SEEN] = torrent->lastSeenComplete().isValid() ? static_cast<int>(torrent->lastSeenComplete().toTime_t()) : -1; dataDict[KEY_PROP_LAST_SEEN] = torrent->lastSeenComplete().isValid() ? torrent->lastSeenComplete().toSecsSinceEpoch() : -1;
dataDict[KEY_PROP_COMPLETION_DATE] = torrent->completedTime().isValid() ? static_cast<int>(torrent->completedTime().toTime_t()) : -1; dataDict[KEY_PROP_COMPLETION_DATE] = torrent->completedTime().isValid() ? torrent->completedTime().toSecsSinceEpoch() : -1;
dataDict[KEY_PROP_CREATION_DATE] = torrent->creationDate().toTime_t(); dataDict[KEY_PROP_CREATION_DATE] = static_cast<double>(torrent->creationDate().toSecsSinceEpoch());
} }
else { else {
dataDict[KEY_PROP_LAST_SEEN] = -1; dataDict[KEY_PROP_LAST_SEEN] = -1;
@ -358,7 +358,7 @@ void TorrentsController::propertiesAction()
dataDict[KEY_PROP_SAVE_PATH] = Utils::Fs::toNativePath(torrent->savePath()); dataDict[KEY_PROP_SAVE_PATH] = Utils::Fs::toNativePath(torrent->savePath());
dataDict[KEY_PROP_COMMENT] = torrent->comment(); dataDict[KEY_PROP_COMMENT] = torrent->comment();
setResult(QJsonObject::fromVariantMap(dataDict)); setResult(dataDict);
} }
// Returns the trackers for a torrent in JSON format. // Returns the trackers for a torrent in JSON format.
@ -381,13 +381,13 @@ void TorrentsController::trackersAction()
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
QVariantList trackerList = getStickyTrackers(torrent); QJsonArray trackerList = getStickyTrackers(torrent);
QHash<QString, BitTorrent::TrackerInfo> trackersData = torrent->trackerInfos(); QHash<QString, BitTorrent::TrackerInfo> trackersData = torrent->trackerInfos();
for (const BitTorrent::TrackerEntry &tracker : asConst(torrent->trackers())) { for (const BitTorrent::TrackerEntry &tracker : asConst(torrent->trackers())) {
const BitTorrent::TrackerInfo data = trackersData.value(tracker.url()); const BitTorrent::TrackerInfo data = trackersData.value(tracker.url());
trackerList << QVariantMap { trackerList << QJsonObject {
{KEY_TRACKER_URL, tracker.url()}, {KEY_TRACKER_URL, tracker.url()},
{KEY_TRACKER_TIER, tracker.tier()}, {KEY_TRACKER_TIER, tracker.tier()},
{KEY_TRACKER_STATUS, static_cast<int>(tracker.status())}, {KEY_TRACKER_STATUS, static_cast<int>(tracker.status())},
@ -399,7 +399,7 @@ void TorrentsController::trackersAction()
}; };
} }
setResult(QJsonArray::fromVariantList(trackerList)); setResult(trackerList);
} }
// Returns the web seeds for a torrent in JSON format. // Returns the web seeds for a torrent in JSON format.
@ -411,18 +411,18 @@ void TorrentsController::webseedsAction()
checkParams({"hash"}); checkParams({"hash"});
const QString hash {params()["hash"]}; const QString hash {params()["hash"]};
QVariantList webSeedList; QJsonArray webSeedList;
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
for (const QUrl &webseed : asConst(torrent->urlSeeds())) { for (const QUrl &webseed : asConst(torrent->urlSeeds())) {
QVariantMap webSeedDict; webSeedList.append(QJsonObject {
webSeedDict[KEY_WEBSEED_URL] = webseed.toString(); {KEY_WEBSEED_URL, webseed.toString()}
webSeedList.append(webSeedDict); });
} }
setResult(QJsonArray::fromVariantList(webSeedList)); setResult(webSeedList);
} }
// Returns the files in a torrent in JSON format. // Returns the files in a torrent in JSON format.
@ -440,7 +440,7 @@ void TorrentsController::filesAction()
checkParams({"hash"}); checkParams({"hash"});
const QString hash {params()["hash"]}; const QString hash {params()["hash"]};
QVariantList fileList; QJsonArray fileList;
const BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); const BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -451,11 +451,12 @@ void TorrentsController::filesAction()
const QVector<qreal> fileAvailability = torrent->availableFileFractions(); const QVector<qreal> fileAvailability = torrent->availableFileFractions();
const BitTorrent::TorrentInfo info = torrent->info(); const BitTorrent::TorrentInfo info = torrent->info();
for (int i = 0; i < torrent->filesCount(); ++i) { for (int i = 0; i < torrent->filesCount(); ++i) {
QVariantMap fileDict; QJsonObject fileDict = {
fileDict[KEY_FILE_PROGRESS] = fp[i]; {KEY_FILE_PROGRESS, fp[i]},
fileDict[KEY_FILE_PRIORITY] = static_cast<int>(priorities[i]); {KEY_FILE_PRIORITY, static_cast<int>(priorities[i])},
fileDict[KEY_FILE_SIZE] = torrent->fileSize(i); {KEY_FILE_SIZE, torrent->fileSize(i)},
fileDict[KEY_FILE_AVAILABILITY] = fileAvailability[i]; {KEY_FILE_AVAILABILITY, fileAvailability[i]}
};
QString fileName = torrent->filePath(i); QString fileName = torrent->filePath(i);
if (fileName.endsWith(QB_EXT, Qt::CaseInsensitive)) if (fileName.endsWith(QB_EXT, Qt::CaseInsensitive))
@ -463,7 +464,7 @@ void TorrentsController::filesAction()
fileDict[KEY_FILE_NAME] = Utils::Fs::toNativePath(fileName); fileDict[KEY_FILE_NAME] = Utils::Fs::toNativePath(fileName);
const BitTorrent::TorrentInfo::PieceRange idx = info.filePieces(i); const BitTorrent::TorrentInfo::PieceRange idx = info.filePieces(i);
fileDict[KEY_FILE_PIECE_RANGE] = QVariantList {idx.first(), idx.last()}; fileDict[KEY_FILE_PIECE_RANGE] = QJsonArray {idx.first(), idx.last()};
if (i == 0) if (i == 0)
fileDict[KEY_FILE_IS_SEED] = torrent->isSeed(); fileDict[KEY_FILE_IS_SEED] = torrent->isSeed();
@ -472,7 +473,7 @@ void TorrentsController::filesAction()
} }
} }
setResult(QJsonArray::fromVariantList(fileList)); setResult(fileList);
} }
// Returns an array of hashes (of each pieces respectively) for a torrent in JSON format. // Returns an array of hashes (of each pieces respectively) for a torrent in JSON format.
@ -482,17 +483,16 @@ void TorrentsController::pieceHashesAction()
checkParams({"hash"}); checkParams({"hash"});
const QString hash {params()["hash"]}; const QString hash {params()["hash"]};
QVariantList pieceHashes; QJsonArray pieceHashes;
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
const QVector<QByteArray> hashes = torrent->info().pieceHashes(); const QVector<QByteArray> hashes = torrent->info().pieceHashes();
pieceHashes.reserve(hashes.size());
for (const QByteArray &hash : hashes) for (const QByteArray &hash : hashes)
pieceHashes.append(hash.toHex()); pieceHashes.append(QString(hash.toHex()));
setResult(QJsonArray::fromVariantList(pieceHashes)); setResult(pieceHashes);
} }
// Returns an array of states (of each pieces respectively) for a torrent in JSON format. // Returns an array of states (of each pieces respectively) for a torrent in JSON format.
@ -505,13 +505,12 @@ void TorrentsController::pieceStatesAction()
checkParams({"hash"}); checkParams({"hash"});
const QString hash {params()["hash"]}; const QString hash {params()["hash"]};
QVariantList pieceStates; QJsonArray pieceStates;
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
const QBitArray states = torrent->pieces(); const QBitArray states = torrent->pieces();
pieceStates.reserve(states.size());
for (int i = 0; i < states.size(); ++i) for (int i = 0; i < states.size(); ++i)
pieceStates.append(static_cast<int>(states[i]) * 2); pieceStates.append(static_cast<int>(states[i]) * 2);
@ -521,7 +520,7 @@ void TorrentsController::pieceStatesAction()
pieceStates[i] = 1; pieceStates[i] = 1;
} }
setResult(QJsonArray::fromVariantList(pieceStates)); setResult(pieceStates);
} }
void TorrentsController::addAction() void TorrentsController::addAction()
@ -742,7 +741,7 @@ void TorrentsController::uploadLimitAction()
checkParams({"hashes"}); checkParams({"hashes"});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
QVariantMap map; QJsonObject map;
for (const QString &hash : hashes) { for (const QString &hash : hashes) {
int limit = -1; int limit = -1;
const BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); const BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
@ -751,7 +750,7 @@ void TorrentsController::uploadLimitAction()
map[hash] = limit; map[hash] = limit;
} }
setResult(QJsonObject::fromVariantMap(map)); setResult(map);
} }
void TorrentsController::downloadLimitAction() void TorrentsController::downloadLimitAction()
@ -759,7 +758,7 @@ void TorrentsController::downloadLimitAction()
checkParams({"hashes"}); checkParams({"hashes"});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
QVariantMap map; QJsonObject map;
for (const QString &hash : hashes) { for (const QString &hash : hashes) {
int limit = -1; int limit = -1;
const BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash); const BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
@ -768,7 +767,7 @@ void TorrentsController::downloadLimitAction()
map[hash] = limit; map[hash] = limit;
} }
setResult(QJsonObject::fromVariantMap(map)); setResult(map);
} }
void TorrentsController::setUploadLimitAction() void TorrentsController::setUploadLimitAction()
@ -1102,6 +1101,8 @@ void TorrentsController::deleteTagsAction()
void TorrentsController::tagsAction() void TorrentsController::tagsAction()
{ {
const QStringList tags = BitTorrent::Session::instance()->tags().toList(); QJsonArray result;
setResult(QJsonArray::fromStringList(tags)); for (const QString &tag : asConst(BitTorrent::Session::instance()->tags()))
result << tag;
setResult(result);
} }

Loading…
Cancel
Save