qBittorrent
SyncController Class Reference

#include <synccontroller.h>

Inheritance diagram for SyncController:
Collaboration diagram for SyncController:

Public Member Functions

 SyncController (ISessionManager *sessionManager, QObject *parent=nullptr)
 
 ~SyncController () override
 
 APIController (ISessionManager *sessionManager, QObject *parent=nullptr)
 
- Public Member Functions inherited from APIController
 APIController (ISessionManager *sessionManager, QObject *parent=nullptr)
 
QVariant run (const QString &action, const StringMap &params, const DataMap &data={})
 
ISessionManagersessionManager () const
 

Private Slots

void maindataAction ()
 
void torrentPeersAction ()
 
void freeDiskSpaceSizeUpdated (qint64 freeSpaceSize)
 

Private Member Functions

qint64 getFreeDiskSpace ()
 
void invokeChecker () const
 

Private Attributes

qint64 m_freeDiskSpace = 0
 
FreeDiskSpaceCheckerm_freeDiskSpaceChecker = nullptr
 
QThread * m_freeDiskSpaceThread = nullptr
 
QElapsedTimer m_freeDiskSpaceElapsedTimer
 

Additional Inherited Members

- Protected Member Functions inherited from APIController
const StringMapparams () const
 
const DataMapdata () const
 
void requireParams (const QVector< QString > &requiredParams) const
 
void setResult (const QString &result)
 
void setResult (const QJsonArray &result)
 
void setResult (const QJsonObject &result)
 

Detailed Description

Definition at line 41 of file synccontroller.h.

Constructor & Destructor Documentation

◆ SyncController()

SyncController::SyncController ( ISessionManager sessionManager,
QObject *  parent = nullptr 
)
explicit

Definition at line 369 of file synccontroller.cpp.

370  : APIController(sessionManager, parent)
371 {
372  m_freeDiskSpaceThread = new QThread(this);
375 
376  connect(m_freeDiskSpaceThread, &QThread::finished, m_freeDiskSpaceChecker, &QObject::deleteLater);
378 
379  m_freeDiskSpaceThread->start();
380  invokeChecker();
382 }
ISessionManager * sessionManager() const
void checked(qint64 freeSpaceSize)
APIController(ISessionManager *sessionManager, QObject *parent=nullptr)
void invokeChecker() const
QThread * m_freeDiskSpaceThread
FreeDiskSpaceChecker * m_freeDiskSpaceChecker
void freeDiskSpaceSizeUpdated(qint64 freeSpaceSize)
QElapsedTimer m_freeDiskSpaceElapsedTimer

References FreeDiskSpaceChecker::checked(), freeDiskSpaceSizeUpdated(), invokeChecker(), m_freeDiskSpaceChecker, m_freeDiskSpaceElapsedTimer, and m_freeDiskSpaceThread.

Here is the call graph for this function:

◆ ~SyncController()

SyncController::~SyncController ( )
override

Definition at line 384 of file synccontroller.cpp.

385 {
386  m_freeDiskSpaceThread->quit();
387  m_freeDiskSpaceThread->wait();
388 }

References m_freeDiskSpaceThread.

Member Function Documentation

◆ APIController()

APIController::APIController
explicit

Definition at line 53 of file apicontroller.cpp.

41  : QObject {parent}
43 {
44 }
ISessionManager * m_sessionManager
Definition: apicontroller.h:69

◆ freeDiskSpaceSizeUpdated

void SyncController::freeDiskSpaceSizeUpdated ( qint64  freeSpaceSize)
privateslot

Definition at line 610 of file synccontroller.cpp.

611 {
612  m_freeDiskSpace = freeSpaceSize;
613 }
qint64 m_freeDiskSpace

References m_freeDiskSpace.

Referenced by SyncController().

Here is the caller graph for this function:

◆ getFreeDiskSpace()

qint64 SyncController::getFreeDiskSpace ( )
private

Definition at line 599 of file synccontroller.cpp.

600 {
602  {
603  invokeChecker();
604  m_freeDiskSpaceElapsedTimer.restart();
605  }
606 
607  return m_freeDiskSpace;
608 }

References anonymous_namespace{synccontroller.cpp}::FREEDISKSPACE_CHECK_TIMEOUT, invokeChecker(), m_freeDiskSpace, and m_freeDiskSpaceElapsedTimer.

Referenced by maindataAction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ invokeChecker()

void SyncController::invokeChecker ( ) const
private

Definition at line 615 of file synccontroller.cpp.

616 {
617  QMetaObject::invokeMethod(m_freeDiskSpaceChecker, &FreeDiskSpaceChecker::check, Qt::QueuedConnection);
618 }

References FreeDiskSpaceChecker::check(), and m_freeDiskSpaceChecker.

Referenced by getFreeDiskSpace(), and SyncController().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ maindataAction

void SyncController::maindataAction ( )
privateslot

Definition at line 453 of file synccontroller.cpp.

454 {
455  const auto *session = BitTorrent::Session::instance();
456 
457  QVariantMap data;
458 
459  QVariantMap lastResponse = sessionManager()->session()->getData(QLatin1String("syncMainDataLastResponse")).toMap();
460  QVariantMap lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncMainDataLastAcceptedResponse")).toMap();
461 
462  QVariantHash torrents;
463  QHash<QString, QStringList> trackers;
464  for (const BitTorrent::Torrent *torrent : asConst(session->torrents()))
465  {
466  const BitTorrent::TorrentID torrentID = torrent->id();
467 
468  QVariantMap map = serialize(*torrent);
469  map.remove(KEY_TORRENT_ID);
470 
471  // Calculated last activity time can differ from actual value by up to 10 seconds (this is a libtorrent issue).
472  // So we don't need unnecessary updates of last activity time in response.
473  const auto iterTorrents = lastResponse.find("torrents");
474  if (iterTorrents != lastResponse.end())
475  {
476  const QVariantHash lastResponseTorrents = iterTorrents->toHash();
477  const auto iterID = lastResponseTorrents.find(torrentID.toString());
478 
479  if (iterID != lastResponseTorrents.end())
480  {
481  const QVariantMap torrentData = iterID->toMap();
482  const auto iterLastActivity = torrentData.find(KEY_TORRENT_LAST_ACTIVITY_TIME);
483 
484  if (iterLastActivity != torrentData.end())
485  {
486  const int lastValue = iterLastActivity->toInt();
487  if (qAbs(lastValue - map[KEY_TORRENT_LAST_ACTIVITY_TIME].toInt()) < 15)
488  map[KEY_TORRENT_LAST_ACTIVITY_TIME] = lastValue;
489  }
490  }
491  }
492 
493  for (const BitTorrent::TrackerEntry &tracker : asConst(torrent->trackers()))
494  trackers[tracker.url] << torrentID.toString();
495 
496  torrents[torrentID.toString()] = map;
497  }
498  data["torrents"] = torrents;
499 
500  QVariantHash categories;
501  const QStringList categoriesList = session->categories();
502  for (const auto &categoryName : categoriesList)
503  {
504  const BitTorrent::CategoryOptions categoryOptions = session->categoryOptions(categoryName);
505  QJsonObject category = categoryOptions.toJSON();
506  category.insert(QLatin1String("name"), categoryName);
507  categories[categoryName] = category.toVariantMap();
508  }
509  data["categories"] = categories;
510 
511  QVariantList tags;
512  for (const QString &tag : asConst(session->tags()))
513  tags << tag;
514  data["tags"] = tags;
515 
516  QVariantHash trackersHash;
517  for (auto i = trackers.constBegin(); i != trackers.constEnd(); ++i)
518  {
519  trackersHash[i.key()] = i.value();
520  }
521  data["trackers"] = trackersHash;
522 
523  QVariantMap serverState = getTransferInfo();
525  serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled();
526  serverState[KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS] = session->isAltGlobalSpeedLimitEnabled();
527  serverState[KEY_SYNC_MAINDATA_REFRESH_INTERVAL] = session->refreshInterval();
528  data["server_state"] = serverState;
529 
530  const int acceptedResponseId {params()["rid"].toInt()};
531  setResult(QJsonObject::fromVariantMap(generateSyncData(acceptedResponseId, data, lastAcceptedResponse, lastResponse)));
532 
533  sessionManager()->session()->setData(QLatin1String("syncMainDataLastResponse"), lastResponse);
534  sessionManager()->session()->setData(QLatin1String("syncMainDataLastAcceptedResponse"), lastAcceptedResponse);
535 }
const StringMap & params() const
const DataMap & data() const
void setResult(const QString &result)
static Session * instance()
Definition: session.cpp:997
QString toString() const
Definition: digest32.h:85
qint64 getFreeDiskSpace()
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42
QVariantMap generateSyncData(int acceptedResponseId, const QVariantMap &data, QVariantMap &lastAcceptedData, QVariantMap &lastData)
QVariantMap serialize(const BitTorrent::Torrent &torrent)
const char KEY_TORRENT_LAST_ACTIVITY_TIME[]
const char KEY_TORRENT_ID[]
QJsonObject toJSON() const
Definition: trackerentry.h:38
virtual QVariant getData(const QString &id) const =0
virtual void setData(const QString &id, const QVariant &data)=0
virtual ISession * session()=0

