WebAPI: Add "private" filter for 'info' endpoint

PR #20833.

---------

Co-authored-by: Vladimir Golovnev <glassez@yandex.ru>
Co-authored-by: Chocobo1 <Chocobo1@users.noreply.github.com>
This commit is contained in:
ManiMatter 2024-06-16 07:57:12 +00:00 committed by GitHub
parent c36100fa85
commit 914728d9a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 48 additions and 14 deletions

View file

@ -52,19 +52,21 @@ const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored);
using BitTorrent::Torrent; using BitTorrent::Torrent;
TorrentFilter::TorrentFilter(const Type type, const std::optional<TorrentIDSet> &idSet TorrentFilter::TorrentFilter(const Type type, const std::optional<TorrentIDSet> &idSet
, const std::optional<QString> &category, const std::optional<Tag> &tag) , const std::optional<QString> &category, const std::optional<Tag> &tag, const std::optional<bool> isPrivate)
: m_type {type} : m_type {type}
, m_category {category} , m_category {category}
, m_tag {tag} , m_tag {tag}
, m_idSet {idSet} , m_idSet {idSet}
, m_private {isPrivate}
{ {
} }
TorrentFilter::TorrentFilter(const QString &filter, const std::optional<TorrentIDSet> &idSet TorrentFilter::TorrentFilter(const QString &filter, const std::optional<TorrentIDSet> &idSet
, const std::optional<QString> &category, const std::optional<Tag> &tag) , const std::optional<QString> &category, const std::optional<Tag> &tag, const std::optional<bool> isPrivate)
: m_category {category} : m_category {category}
, m_tag {tag} , m_tag {tag}
, m_idSet {idSet} , m_idSet {idSet}
, m_private {isPrivate}
{ {
setTypeByName(filter); setTypeByName(filter);
} }
@ -147,11 +149,22 @@ bool TorrentFilter::setTag(const std::optional<Tag> &tag)
return false; return false;
} }
bool TorrentFilter::setPrivate(const std::optional<bool> isPrivate)
{
if (m_private != isPrivate)
{
m_private = isPrivate;
return true;
}
return false;
}
bool TorrentFilter::match(const Torrent *const torrent) const bool TorrentFilter::match(const Torrent *const torrent) const
{ {
if (!torrent) return false; 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 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); return torrent->hasTag(*m_tag);
} }
bool TorrentFilter::matchPrivate(const BitTorrent::Torrent *const torrent) const
{
if (!m_private)
return true;
return m_private == torrent->isPrivate();
}

View file

@ -87,16 +87,24 @@ public:
TorrentFilter() = default; TorrentFilter() = default;
// category & tags: pass empty string for uncategorized / untagged torrents. // category & tags: pass empty string for uncategorized / untagged torrents.
TorrentFilter(Type type, const std::optional<TorrentIDSet> &idSet = AnyID TorrentFilter(Type type
, const std::optional<QString> &category = AnyCategory, const std::optional<Tag> &tag = AnyTag); , const std::optional<TorrentIDSet> &idSet = AnyID
TorrentFilter(const QString &filter, const std::optional<TorrentIDSet> &idSet = AnyID , const std::optional<QString> &category = AnyCategory
, const std::optional<QString> &category = AnyCategory, const std::optional<Tag> &tags = AnyTag); , const std::optional<Tag> &tag = AnyTag
, std::optional<bool> isPrivate = {});
TorrentFilter(const QString &filter
, const std::optional<TorrentIDSet> &idSet = AnyID
, const std::optional<QString> &category = AnyCategory
, const std::optional<Tag> &tags = AnyTag
, std::optional<bool> isPrivate = {});
bool setType(Type type); bool setType(Type type);
bool setTypeByName(const QString &filter); bool setTypeByName(const QString &filter);
bool setTorrentIDSet(const std::optional<TorrentIDSet> &idSet); bool setTorrentIDSet(const std::optional<TorrentIDSet> &idSet);
bool setCategory(const std::optional<QString> &category); bool setCategory(const std::optional<QString> &category);
bool setTag(const std::optional<Tag> &tag); bool setTag(const std::optional<Tag> &tag);
bool setPrivate(std::optional<bool> isPrivate);
bool match(const BitTorrent::Torrent *torrent) const; bool match(const BitTorrent::Torrent *torrent) const;
@ -105,9 +113,11 @@ private:
bool matchHash(const BitTorrent::Torrent *torrent) const; bool matchHash(const BitTorrent::Torrent *torrent) const;
bool matchCategory(const BitTorrent::Torrent *torrent) const; bool matchCategory(const BitTorrent::Torrent *torrent) const;
bool matchTag(const BitTorrent::Torrent *torrent) const; bool matchTag(const BitTorrent::Torrent *torrent) const;
bool matchPrivate(const BitTorrent::Torrent *torrent) const;
Type m_type {All}; Type m_type {All};
std::optional<QString> m_category; std::optional<QString> m_category;
std::optional<Tag> m_tag; std::optional<Tag> m_tag;
std::optional<TorrentIDSet> m_idSet; std::optional<TorrentIDSet> m_idSet;
std::optional<bool> m_private;
}; };

