From 12a4c3fda28a4023abd80d3724c4b029657effc0 Mon Sep 17 00:00:00 2001 From: ManiMatter <124743318+ManiMatter@users.noreply.github.com> Date: Sun, 16 Jun 2024 07:57:12 +0000 Subject: [PATCH] WebAPI: Add "private" filter for 'info' endpoint PR #20833. --------- Co-authored-by: Vladimir Golovnev Co-authored-by: Chocobo1 --- src/base/torrentfilter.cpp | 27 ++++++++++++++++--- src/base/torrentfilter.h | 18 ++++++++++--- src/webui/api/serialize/serialize_torrent.cpp | 3 +-- src/webui/api/serialize/serialize_torrent.h | 2 +- src/webui/api/torrentscontroller.cpp | 10 ++++--- src/webui/webapplication.h | 2 +- 6 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/base/torrentfilter.cpp b/src/base/torrentfilter.cpp index 7ad8cf112..89d9a97e9 100644 --- a/src/base/torrentfilter.cpp +++ b/src/base/torrentfilter.cpp @@ -52,19 +52,21 @@ const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored); using BitTorrent::Torrent; TorrentFilter::TorrentFilter(const Type type, const std::optional &idSet - , const std::optional &category, const std::optional &tag) + , const std::optional &category, const std::optional &tag, const std::optional isPrivate) : m_type {type} , m_category {category} , m_tag {tag} , m_idSet {idSet} + , m_private {isPrivate} { } TorrentFilter::TorrentFilter(const QString &filter, const std::optional &idSet - , const std::optional &category, const std::optional &tag) + , const std::optional &category, const std::optional &tag, const std::optional isPrivate) : m_category {category} , m_tag {tag} , m_idSet {idSet} + , m_private {isPrivate} { setTypeByName(filter); } @@ -147,11 +149,22 @@ bool TorrentFilter::setTag(const std::optional &tag) return false; } +bool TorrentFilter::setPrivate(const std::optional isPrivate) +{ + if (m_private != isPrivate) + { + m_private = isPrivate; + return true; + } + + return false; +} + bool TorrentFilter::match(const Torrent *const torrent) const { if (!torrent) return false; - return (matchState(torrent) && matchHash(torrent) && matchCategory(torrent) && matchTag(torrent)); + return (matchState(torrent) && matchHash(torrent) && matchCategory(torrent) && matchTag(torrent) && matchPrivate(torrent)); } bool TorrentFilter::matchState(const BitTorrent::Torrent *const torrent) const @@ -224,3 +237,11 @@ bool TorrentFilter::matchTag(const BitTorrent::Torrent *const torrent) const return torrent->hasTag(*m_tag); } + +bool TorrentFilter::matchPrivate(const BitTorrent::Torrent *const torrent) const +{ + if (!m_private) + return true; + + return m_private == torrent->isPrivate(); +} diff --git a/src/base/torrentfilter.h b/src/base/torrentfilter.h index 19092fb8e..39fd3e06f 100644 --- a/src/base/torrentfilter.h +++ b/src/base/torrentfilter.h @@ -87,16 +87,24 @@ public: TorrentFilter() = default; // category & tags: pass empty string for uncategorized / untagged torrents. - TorrentFilter(Type type, const std::optional &idSet = AnyID - , const std::optional &category = AnyCategory, const std::optional &tag = AnyTag); - TorrentFilter(const QString &filter, const std::optional &idSet = AnyID - , const std::optional &category = AnyCategory, const std::optional &tags = AnyTag); + TorrentFilter(Type type + , const std::optional &idSet = AnyID + , const std::optional &category = AnyCategory + , const std::optional &tag = AnyTag + , std::optional isPrivate = {}); + TorrentFilter(const QString &filter + , const std::optional &idSet = AnyID + , const std::optional &category = AnyCategory + , const std::optional &tags = AnyTag + , std::optional isPrivate = {}); + bool setType(Type type); bool setTypeByName(const QString &filter); bool setTorrentIDSet(const std::optional &idSet); bool setCategory(const std::optional &category); bool setTag(const std::optional &tag); + bool setPrivate(std::optional isPrivate); bool match(const BitTorrent::Torrent *torrent) const; @@ -105,9 +113,11 @@ private: bool matchHash(const BitTorrent::Torrent *torrent) const; bool matchCategory(const BitTorrent::Torrent *torrent) const; bool matchTag(const BitTorrent::Torrent *torrent) const; + bool matchPrivate(const BitTorrent::Torrent *torrent) const; Type m_type {All}; std::optional m_category; std::optional m_tag; std::optional m_idSet; + std::optional m_private; }; diff --git a/src/webui/api/serialize/serialize_torrent.cpp b/src/webui/api/serialize/serialize_torrent.cpp index 8883f4b82..88ab5af52 100644 --- a/src/webui/api/serialize/serialize_torrent.cpp +++ b/src/webui/api/serialize/serialize_torrent.cpp @@ -163,8 +163,7 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent) {KEY_TORRENT_AVAILABILITY, torrent.distributedCopies()}, {KEY_TORRENT_REANNOUNCE, torrent.nextAnnounce()}, {KEY_TORRENT_COMMENT, torrent.comment()}, - {KEY_TORRENT_ISPRIVATE, torrent.isPrivate()}, - + {KEY_TORRENT_PRIVATE, torrent.isPrivate()}, {KEY_TORRENT_TOTAL_SIZE, torrent.totalSize()} }; } diff --git a/src/webui/api/serialize/serialize_torrent.h b/src/webui/api/serialize/serialize_torrent.h index ee9d20ab7..ae5088e36 100644 --- a/src/webui/api/serialize/serialize_torrent.h +++ b/src/webui/api/serialize/serialize_torrent.h @@ -93,6 +93,6 @@ inline const QString KEY_TORRENT_SEEDING_TIME = u"seeding_time"_s; inline const QString KEY_TORRENT_AVAILABILITY = u"availability"_s; inline const QString KEY_TORRENT_REANNOUNCE = u"reannounce"_s; inline const QString KEY_TORRENT_COMMENT = u"comment"_s; -inline const QString KEY_TORRENT_ISPRIVATE = u"is_private"_s; +inline const QString KEY_TORRENT_PRIVATE = u"private"_s; QVariantMap serialize(const BitTorrent::Torrent &torrent); diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 2d40d3645..9ec640681 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -111,7 +111,8 @@ const QString KEY_PROP_CREATION_DATE = u"creation_date"_s; const QString KEY_PROP_SAVE_PATH = u"save_path"_s; const QString KEY_PROP_DOWNLOAD_PATH = u"download_path"_s; const QString KEY_PROP_COMMENT = u"comment"_s; -const QString KEY_PROP_ISPRIVATE = u"is_private"_s; +const QString KEY_PROP_IS_PRIVATE = u"is_private"_s; // deprecated, "private" should be used instead +const QString KEY_PROP_PRIVATE = u"private"_s; const QString KEY_PROP_SSL_CERTIFICATE = u"ssl_certificate"_s; const QString KEY_PROP_SSL_PRIVATEKEY = u"ssl_private_key"_s; const QString KEY_PROP_SSL_DHPARAMS = u"ssl_dh_params"_s; @@ -282,6 +283,7 @@ void TorrentsController::countAction() // - category (string): torrent category for filtering by it (empty string means "uncategorized"; no "category" param presented means "any category") // - tag (string): torrent tag for filtering by it (empty string means "untagged"; no "tag" param presented means "any tag") // - hashes (string): filter by hashes, can contain multiple hashes separated by | +// - private (bool): filter torrents that are from private trackers (true) or not (false). Empty means any torrent (no filtering) // - sort (string): name of column for sorting by its value // - reverse (bool): enable reverse sorting // - limit (int): set limit number of torrents returned (if greater than 0, otherwise - unlimited) @@ -296,6 +298,7 @@ void TorrentsController::infoAction() int limit {params()[u"limit"_s].toInt()}; int offset {params()[u"offset"_s].toInt()}; const QStringList hashes {params()[u"hashes"_s].split(u'|', Qt::SkipEmptyParts)}; + const std::optional isPrivate = parseBool(params()[u"private"_s]); std::optional idSet; if (!hashes.isEmpty()) @@ -305,7 +308,7 @@ void TorrentsController::infoAction() idSet->insert(BitTorrent::TorrentID::fromString(hash)); } - const TorrentFilter torrentFilter {filter, idSet, category, tag}; + const TorrentFilter torrentFilter {filter, idSet, category, tag, isPrivate}; QVariantList torrentList; for (const BitTorrent::Torrent *torrent : asConst(BitTorrent::Session::instance()->torrents())) { @@ -470,7 +473,8 @@ void TorrentsController::propertiesAction() {KEY_PROP_PIECE_SIZE, torrent->pieceLength()}, {KEY_PROP_PIECES_HAVE, torrent->piecesHave()}, {KEY_PROP_CREATED_BY, torrent->creator()}, - {KEY_PROP_ISPRIVATE, torrent->isPrivate()}, + {KEY_PROP_IS_PRIVATE, torrent->isPrivate()}, // used for maintaining backward compatibility + {KEY_PROP_PRIVATE, torrent->isPrivate()}, {KEY_PROP_ADDITION_DATE, Utils::DateTime::toSecsSinceEpoch(torrent->addedTime())}, {KEY_PROP_LAST_SEEN, Utils::DateTime::toSecsSinceEpoch(torrent->lastSeenComplete())}, {KEY_PROP_COMPLETION_DATE, Utils::DateTime::toSecsSinceEpoch(torrent->completedTime())}, diff --git a/src/webui/webapplication.h b/src/webui/webapplication.h index b14ce770f..193701314 100644 --- a/src/webui/webapplication.h +++ b/src/webui/webapplication.h @@ -54,7 +54,7 @@ #include "base/utils/version.h" #include "api/isessionmanager.h" -inline const Utils::Version<3, 2> API_VERSION {2, 11, 0}; +inline const Utils::Version<3, 2> API_VERSION {2, 11, 1}; class QTimer;