aboutsummaryrefslogtreecommitdiff
path: root/src/webengine/filter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/webengine/filter.cpp')
-rw-r--r--src/webengine/filter.cpp116
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));
+}