qBittorrent
TorrentsController Class Reference

#include <torrentscontroller.h>

Inheritance diagram for TorrentsController:
Collaboration diagram for TorrentsController:

Public Member Functions

 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 infoAction ()
 
void propertiesAction ()
 
void trackersAction ()
 
void webseedsAction ()
 
void filesAction ()
 
void pieceHashesAction ()
 
void pieceStatesAction ()
 
void resumeAction ()
 
void pauseAction ()
 
void recheckAction ()
 
void reannounceAction ()
 
void renameAction ()
 
void setCategoryAction ()
 
void createCategoryAction ()
 
void editCategoryAction ()
 
void removeCategoriesAction ()
 
void categoriesAction ()
 
void addTagsAction ()
 
void removeTagsAction ()
 
void createTagsAction ()
 
void deleteTagsAction ()
 
void tagsAction ()
 
void addAction ()
 
void deleteAction ()
 
void addTrackersAction ()
 
void editTrackerAction ()
 
void removeTrackersAction ()
 
void addPeersAction ()
 
void filePrioAction ()
 
void uploadLimitAction ()
 
void downloadLimitAction ()
 
void setUploadLimitAction ()
 
void setDownloadLimitAction ()
 
void setShareLimitsAction ()
 
void increasePrioAction ()
 
void decreasePrioAction ()
 
void topPrioAction ()
 
void bottomPrioAction ()
 
void setLocationAction ()
 
void setSavePathAction ()
 
void setDownloadPathAction ()
 
void setAutoManagementAction ()
 
void setSuperSeedingAction ()
 
void setForceStartAction ()
 
void toggleSequentialDownloadAction ()
 
void toggleFirstLastPiecePrioAction ()
 
void renameFileAction ()
 
void renameFolderAction ()
 

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 33 of file torrentscontroller.h.

Member Function Documentation

◆ addAction

void TorrentsController::addAction ( )
privateslot

Definition at line 635 of file torrentscontroller.cpp.

636 {
637  const QString urls = params()["urls"];
638  const QString cookie = params()["cookie"];
639 
640  const bool skipChecking = parseBool(params()["skip_checking"]).value_or(false);
641  const bool seqDownload = parseBool(params()["sequentialDownload"]).value_or(false);
642  const bool firstLastPiece = parseBool(params()["firstLastPiecePrio"]).value_or(false);
643  const std::optional<bool> addPaused = parseBool(params()["paused"]);
644  const QString savepath = params()["savepath"].trimmed();
645  const QString downloadPath = params()["downloadPath"].trimmed();
646  const std::optional<bool> useDownloadPath = parseBool(params()["useDownloadPath"]);
647  const QString category = params()["category"];
648  const QStringList tags = params()["tags"].split(',', Qt::SkipEmptyParts);
649  const QString torrentName = params()["rename"].trimmed();
650  const int upLimit = parseInt(params()["upLimit"]).value_or(-1);
651  const int dlLimit = parseInt(params()["dlLimit"]).value_or(-1);
652  const double ratioLimit = parseDouble(params()["ratioLimit"]).value_or(BitTorrent::Torrent::USE_GLOBAL_RATIO);
653  const int seedingTimeLimit = parseInt(params()["seedingTimeLimit"]).value_or(BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME);
654  const std::optional<bool> autoTMM = parseBool(params()["autoTMM"]);
655 
656  const QString contentLayoutParam = params()["contentLayout"];
657  const std::optional<BitTorrent::TorrentContentLayout> contentLayout = (!contentLayoutParam.isEmpty()
658  ? Utils::String::toEnum(contentLayoutParam, BitTorrent::TorrentContentLayout::Original)
659  : std::optional<BitTorrent::TorrentContentLayout> {});
660 
661  QList<QNetworkCookie> cookies;
662  if (!cookie.isEmpty())
663  {
664  const QStringList cookiesStr = cookie.split("; ");
665  for (QString cookieStr : cookiesStr)
666  {
667  cookieStr = cookieStr.trimmed();
668  int index = cookieStr.indexOf('=');
669  if (index > 1)
670  {
671  QByteArray name = cookieStr.left(index).toLatin1();
672  QByteArray value = cookieStr.right(cookieStr.length() - index - 1).toLatin1();
673  cookies += QNetworkCookie(name, value);
674  }
675  }
676  }
677 
678  BitTorrent::AddTorrentParams addTorrentParams;
679  // TODO: Check if destination actually exists
680  addTorrentParams.skipChecking = skipChecking;
681  addTorrentParams.sequential = seqDownload;
682  addTorrentParams.firstLastPiecePriority = firstLastPiece;
683  addTorrentParams.addPaused = addPaused;
684  addTorrentParams.contentLayout = contentLayout;
685  addTorrentParams.savePath = savepath;
686  addTorrentParams.downloadPath = downloadPath;
687  addTorrentParams.useDownloadPath = useDownloadPath;
688  addTorrentParams.category = category;
689  addTorrentParams.tags.insert(tags.cbegin(), tags.cend());
690  addTorrentParams.name = torrentName;
691  addTorrentParams.uploadLimit = upLimit;
692  addTorrentParams.downloadLimit = dlLimit;
693  addTorrentParams.seedingTimeLimit = seedingTimeLimit;
694  addTorrentParams.ratioLimit = ratioLimit;
695  addTorrentParams.useAutoTMM = autoTMM;
696 
697  bool partialSuccess = false;
698  for (QString url : asConst(urls.split('\n')))
699  {
700  url = url.trimmed();
701  if (!url.isEmpty())
702  {
703  Net::DownloadManager::instance()->setCookiesFromUrl(cookies, QUrl::fromEncoded(url.toUtf8()));
704  partialSuccess |= BitTorrent::Session::instance()->addTorrent(url, addTorrentParams);
705  }
706  }
707 
708  for (auto it = data().constBegin(); it != data().constEnd(); ++it)
709  {
710  const nonstd::expected<BitTorrent::TorrentInfo, QString> result = BitTorrent::TorrentInfo::load(it.value());
711  if (!result)
712  {
714  , tr("Error: '%1' is not a valid torrent file.").arg(it.key()));
715  }
716 
717  partialSuccess |= BitTorrent::Session::instance()->addTorrent(result.value(), addTorrentParams);
718  }
719 
720  if (partialSuccess)
721  setResult(QLatin1String("Ok."));
722  else
723  setResult(QLatin1String("Fails."));
724 }
const StringMap & params() const
static Session * instance()
Definition: session.cpp:997
bool addTorrent(const QString &source, const AddTorrentParams &params=AddTorrentParams())
Definition: session.cpp:2007
static const int USE_GLOBAL_SEEDING_TIME
Definition: torrent.h:107
static const qreal USE_GLOBAL_RATIO
Definition: torrent.h:104
static nonstd::expected< TorrentInfo, QString > load(const QByteArray &data) noexcept
Definition: torrentinfo.cpp:89
bool setCookiesFromUrl(const QList< QNetworkCookie > &cookieList, const QUrl &url)
static DownloadManager * instance()
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42
std::optional< bool > parseBool(const QString &string)
Definition: string.cpp:72
std::optional< int > parseInt(const QString &string)
Definition: string.cpp:82
T toEnum(const QString &serializedValue, const T &defaultValue)
Definition: string.h:77
std::optional< double > parseDouble(const QString &string)
Definition: string.cpp:92
T value(const QString &key, const T &defaultValue={})
Definition: preferences.cpp:64
std::optional< bool > useDownloadPath
std::optional< bool > useAutoTMM
std::optional< bool > addPaused
std::optional< BitTorrent::TorrentContentLayout > contentLayout

References BitTorrent::AddTorrentParams::addPaused, BitTorrent::Session::addTorrent(), asConst(), BadData, BitTorrent::AddTorrentParams::category, BitTorrent::AddTorrentParams::contentLayout, APIController::data(), BitTorrent::AddTorrentParams::downloadLimit, BitTorrent::AddTorrentParams::downloadPath, BitTorrent::AddTorrentParams::firstLastPiecePriority, BitTorrent::Session::instance(), Net::DownloadManager::instance(), BitTorrent::TorrentInfo::load(), BitTorrent::AddTorrentParams::name, APIController::params(), Utils::String::parseBool(), Utils::String::parseDouble(), Utils::String::parseInt(), BitTorrent::AddTorrentParams::ratioLimit, BitTorrent::AddTorrentParams::savePath, BitTorrent::AddTorrentParams::seedingTimeLimit, BitTorrent::AddTorrentParams::sequential, Net::DownloadManager::setCookiesFromUrl(), APIController::setResult(), BitTorrent::AddTorrentParams::skipChecking, BitTorrent::AddTorrentParams::tags, Utils::String::toEnum(), BitTorrent::AddTorrentParams::uploadLimit, BitTorrent::Torrent::USE_GLOBAL_RATIO, BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME, BitTorrent::AddTorrentParams::useAutoTMM, BitTorrent::AddTorrentParams::useDownloadPath, and anonymous_namespace{preferences.cpp}::value().

