mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-27 11:49:01 +03:00
parent
c627ed4b6f
commit
2d3ff6a97c
3 changed files with 59 additions and 42 deletions
|
@ -31,9 +31,9 @@
|
||||||
#include "bittorrent/infohash.h"
|
#include "bittorrent/infohash.h"
|
||||||
#include "bittorrent/torrent.h"
|
#include "bittorrent/torrent.h"
|
||||||
|
|
||||||
const QString TorrentFilter::AnyCategory;
|
const std::optional<QString> TorrentFilter::AnyCategory;
|
||||||
const TorrentIDSet TorrentFilter::AnyID {{}};
|
const std::optional<TorrentIDSet> TorrentFilter::AnyID;
|
||||||
const QString TorrentFilter::AnyTag;
|
const std::optional<QString> TorrentFilter::AnyTag;
|
||||||
|
|
||||||
const TorrentFilter TorrentFilter::DownloadingTorrent(TorrentFilter::Downloading);
|
const TorrentFilter TorrentFilter::DownloadingTorrent(TorrentFilter::Downloading);
|
||||||
const TorrentFilter TorrentFilter::SeedingTorrent(TorrentFilter::Seeding);
|
const TorrentFilter TorrentFilter::SeedingTorrent(TorrentFilter::Seeding);
|
||||||
|
@ -50,7 +50,8 @@ const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored);
|
||||||
|
|
||||||
using BitTorrent::Torrent;
|
using BitTorrent::Torrent;
|
||||||
|
|
||||||
TorrentFilter::TorrentFilter(const Type type, const TorrentIDSet &idSet, const QString &category, const QString &tag)
|
TorrentFilter::TorrentFilter(const Type type, const std::optional<TorrentIDSet> &idSet
|
||||||
|
, const std::optional<QString> &category, const std::optional<QString> &tag)
|
||||||
: m_type(type)
|
: m_type(type)
|
||||||
, m_category(category)
|
, m_category(category)
|
||||||
, m_tag(tag)
|
, m_tag(tag)
|
||||||
|
@ -58,7 +59,8 @@ TorrentFilter::TorrentFilter(const Type type, const TorrentIDSet &idSet, const Q
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentFilter::TorrentFilter(const QString &filter, const TorrentIDSet &idSet, const QString &category, const QString &tag)
|
TorrentFilter::TorrentFilter(const QString &filter, const std::optional<TorrentIDSet> &idSet
|
||||||
|
, const std::optional<QString> &category, const std::optional<QString> &tag)
|
||||||
: m_type(All)
|
: m_type(All)
|
||||||
, m_category(category)
|
, m_category(category)
|
||||||
, m_tag(tag)
|
, m_tag(tag)
|
||||||
|
@ -110,7 +112,7 @@ bool TorrentFilter::setTypeByName(const QString &filter)
|
||||||
return setType(type);
|
return setType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::setTorrentIDSet(const TorrentIDSet &idSet)
|
bool TorrentFilter::setTorrentIDSet(const std::optional<TorrentIDSet> &idSet)
|
||||||
{
|
{
|
||||||
if (m_idSet != idSet)
|
if (m_idSet != idSet)
|
||||||
{
|
{
|
||||||
|
@ -121,12 +123,9 @@ bool TorrentFilter::setTorrentIDSet(const TorrentIDSet &idSet)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::setCategory(const QString &category)
|
bool TorrentFilter::setCategory(const std::optional<QString> &category)
|
||||||
{
|
{
|
||||||
// QString::operator==() doesn't distinguish between empty and null strings.
|
if (m_category != category)
|
||||||
if ((m_category != category)
|
|
||||||
|| (m_category.isNull() && !category.isNull())
|
|
||||||
|| (!m_category.isNull() && category.isNull()))
|
|
||||||
{
|
{
|
||||||
m_category = category;
|
m_category = category;
|
||||||
return true;
|
return true;
|
||||||
|
@ -135,12 +134,9 @@ bool TorrentFilter::setCategory(const QString &category)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::setTag(const QString &tag)
|
bool TorrentFilter::setTag(const std::optional<QString> &tag)
|
||||||
{
|
{
|
||||||
// QString::operator==() doesn't distinguish between empty and null strings.
|
if (m_tag != tag)
|
||||||
if ((m_tag != tag)
|
|
||||||
|| (m_tag.isNull() && !tag.isNull())
|
|
||||||
|| (!m_tag.isNull() && tag.isNull()))
|
|
||||||
{
|
{
|
||||||
m_tag = tag;
|
m_tag = tag;
|
||||||
return true;
|
return true;
|
||||||
|
@ -196,23 +192,28 @@ bool TorrentFilter::matchState(const BitTorrent::Torrent *const torrent) const
|
||||||
|
|
||||||
bool TorrentFilter::matchHash(const BitTorrent::Torrent *const torrent) const
|
bool TorrentFilter::matchHash(const BitTorrent::Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
if (m_idSet == AnyID) return true;
|
if (!m_idSet)
|
||||||
|
return true;
|
||||||
|
|
||||||
return m_idSet.contains(torrent->id());
|
return m_idSet->contains(torrent->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::matchCategory(const BitTorrent::Torrent *const torrent) const
|
bool TorrentFilter::matchCategory(const BitTorrent::Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
if (m_category.isNull()) return true;
|
if (!m_category)
|
||||||
|
return true;
|
||||||
|
|
||||||
return (torrent->belongsToCategory(m_category));
|
return (torrent->belongsToCategory(*m_category));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::matchTag(const BitTorrent::Torrent *const torrent) const
|
bool TorrentFilter::matchTag(const BitTorrent::Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
// Empty tag is a special value to indicate we're filtering for untagged torrents.
|
if (!m_tag)
|
||||||
if (m_tag.isNull()) return true;
|
return true;
|
||||||
if (m_tag.isEmpty()) return torrent->tags().isEmpty();
|
|
||||||
|
|
||||||
return (torrent->hasTag(m_tag));
|
// Empty tag is a special value to indicate we're filtering for untagged torrents.
|
||||||
|
if (m_tag->isEmpty())
|
||||||
|
return torrent->tags().isEmpty();
|
||||||
|
|
||||||
|
return torrent->hasTag(*m_tag);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
@ -61,9 +63,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// These mean any permutation, including no category / tag.
|
// These mean any permutation, including no category / tag.
|
||||||
static const QString AnyCategory;
|
static const std::optional<QString> AnyCategory;
|
||||||
static const TorrentIDSet AnyID;
|
static const std::optional<TorrentIDSet> AnyID;
|
||||||
static const QString AnyTag;
|
static const std::optional<QString> AnyTag;
|
||||||
|
|
||||||
static const TorrentFilter DownloadingTorrent;
|
static const TorrentFilter DownloadingTorrent;
|
||||||
static const TorrentFilter SeedingTorrent;
|
static const TorrentFilter SeedingTorrent;
|
||||||
|
@ -80,15 +82,16 @@ public:
|
||||||
|
|
||||||
TorrentFilter() = default;
|
TorrentFilter() = default;
|
||||||
// category & tags: pass empty string for uncategorized / untagged torrents.
|
// category & tags: pass empty string for uncategorized / untagged torrents.
|
||||||
// Pass null string (QString()) to disable filtering (i.e. all torrents).
|
TorrentFilter(Type type, const std::optional<TorrentIDSet> &idSet = AnyID
|
||||||
TorrentFilter(Type type, const TorrentIDSet &idSet = AnyID, const QString &category = AnyCategory, const QString &tag = AnyTag);
|
, const std::optional<QString> &category = AnyCategory, const std::optional<QString> &tag = AnyTag);
|
||||||
TorrentFilter(const QString &filter, const TorrentIDSet &idSet = AnyID, const QString &category = AnyCategory, const QString &tags = AnyTag);
|
TorrentFilter(const QString &filter, const std::optional<TorrentIDSet> &idSet = AnyID
|
||||||
|
, const std::optional<QString> &category = AnyCategory, const std::optional<QString> &tags = AnyTag);
|
||||||
|
|
||||||
bool setType(Type type);
|
bool setType(Type type);
|
||||||
bool setTypeByName(const QString &filter);
|
bool setTypeByName(const QString &filter);
|
||||||
bool setTorrentIDSet(const TorrentIDSet &idSet);
|
bool setTorrentIDSet(const std::optional<TorrentIDSet> &idSet);
|
||||||
bool setCategory(const QString &category);
|
bool setCategory(const std::optional<QString> &category);
|
||||||
bool setTag(const QString &tag);
|
bool setTag(const std::optional<QString> &tag);
|
||||||
|
|
||||||
bool match(const BitTorrent::Torrent *torrent) const;
|
bool match(const BitTorrent::Torrent *torrent) const;
|
||||||
|
|
||||||
|
@ -99,7 +102,7 @@ private:
|
||||||
bool matchTag(const BitTorrent::Torrent *torrent) const;
|
bool matchTag(const BitTorrent::Torrent *torrent) const;
|
||||||
|
|
||||||
Type m_type {All};
|
Type m_type {All};
|
||||||
QString m_category;
|
std::optional<QString> m_category;
|
||||||
QString m_tag;
|
std::optional<QString> m_tag;
|
||||||
TorrentIDSet m_idSet;
|
std::optional<TorrentIDSet> m_idSet;
|
||||||
};
|
};
|
||||||
|
|
|
@ -140,6 +140,15 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<QString> getOptionalString(const StringMap ¶ms, const QString &name)
|
||||||
|
{
|
||||||
|
const auto it = params.constFind(name);
|
||||||
|
if (it == params.cend())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return it.value();
|
||||||
|
}
|
||||||
|
|
||||||
QJsonArray getStickyTrackers(const BitTorrent::Torrent *const torrent)
|
QJsonArray getStickyTrackers(const BitTorrent::Torrent *const torrent)
|
||||||
{
|
{
|
||||||
int seedsDHT = 0, seedsPeX = 0, seedsLSD = 0, leechesDHT = 0, leechesPeX = 0, leechesLSD = 0;
|
int seedsDHT = 0, seedsPeX = 0, seedsLSD = 0, leechesDHT = 0, leechesPeX = 0, leechesLSD = 0;
|
||||||
|
@ -255,19 +264,23 @@ namespace
|
||||||
void TorrentsController::infoAction()
|
void TorrentsController::infoAction()
|
||||||
{
|
{
|
||||||
const QString filter {params()["filter"]};
|
const QString filter {params()["filter"]};
|
||||||
const QString category {params()["category"]};
|
const std::optional<QString> category = getOptionalString(params(), QLatin1String("category"));
|
||||||
const QString tag {params()["tag"]};
|
const std::optional<QString> tag = getOptionalString(params(), QLatin1String("tag"));
|
||||||
const QString sortedColumn {params()["sort"]};
|
const QString sortedColumn {params()["sort"]};
|
||||||
const bool reverse {parseBool(params()["reverse"]).value_or(false)};
|
const bool reverse {parseBool(params()["reverse"]).value_or(false)};
|
||||||
int limit {params()["limit"].toInt()};
|
int limit {params()["limit"].toInt()};
|
||||||
int offset {params()["offset"].toInt()};
|
int offset {params()["offset"].toInt()};
|
||||||
const QStringList hashes {params()["hashes"].split('|', Qt::SkipEmptyParts)};
|
const QStringList hashes {params()["hashes"].split('|', Qt::SkipEmptyParts)};
|
||||||
|
|
||||||
TorrentIDSet idSet;
|
std::optional<TorrentIDSet> idSet;
|
||||||
|
if (!hashes.isEmpty())
|
||||||
|
{
|
||||||
|
idSet = TorrentIDSet();
|
||||||
for (const QString &hash : hashes)
|
for (const QString &hash : hashes)
|
||||||
idSet.insert(BitTorrent::TorrentID::fromString(hash));
|
idSet->insert(BitTorrent::TorrentID::fromString(hash));
|
||||||
|
}
|
||||||
|
|
||||||
const TorrentFilter torrentFilter(filter, (hashes.isEmpty() ? TorrentFilter::AnyID : idSet), category, tag);
|
const TorrentFilter torrentFilter {filter, idSet, category, tag};
|
||||||
QVariantList torrentList;
|
QVariantList torrentList;
|
||||||
for (const BitTorrent::Torrent *torrent : asConst(BitTorrent::Session::instance()->torrents()))
|
for (const BitTorrent::Torrent *torrent : asConst(BitTorrent::Session::instance()->torrents()))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue