add premade filters option to article filters

This commit is contained in:
Martin Rotter 2022-11-21 09:05:17 +01:00
parent bcdbf9e988
commit 19c3577b6c
8 changed files with 245 additions and 132 deletions

View File

@ -60,7 +60,7 @@
<content_rating type="oars-1.0" /> <content_rating type="oars-1.0" />
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1" />
<releases> <releases>
<release version="4.2.5" date="2022-11-11" /> <release version="4.2.5" date="2022-11-21" />
</releases> </releases>
<provides> <provides>
<binary>rssguard</binary> <binary>rssguard</binary>

View File

@ -20,6 +20,9 @@
<file>scripts/adblock/adblock-server.js</file> <file>scripts/adblock/adblock-server.js</file>
<file>scripts/readability/readabilize-article.js</file> <file>scripts/readability/readabilize-article.js</file>
<file>scripts/filters/blacklist.js</file>
<file>scripts/filters/whitelist.js</file>
<file>graphics/rssguard.ico</file> <file>graphics/rssguard.ico</file>
<file>graphics/rssguard.png</file> <file>graphics/rssguard.png</file>

View File

@ -0,0 +1,15 @@
// This filter rejects all messages whose title
// is on the blacklist.
var blacklist = [
'abc',
'123'
];
function filterMessage() {
if (blacklist.some(i => msg.title.indexOf(i) != -1)) {
return MessageObject.Ignore;
} else {
return MessageObject.Accept;
}
}

View File

@ -0,0 +1,15 @@
// This filter accepts only messages whose title
// is on the whitelist.
var whitelist = [
'abc',
'123'
];
function filterMessage() {
if (whitelist.some(i => msg.title.indexOf(i) != -1)) {
return MessageObject.Accept;
} else {
return MessageObject.Ignore;
}
}

View File