Here is the call graph for this function:

◆ addPeersAction

void TorrentsController::addPeersAction ( )
privateslot

Definition at line 815 of file torrentscontroller.cpp.

816 {
817  requireParams({"hashes", "peers"});
818 
819  const QStringList hashes = params()["hashes"].split('|');
820  const QStringList peers = params()["peers"].split('|');
821 
822  QVector<BitTorrent::PeerAddress> peerList;
823  peerList.reserve(peers.size());
824  for (const QString &peer : peers)
825  {
826  const BitTorrent::PeerAddress addr = BitTorrent::PeerAddress::parse(peer.trimmed());
827  if (!addr.ip.isNull())
828  peerList.append(addr);
829  }
830 
831  if (peerList.isEmpty())
832  throw APIError(APIErrorType::BadParams, "No valid peers were specified");
833 
834  QJsonObject results;
835 
836  applyToTorrents(hashes, [peers, peerList, &results](BitTorrent::Torrent *const torrent)
837  {
838  const int peersAdded = std::count_if(peerList.cbegin(), peerList.cend(), [torrent](const BitTorrent::PeerAddress &peer)
839  {
840  return torrent->connectPeer(peer);
841  });
842 
843  results[torrent->id().toString()] = QJsonObject
844  {
845  {"added", peersAdded},
846  {"failed", (peers.size() - peersAdded)}
847  };
848  });
849 
850  setResult(results);
851 }
void requireParams(const QVector< QString > &requiredParams) const
void setResult(const QString &result)
TorrentID id() const
Definition: torrent.cpp:54
QString toString() const
Definition: digest32.h:85
void applyToTorrents(const QStringList &idList, const std::function< void(BitTorrent::Torrent *torrent)> &func)
static PeerAddress parse(QStringView address)
Definition: peeraddress.cpp:35

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), BadParams, BitTorrent::Torrent::id(), BitTorrent::PeerAddress::ip, APIController::params(), BitTorrent::PeerAddress::parse(), APIController::requireParams(), APIController::setResult(), and Digest32< N >::toString().

Here is the call graph for this function:

◆ addTagsAction

void TorrentsController::addTagsAction ( )
privateslot

Definition at line 1290 of file torrentscontroller.cpp.

1291 {
1292  requireParams({"hashes", "tags"});
1293 
1294  const QStringList hashes {params()["hashes"].split('|')};
1295  const QStringList tags {params()["tags"].split(',', Qt::SkipEmptyParts)};
1296 
1297  for (const QString &tag : tags)
1298  {
1299  const QString tagTrimmed {tag.trimmed()};
1300  applyToTorrents(hashes, [&tagTrimmed](BitTorrent::Torrent *const torrent)
1301  {
1302  torrent->addTag(tagTrimmed);
1303  });
1304  }
1305 }
virtual bool addTag(const QString &tag)=0

References BitTorrent::Torrent::addTag(), anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), and APIController::requireParams().

Here is the call graph for this function:

◆ addTrackersAction

void TorrentsController::addTrackersAction ( )
privateslot

Definition at line 726 of file torrentscontroller.cpp.

727 {
728  requireParams({"hash", "urls"});
729 
730  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
732  if (!torrent)
734 
735  QVector<BitTorrent::TrackerEntry> trackers;
736  for (const QString &urlStr : asConst(params()["urls"].split('\n')))
737  {
738  const QUrl url {urlStr.trimmed()};
739  if (url.isValid())
740  trackers.append({url.toString()});
741  }
742  torrent->addTrackers(trackers);
743 }
Torrent * findTorrent(const TorrentID &id) const
Definition: session.cpp:1742
virtual void addTrackers(const QVector< TrackerEntry > &trackers)=0
static TorrentID fromString(const QString &hashString)
Definition: infohash.cpp:76

References BitTorrent::Torrent::addTrackers(), asConst(), BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), NotFound, APIController::params(), and APIController::requireParams().

Here is the call graph for this function:

◆ APIController()

APIController::APIController
explicit

Definition at line 53 of file apicontroller.cpp.

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

◆ bottomPrioAction

void TorrentsController::bottomPrioAction ( )
privateslot

Definition at line 1068 of file torrentscontroller.cpp.

1069 {
1070  requireParams({"hashes"});
1071 
1072  if (!BitTorrent::Session::instance()->isQueueingSystemEnabled())
1073  throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
1074 
1075  const QStringList hashes {params()["hashes"].split('|')};
1077 }
void bottomTorrentsQueuePos(const QVector< TorrentID > &ids)
Definition: session.cpp:1942
QVector< BitTorrent::TorrentID > toTorrentIDs(const QStringList &idStrings)

References BitTorrent::Session::bottomTorrentsQueuePos(), Conflict, BitTorrent::Session::instance(), APIController::params(), APIController::requireParams(), and anonymous_namespace{torrentscontroller.cpp}::toTorrentIDs().

Here is the call graph for this function:

◆ categoriesAction

void TorrentsController::categoriesAction ( )
privateslot

Definition at line 1273 of file torrentscontroller.cpp.

1274 {
1275  const auto session = BitTorrent::Session::instance();
1276 
1277  QJsonObject categories;
1278  const QStringList categoriesList = session->categories();
1279  for (const auto &categoryName : categoriesList)
1280  {
1281  const BitTorrent::CategoryOptions categoryOptions = session->categoryOptions(categoryName);
1282  QJsonObject category = categoryOptions.toJSON();
1283  category.insert(QLatin1String("name"), categoryName);
1284  categories[categoryName] = category;
1285  }
1286 
1287  setResult(categories);
1288 }
QJsonObject toJSON() const

References BitTorrent::Session::instance(), APIController::setResult(), and BitTorrent::CategoryOptions::toJSON().

Here is the call graph for this function:

◆ createCategoryAction

void TorrentsController::createCategoryAction ( )
privateslot

Definition at line 1217 of file torrentscontroller.cpp.

1218 {
1219  requireParams({"category"});
1220 
1221  const QString category = params()["category"];
1222  if (category.isEmpty())
1223  throw APIError(APIErrorType::BadParams, tr("Category cannot be empty"));
1224 
1226  throw APIError(APIErrorType::Conflict, tr("Incorrect category name"));
1227 
1228  const QString savePath = params()["savePath"];
1229  const auto useDownloadPath = parseBool(params()["downloadPathEnabled"]);
1230  BitTorrent::CategoryOptions categoryOptions;
1231  categoryOptions.savePath = savePath;
1232  if (useDownloadPath.has_value())
1233  {
1234  const QString downloadPath = params()["downloadPath"];
1235  categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath};
1236  }
1237 
1238  if (!BitTorrent::Session::instance()->addCategory(category, categoryOptions))
1239  throw APIError(APIErrorType::Conflict, tr("Unable to create category"));
1240 }
static bool isValidCategoryName(const QString &name)
Definition: session.cpp:630
std::optional< DownloadPathOption > downloadPath

References BadParams, Conflict, BitTorrent::CategoryOptions::downloadPath, BitTorrent::Session::instance(), BitTorrent::Session::isValidCategoryName(), APIController::params(), Utils::String::parseBool(), APIController::requireParams(), and BitTorrent::CategoryOptions::savePath.

Here is the call graph for this function:

◆ createTagsAction

void TorrentsController::createTagsAction ( )
privateslot

Definition at line 1332 of file torrentscontroller.cpp.

1333 {
1334  requireParams({"tags"});
1335 
1336  const QStringList tags {params()["tags"].split(',', Qt::SkipEmptyParts)};
1337 
1338  for (const QString &tag : tags)
1339  BitTorrent::Session::instance()->addTag(tag.trimmed());
1340 }
bool addTag(const QString &tag)
Definition: session.cpp:839

References BitTorrent::Session::addTag(), BitTorrent::Session::instance(), APIController::params(), and APIController::requireParams().

Here is the call graph for this function:

◆ decreasePrioAction

void TorrentsController::decreasePrioAction ( )
privateslot

Definition at line 1046 of file torrentscontroller.cpp.

1047 {
1048  requireParams({"hashes"});
1049 
1050  if (!BitTorrent::Session::instance()->isQueueingSystemEnabled())
1051  throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
1052 
1053  const QStringList hashes {params()["hashes"].split('|')};
1055 }
void decreaseTorrentsQueuePos(const QVector< TorrentID > &ids)
Definition: session.cpp:1889

References Conflict, BitTorrent::Session::decreaseTorrentsQueuePos(), BitTorrent::Session::instance(), APIController::params(), APIController::requireParams(), and anonymous_namespace{torrentscontroller.cpp}::toTorrentIDs().

Here is the call graph for this function:

◆ deleteAction

void TorrentsController::deleteAction ( )
privateslot

Definition at line 1022 of file torrentscontroller.cpp.

