Skip to content

Commit

Permalink
preliminary filter option support (similar to 4chanX)
Browse files Browse the repository at this point in the history
  • Loading branch information
siavash119 committed May 9, 2018
1 parent b6e4cae commit e599a9b
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 36 deletions.
6 changes: 4 additions & 2 deletions boardtabhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ void BoardTabHelper::startUp(Chan *api, QString &board, BoardType type, QString
}
request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
getPosts();
filterMe.filterMatchedPerTab(board,"board");
/*updateTimer = new QTimer();
updateTimer->setInterval(60000);
updateTimer->start();
Expand Down Expand Up @@ -127,7 +128,7 @@ void BoardTabHelper::loadPosts() {
tf->load(p);
tfMap.insert(tf->post.no,tf);
//if(filter.filterMatched(tf->matchThis()) || filter.filterMatched2(&(tf->post))){
if(filter.filterMatched2(&(tf->post))){
if(filterMe.filterMatched2(&(tf->post))){
tf->hidden=true;
}
emit newThread(tf);
Expand All @@ -144,8 +145,9 @@ void BoardTabHelper::loadPosts() {
}

void BoardTabHelper::reloadFilters(){
filterMe.filters2 = filter.filterMatchedPerTab(this->board,"board");
foreach(ThreadForm* tf,tfMap){
if(filter.filterMatched2(&(tf->post))){
if(filterMe.filterMatched2(&(tf->post))){
tf->hidden=true;
emit removeTF(tf);
}
Expand Down
2 changes: 2 additions & 0 deletions boardtabhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define BOARDTABHELPER_H

#include "chans.h"
#include "filter.h"
#include "threadform.h"

enum BoardType{Index,Catalog};
Expand All @@ -11,6 +12,7 @@ class BoardTabHelper : public QObject
Q_OBJECT
bool gettingReply = false;
Qt::ConnectionType UniqueDirect = static_cast<Qt::ConnectionType>(Qt::DirectConnection | Qt::UniqueConnection);
Filter filterMe = filter;
public:
BoardTabHelper();
~BoardTabHelper();
Expand Down
186 changes: 156 additions & 30 deletions filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,29 @@ void Filter::loadFilterFile2(){
QString line = in.readLine();
if(!line.isEmpty() && line.at(0)=='!'){
QString key = line.mid(1);
QSet<QRegularExpression> set = filters2.value(key);
QHash<QRegularExpression,QString> hash = filters2.value(key);
while(!in.atEnd()){
QString exp = in.readLine();
if(exp.isEmpty() || exp.at(0)=='#'){
line = in.readLine();
if(line.isEmpty() || line.at(0)=='#'){
continue;
}
else if(exp.at(0) == '!') break;
exp = exp.replace("\\\\","\\\\\\\\");
set.insert(QRegularExpression(exp,QRegularExpression::CaseInsensitiveOption));
else if(line.at(0) == '!') break;
line = line.replace("\\\\","\\\\\\\\");
int ind = line.lastIndexOf('$');
QRegularExpression exp;
QString options;
if(ind != -1){
exp.setPattern(line.mid(0,ind));
if(line.length() > ind+1)
options = line.mid(ind+1);
}
else{
exp.setPattern(line);
}
exp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
hash.insert(exp,options);
}
filters2.insert(key,set);
filters2.insert(key,hash);
}
}
inputFile.close();
Expand All @@ -80,9 +92,9 @@ void Filter::loadFilterFile2(){
}

void Filter::addFilter2(QString key, QString newFilter){
QSet<QRegularExpression> set = filters2.value(key);
set.insert(QRegularExpression(newFilter,QRegularExpression::CaseInsensitiveOption));
filters2.insert(key,set);
QHash<QRegularExpression,QString> hash = filters2.value(key);
hash.insert(QRegularExpression(newFilter,QRegularExpression::CaseInsensitiveOption),QString());
filters2.insert(key,hash);
writeFilterFile2();
}

Expand All @@ -91,43 +103,146 @@ void Filter::writeFilterFile2(){
QFile file(filterFile);
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
QTextStream out(&file);
foreach(QString key, filters2.keys()){
out << '!' << key;
foreach(QRegularExpression exp, filters2.value(key)){
out << endl << exp.pattern();
QHashIterator<QString, QHash<QRegularExpression,QString>> i(filters2);
while(i.hasNext()){
i.next();
out << '!' << i.key();
QHashIterator<QRegularExpression,QString> j(i.value());
while(j.hasNext()){
j.next();
out << endl << j.key().pattern() << j.value();
}
out << endl << '!' << endl << endl;
}
}
}

void Filter::addFilter(QString &newFilter){
filters.insert(QRegularExpression(newFilter));
QString filterFile = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/qtchan/" + "filters.conf";
QFile file(filterFile);
if(file.open(QIODevice::WriteOnly | QIODevice::Append)){
newFilter.prepend("\n");
file.write(newFilter.toUtf8());
file.close();
}
}

bool Filter::filterMatched2(Post *p){
QHashIterator<QString, QSet<QRegularExpression>> i(filters2);
QHashIterator<QString, QHash<QRegularExpression,QString>> i(filters2);
while (i.hasNext()) {
i.next();
QString key = i.key();
QSet<QRegularExpression> set = i.value();
QString *temp = p->get(key);
foreach(QRegularExpression exp, set){
if(temp != Q_NULLPTR && !temp->isEmpty() && temp->contains(exp)){
QHashIterator<QRegularExpression,QString> j(i.value());
while(j.hasNext()){
j.next();
QRegularExpression exp = j.key();
//QString options = j.value();
//&& useFilter(options,p)
if(temp != Q_NULLPTR && temp->contains(exp))
return true;
}
}
}
return false;
}

bool Filter::useFilter(QString &options, Post *p){
if(options.isEmpty()) return true;
QStringList optionsList = options.split(';');
QVector<bool> useIt(optionsList.size(),false);
int i = 0;
foreach(QString option,optionsList){
if(option.isEmpty()) return true;
QStringList kvPairs = option.split(':');
if(kvPairs.size() != 2){
useIt.data()[i++] = true;
continue;
}
QString key = kvPairs.at(0);
QString values = kvPairs.at(1);
QStringList valuesList = values.split(',');
foreach(QString value, valuesList){
if(key == "boards"){
if(value == p->board){
useIt.data()[i] = true;
break;
}
}
else if(key == "op" && p->resto == 0){
if(value == "only" || value == "yes"){
useIt.data()[i] = true;
break;
}
else{
return false;
}
}
else if(key == "exclude"){
if(value == p->board) return false;
}
}
i++;
}
foreach(bool temp, useIt){
if(!temp) return false;
}
return true;
}

QHash<QString,QHash<QRegularExpression,QString>> Filter::filterMatchedPerTab(QString board, QString tabType){
QHashIterator<QString, QHash<QRegularExpression,QString>> i(filters2);
while (i.hasNext()) {
i.next();
QHash<QRegularExpression,QString> temp = i.value();
QHashIterator<QRegularExpression,QString> j(temp);
while(j.hasNext()){
j.next();
QString options = j.value();
//TODO build useFilters per tab instead of checking per post
if(!useFilterPerTab(options,board,tabType)) {
temp.remove(j.key());
}
}
filters2.insert(i.key(),temp);
}
return filters2;
}

bool Filter::useFilterPerTab(QString &options, QString board, QString tabType){
if(options.isEmpty()) return true;
QStringList optionsList = options.split(';');
QVector<bool> useIt(optionsList.size(),false);
int i = 0;
foreach(QString option,optionsList){
if(option.isEmpty()) return true;
QStringList kvPairs = option.split(':');
if(kvPairs.size() != 2){
useIt.data()[i++] = true;
continue;
}
QString key = kvPairs.at(0);
QString values = kvPairs.at(1);
QStringList valuesList = values.split(',');
foreach(QString value, valuesList){
if(key == "boards"){
if(value == board){
useIt.data()[i] = true;
break;
}
}
else if(key == "op"){
if(tabType == "board" && (value == "only" || value == "yes")){
useIt.data()[i] = true;
break;
}
else if(tabType == "thread" && value == "no"){
useIt.data()[i] = true;
break;
}
else return false;
}
else if(key == "exclude"){
if(value == board) return false;
}
}
i++;
}
foreach(bool temp, useIt){
if(!temp) return false;
}
return true;
}

bool Filter::filterMatched(QString post){
QSetIterator<QRegularExpression> i(filters);
while (i.hasNext()){
Expand All @@ -140,6 +255,17 @@ bool Filter::filterMatched(QString post){
return false;
}

void Filter::addFilter(QString &newFilter){
filters.insert(QRegularExpression(newFilter));
QString filterFile = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/qtchan/" + "filters.conf";
QFile file(filterFile);
if(file.open(QIODevice::WriteOnly | QIODevice::Append)){
newFilter.prepend("\n");
file.write(newFilter.toUtf8());
file.close();
}
}

/*
QSet<QString> Filter::crossthread(QString search) {
QRegularExpression quotelink;
Expand Down
5 changes: 4 additions & 1 deletion filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Filter
static QSet<QString> findQuotes(QString post);
bool filterMatched(QString post);
QSet<QRegularExpression> filters;
QHash<QString,QSet<QRegularExpression>> filters2;
QHash<QString,QHash<QRegularExpression,QString>> filters2;
static QRegularExpression quoteRegExp;
static QRegularExpression quotelinkRegExp;
static QString colorString;
Expand All @@ -36,12 +36,15 @@ class Filter
void addFilter2(QString key, QString newFilter);
bool filterMatched2(Post *p);
void loadFilterFile2();
QHash<QString,QHash<QRegularExpression,QString>> filterMatchedPerTab(QString board, QString tabType);
bool useFilterPerTab(QString &options, QString board, QString tabType);

private:
QRegularExpressionMatch quotelinkMatch;
QRegularExpressionMatchIterator quotelinkMatches;
void loadFilterFile();
void writeFilterFile2();
bool useFilter(QString &options, Post *p);
};

extern Filter filter;
Expand Down
1 change: 1 addition & 0 deletions post.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ QString* Post::get(QString key){
else if(key == "md5") return &md5;
else if(key == "size") return &size_img;
else if(key == "filename") return &filename;
else if(key == "country_name") return &country_name;
else return Q_NULLPTR;
}

Expand Down
8 changes: 5 additions & 3 deletions threadtabhelper.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "threadtabhelper.h"
#include "netcontroller.h"
#include "you.h"
#include "filter.h"
#include "notificationview.h"
#include <QJsonArray>

Expand Down Expand Up @@ -33,6 +32,8 @@ void ThreadTabHelper::startUp(Chan *api, QString &board, QString &thread, QWidge
this,&ThreadTabHelper::getPosts,UniqueDirect);
}

filterMe.filterMatchedPerTab(board,"thread");

//self-archive check
QFile jsonFile(board+"/"+thread+"/"+thread+".json");
if(jsonFile.exists() && jsonFile.open(QIODevice::ReadOnly)){
Expand Down Expand Up @@ -190,7 +191,7 @@ void ThreadTabHelper::loadPosts(QByteArray &postData, bool writeIt){
}
//Use another thread?
//if(filter.filterMatched(tf->matchThis()) || filter.filterMatched2(&(tf->post))){
if(filter.filterMatched2(&(tf->post))){
if(filterMe.filterMatched2(&(tf->post))){
tf->hidden=true;
}
emit newTF(tf);
Expand Down Expand Up @@ -233,8 +234,9 @@ void ThreadTabHelper::loadPosts(QByteArray &postData, bool writeIt){
}

void ThreadTabHelper::reloadFilters(){
filterMe.filters2 = filter.filterMatchedPerTab(this->board,"thread");
foreach(ThreadForm* tf,tfMap){
if(filter.filterMatched2(&(tf->post))){
if(filterMe.filterMatched2(&(tf->post))){
tf->hidden=true;
emit removeTF(tf);
}
Expand Down
2 changes: 2 additions & 0 deletions threadtabhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "threadform.h"
#include "chans.h"
#include "filter.h"
#include <QNetworkReply>
#include <QtConcurrent/QtConcurrent>
#include <QImage>
Expand All @@ -17,6 +18,7 @@ class ThreadTabHelper : public QObject
QString quoteString = "class=\\\"quote\\\" style=\\\"color:#897399\\\"";
QRegExp quotesRegExp;
QRegExp quotelinksRegExp;
Filter filterMe = filter;
public:
ThreadTabHelper();
~ThreadTabHelper();
Expand Down

1 comment on commit e599a9b

@siavash119
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to put in readme

~/.config/qtchan/filters2.conf

!key
regex (don't surround with or escape forward slashes; always case insensitive)
regex
regex$option:value,value;option:value
#comment
!

!sub
/yourbadgeneral/$boards:g;op:only
##all generals
general$op:only
!

!name
##name users
^(?!Anonymous$)$
!

!filename
##fap
#^$$
##work
#^(?!$)$
!

Please sign in to comment.