View file

@ -163,8 +163,7 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent)
{KEY_TORRENT_AVAILABILITY, torrent.distributedCopies()}, {KEY_TORRENT_AVAILABILITY, torrent.distributedCopies()},
{KEY_TORRENT_REANNOUNCE, torrent.nextAnnounce()}, {KEY_TORRENT_REANNOUNCE, torrent.nextAnnounce()},
{KEY_TORRENT_COMMENT, torrent.comment()}, {KEY_TORRENT_COMMENT, torrent.comment()},
{KEY_TORRENT_ISPRIVATE, torrent.isPrivate()}, {KEY_TORRENT_PRIVATE, torrent.isPrivate()},
{KEY_TORRENT_TOTAL_SIZE, torrent.totalSize()} {KEY_TORRENT_TOTAL_SIZE, torrent.totalSize()}
}; };
} }

View file

@ -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_AVAILABILITY = u"availability"_s;
inline const QString KEY_TORRENT_REANNOUNCE = u"reannounce"_s; inline const QString KEY_TORRENT_REANNOUNCE = u"reannounce"_s;
inline const QString KEY_TORRENT_COMMENT = u"comment"_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); QVariantMap serialize(const BitTorrent::Torrent &torrent);

View file

@ -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_SAVE_PATH = u"save_path"_s;
const QString KEY_PROP_DOWNLOAD_PATH = u"download_path"_s; const QString KEY_PROP_DOWNLOAD_PATH = u"download_path"_s;
const QString KEY_PROP_COMMENT = u"comment"_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_CERTIFICATE = u"ssl_certificate"_s;
const QString KEY_PROP_SSL_PRIVATEKEY = u"ssl_private_key"_s; const QString KEY_PROP_SSL_PRIVATEKEY = u"ssl_private_key"_s;
const QString KEY_PROP_SSL_DHPARAMS = u"ssl_dh_params"_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") // - 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") // - 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 | // - 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 // - sort (string): name of column for sorting by its value
// - reverse (bool): enable reverse sorting // - reverse (bool): enable reverse sorting
// - limit (int): set limit number of torrents returned (if greater than 0, otherwise - unlimited) // - 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 limit {params()[u"limit"_s].toInt()};
int offset {params()[u"offset"_s].toInt()}; int offset {params()[u"offset"_s].toInt()};
const QStringList hashes {params()[u"hashes"_s].split(u'|', Qt::SkipEmptyParts)}; const QStringList hashes {params()[u"hashes"_s].split(u'|', Qt::SkipEmptyParts)};
const std::optional<bool> isPrivate = parseBool(params()[u"private"_s]);
std::optional<TorrentIDSet> idSet; std::optional<TorrentIDSet> idSet;
if (!hashes.isEmpty()) if (!hashes.isEmpty())
@ -305,7 +308,7 @@ void TorrentsController::infoAction()
idSet->insert(BitTorrent::TorrentID::fromString(hash)); idSet->insert(BitTorrent::TorrentID::fromString(hash));
} }
const TorrentFilter torrentFilter {filter, idSet, category, tag}; const TorrentFilter torrentFilter {filter, idSet, category, tag, isPrivate};
QVariantList torrentList; QVariantList torrentList;
for (const BitTorrent::Torrent *torrent : asConst(BitTorrent::Session::instance()->torrents())) 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_PIECE_SIZE, torrent->pieceLength()},
{KEY_PROP_PIECES_HAVE, torrent->piecesHave()}, {KEY_PROP_PIECES_HAVE, torrent->piecesHave()},
{KEY_PROP_CREATED_BY, torrent->creator()}, {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_ADDITION_DATE, Utils::DateTime::toSecsSinceEpoch(torrent->addedTime())},
{KEY_PROP_LAST_SEEN, Utils::DateTime::toSecsSinceEpoch(torrent->lastSeenComplete())}, {KEY_PROP_LAST_SEEN, Utils::DateTime::toSecsSinceEpoch(torrent->lastSeenComplete())},
{KEY_PROP_COMPLETION_DATE, Utils::DateTime::toSecsSinceEpoch(torrent->completedTime())}, {KEY_PROP_COMPLETION_DATE, Utils::DateTime::toSecsSinceEpoch(torrent->completedTime())},

View file

@ -54,7 +54,7 @@
#include "base/utils/version.h" #include "base/utils/version.h"
#include "api/isessionmanager.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; class QTimer;