1023 {
1024  requireParams({"hashes", "deleteFiles"});
1025 
1026  const QStringList hashes {params()["hashes"].split('|')};
1027  const DeleteOption deleteOption = parseBool(params()["deleteFiles"]).value_or(false)
1029  applyToTorrents(hashes, [deleteOption](const BitTorrent::Torrent *torrent)
1030  {
1031  BitTorrent::Session::instance()->deleteTorrent(torrent->id(), deleteOption);
1032  });
1033 }
bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption=DeleteTorrent)
Definition: session.cpp:1792
DeleteOption
Definition: session.h:80
@ DeleteTorrent
Definition: session.h:81
@ DeleteTorrentAndFiles
Definition: session.h:82

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), DeleteTorrent, BitTorrent::Session::deleteTorrent(), DeleteTorrentAndFiles, BitTorrent::Torrent::id(), BitTorrent::Session::instance(), APIController::params(), Utils::String::parseBool(), and APIController::requireParams().

Here is the call graph for this function:

◆ deleteTagsAction

void TorrentsController::deleteTagsAction ( )
privateslot

Definition at line 1342 of file torrentscontroller.cpp.

1343 {
1344  requireParams({"tags"});
1345 
1346  const QStringList tags {params()["tags"].split(',', Qt::SkipEmptyParts)};
1347  for (const QString &tag : tags)
1348  BitTorrent::Session::instance()->removeTag(tag.trimmed());
1349 }
bool removeTag(const QString &tag)
Definition: session.cpp:850

References BitTorrent::Session::instance(), APIController::params(), BitTorrent::Session::removeTag(), and APIController::requireParams().

Here is the call graph for this function:

◆ downloadLimitAction

void TorrentsController::downloadLimitAction ( )
privateslot

Definition at line 928 of file torrentscontroller.cpp.

929 {
930  requireParams({"hashes"});
931 
932  const QStringList idList {params()["hashes"].split('|')};
933  QJsonObject map;
934  for (const QString &id : idList)
935  {
936  int limit = -1;
938  if (torrent)
939  limit = torrent->downloadLimit();
940  map[id] = limit;
941  }
942 
943  setResult(map);
944 }
virtual int downloadLimit() const =0

References BitTorrent::Torrent::downloadLimit(), BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), APIController::params(), APIController::requireParams(), and APIController::setResult().

Here is the call graph for this function:

◆ editCategoryAction

void TorrentsController::editCategoryAction ( )
privateslot

Definition at line 1242 of file torrentscontroller.cpp.

1243 {
1244  requireParams({"category", "savePath"});
1245 
1246  const QString category = params()["category"];
1247  if (category.isEmpty())
1248  throw APIError(APIErrorType::BadParams, tr("Category cannot be empty"));
1249 
1250  const QString savePath = params()["savePath"];
1251  const auto useDownloadPath = parseBool(params()["downloadPathEnabled"]);
1252  BitTorrent::CategoryOptions categoryOptions;
1253  categoryOptions.savePath = savePath;
1254  if (useDownloadPath.has_value())
1255  {
1256  const QString downloadPath = params()["downloadPath"];
1257  categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath};
1258  }
1259 
1260  if (!BitTorrent::Session::instance()->editCategory(category, categoryOptions))
1261  throw APIError(APIErrorType::Conflict, tr("Unable to edit category"));
1262 }

References BadParams, Conflict, BitTorrent::CategoryOptions::downloadPath, BitTorrent::Session::instance(), APIController::params(), Utils::String::parseBool(), APIController::requireParams(), and BitTorrent::CategoryOptions::savePath.

Here is the call graph for this function:

◆ editTrackerAction

void TorrentsController::editTrackerAction ( )
privateslot

Definition at line 745 of file torrentscontroller.cpp.

746 {
747  requireParams({"hash", "origUrl", "newUrl"});
748 
749  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
750  const QString origUrl = params()["origUrl"];
751  const QString newUrl = params()["newUrl"];
752 
754  if (!torrent)
756 
757  const QUrl origTrackerUrl(origUrl);
758  const QUrl newTrackerUrl(newUrl);
759  if (origTrackerUrl == newTrackerUrl)
760  return;
761  if (!newTrackerUrl.isValid())
762  throw APIError(APIErrorType::BadParams, "New tracker URL is invalid");
763 
764  QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
765  bool match = false;
766  for (BitTorrent::TrackerEntry &tracker : trackers)
767  {
768  const QUrl trackerUrl(tracker.url);
769  if (trackerUrl == newTrackerUrl)
770  throw APIError(APIErrorType::Conflict, "New tracker URL already exists");
771  if (trackerUrl == origTrackerUrl)
772  {
773  match = true;
774  tracker.url = newTrackerUrl.toString();
775  }
776  }
777  if (!match)
778  throw APIError(APIErrorType::Conflict, "Tracker not found");
779 
780  torrent->replaceTrackers(trackers);
781 
782  if (!torrent->isPaused())
783  torrent->forceReannounce();
784 }
virtual void forceReannounce(int index=-1)=0
virtual bool isPaused() const =0
virtual QVector< TrackerEntry > trackers() const =0
virtual void replaceTrackers(const QVector< TrackerEntry > &trackers)=0
Definition: trackerentry.h:38

References BadParams, Conflict, BitTorrent::Session::findTorrent(), BitTorrent::Torrent::forceReannounce(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), BitTorrent::Torrent::isPaused(), NotFound, APIController::params(), BitTorrent::Torrent::replaceTrackers(), APIController::requireParams(), and BitTorrent::Torrent::trackers().

Here is the call graph for this function:

◆ filePrioAction

void TorrentsController::filePrioAction ( )
privateslot

Definition at line 869 of file torrentscontroller.cpp.

870 {
871  requireParams({"hash", "id", "priority"});
872 
873  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
874  bool ok = false;
875  const auto priority = static_cast<BitTorrent::DownloadPriority>(params()["priority"].toInt(&ok));
876  if (!ok)
877  throw APIError(APIErrorType::BadParams, tr("Priority must be an integer"));
878 
880  throw APIError(APIErrorType::BadParams, tr("Priority is not valid"));
881 
883  if (!torrent)
885  if (!torrent->hasMetadata())
886  throw APIError(APIErrorType::Conflict, tr("Torrent's metadata has not yet downloaded"));
887 
888  const int filesCount = torrent->filesCount();
889  QVector<BitTorrent::DownloadPriority> priorities = torrent->filePriorities();
890  bool priorityChanged = false;
891  for (const QString &fileID : params()["id"].split('|'))
892  {
893  const int id = fileID.toInt(&ok);
894  if (!ok)
895  throw APIError(APIErrorType::BadParams, tr("File IDs must be integers"));
896  if ((id < 0) || (id >= filesCount))
897  throw APIError(APIErrorType::Conflict, tr("File ID is not valid"));
898 
899  if (priorities[id] != priority)
900  {
901  priorities[id] = priority;
902  priorityChanged = true;
903  }
904  }
905 
906  if (priorityChanged)
907  torrent->prioritizeFiles(priorities);
908 }
virtual int filesCount() const =0
virtual QVector< DownloadPriority > filePriorities() const =0
virtual void prioritizeFiles(const QVector< DownloadPriority > &priorities)=0
virtual bool hasMetadata() const =0
bool isValidDownloadPriority(const DownloadPriority priority)

References BadParams, Conflict, BitTorrent::Torrent::filePriorities(), BitTorrent::AbstractFileStorage::filesCount(), BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Torrent::hasMetadata(), BitTorrent::Session::instance(), BitTorrent::isValidDownloadPriority(), NotFound, APIController::params(), BitTorrent::Torrent::prioritizeFiles(), and APIController::requireParams().

Here is the call graph for this function:

◆ filesAction

void TorrentsController::filesAction ( )
privateslot

Definition at line 517 of file torrentscontroller.cpp.