References asConst(), APIController::data(), anonymous_namespace{synccontroller.cpp}::generateSyncData(), ISession::getData(), getFreeDiskSpace(), anonymous_namespace{synccontroller.cpp}::getTransferInfo(), BitTorrent::Session::instance(), anonymous_namespace{synccontroller.cpp}::KEY_SYNC_MAINDATA_QUEUEING, anonymous_namespace{synccontroller.cpp}::KEY_SYNC_MAINDATA_REFRESH_INTERVAL, anonymous_namespace{synccontroller.cpp}::KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS, KEY_TORRENT_ID, KEY_TORRENT_LAST_ACTIVITY_TIME, anonymous_namespace{synccontroller.cpp}::KEY_TRANSFER_FREESPACEONDISK, APIController::params(), serialize(), ISessionManager::session(), APIController::sessionManager(), ISession::setData(), APIController::setResult(), BitTorrent::CategoryOptions::toJSON(), and Digest32< N >::toString().

Here is the call graph for this function:

◆ torrentPeersAction

void SyncController::torrentPeersAction ( )
privateslot

Definition at line 540 of file synccontroller.cpp.

541 {
542  auto lastResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastResponse")).toMap();
543  auto lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastAcceptedResponse")).toMap();
544 
545  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
547  if (!torrent)
549 
550  QVariantMap data;
551  QVariantHash peers;
552 
553  const QVector<BitTorrent::PeerInfo> peersList = torrent->peers();
554 
555  bool resolvePeerCountries = Preferences::instance()->resolvePeerCountries();
556 
557  data[KEY_SYNC_TORRENT_PEERS_SHOW_FLAGS] = resolvePeerCountries;
558 
559  for (const BitTorrent::PeerInfo &pi : peersList)
560  {
561  if (pi.address().ip.isNull()) continue;
562 
563  QVariantMap peer =
564  {
565  {KEY_PEER_IP, pi.address().ip.toString()},
566  {KEY_PEER_PORT, pi.address().port},
567  {KEY_PEER_CLIENT, pi.client()},
568  {KEY_PEER_PROGRESS, pi.progress()},
569  {KEY_PEER_DOWN_SPEED, pi.payloadDownSpeed()},
570  {KEY_PEER_UP_SPEED, pi.payloadUpSpeed()},
571  {KEY_PEER_TOT_DOWN, pi.totalDownload()},
572  {KEY_PEER_TOT_UP, pi.totalUpload()},
573  {KEY_PEER_CONNECTION_TYPE, pi.connectionType()},
574  {KEY_PEER_FLAGS, pi.flags()},
575  {KEY_PEER_FLAGS_DESCRIPTION, pi.flagsDescription()},
576  {KEY_PEER_RELEVANCE, pi.relevance()}
577  };
578 
579  if (torrent->hasMetadata())
580  peer.insert(KEY_PEER_FILES, torrent->info().filesForPiece(pi.downloadingPieceIndex()).join('\n'));
581 
582  if (resolvePeerCountries)
583  {
584  peer[KEY_PEER_COUNTRY_CODE] = pi.country().toLower();
585  peer[KEY_PEER_COUNTRY] = Net::GeoIPManager::CountryName(pi.country());
586  }
587 
588  peers[pi.address().toString()] = peer;
589  }
590  data["peers"] = peers;
591 
592  const int acceptedResponseId {params()["rid"].toInt()};
593  setResult(QJsonObject::fromVariantMap(generateSyncData(acceptedResponseId, data, lastAcceptedResponse, lastResponse)));
594 
595  sessionManager()->session()->setData(QLatin1String("syncTorrentPeersLastResponse"), lastResponse);
596  sessionManager()->session()->setData(QLatin1String("syncTorrentPeersLastAcceptedResponse"), lastAcceptedResponse);
597 }
Torrent * findTorrent(const TorrentID &id) const
Definition: session.cpp:1742
virtual QVector< PeerInfo > peers() const =0
virtual TorrentInfo info() const =0
virtual bool hasMetadata() const =0
static TorrentID fromString(const QString &hashString)
Definition: infohash.cpp:76
QStringList filesForPiece(int pieceIndex) const
static QString CountryName(const QString &countryISOCode)
bool resolvePeerCountries() const
static Preferences * instance()

