diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2018-10-16 17:25:40 +0200 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2018-10-16 17:25:40 +0200 |
commit | c74367d82c1c7bec393548d2e5014c794333822f (patch) | |
tree | 909bcde935c84e566db528b1ab25d81778e13036 /lib/urlfilter/filtertree.cpp | |
parent | Add workaround for QTBUG-62511 (diff) | |
download | smolbote-c74367d82c1c7bec393548d2e5014c794333822f.tar.xz |
urlfilter: Add FilterTree class
FilterTree is a class that holds filter rules, sorted by the domain they
are to be applied on. The rules are to follow FilterLeaf as interface.
- Add a hostlist rule format to FilterTree.
- Add a test for hostlist format.
Diffstat (limited to 'lib/urlfilter/filtertree.cpp')
-rw-r--r-- | lib/urlfilter/filtertree.cpp | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/lib/urlfilter/filtertree.cpp b/lib/urlfilter/filtertree.cpp new file mode 100644 index 0000000..8844a76 --- /dev/null +++ b/lib/urlfilter/filtertree.cpp @@ -0,0 +1,86 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "filtertree.h" +#include "filterleaf.h" +#include <QTextStream> +#include "formats/hostlistrule.h" + +bool loadHostlist(QIODevice &from, FilterTree* tree) +{ + Q_ASSERT(from.isReadable()); + QTextStream stream(&from); + while(!stream.atEnd()) { + const QString line = stream.readLine().trimmed(); + if(line.isEmpty() || line.startsWith(QLatin1Literal("#"))) + continue; + + const QStringList &parts = line.split(QLatin1Literal(" ")); + if(parts.length() < 2) { +#ifdef QT_DEBUG + qDebug("Cannot parse: %s", qUtf8Printable(line)); +#endif + return false; + } + + for(int i = 1; i < parts.length(); ++i) { + // HostlistRule(domain, redirect) + auto *rule = new HostlistRule(parts.at(i), parts.constFirst()); + // addRule(rule, enable_on_domain) + const bool added = tree->addRule(rule, QString()); + if(!added) + return false; + } + + } + return true; +} + +const QStringList FilterTree::branches() const +{ + QStringList branches; + for(auto &branch : m_branches) { + branches.append(QString::fromStdString(branch.domain)); + } + return branches; +} + +QVector<const FilterLeaf *> FilterTree::match(const QString& domain, const QString& requestUrl) const +{ + QVector<const FilterLeaf *> leaves; + for(const auto &branch : m_branches) { + if(branch.domain == domain.toStdString()) { + + for(const auto leaf : branch.leaves) { + if(leaf->match(requestUrl)) { + leaves.append(leaf); + } + } + + } + } + return leaves; +} + +bool FilterTree::addRule(FilterLeaf *rule, const QString& domain) +{ + for(auto &branch : m_branches) { + if(branch.domain == domain.toStdString()) { + branch.leaves.emplace_back(rule); + return true; + } + } + + // no branch was found + Branch branch; + branch.domain = domain.toStdString(); + // TODO: for some reason, can't add rule here + //branch.leaves.emplace_back(rule); + m_branches.emplace_back(std::move(branch)); + return this->addRule(rule, domain); +} |