518 {
519  requireParams({"hash"});
520 
521  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
522  const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
523  if (!torrent)
525 
526  const int filesCount = torrent->filesCount();
527  QVector<int> fileIndexes;
528  const auto idxIt = params().constFind(QLatin1String("indexes"));
529  if (idxIt != params().cend())
530  {
531  const QStringList indexStrings = idxIt.value().split('|');
532  fileIndexes.reserve(indexStrings.size());
533  std::transform(indexStrings.cbegin(), indexStrings.cend(), std::back_inserter(fileIndexes)
534  , [&filesCount](const QString &indexString) -> int
535  {
536  bool ok = false;
537  const int index = indexString.toInt(&ok);
538  if (!ok || (index < 0))
539  throw APIError(APIErrorType::Conflict, tr("\"%1\" is not a valid file index.").arg(indexString));
540  if (index >= filesCount)
541  throw APIError(APIErrorType::Conflict, tr("Index %1 is out of bounds.").arg(indexString));
542  return index;
543  });
544  }
545  else
546  {
547  fileIndexes.reserve(filesCount);
548  for (int i = 0; i < filesCount; ++i)
549  fileIndexes.append(i);
550  }
551 
552  QJsonArray fileList;
553  if (torrent->hasMetadata())
554  {
555  const QVector<BitTorrent::DownloadPriority> priorities = torrent->filePriorities();
556  const QVector<qreal> fp = torrent->filesProgress();
557  const QVector<qreal> fileAvailability = torrent->availableFileFractions();
558  const BitTorrent::TorrentInfo info = torrent->info();
559  for (const int index : asConst(fileIndexes))
560  {
561  QJsonObject fileDict =
562  {
563  {KEY_FILE_INDEX, index},
564  {KEY_FILE_PROGRESS, fp[index]},
565  {KEY_FILE_PRIORITY, static_cast<int>(priorities[index])},
566  {KEY_FILE_SIZE, torrent->fileSize(index)},
567  {KEY_FILE_AVAILABILITY, fileAvailability[index]},
569  };
570 
571  const BitTorrent::TorrentInfo::PieceRange idx = info.filePieces(index);
572  fileDict[KEY_FILE_PIECE_RANGE] = QJsonArray {idx.first(), idx.last()};
573 
574  if (index == 0)
575  fileDict[KEY_FILE_IS_SEED] = torrent->isSeed();
576 
577  fileList.append(fileDict);
578  }
579  }
580 
581  setResult(fileList);
582 }
virtual qlonglong fileSize(int index) const =0
virtual QString filePath(int index) const =0
virtual QVector< qreal > filesProgress() const =0
virtual QVector< qreal > availableFileFractions() const =0
fraction of file pieces that are available at least from one peer
virtual TorrentInfo info() const =0
virtual bool isSeed() const =0
PieceRange filePieces(const QString &file) const
constexpr IndexType last() const
Definition: indexrange.h:156
constexpr IndexType first() const
Definition: indexrange.h:151
QString toUniformPath(const QString &path)
Definition: fs.cpp:69
const char KEY_FILE_NAME[]
const char KEY_FILE_SIZE[]
const char KEY_FILE_IS_SEED[]
const char KEY_FILE_INDEX[]
const char KEY_FILE_PIECE_RANGE[]
const char KEY_FILE_PRIORITY[]
const char KEY_FILE_AVAILABILITY[]
const char KEY_FILE_PROGRESS[]

References asConst(), BitTorrent::Torrent::availableFileFractions(), BitTorrent::AbstractFileStorage::filePath(), BitTorrent::TorrentInfo::filePieces(), BitTorrent::Torrent::filePriorities(), BitTorrent::AbstractFileStorage::filesCount(), BitTorrent::AbstractFileStorage::fileSize(), BitTorrent::Torrent::filesProgress(), BitTorrent::Session::findTorrent(), IndexRange< Index, IndexDiff >::first(), BitTorrent::TorrentID::fromString(), BitTorrent::Torrent::hasMetadata(), BitTorrent::Torrent::info(), BitTorrent::Session::instance(), BitTorrent::Torrent::isSeed(), KEY_FILE_AVAILABILITY, KEY_FILE_INDEX, KEY_FILE_IS_SEED, KEY_FILE_NAME, KEY_FILE_PIECE_RANGE, KEY_FILE_PRIORITY, KEY_FILE_PROGRESS, KEY_FILE_SIZE, IndexRange< Index, IndexDiff >::last(), NotFound, APIController::params(), APIController::requireParams(), APIController::setResult(), and Utils::Fs::toUniformPath().

Here is the call graph for this function:

◆ increasePrioAction

void TorrentsController::increasePrioAction ( )
privateslot

Definition at line 1035 of file torrentscontroller.cpp.

1036 {
1037  requireParams({"hashes"});
1038 
1039  if (!BitTorrent::Session::instance()->isQueueingSystemEnabled())
1040  throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
1041 
1042  const QStringList hashes {params()["hashes"].split('|')};
1044 }
void increaseTorrentsQueuePos(const QVector< TorrentID > &ids)
Definition: session.cpp:1862

References Conflict, BitTorrent::Session::increaseTorrentsQueuePos(), BitTorrent::Session::instance(), APIController::params(), APIController::requireParams(), and anonymous_namespace{torrentscontroller.cpp}::toTorrentIDs().

Here is the call graph for this function:

◆ infoAction

void TorrentsController::infoAction ( )
privateslot

Definition at line 256 of file torrentscontroller.cpp.

257 {
258  const QString filter {params()["filter"]};
259  const QString category {params()["category"]};
260  const QString tag {params()["tag"]};
261  const QString sortedColumn {params()["sort"]};
262  const bool reverse {parseBool(params()["reverse"]).value_or(false)};
263  int limit {params()["limit"].toInt()};
264  int offset {params()["offset"].toInt()};
265  const QStringList hashes {params()["hashes"].split('|', Qt::SkipEmptyParts)};
266 
267  TorrentIDSet idSet;
268  for (const QString &hash : hashes)
269  idSet.insert(BitTorrent::TorrentID::fromString(hash));
270 
271  const TorrentFilter torrentFilter(filter, (hashes.isEmpty() ? TorrentFilter::AnyID : idSet), category, tag);
272  QVariantList torrentList;
273  for (const BitTorrent::Torrent *torrent : asConst(BitTorrent::Session::instance()->torrents()))
274  {
275  if (torrentFilter.match(torrent))
276  torrentList.append(serialize(*torrent));
277  }
278 
279  if (torrentList.isEmpty())
280  {
281  setResult(QJsonArray {});
282  return;
283  }
284 
285  if (!sortedColumn.isEmpty())
286  {
287  if (!torrentList[0].toMap().contains(sortedColumn))
288  throw APIError(APIErrorType::BadParams, tr("'sort' parameter is invalid"));
289 
290  const auto lessThan = [](const QVariant &left, const QVariant &right) -> bool
291  {
292  Q_ASSERT(left.type() == right.type());
293 
294  switch (static_cast<QMetaType::Type>(left.type()))
295  {
296  case QMetaType::Bool:
297  return left.value<bool>() < right.value<bool>();
298  case QMetaType::Double:
299  return left.value<double>() < right.value<double>();
300  case QMetaType::Float:
301  return left.value<float>() < right.value<float>();
302  case QMetaType::Int:
303  return left.value<int>() < right.value<int>();
304  case QMetaType::LongLong:
305  return left.value<qlonglong>() < right.value<qlonglong>();
306  case QMetaType::QString:
307  return left.value<QString>() < right.value<QString>();
308  default:
309  qWarning("Unhandled QVariant comparison, type: %d, name: %s", left.type()
310  , QMetaType::typeName(left.type()));
311  break;
312  }
313  return false;
314  };
315 
316  std::sort(torrentList.begin(), torrentList.end()
317  , [reverse, &sortedColumn, &lessThan](const QVariant &torrent1, const QVariant &torrent2)
318  {
319  const QVariant value1 {torrent1.toMap().value(sortedColumn)};
320  const QVariant value2 {torrent2.toMap().value(sortedColumn)};
321  return reverse ? lessThan(value2, value1) : lessThan(value1, value2);
322  });
323  }
324 
325  const int size = torrentList.size();
326  // normalize offset
327  if (offset < 0)
328  offset = size + offset;
329  if ((offset >= size) || (offset < 0))
330  offset = 0;
331  // normalize limit
332  if (limit <= 0)
333  limit = -1; // unlimited
334 
335  if ((limit > 0) || (offset > 0))
336  torrentList = torrentList.mid(offset, limit);
337 
338  setResult(QJsonArray::fromVariantList(torrentList));
339 }
static const TorrentIDSet AnyID
Definition: torrentfilter.h:65
QVariantMap serialize(const BitTorrent::Torrent &torrent)
QSet< BitTorrent::TorrentID > TorrentIDSet
Definition: torrentfilter.h:41

References TorrentFilter::AnyID, asConst(), BadParams, BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), TorrentFilter::match(), APIController::params(), Utils::String::parseBool(), serialize(), and APIController::setResult().

Here is the call graph for this function:

◆ pauseAction

void TorrentsController::pauseAction ( )
privateslot

Definition at line 853 of file torrentscontroller.cpp.

854 {
855  requireParams({"hashes"});
856 
857  const QStringList hashes = params()["hashes"].split('|');
858  applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->pause(); });
859 }
virtual void pause()=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), BitTorrent::Torrent::pause(), and APIController::requireParams().

Here is the call graph for this function:

◆ pieceHashesAction

void TorrentsController::pieceHashesAction ( )
privateslot

Definition at line 586 of file torrentscontroller.cpp.

587 {
588  requireParams({"hash"});
589 
590  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
592  if (!torrent)
594 
595  QJsonArray pieceHashes;
596  if (torrent->hasMetadata())
597  {
598  const QVector<QByteArray> hashes = torrent->info().pieceHashes();
599  for (const QByteArray &hash : hashes)
600  pieceHashes.append(QString(hash.toHex()));
601  }
602 
603  setResult(pieceHashes);
604 }
QVector< QByteArray > pieceHashes() const

References BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Torrent::hasMetadata(), BitTorrent::Torrent::info(), BitTorrent::Session::instance(), NotFound, APIController::params(), BitTorrent::TorrentInfo::pieceHashes(), APIController::requireParams(), and APIController::setResult().

Here is the call graph for this function:

◆ pieceStatesAction

void TorrentsController::pieceStatesAction ( )
privateslot

Definition at line 611 of file torrentscontroller.cpp.

612 {
613  requireParams({"hash"});
614 
615  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
617  if (!torrent)
619 
620  QJsonArray pieceStates;
621  const QBitArray states = torrent->pieces();
622  for (int i = 0; i < states.size(); ++i)
623  pieceStates.append(static_cast<int>(states[i]) * 2);
624 
625  const QBitArray dlstates = torrent->downloadingPieces();
626  for (int i = 0; i < states.size(); ++i)
627  {
628  if (dlstates[i])
629  pieceStates[i] = 1;
630  }
631 
632  setResult(pieceStates);
633 }
virtual QBitArray downloadingPieces() const =0
virtual QBitArray pieces() const =0

References BitTorrent::Torrent::downloadingPieces(), BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), NotFound, APIController::params(), BitTorrent::Torrent::pieces(), APIController::requireParams(), and APIController::setResult().

Here is the call graph for this function:

◆ propertiesAction

void TorrentsController::propertiesAction ( )
privateslot

Definition at line 378 of file torrentscontroller.cpp.

379 {
380  requireParams({"hash"});
381 
382  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
384  if (!torrent)
386 
387  QJsonObject dataDict;
388 
389  dataDict[KEY_TORRENT_INFOHASHV1] = torrent->infoHash().v1().toString();
390  dataDict[KEY_TORRENT_INFOHASHV2] = torrent->infoHash().v2().toString();
391  dataDict[KEY_PROP_TIME_ELAPSED] = torrent->activeTime();
392  dataDict[KEY_PROP_SEEDING_TIME] = torrent->finishedTime();
393  dataDict[KEY_PROP_ETA] = static_cast<double>(torrent->eta());
394  dataDict[KEY_PROP_CONNECT_COUNT] = torrent->connectionsCount();
395  dataDict[KEY_PROP_CONNECT_COUNT_LIMIT] = torrent->connectionsLimit();
396  dataDict[KEY_PROP_DOWNLOADED] = torrent->totalDownload();
397  dataDict[KEY_PROP_DOWNLOADED_SESSION] = torrent->totalPayloadDownload();
398  dataDict[KEY_PROP_UPLOADED] = torrent->totalUpload();
399  dataDict[KEY_PROP_UPLOADED_SESSION] = torrent->totalPayloadUpload();
400  dataDict[KEY_PROP_DL_SPEED] = torrent->downloadPayloadRate();
401  const qlonglong dlDuration = torrent->activeTime() - torrent->finishedTime();
402  dataDict[KEY_PROP_DL_SPEED_AVG] = torrent->totalDownload() / ((dlDuration == 0) ? -1 : dlDuration);
403  dataDict[KEY_PROP_UP_SPEED] = torrent->uploadPayloadRate();
404  const qlonglong ulDuration = torrent->activeTime();
405  dataDict[KEY_PROP_UP_SPEED_AVG] = torrent->totalUpload() / ((ulDuration == 0) ? -1 : ulDuration);
406  dataDict[KEY_PROP_DL_LIMIT] = torrent->downloadLimit() <= 0 ? -1 : torrent->downloadLimit();
407  dataDict[KEY_PROP_UP_LIMIT] = torrent->uploadLimit() <= 0 ? -1 : torrent->uploadLimit();
408  dataDict[KEY_PROP_WASTED] = torrent->wastedSize();
409  dataDict[KEY_PROP_SEEDS] = torrent->seedsCount();
410  dataDict[KEY_PROP_SEEDS_TOTAL] = torrent->totalSeedsCount();
411  dataDict[KEY_PROP_PEERS] = torrent->leechsCount();
412  dataDict[KEY_PROP_PEERS_TOTAL] = torrent->totalLeechersCount();
413  const qreal ratio = torrent->realRatio();
414  dataDict[KEY_PROP_RATIO] = ratio > BitTorrent::Torrent::MAX_RATIO ? -1 : ratio;
415  dataDict[KEY_PROP_REANNOUNCE] = torrent->nextAnnounce();
416  dataDict[KEY_PROP_TOTAL_SIZE] = torrent->totalSize();
417  dataDict[KEY_PROP_PIECES_NUM] = torrent->piecesCount();
418  dataDict[KEY_PROP_PIECE_SIZE] = torrent->pieceLength();
419  dataDict[KEY_PROP_PIECES_HAVE] = torrent->piecesHave();
420  dataDict[KEY_PROP_CREATED_BY] = torrent->creator();
421  dataDict[KEY_PROP_ADDITION_DATE] = static_cast<double>(torrent->addedTime().toSecsSinceEpoch());
422  if (torrent->hasMetadata())
423  {
424  dataDict[KEY_PROP_LAST_SEEN] = torrent->lastSeenComplete().isValid() ? torrent->lastSeenComplete().toSecsSinceEpoch() : -1;
425  dataDict[KEY_PROP_COMPLETION_DATE] = torrent->completedTime().isValid() ? torrent->completedTime().toSecsSinceEpoch() : -1;
426  dataDict[KEY_PROP_CREATION_DATE] = static_cast<double>(torrent->creationDate().toSecsSinceEpoch());
427  }
428  else
429  {
430  dataDict[KEY_PROP_LAST_SEEN] = -1;
431  dataDict[KEY_PROP_COMPLETION_DATE] = -1;
432  dataDict[KEY_PROP_CREATION_DATE] = -1;
433  }
434  dataDict[KEY_PROP_SAVE_PATH] = Utils::Fs::toNativePath(torrent->savePath());
436  dataDict[KEY_PROP_COMMENT] = torrent->comment();
437 
438  setResult(dataDict);
439 }
SHA1Hash v1() const
Definition: infohash.cpp:44
SHA256Hash v2() const
Definition: infohash.cpp:53
virtual qlonglong totalSize() const =0
virtual int uploadPayloadRate() const =0
virtual int seedsCount() const =0
virtual qlonglong nextAnnounce() const =0
virtual qlonglong totalUpload() const =0
virtual int piecesHave() const =0
virtual QDateTime creationDate() const =0
virtual QString comment() const =0
virtual qlonglong pieceLength() const =0
virtual qlonglong activeTime() const =0
virtual qlonglong totalPayloadDownload() const =0
virtual InfoHash infoHash() const =0
virtual qlonglong finishedTime() const =0
virtual int piecesCount() const =0
virtual int uploadLimit() const =0
virtual int connectionsLimit() const =0
virtual int totalSeedsCount() const =0
virtual qlonglong totalDownload() const =0
virtual QString creator() const =0
virtual QString savePath() const =0
virtual qreal realRatio() const =0
virtual QString downloadPath() const =0
virtual QDateTime addedTime() const =0
virtual qlonglong totalPayloadUpload() const =0
virtual int connectionsCount() const =0
virtual QDateTime completedTime() const =0
virtual qlonglong wastedSize() const =0
virtual QDateTime lastSeenComplete() const =0
virtual int leechsCount() const =0
virtual qlonglong eta() const =0
static const qreal MAX_RATIO
Definition: torrent.h:110
virtual int downloadPayloadRate() const =0
virtual int totalLeechersCount() const =0
QString toNativePath(const QString &path)
Definition: fs.cpp:64
const char KEY_TORRENT_INFOHASHV1[]
const char KEY_TORRENT_INFOHASHV2[]
const char KEY_PROP_DOWNLOADED_SESSION[]
const char KEY_PROP_DL_LIMIT[]
const char KEY_PROP_PEERS_TOTAL[]
const char KEY_PROP_SAVE_PATH[]
const char KEY_PROP_DL_SPEED_AVG[]
const char KEY_PROP_COMPLETION_DATE[]
const char KEY_PROP_UP_SPEED_AVG[]
const char KEY_PROP_TOTAL_SIZE[]
const char KEY_PROP_PEERS[]
const char KEY_PROP_DL_SPEED[]
const char KEY_PROP_UP_SPEED[]
const char KEY_PROP_PIECE_SIZE[]
const char KEY_PROP_CONNECT_COUNT[]
const char KEY_PROP_UPLOADED_SESSION[]
const char KEY_PROP_UP_LIMIT[]
const char KEY_PROP_SEEDS_TOTAL[]
const char KEY_PROP_PIECES_HAVE[]
const char KEY_PROP_TIME_ELAPSED[]
const char KEY_PROP_COMMENT[]
const char KEY_PROP_UPLOADED[]
const char KEY_PROP_CREATION_DATE[]
const char KEY_PROP_ETA[]
const char KEY_PROP_CREATED_BY[]
const char KEY_PROP_CONNECT_COUNT_LIMIT[]
const char KEY_PROP_ADDITION_DATE[]
const char KEY_PROP_DOWNLOAD_PATH[]
const char KEY_PROP_DOWNLOADED[]
const char KEY_PROP_PIECES_NUM[]
const char KEY_PROP_WASTED[]
const char KEY_PROP_LAST_SEEN[]
const char KEY_PROP_SEEDING_TIME[]
const char KEY_PROP_SEEDS[]
const char KEY_PROP_REANNOUNCE[]
const char KEY_PROP_RATIO[]