@ -21,9 +21,11 @@
#include "services/abstract/feed.h" #include "services/abstract/feed.h"
#include "services/abstract/labelsnode.h" #include "services/abstract/labelsnode.h"
FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader, const QList<ServiceRoot*>& accounts, QWidget* parent) FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader,
: QDialog(parent), m_feedsModel(new AccountCheckSortedModel(this)), m_rootItem(new RootItem()), const QList<ServiceRoot*>& accounts,
m_accounts(accounts), m_reader(reader), m_loadingFilter(false), m_msgModel(new MessagesForFiltersModel(this)) { QWidget* parent)
: QDialog(parent), m_feedsModel(new AccountCheckSortedModel(this)), m_rootItem(new RootItem()), m_accounts(accounts),
m_reader(reader), m_loadingFilter(false), m_msgModel(new MessagesForFiltersModel(this)) {
m_ui.setupUi(this); m_ui.setupUi(this);
std::sort(m_accounts.begin(), m_accounts.end(), [](const ServiceRoot* lhs, const ServiceRoot* rhs) { std::sort(m_accounts.begin(), m_accounts.end(), [](const ServiceRoot* lhs, const ServiceRoot* rhs) {
@ -47,44 +49,58 @@ FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader, const Q
m_ui.m_txtScript->setFont(QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont)); m_ui.m_txtScript->setFont(QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont));
m_ui.m_treeExistingMessages->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); m_ui.m_treeExistingMessages->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_ISREAD, QHeaderView::ResizeMode::ResizeToContents); m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_ISREAD,
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_ISIMPORTANT, QHeaderView::ResizeMode::ResizeToContents); QHeaderView::ResizeMode::ResizeToContents);
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_ISDELETED, QHeaderView::ResizeMode::ResizeToContents); m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_ISIMPORTANT,
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_AUTHOR, QHeaderView::ResizeMode::ResizeToContents); QHeaderView::ResizeMode::ResizeToContents);
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_CREATED, QHeaderView::ResizeMode::ResizeToContents); m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_ISDELETED,
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_SCORE, QHeaderView::ResizeMode::ResizeToContents); QHeaderView::ResizeMode::ResizeToContents);
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_AUTHOR,
QHeaderView::ResizeMode::ResizeToContents);
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_CREATED,
QHeaderView::ResizeMode::ResizeToContents);
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_SCORE,
QHeaderView::ResizeMode::ResizeToContents);
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_TITLE, QHeaderView::ResizeMode::Interactive); m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_TITLE, QHeaderView::ResizeMode::Interactive);
m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_URL, QHeaderView::ResizeMode::Interactive); m_ui.m_treeExistingMessages->header()->setSectionResizeMode(MFM_MODEL_URL, QHeaderView::ResizeMode::Interactive);
connect(m_ui.m_btnDetailedHelp, &QPushButton::clicked, this, []() { connect(m_ui.m_btnDetailedHelp, &QPushButton::clicked, this, []() {
qApp->web()->openUrlInExternalBrowser(QSL(MSG_FILTERING_HELP)); qApp->web()->openUrlInExternalBrowser(QSL(MSG_FILTERING_HELP));
}); });
connect(m_ui.m_listFilters, &QListWidget::currentRowChanged, connect(m_ui.m_listFilters, &QListWidget::currentRowChanged, this, &FormMessageFiltersManager::loadFilter);
this, &FormMessageFiltersManager::loadFilter);
connect(m_ui.m_btnAddNew, &QPushButton::clicked, this, [this]() { connect(m_ui.m_btnAddNew, &QPushButton::clicked, this, [this]() {
addNewFilter(); addNewFilter();
}); });
connect(m_ui.m_btnRemoveSelected, &QPushButton::clicked, connect(m_ui.m_btnRemoveSelected, &QPushButton::clicked, this, &FormMessageFiltersManager::removeSelectedFilter);
this, &FormMessageFiltersManager::removeSelectedFilter);
connect(m_ui.m_txtTitle, &QLineEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter); connect(m_ui.m_txtTitle, &QLineEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter);
connect(m_ui.m_txtScript, &QPlainTextEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter); connect(m_ui.m_txtScript, &QPlainTextEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter);
connect(m_ui.m_btnTest, &QPushButton::clicked, this, &FormMessageFiltersManager::testFilter); connect(m_ui.m_btnTest, &QPushButton::clicked, this, &FormMessageFiltersManager::testFilter);
connect(m_ui.m_btnBeautify, &QPushButton::clicked, this, &FormMessageFiltersManager::beautifyScript); connect(m_ui.m_btnBeautify, &QPushButton::clicked, this, &FormMessageFiltersManager::beautifyScript);
connect(m_ui.m_cmbAccounts, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), connect(m_ui.m_cmbAccounts,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, this,
&FormMessageFiltersManager::onAccountChanged); &FormMessageFiltersManager::onAccountChanged);
connect(m_ui.m_btnCheckAll, &QPushButton::clicked, m_feedsModel->sourceModel(), &AccountCheckModel::checkAllItems); connect(m_ui.m_btnCheckAll, &QPushButton::clicked, m_feedsModel->sourceModel(), &AccountCheckModel::checkAllItems);
connect(m_ui.m_btnUncheckAll, &QPushButton::clicked, m_feedsModel->sourceModel(), &AccountCheckModel::uncheckAllItems); connect(m_ui.m_btnUncheckAll,
connect(m_feedsModel->sourceModel(), &AccountCheckModel::checkStateChanged, &QPushButton::clicked,
this, &FormMessageFiltersManager::onFeedChecked); m_feedsModel->sourceModel(),
connect(m_ui.m_treeFeeds->selectionModel(), &QItemSelectionModel::selectionChanged, &AccountCheckModel::uncheckAllItems);
this, &FormMessageFiltersManager::displayMessagesOfFeed); connect(m_feedsModel->sourceModel(),
connect(m_ui.m_btnRunOnMessages, &QPushButton::clicked, &AccountCheckModel::checkStateChanged,
this, &FormMessageFiltersManager::processCheckedFeeds); this,
connect(m_ui.m_treeExistingMessages, &QTreeView::customContextMenuRequested, &FormMessageFiltersManager::onFeedChecked);
this, &FormMessageFiltersManager::showMessageContextMenu); connect(m_ui.m_treeFeeds->selectionModel(),
&QItemSelectionModel::selectionChanged,
this,
&FormMessageFiltersManager::displayMessagesOfFeed);
connect(m_ui.m_btnRunOnMessages, &QPushButton::clicked, this, &FormMessageFiltersManager::processCheckedFeeds);
connect(m_ui.m_treeExistingMessages,
&QTreeView::customContextMenuRequested,
this,
&FormMessageFiltersManager::showMessageContextMenu);
initializeTestingMessage(); initializeTestingMessage();
initializePremadeFilters();
loadFilters(); loadFilters();
loadFilter(); loadFilter();
loadAccounts(); loadAccounts();
@ -110,7 +126,8 @@ ServiceRoot* FormMessageFiltersManager::selectedAccount() const {
} }
void FormMessageFiltersManager::filterMessagesLikeThis(const Message& msg) { void FormMessageFiltersManager::filterMessagesLikeThis(const Message& msg) {
QString filter_script = QSL("function filterMessage() {\n" QString filter_script =
QSL("function filterMessage() {\n"
" // Adjust the condition to suit your needs.\n" " // Adjust the condition to suit your needs.\n"
" var is_message_same =\n" " var is_message_same =\n"
" msg.isRead == %1 &&\n" " msg.isRead == %1 &&\n"
@ -124,10 +141,8 @@ void FormMessageFiltersManager::filterMessagesLikeThis(const Message& msg) {
" else {\n" " else {\n"
" return MessageObject.Ignore;\n" " return MessageObject.Ignore;\n"
" }\n" " }\n"
"}").arg(QString::number(int(msg.m_isRead)), "}")
QString::number(int(msg.m_isImportant)), .arg(QString::number(int(msg.m_isRead)), QString::number(int(msg.m_isImportant)), msg.m_title, msg.m_url);
msg.m_title,
msg.m_url);
addNewFilter(filter_script); addNewFilter(filter_script);
} }
@ -152,9 +167,12 @@ void FormMessageFiltersManager::removeSelectedFilter() {
return; return;
} }
if (MsgBox::show(this, QMessageBox::Icon::Question, tr("Are you sure?"), if (MsgBox::show(this,
QMessageBox::Icon::Question,
tr("Are you sure?"),
tr("Do you really want to remove selected filter?"), tr("Do you really want to remove selected filter?"),
{}, fltr->name(), {},
fltr->name(),
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No,
QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes) { QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes) {
m_reader->removeMessageFilter(fltr); m_reader->removeMessageFilter(fltr);
@ -174,8 +192,7 @@ void FormMessageFiltersManager::loadFilters() {
void FormMessageFiltersManager::addNewFilter(const QString& filter_script) { void FormMessageFiltersManager::addNewFilter(const QString& filter_script) {
try { try {
auto* fltr = m_reader->addMessageFilter( auto* fltr = m_reader->addMessageFilter(tr("New article filter"),
tr("New article filter"),
filter_script.isEmpty() filter_script.isEmpty()
? QSL("function filterMessage() { return MessageObject.Accept; }") ? QSL("function filterMessage() { return MessageObject.Accept; }")
: filter_script); : filter_script);
@ -186,7 +203,9 @@ void FormMessageFiltersManager::addNewFilter(const QString& filter_script) {
m_ui.m_listFilters->setCurrentRow(m_ui.m_listFilters->count() - 1); m_ui.m_listFilters->setCurrentRow(m_ui.m_listFilters->count() - 1);
} }
catch (const ApplicationException& ex) { catch (const ApplicationException& ex) {
MsgBox::show(this, QMessageBox::Icon::Critical, tr("Error"), MsgBox::show(this,
QMessageBox::Icon::Critical,
tr("Error"),
tr("Cannot save new filter, error: '%1'.").arg(ex.message())); tr("Cannot save new filter, error: '%1'.").arg(ex.message()));
} }
} }
@ -226,12 +245,9 @@ void FormMessageFiltersManager::testFilter() {
QJSEngine filter_engine; QJSEngine filter_engine;
QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className()); QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className());
MessageObject msg_obj(&database, MessageObject msg_obj(&database,
selected_fd_cat->kind() == RootItem::Kind::Feed selected_fd_cat->kind() == RootItem::Kind::Feed ? selected_fd_cat->customId()
? selected_fd_cat->customId()
: QString::number(NO_PARENT_CATEGORY), : QString::number(NO_PARENT_CATEGORY),
selectedAccount() != nullptr selectedAccount() != nullptr ? selectedAccount()->accountId() : NO_PARENT_CATEGORY,
? selectedAccount()->accountId()
: NO_PARENT_CATEGORY,
selected_fd_cat->getParentServiceRoot()->labelsNode()->labels(), selected_fd_cat->getParentServiceRoot()->labelsNode()->labels(),
false); false);
auto* fltr = selectedFilter(); auto* fltr = selectedFilter();
@ -258,11 +274,11 @@ void FormMessageFiltersManager::testFilter() {
try { try {
MessageObject::FilteringAction decision = fltr->filterMessage(&filter_engine); MessageObject::FilteringAction decision = fltr->filterMessage(&filter_engine);
m_ui.m_txtErrors->setTextColor(decision == MessageObject::FilteringAction::Accept ? Qt::GlobalColor::darkGreen : Qt::GlobalColor::red); m_ui.m_txtErrors->setTextColor(decision == MessageObject::FilteringAction::Accept ? Qt::GlobalColor::darkGreen
: Qt::GlobalColor::red);
QString answer = tr("Article will be %1.\n\n").arg(decision == MessageObject::FilteringAction::Accept QString answer = tr("Article will be %1.\n\n")
? tr("ACCEPTED") .arg(decision == MessageObject::FilteringAction::Accept ? tr("ACCEPTED") : tr("REJECTED"));
: tr("REJECTED"));
answer += tr("Output (modified) article is:\n" answer += tr("Output (modified) article is:\n"
" Title = '%1'\n" " Title = '%1'\n"
@ -271,7 +287,10 @@ void FormMessageFiltersManager::testFilter() {
" Is read/important = '%4/%5'\n" " Is read/important = '%4/%5'\n"
" Created on = '%6'\n" " Created on = '%6'\n"
" Contents = '%7'\n" " Contents = '%7'\n"
" RAW contents = '%8'").arg(msg.m_title, msg.m_url, msg.m_author, " RAW contents = '%8'")
.arg(msg.m_title,
msg.m_url,
msg.m_author,
msg.m_isRead ? tr("yes") : tr("no"), msg.m_isRead ? tr("yes") : tr("no"),
msg.m_isImportant ? tr("yes") : tr("no"), msg.m_isImportant ? tr("yes") : tr("no"),
QString::number(msg.m_created.toMSecsSinceEpoch()), QString::number(msg.m_created.toMSecsSinceEpoch()),
@ -324,7 +343,8 @@ void FormMessageFiltersManager::processCheckedFeeds() {
auto labels_in_message = DatabaseQueries::getLabelsForMessage(database, msgs[i], msg_obj.availableLabels()); auto labels_in_message = DatabaseQueries::getLabelsForMessage(database, msgs[i], msg_obj.availableLabels());
// Create backup of message. // Create backup of message.
Message* msg = &msgs[i]; msg->m_assignedLabels = labels_in_message; Message* msg = &msgs[i];
msg->m_assignedLabels = labels_in_message;
msg->m_rawContents = Message::generateRawAtomContents(*msg); msg->m_rawContents = Message::generateRawAtomContents(*msg);
@ -349,21 +369,22 @@ void FormMessageFiltersManager::processCheckedFeeds() {
} }
} }
catch (const FilteringException& ex) { catch (const FilteringException& ex) {
qCriticalNN << LOGSEC_CORE qCriticalNN << LOGSEC_CORE << "Error when running script when processing existing messages:"
<< "Error when running script when processing existing messages:"
<< QUOTE_W_SPACE_DOT(ex.message()); << QUOTE_W_SPACE_DOT(ex.message());
continue; continue;
} }
if (!msg_backup.m_isRead && msg->m_isRead) { if (!msg_backup.m_isRead && msg->m_isRead) {
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Message with custom ID: '" << msg_backup.m_customId << "' was marked as read by message scripts."; qDebugNN << LOGSEC_FEEDDOWNLOADER << "Message with custom ID: '" << msg_backup.m_customId
<< "' was marked as read by message scripts.";
read_msgs << *msg; read_msgs << *msg;
} }
if (!msg_backup.m_isImportant && msg->m_isImportant) { if (!msg_backup.m_isImportant && msg->m_isImportant) {
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Message with custom ID: '" << msg_backup.m_customId << "' was marked as important by message scripts."; qDebugNN << LOGSEC_FEEDDOWNLOADER << "Message with custom ID: '" << msg_backup.m_customId
<< "' was marked as important by message scripts.";
important_msgs << *msg; important_msgs << *msg;
} }
@ -374,10 +395,8 @@ void FormMessageFiltersManager::processCheckedFeeds() {
// Label is not there anymore, it was deassigned. // Label is not there anymore, it was deassigned.
lbl->deassignFromMessage(*msg); lbl->deassignFromMessage(*msg);
qDebugNN << LOGSEC_FEEDDOWNLOADER qDebugNN << LOGSEC_FEEDDOWNLOADER << "It was detected that label" << QUOTE_W_SPACE(lbl->customId())
<< "It was detected that label" << QUOTE_W_SPACE(lbl->customId()) << "was DEASSIGNED from message" << QUOTE_W_SPACE(msg->m_customId) << "by message filter(s).";
<< "was DEASSIGNED from message" << QUOTE_W_SPACE(msg->m_customId)
<< "by message filter(s).";
} }
} }
@ -387,10 +406,8 @@ void FormMessageFiltersManager::processCheckedFeeds() {
// was newly assigned. // was newly assigned.
lbl->assignToMessage(*msg); lbl->assignToMessage(*msg);
qDebugNN << LOGSEC_FEEDDOWNLOADER qDebugNN << LOGSEC_FEEDDOWNLOADER << "It was detected that label" << QUOTE_W_SPACE(lbl->customId())
<< "It was detected that label" << QUOTE_W_SPACE(lbl->customId()) << "was ASSIGNED to message" << QUOTE_W_SPACE(msg->m_customId) << "by message filter(s).";
<< "was ASSIGNED to message" << QUOTE_W_SPACE(msg->m_customId)
<< "by message filter(s).";
} }
} }
@ -403,8 +420,7 @@ void FormMessageFiltersManager::processCheckedFeeds() {
if (!read_msgs.isEmpty()) { if (!read_msgs.isEmpty()) {
// Now we push new read states to the service. // Now we push new read states to the service.
if (it->getParentServiceRoot()->onBeforeSetMessagesRead(it, read_msgs, RootItem::ReadStatus::Read)) { if (it->getParentServiceRoot()->onBeforeSetMessagesRead(it, read_msgs, RootItem::ReadStatus::Read)) {
qDebugNN << LOGSEC_FEEDDOWNLOADER qDebugNN << LOGSEC_FEEDDOWNLOADER << "Notified services about messages marked as read by message filters.";
<< "Notified services about messages marked as read by message filters.";
} }
else { else {
qCriticalNN << LOGSEC_FEEDDOWNLOADER qCriticalNN << LOGSEC_FEEDDOWNLOADER
@ -414,9 +430,11 @@ void FormMessageFiltersManager::processCheckedFeeds() {
if (!important_msgs.isEmpty()) { if (!important_msgs.isEmpty()) {
// Now we push new read states to the service. // Now we push new read states to the service.
auto list = boolinq::from(important_msgs).select([](const Message& msg) { auto list = boolinq::from(important_msgs)
.select([](const Message& msg) {
return ImportanceChange(msg, RootItem::Importance::Important); return ImportanceChange(msg, RootItem::Importance::Important);
}).toStdList(); })
.toStdList();
QList<ImportanceChange> chngs = FROM_STD_LIST(QList<ImportanceChange>, list); QList<ImportanceChange> chngs = FROM_STD_LIST(QList<ImportanceChange>, list);
if (it->getParentServiceRoot()->onBeforeSwitchMessageImportance(it, chngs)) { if (it->getParentServiceRoot()->onBeforeSwitchMessageImportance(it, chngs)) {
@ -538,18 +556,18 @@ void FormMessageFiltersManager::beautifyScript() {
QProcess proc_clang_format(this); QProcess proc_clang_format(this);
proc_clang_format.setInputChannelMode(QProcess::InputChannelMode::ManagedInputChannel); proc_clang_format.setInputChannelMode(QProcess::InputChannelMode::ManagedInputChannel);
proc_clang_format.setArguments({ "--assume-filename=script.js", "--style=Chromium" }); proc_clang_format.setArguments({"--assume-filename=script.js", "--style=Chromium"});
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
proc_clang_format.setProgram(qApp->applicationDirPath() + QDir::separator() + proc_clang_format.setProgram(qApp->applicationDirPath() + QDir::separator() + QSL("clang-format") +
QSL("clang-format") + QDir::separator() + QDir::separator() + QSL("clang-format.exe"));
QSL("clang-format.exe"));
#else #else
proc_clang_format.setProgram(QSL("clang-format")); proc_clang_format.setProgram(QSL("clang-format"));
#endif #endif
if (!proc_clang_format.open() || proc_clang_format.error() == QProcess::ProcessError::FailedToStart) { if (!proc_clang_format.open() || proc_clang_format.error() == QProcess::ProcessError::FailedToStart) {
MsgBox::show(this, QMessageBox::Icon::Critical, MsgBox::show(this,
QMessageBox::Icon::Critical,
tr("Cannot find 'clang-format'"), tr("Cannot find 'clang-format'"),
tr("Script was not beautified, because 'clang-format' tool was not found.")); tr("Script was not beautified, because 'clang-format' tool was not found."));
return; return;
@ -567,7 +585,8 @@ void FormMessageFiltersManager::beautifyScript() {
else { else {
auto err = proc_clang_format.readAllStandardError(); auto err = proc_clang_format.readAllStandardError();
MsgBox::show(this, QMessageBox::Icon::Critical, MsgBox::show(this,
QMessageBox::Icon::Critical,
tr("Error"), tr("Error"),
tr("Script was not beautified, because 'clang-format' tool thrown error."), tr("Script was not beautified, because 'clang-format' tool thrown error."),
QString(), QString(),
@ -576,12 +595,37 @@ void FormMessageFiltersManager::beautifyScript() {
} }
else { else {
proc_clang_format.kill(); proc_clang_format.kill();
MsgBox::show(this, QMessageBox::Icon::Critical, MsgBox::show(this,
QMessageBox::Icon::Critical,
tr("Beautifier was running for too long time"), tr("Beautifier was running for too long time"),
tr("Script was not beautified, is 'clang-format' installed?")); tr("Script was not beautified, is 'clang-format' installed?"));
} }
} }
void FormMessageFiltersManager::insertPremadeFilter(QAction* act_filter) {
QString filter_path = QSL(":/scripts/filters/") + act_filter->text();
try {
m_ui.m_txtScript->setPlainText(QString::fromUtf8(IOFactory::readFile(filter_path)));
}
catch (...) {
}
}
void FormMessageFiltersManager::initializePremadeFilters() {
QMenu* mn_filters = new QMenu(this);
connect(mn_filters, &QMenu::triggered, this, &FormMessageFiltersManager::insertPremadeFilter);
auto js_files = QDir(QSL(":/scripts/filters")).entryList();
for (const QString& js_file : js_files) {
mn_filters->addAction(js_file);
}
m_ui.m_btnPremadeFilters->setMenu(mn_filters);
}
void FormMessageFiltersManager::initializeTestingMessage() { void FormMessageFiltersManager::initializeTestingMessage() {
m_ui.m_cbSampleImportant->setChecked(true); m_ui.m_cbSampleImportant->setChecked(true);
m_ui.m_txtSampleUrl->setText(QSL("https://mynews.com/news/5")); m_ui.m_txtSampleUrl->setText(QSL("https://mynews.com/news/5"));

View File

@ -18,7 +18,9 @@ class FormMessageFiltersManager : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit FormMessageFiltersManager(FeedReader* reader, const QList<ServiceRoot*>& accounts, QWidget* parent = nullptr); explicit FormMessageFiltersManager(FeedReader* reader,
const QList<ServiceRoot*>& accounts,
QWidget* parent = nullptr);
virtual ~FormMessageFiltersManager(); virtual ~FormMessageFiltersManager();
MessageFilter* selectedFilter() const; MessageFilter* selectedFilter() const;
@ -48,9 +50,12 @@ class FormMessageFiltersManager : public QDialog {
// Display filter title/contents. // Display filter title/contents.
void showFilter(MessageFilter* filter); void showFilter(MessageFilter* filter);
void insertPremadeFilter(QAction* act_filter);
private: private:
void loadAccounts(); void loadAccounts();
void beautifyScript(); void beautifyScript();
void initializePremadeFilters();
void initializeTestingMessage(); void initializeTestingMessage();
RootItem* selectedCategoryFeed() const; RootItem* selectedCategoryFeed() const;

View File

@ -126,6 +126,8 @@
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="m_txtTitle"> <widget class="QLineEdit" name="m_txtTitle">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -144,6 +146,28 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="m_btnPremadeFilters">
<property name="text">
<string>Pre-made filters</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
@ -430,6 +454,7 @@
<tabstop>m_btnCheckAll</tabstop> <tabstop>m_btnCheckAll</tabstop>
<tabstop>m_btnUncheckAll</tabstop> <tabstop>m_btnUncheckAll</tabstop>
<tabstop>m_txtTitle</tabstop> <tabstop>m_txtTitle</tabstop>
<tabstop>m_btnPremadeFilters</tabstop>
<tabstop>m_txtScript</tabstop> <tabstop>m_txtScript</tabstop>
<tabstop>m_btnTest</tabstop> <tabstop>m_btnTest</tabstop>
<tabstop>m_btnRunOnMessages</tabstop> <tabstop>m_btnRunOnMessages</tabstop>
@ -437,6 +462,14 @@
<tabstop>m_btnDetailedHelp</tabstop> <tabstop>m_btnDetailedHelp</tabstop>
<tabstop>m_twMessages</tabstop> <tabstop>m_twMessages</tabstop>
<tabstop>m_treeExistingMessages</tabstop> <tabstop>m_treeExistingMessages</tabstop>
<tabstop>m_txtSampleTitle</tabstop>
<tabstop>m_txtSampleUrl</tabstop>
<tabstop>m_txtSampleAuthor</tabstop>
<tabstop>m_txtSampleCreatedOn</tabstop>
<tabstop>m_txtSampleContents</tabstop>
<tabstop>m_cbSampleRead</tabstop>
<tabstop>m_cbSampleImportant</tabstop>
<tabstop>m_txtErrors</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections> <connections>

View File

@ -13,8 +13,8 @@
#include <utility> #include <utility>
FeedParser::FeedParser(QString data, bool is_xml) : m_isXml(is_xml), m_data(std::move(data)), FeedParser::FeedParser(QString data, bool is_xml)
m_mrssNamespace(QSL("http://search.yahoo.com/mrss/")) { : m_isXml(is_xml), m_data(std::move(data)), m_mrssNamespace(QSL("http://search.yahoo.com/mrss/")) {
if (m_isXml) { if (m_isXml) {
// XML. // XML.
@ -109,9 +109,7 @@ QList<Message> FeedParser::messages() {
messages.append(new_message); messages.append(new_message);
} }
catch (const ApplicationException& ex) { catch (const ApplicationException& ex) {
qDebugNN << LOGSEC_CORE qDebugNN << LOGSEC_CORE << "Problem when extracting XML message: " << ex.message();
<< "Problem when extracting XML message: "
<< ex.message();
} }
} }
} }
@ -137,9 +135,7 @@ QList<Message> FeedParser::messages() {
messages.append(new_message); messages.append(new_message);
} }
catch (const ApplicationException& ex) { catch (const ApplicationException& ex) {
qDebugNN << LOGSEC_CORE qDebugNN << LOGSEC_CORE << "Problem when extracting JSON message: " << ex.message();
<< "Problem when extracting JSON message: "
<< ex.message();
} }
} }
} }
@ -249,8 +245,10 @@ QString FeedParser::xmlRawChild(const QDomElement& container) const {
return raw; return raw;
} }
QStringList FeedParser::xmlTextsFromPath(const QDomElement& element, const QString& namespace_uri, QStringList FeedParser::xmlTextsFromPath(const QDomElement& element,
const QString& xml_path, bool only_first) const { const QString& namespace_uri,
const QString& xml_path,
bool only_first) const {
QStringList paths = xml_path.split('/'); QStringList paths = xml_path.split('/');
QStringList result; QStringList result;
QList<QDomElement> current_elements; QList<QDomElement> current_elements;