diff options
Diffstat (limited to 'src/webengine/filter.cpp')
-rw-r--r-- | src/webengine/filter.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/webengine/filter.cpp b/src/webengine/filter.cpp new file mode 100644 index 0000000..b250843 --- /dev/null +++ b/src/webengine/filter.cpp @@ -0,0 +1,116 @@ +/* + * 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 "filter.h" +#include "urlinterceptor.h" +#include <QDir> +#include <QJsonArray> +#include <QJsonDocument> +#include <QTextStream> +#include <configuration/configuration.h> +#include "util.h" + + +QHash<QString, Filter::HostRule> parseHostlist(const QString &filename) +{ + QHash<QString, Filter::HostRule> rules; + + if(QFile hostfile(filename); hostfile.open(QIODevice::ReadOnly | QIODevice::Text)) { + + // with a QTextStream we can read lines without getting linebreaks at the end + QTextStream hostfile_stream(&hostfile); + + while(!hostfile_stream.atEnd()) { + + // read line and remove any whitespace at the end + const QString &line = hostfile_stream.readLine().trimmed(); + + // skip comments and empty lines + if(line.isEmpty() || line.startsWith('#')) + continue; + + // everything else should be a rule + // format is <redirect> <host> + // 0.0.0.0 hostname + const QStringList &parts = line.split(' '); + const QString &redirect = parts.at(0); + + for(auto i = parts.constBegin() + 1; i != parts.constEnd(); ++i) { + if(!rules.contains(*i)) { + Filter::HostRule rule{}; + rule.isBlocking = (redirect == "0.0.0.0"); + rules.insert(*i, rule); + } + } + + // for(const QString &host : parts.mid(1)) { + // if(!rules.contains(host)) { + // UrlRequestInterceptor::HostRule rule{}; + // rule.isBlocking = redirect == "0.0.0.0"; + // rules.insert(host, rule); + // } + // } + } + + hostfile.close(); + } + + return rules; +} +/* +inline std::vector<FilterRule> parseAdBlockList(const QString &filename) +{ + std::vector<FilterRule> rules; + QFile list(filename); + + if(list.open(QIODevice::ReadOnly | QIODevice::Text), true) { + QTextStream l(&list); + QString line; + while(l.readLineInto(&line)) { + AdBlockRule rule(line); + if(rule.isEnabled()) { + rules.emplace_back(std::move(rule)); + } + } + list.close(); + } + + return rules; +}*/ + +Filter::Filter::Filter(const std::unique_ptr<Configuration> &config, QObject* parent) + : QObject(parent) +{ + // parse headers + if(const auto headers = config->value<QStringList>("filter.header"); headers) { + for(const QString &header : headers.value()) { + const auto list = header.split(QLatin1Literal(":")); + if(list.length() == 2) + m_headers.insert(list.at(0).toLatin1(), list.at(1).toLatin1()); + } + } + + const QStringList hostfiles = Util::files(config->value<QString>("filter.path").value()); + for(const QString &hostfile : hostfiles) { + m_hostlist.unite(parseHostlist(hostfile)); + } + + /* + auto filtersPath = config->value<QString>("filter.adblock"); + if(filtersPath) + filters = parseAdBlockList(filtersPath.value()); + */ +} + +std::optional<Filter::HostRule> Filter::hostlistRule(const QString& url) const +{ + if(!m_hostlist.contains(url)) + return std::nullopt; + + return std::optional<Filter::HostRule>(m_hostlist.value(url)); +} |