References BitTorrent::Torrent::activeTime(), BitTorrent::Torrent::addedTime(), BitTorrent::Torrent::comment(), BitTorrent::Torrent::completedTime(), BitTorrent::Torrent::connectionsCount(), BitTorrent::Torrent::connectionsLimit(), BitTorrent::Torrent::creationDate(), BitTorrent::Torrent::creator(), BitTorrent::Torrent::downloadLimit(), BitTorrent::Torrent::downloadPath(), BitTorrent::Torrent::downloadPayloadRate(), BitTorrent::Torrent::eta(), BitTorrent::Session::findTorrent(), BitTorrent::Torrent::finishedTime(), BitTorrent::TorrentID::fromString(), BitTorrent::Torrent::hasMetadata(), BitTorrent::Torrent::infoHash(), BitTorrent::Session::instance(), KEY_PROP_ADDITION_DATE, KEY_PROP_COMMENT, KEY_PROP_COMPLETION_DATE, KEY_PROP_CONNECT_COUNT, KEY_PROP_CONNECT_COUNT_LIMIT, KEY_PROP_CREATED_BY, KEY_PROP_CREATION_DATE, KEY_PROP_DL_LIMIT, KEY_PROP_DL_SPEED, KEY_PROP_DL_SPEED_AVG, KEY_PROP_DOWNLOAD_PATH, KEY_PROP_DOWNLOADED, KEY_PROP_DOWNLOADED_SESSION, KEY_PROP_ETA, KEY_PROP_LAST_SEEN, KEY_PROP_PEERS, KEY_PROP_PEERS_TOTAL, KEY_PROP_PIECE_SIZE, KEY_PROP_PIECES_HAVE, KEY_PROP_PIECES_NUM, KEY_PROP_RATIO, KEY_PROP_REANNOUNCE, KEY_PROP_SAVE_PATH, KEY_PROP_SEEDING_TIME, KEY_PROP_SEEDS, KEY_PROP_SEEDS_TOTAL, KEY_PROP_TIME_ELAPSED, KEY_PROP_TOTAL_SIZE, KEY_PROP_UP_LIMIT, KEY_PROP_UP_SPEED, KEY_PROP_UP_SPEED_AVG, KEY_PROP_UPLOADED, KEY_PROP_UPLOADED_SESSION, KEY_PROP_WASTED, KEY_TORRENT_INFOHASHV1, KEY_TORRENT_INFOHASHV2, BitTorrent::Torrent::lastSeenComplete(), BitTorrent::Torrent::leechsCount(), BitTorrent::Torrent::MAX_RATIO, BitTorrent::Torrent::nextAnnounce(), NotFound, APIController::params(), BitTorrent::Torrent::pieceLength(), BitTorrent::Torrent::piecesCount(), BitTorrent::Torrent::piecesHave(), BitTorrent::Torrent::realRatio(), APIController::requireParams(), BitTorrent::Torrent::savePath(), BitTorrent::Torrent::seedsCount(), APIController::setResult(), Utils::Fs::toNativePath(), Digest32< N >::toString(), BitTorrent::Torrent::totalDownload(), BitTorrent::Torrent::totalLeechersCount(), BitTorrent::Torrent::totalPayloadDownload(), BitTorrent::Torrent::totalPayloadUpload(), BitTorrent::Torrent::totalSeedsCount(), BitTorrent::Torrent::totalSize(), BitTorrent::Torrent::totalUpload(), BitTorrent::Torrent::uploadLimit(), BitTorrent::Torrent::uploadPayloadRate(), BitTorrent::InfoHash::v1(), BitTorrent::InfoHash::v2(), and BitTorrent::Torrent::wastedSize().

Here is the call graph for this function:

◆ reannounceAction

void TorrentsController::reannounceAction ( )
privateslot

Definition at line 1195 of file torrentscontroller.cpp.

1196 {
1197  requireParams({"hashes"});
1198 
1199  const QStringList hashes {params()["hashes"].split('|')};
1200  applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->forceReannounce(); });
1201 }

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), BitTorrent::Torrent::forceReannounce(), APIController::params(), and APIController::requireParams().

Here is the call graph for this function:

◆ recheckAction

void TorrentsController::recheckAction ( )
privateslot

Definition at line 1187 of file torrentscontroller.cpp.

1188 {
1189  requireParams({"hashes"});
1190 
1191  const QStringList hashes {params()["hashes"].split('|')};
1192  applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->forceRecheck(); });
1193 }
virtual void forceRecheck()=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), BitTorrent::Torrent::forceRecheck(), APIController::params(), and APIController::requireParams().

Here is the call graph for this function:

◆ removeCategoriesAction

void TorrentsController::removeCategoriesAction ( )
privateslot

Definition at line 1264 of file torrentscontroller.cpp.

1265 {
1266  requireParams({"categories"});
1267 
1268  const QStringList categories {params()["categories"].split('\n')};
1269  for (const QString &category : categories)
1271 }
bool removeCategory(const QString &name)
Definition: session.cpp:760

References BitTorrent::Session::instance(), APIController::params(), BitTorrent::Session::removeCategory(), and APIController::requireParams().

Here is the call graph for this function:

◆ removeTagsAction

void TorrentsController::removeTagsAction ( )
privateslot

Definition at line 1307 of file torrentscontroller.cpp.

1308 {
1309  requireParams({"hashes"});
1310 
1311  const QStringList hashes {params()["hashes"].split('|')};
1312  const QStringList tags {params()["tags"].split(',', Qt::SkipEmptyParts)};
1313 
1314  for (const QString &tag : tags)
1315  {
1316  const QString tagTrimmed {tag.trimmed()};
1317  applyToTorrents(hashes, [&tagTrimmed](BitTorrent::Torrent *const torrent)
1318  {
1319  torrent->removeTag(tagTrimmed);
1320  });
1321  }
1322 
1323  if (tags.isEmpty())
1324  {
1325  applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent)
1326  {
1327  torrent->removeAllTags();
1328  });
1329  }
1330 }
virtual bool removeTag(const QString &tag)=0
virtual void removeAllTags()=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), BitTorrent::Torrent::removeAllTags(), BitTorrent::Torrent::removeTag(), and APIController::requireParams().

Here is the call graph for this function:

◆ removeTrackersAction

void TorrentsController::removeTrackersAction ( )
privateslot

Definition at line 786 of file torrentscontroller.cpp.

787 {
788  requireParams({"hash", "urls"});
789 
790  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
792  if (!torrent)
794 
795  const QStringList urls = params()["urls"].split('|');
796 
797  const QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
798  QVector<BitTorrent::TrackerEntry> remainingTrackers;
799  remainingTrackers.reserve(trackers.size());
800  for (const BitTorrent::TrackerEntry &entry : trackers)
801  {
802  if (!urls.contains(entry.url))
803  remainingTrackers.push_back(entry);
804  }
805 
806  if (remainingTrackers.size() == trackers.size())
807  throw APIError(APIErrorType::Conflict, "No trackers were removed");
808 
809  torrent->replaceTrackers(remainingTrackers);
810 
811  if (!torrent->isPaused())
812  torrent->forceReannounce();
813 }

References Conflict, BitTorrent::Session::findTorrent(), BitTorrent::Torrent::forceReannounce(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), BitTorrent::Torrent::isPaused(), NotFound, APIController::params(), BitTorrent::Torrent::replaceTrackers(), APIController::requireParams(), and BitTorrent::Torrent::trackers().

Here is the call graph for this function:

◆ renameAction

void TorrentsController::renameAction ( )
privateslot

Definition at line 1156 of file torrentscontroller.cpp.

1157 {
1158  requireParams({"hash", "name"});
1159 
1160  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
1161  QString name = params()["name"].trimmed();
1162 
1163  if (name.isEmpty())
1164  throw APIError(APIErrorType::Conflict, tr("Incorrect torrent name"));
1165 
1167  if (!torrent)
1169 
1170  name.replace(QRegularExpression("\r?\n|\r"), " ");
1171  torrent->setName(name);
1172 }
virtual void setName(const QString &name)=0

References Conflict, BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), NotFound, APIController::params(), APIController::requireParams(), and BitTorrent::Torrent::setName().

Here is the call graph for this function:

◆ renameFileAction

void TorrentsController::renameFileAction ( )
privateslot

Definition at line 1359 of file torrentscontroller.cpp.

1360 {
1361  requireParams({"hash", "oldPath", "newPath"});
1362 
1363  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
1365  if (!torrent)
1367 
1368  const QString oldPath = params()["oldPath"];
1369  const QString newPath = params()["newPath"];
1370 
1371  try
1372  {
1373  torrent->renameFile(oldPath, newPath);
1374  }
1375  catch (const RuntimeError &error)
1376  {
1377  throw APIError(APIErrorType::Conflict, error.message());
1378  }
1379 }
virtual void renameFile(int index, const QString &name)=0
QString message() const noexcept
Definition: exceptions.cpp:36

References Conflict, BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), Exception::message(), NotFound, APIController::params(), BitTorrent::AbstractFileStorage::renameFile(), and APIController::requireParams().

Here is the call graph for this function:

◆ renameFolderAction

void TorrentsController::renameFolderAction ( )
privateslot

Definition at line 1381 of file torrentscontroller.cpp.

1382 {
1383  requireParams({"hash", "oldPath", "newPath"});
1384 
1385  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
1387  if (!torrent)
1389 
1390  const QString oldPath = params()["oldPath"];
1391  const QString newPath = params()["newPath"];
1392 
1393  try
1394  {
1395  torrent->renameFolder(oldPath, newPath);
1396  }
1397  catch (const RuntimeError &error)
1398  {
1399  throw APIError(APIErrorType::Conflict, error.message());
1400  }
1401 }
void renameFolder(const QString &oldPath, const QString &newPath)

References Conflict, BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), Exception::message(), NotFound, APIController::params(), BitTorrent::AbstractFileStorage::renameFolder(), and APIController::requireParams().

Here is the call graph for this function:

◆ resumeAction

void TorrentsController::resumeAction ( )
privateslot

Definition at line 861 of file torrentscontroller.cpp.

862 {
863  requireParams({"hashes"});
864 
865  const QStringList idStrings = params()["hashes"].split('|');
866  applyToTorrents(idStrings, [](BitTorrent::Torrent *const torrent) { torrent->resume(); });
867 }
virtual void resume(TorrentOperatingMode mode=TorrentOperatingMode::AutoManaged)=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), APIController::requireParams(), and BitTorrent::Torrent::resume().

Here is the call graph for this function:

◆ setAutoManagementAction

void TorrentsController::setAutoManagementAction ( )
privateslot

Definition at line 1174 of file torrentscontroller.cpp.

1175 {
1176  requireParams({"hashes", "enable"});
1177 
1178  const QStringList hashes {params()["hashes"].split('|')};
1179  const bool isEnabled {parseBool(params()["enable"]).value_or(false)};
1180 
1181  applyToTorrents(hashes, [isEnabled](BitTorrent::Torrent *const torrent)
1182  {
1183  torrent->setAutoTMMEnabled(isEnabled);
1184  });
1185 }
virtual void setAutoTMMEnabled(bool enabled)=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), Utils::String::parseBool(), APIController::requireParams(), and BitTorrent::Torrent::setAutoTMMEnabled().

Here is the call graph for this function:

◆ setCategoryAction

void TorrentsController::setCategoryAction ( )
privateslot

Definition at line 1203 of file torrentscontroller.cpp.

1204 {
1205  requireParams({"hashes", "category"});
1206 
1207  const QStringList hashes {params()["hashes"].split('|')};
1208  const QString category {params()["category"]};
1209 
1210  applyToTorrents(hashes, [category](BitTorrent::Torrent *const torrent)
1211  {
1212  if (!torrent->setCategory(category))
1213  throw APIError(APIErrorType::Conflict, tr("Incorrect category name"));
1214  });
1215 }
virtual bool setCategory(const QString &category)=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), Conflict, APIController::params(), APIController::requireParams(), and BitTorrent::Torrent::setCategory().

Here is the call graph for this function:

◆ setDownloadLimitAction

void TorrentsController::setDownloadLimitAction ( )
privateslot

Definition at line 958 of file torrentscontroller.cpp.

959 {
960  requireParams({"hashes", "limit"});
961 
962  qlonglong limit = params()["limit"].toLongLong();
963  if (limit == 0)
964  limit = -1;
965 
966  const QStringList hashes {params()["hashes"].split('|')};
967  applyToTorrents(hashes, [limit](BitTorrent::Torrent *const torrent) { torrent->setDownloadLimit(limit); });
968 }
virtual void setDownloadLimit(int limit)=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), APIController::requireParams(), and BitTorrent::Torrent::setDownloadLimit().

Here is the call graph for this function:

◆ setDownloadPathAction

void TorrentsController::setDownloadPathAction ( )
privateslot

Definition at line 1131 of file torrentscontroller.cpp.

1132 {
1133  requireParams({"id", "path"});
1134 
1135  const QStringList ids {params()["id"].split('|')};
1136  const QString newPath {params()["path"]};
1137 
1138  if (!newPath.isEmpty())
1139  {
1140  // try to create the directory if it does not exist
1141  if (!QDir(newPath).mkpath("."))
1142  throw APIError(APIErrorType::Conflict, tr("Cannot create target directory"));
1143 
1144  // check permissions
1145  if (!QFileInfo(newPath).isWritable())
1146  throw APIError(APIErrorType::AccessDenied, tr("Cannot write to directory"));
1147  }
1148 
1149  applyToTorrents(ids, [&newPath](BitTorrent::Torrent *const torrent)
1150  {
1151  if (!torrent->isAutoTMMEnabled())
1152  torrent->setDownloadPath(newPath);
1153  });
1154 }
virtual void setDownloadPath(const QString &downloadPath)=0
virtual bool isAutoTMMEnabled() const =0

References AccessDenied, anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), Conflict, BitTorrent::Torrent::isAutoTMMEnabled(), APIController::params(), APIController::requireParams(), and BitTorrent::Torrent::setDownloadPath().

Here is the call graph for this function:

◆ setForceStartAction

void TorrentsController::setForceStartAction ( )
privateslot

Definition at line 1010 of file torrentscontroller.cpp.

1011 {
1012  requireParams({"hashes", "value"});
1013 
1014  const bool value {parseBool(params()["value"]).value_or(false)};
1015  const QStringList hashes {params()["hashes"].split('|')};
1016  applyToTorrents(hashes, [value](BitTorrent::Torrent *const torrent)
1017  {
1018  torrent->resume(value ? BitTorrent::TorrentOperatingMode::Forced : BitTorrent::TorrentOperatingMode::AutoManaged);
1019  });
1020 }

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), Utils::String::parseBool(), APIController::requireParams(), BitTorrent::Torrent::resume(), and anonymous_namespace{preferences.cpp}::value().

Here is the call graph for this function:

◆ setLocationAction

void TorrentsController::setLocationAction ( )
privateslot

Definition at line 1079 of file torrentscontroller.cpp.

1080 {
1081  requireParams({"hashes", "location"});
1082 
1083  const QStringList hashes {params()["hashes"].split('|')};
1084  const QString newLocation {params()["location"].trimmed()};
1085 
1086  if (newLocation.isEmpty())
1087  throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty"));
1088 
1089  // try to create the location if it does not exist
1090  if (!QDir(newLocation).mkpath("."))
1091  throw APIError(APIErrorType::Conflict, tr("Cannot make save path"));
1092 
1093  // check permissions
1094  if (!QFileInfo(newLocation).isWritable())
1095  throw APIError(APIErrorType::AccessDenied, tr("Cannot write to directory"));
1096 
1097  applyToTorrents(hashes, [newLocation](BitTorrent::Torrent *const torrent)
1098  {
1099  LogMsg(tr("WebUI Set location: moving \"%1\", from \"%2\" to \"%3\"")
1100  .arg(torrent->name(), Utils::Fs::toNativePath(torrent->savePath()), Utils::Fs::toNativePath(newLocation)));
1101  torrent->setAutoTMMEnabled(false);
1102  torrent->setSavePath(Utils::Fs::expandPathAbs(newLocation));
1103  });
1104 }
virtual void setSavePath(const QString &savePath)=0
virtual QString name() const =0
void LogMsg(const QString &message, const Log::MsgType &type)
Definition: logger.cpp:125
QString expandPathAbs(const QString &path)
Definition: fs.cpp:309

References AccessDenied, anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), BadParams, Conflict, Utils::Fs::expandPathAbs(), LogMsg(), BitTorrent::Torrent::name(), APIController::params(), APIController::requireParams(), BitTorrent::Torrent::savePath(), BitTorrent::Torrent::setAutoTMMEnabled(), BitTorrent::Torrent::setSavePath(), and Utils::Fs::toNativePath().

Here is the call graph for this function:

◆ setSavePathAction

void TorrentsController::setSavePathAction ( )
privateslot

Definition at line 1106 of file torrentscontroller.cpp.

1107 {
1108  requireParams({"id", "path"});
1109 
1110  const QStringList ids {params()["id"].split('|')};
1111  const QString newPath {params()["path"]};
1112 
1113  if (newPath.isEmpty())
1114  throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty"));
1115 
1116  // try to create the directory if it does not exist
1117  if (!QDir(newPath).mkpath("."))
1118  throw APIError(APIErrorType::Conflict, tr("Cannot create target directory"));
1119 
1120  // check permissions
1121  if (!QFileInfo(newPath).isWritable())
1122  throw APIError(APIErrorType::AccessDenied, tr("Cannot write to directory"));
1123 
1124  applyToTorrents(ids, [&newPath](BitTorrent::Torrent *const torrent)
1125  {
1126  if (!torrent->isAutoTMMEnabled())
1127  torrent->setSavePath(newPath);
1128  });
1129 }

References AccessDenied, anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), BadParams, Conflict, BitTorrent::Torrent::isAutoTMMEnabled(), APIController::params(), APIController::requireParams(), and BitTorrent::Torrent::setSavePath().

Here is the call graph for this function:

◆ setShareLimitsAction

void TorrentsController::setShareLimitsAction ( )
privateslot

Definition at line 970 of file torrentscontroller.cpp.

971 {
972  requireParams({"hashes", "ratioLimit", "seedingTimeLimit"});
973 
974  const qreal ratioLimit = params()["ratioLimit"].toDouble();
975  const qlonglong seedingTimeLimit = params()["seedingTimeLimit"].toLongLong();
976  const QStringList hashes = params()["hashes"].split('|');
977 
978  applyToTorrents(hashes, [ratioLimit, seedingTimeLimit](BitTorrent::Torrent *const torrent)
979  {
980  torrent->setRatioLimit(ratioLimit);
981  torrent->setSeedingTimeLimit(seedingTimeLimit);
982  });
983 }
virtual void setSeedingTimeLimit(int limit)=0
virtual void setRatioLimit(qreal limit)=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), APIController::requireParams(), BitTorrent::Torrent::setRatioLimit(), and BitTorrent::Torrent::setSeedingTimeLimit().

Here is the call graph for this function:

◆ setSuperSeedingAction

void TorrentsController::setSuperSeedingAction ( )
privateslot

Definition at line 1001 of file torrentscontroller.cpp.

1002 {
1003  requireParams({"hashes", "value"});
1004 
1005  const bool value {parseBool(params()["value"]).value_or(false)};
1006  const QStringList hashes {params()["hashes"].split('|')};
1007  applyToTorrents(hashes, [value](BitTorrent::Torrent *const torrent) { torrent->setSuperSeeding(value); });
1008 }
virtual void setSuperSeeding(bool enable)=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), Utils::String::parseBool(), APIController::requireParams(), BitTorrent::Torrent::setSuperSeeding(), and anonymous_namespace{preferences.cpp}::value().

Here is the call graph for this function:

◆ setUploadLimitAction

void TorrentsController::setUploadLimitAction ( )
privateslot

Definition at line 946 of file torrentscontroller.cpp.

947 {
948  requireParams({"hashes", "limit"});
949 
950  qlonglong limit = params()["limit"].toLongLong();
951  if (limit == 0)
952  limit = -1;
953 
954  const QStringList hashes {params()["hashes"].split('|')};
955  applyToTorrents(hashes, [limit](BitTorrent::Torrent *const torrent) { torrent->setUploadLimit(limit); });
956 }
virtual void setUploadLimit(int limit)=0

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), APIController::requireParams(), and BitTorrent::Torrent::setUploadLimit().

Here is the call graph for this function:

◆ tagsAction

void TorrentsController::tagsAction ( )
privateslot

Definition at line 1351 of file torrentscontroller.cpp.

1352 {
1353  QJsonArray result;
1354  for (const QString &tag : asConst(BitTorrent::Session::instance()->tags()))
1355  result << tag;
1356  setResult(result);
1357 }

References asConst(), BitTorrent::Session::instance(), and APIController::setResult().

Here is the call graph for this function:

◆ toggleFirstLastPiecePrioAction

void TorrentsController::toggleFirstLastPiecePrioAction ( )
privateslot

Definition at line 993 of file torrentscontroller.cpp.

994 {
995  requireParams({"hashes"});
996 
997  const QStringList hashes {params()["hashes"].split('|')};
998  applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->toggleFirstLastPiecePriority(); });
999 }
void toggleFirstLastPiecePriority()
Definition: torrent.cpp:74

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), APIController::requireParams(), and BitTorrent::Torrent::toggleFirstLastPiecePriority().

Here is the call graph for this function:

◆ toggleSequentialDownloadAction

void TorrentsController::toggleSequentialDownloadAction ( )
privateslot

Definition at line 985 of file torrentscontroller.cpp.

986 {
987  requireParams({"hashes"});
988 
989  const QStringList hashes {params()["hashes"].split('|')};
990  applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->toggleSequentialDownload(); });
991 }
void toggleSequentialDownload()
Definition: torrent.cpp:69

References anonymous_namespace{torrentscontroller.cpp}::applyToTorrents(), APIController::params(), APIController::requireParams(), and BitTorrent::Torrent::toggleSequentialDownload().

Here is the call graph for this function:

◆ topPrioAction

void TorrentsController::topPrioAction ( )
privateslot

Definition at line 1057 of file torrentscontroller.cpp.

1058 {
1059  requireParams({"hashes"});
1060 
1061  if (!BitTorrent::Session::instance()->isQueueingSystemEnabled())
1062  throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
1063 
1064  const QStringList hashes {params()["hashes"].split('|')};
1066 }
void topTorrentsQueuePos(const QVector< TorrentID > &ids)
Definition: session.cpp:1917

References Conflict, BitTorrent::Session::instance(), APIController::params(), APIController::requireParams(), BitTorrent::Session::topTorrentsQueuePos(), and anonymous_namespace{torrentscontroller.cpp}::toTorrentIDs().

Here is the call graph for this function:

◆ trackersAction

void TorrentsController::trackersAction ( )
privateslot

Definition at line 452 of file torrentscontroller.cpp.

453 {
454  requireParams({"hash"});
455 
456  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
457  const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
458  if (!torrent)
460 
461  QJsonArray trackerList = getStickyTrackers(torrent);
462 
463  for (const BitTorrent::TrackerEntry &tracker : asConst(torrent->trackers()))
464  {
465  trackerList << QJsonObject
466  {
467  {KEY_TRACKER_URL, tracker.url},
468  {KEY_TRACKER_TIER, tracker.tier},
469  {KEY_TRACKER_STATUS, static_cast<int>(tracker.status)},
470  {KEY_TRACKER_MSG, tracker.message},
471  {KEY_TRACKER_PEERS_COUNT, tracker.numPeers},
472  {KEY_TRACKER_SEEDS_COUNT, tracker.numSeeds},
473  {KEY_TRACKER_LEECHES_COUNT, tracker.numLeeches},
474  {KEY_TRACKER_DOWNLOADED_COUNT, tracker.numDownloaded}
475  };
476  }
477 
478  setResult(trackerList);
479 }
QJsonArray getStickyTrackers(const BitTorrent::Torrent *const torrent)
const char KEY_TRACKER_DOWNLOADED_COUNT[]
const char KEY_TRACKER_LEECHES_COUNT[]
const char KEY_TRACKER_SEEDS_COUNT[]
const char KEY_TRACKER_PEERS_COUNT[]
const char KEY_TRACKER_MSG[]
const char KEY_TRACKER_URL[]
const char KEY_TRACKER_TIER[]
const char KEY_TRACKER_STATUS[]

References asConst(), BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), anonymous_namespace{torrentscontroller.cpp}::getStickyTrackers(), BitTorrent::Session::instance(), KEY_TRACKER_DOWNLOADED_COUNT, KEY_TRACKER_LEECHES_COUNT, KEY_TRACKER_MSG, KEY_TRACKER_PEERS_COUNT, KEY_TRACKER_SEEDS_COUNT, KEY_TRACKER_STATUS, KEY_TRACKER_TIER, KEY_TRACKER_URL, NotFound, APIController::params(), APIController::requireParams(), APIController::setResult(), and BitTorrent::Torrent::trackers().

Here is the call graph for this function:

◆ uploadLimitAction

void TorrentsController::uploadLimitAction ( )
privateslot

Definition at line 910 of file torrentscontroller.cpp.

911 {
912  requireParams({"hashes"});
913 
914  const QStringList idList {params()["hashes"].split('|')};
915  QJsonObject map;
916  for (const QString &id : idList)
917  {
918  int limit = -1;
920  if (torrent)
921  limit = torrent->uploadLimit();
922  map[id] = limit;
923  }
924 
925  setResult(map);
926 }

References BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), APIController::params(), APIController::requireParams(), APIController::setResult(), and BitTorrent::Torrent::uploadLimit().

Here is the call graph for this function:

◆ webseedsAction

void TorrentsController::webseedsAction ( )
privateslot

Definition at line 485 of file torrentscontroller.cpp.

486 {
487  requireParams({"hash"});
488 
489  const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
491  if (!torrent)
493 
494  QJsonArray webSeedList;
495  for (const QUrl &webseed : asConst(torrent->urlSeeds()))
496  {
497  webSeedList.append(QJsonObject
498  {
499  {KEY_WEBSEED_URL, webseed.toString()}
500  });
501  }
502 
503  setResult(webSeedList);
504 }
virtual QVector< QUrl > urlSeeds() const =0
const char KEY_WEBSEED_URL[]

References asConst(), BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromString(), BitTorrent::Session::instance(), KEY_WEBSEED_URL, NotFound, APIController::params(), APIController::requireParams(), APIController::setResult(), and BitTorrent::Torrent::urlSeeds().

Here is the call graph for this function:

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