References Net::GeoIPManager::CountryName(), APIController::data(), BitTorrent::TorrentInfo::filesForPiece(), BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), anonymous_namespace{synccontroller.cpp}::generateSyncData(), ISession::getData(), BitTorrent::Torrent::hasMetadata(), BitTorrent::Torrent::info(), BitTorrent::Session::instance(), Preferences::instance(), anonymous_namespace{synccontroller.cpp}::KEY_PEER_CLIENT, anonymous_namespace{synccontroller.cpp}::KEY_PEER_CONNECTION_TYPE, anonymous_namespace{synccontroller.cpp}::KEY_PEER_COUNTRY, anonymous_namespace{synccontroller.cpp}::KEY_PEER_COUNTRY_CODE, anonymous_namespace{synccontroller.cpp}::KEY_PEER_DOWN_SPEED, anonymous_namespace{synccontroller.cpp}::KEY_PEER_FILES, anonymous_namespace{synccontroller.cpp}::KEY_PEER_FLAGS, anonymous_namespace{synccontroller.cpp}::KEY_PEER_FLAGS_DESCRIPTION, anonymous_namespace{synccontroller.cpp}::KEY_PEER_IP, anonymous_namespace{synccontroller.cpp}::KEY_PEER_PORT, anonymous_namespace{synccontroller.cpp}::KEY_PEER_PROGRESS, anonymous_namespace{synccontroller.cpp}::KEY_PEER_RELEVANCE, anonymous_namespace{synccontroller.cpp}::KEY_PEER_TOT_DOWN, anonymous_namespace{synccontroller.cpp}::KEY_PEER_TOT_UP, anonymous_namespace{synccontroller.cpp}::KEY_PEER_UP_SPEED, anonymous_namespace{synccontroller.cpp}::KEY_SYNC_TORRENT_PEERS_SHOW_FLAGS, NotFound, APIController::params(), BitTorrent::Torrent::peers(), Preferences::resolvePeerCountries(), ISessionManager::session(), APIController::sessionManager(), ISession::setData(), and APIController::setResult().

Here is the call graph for this function:

Member Data Documentation

◆ m_freeDiskSpace

qint64 SyncController::m_freeDiskSpace = 0
private

Definition at line 61 of file synccontroller.h.

Referenced by freeDiskSpaceSizeUpdated(), and getFreeDiskSpace().

◆ m_freeDiskSpaceChecker

FreeDiskSpaceChecker* SyncController::m_freeDiskSpaceChecker = nullptr
private

Definition at line 62 of file synccontroller.h.

Referenced by invokeChecker(), and SyncController().

◆ m_freeDiskSpaceElapsedTimer

QElapsedTimer SyncController::m_freeDiskSpaceElapsedTimer
private

Definition at line 64 of file synccontroller.h.

Referenced by getFreeDiskSpace(), and SyncController().

◆ m_freeDiskSpaceThread

QThread* SyncController::m_freeDiskSpaceThread = nullptr
private

Definition at line 63 of file synccontroller.h.

Referenced by SyncController(), and ~SyncController().


The documentation for this class was generated from the following files: