Work on filters, some code cleanups.

This commit is contained in:
Martin Rotter 2020-06-23 20:57:05 +02:00
parent b02232a58a
commit 7017aa9e66
14 changed files with 74 additions and 32 deletions

View File

@ -4,7 +4,7 @@ APP_REVERSE_NAME = "com.github.rssguard"
APP_LOW_H_NAME = ".rssguard" APP_LOW_H_NAME = ".rssguard"
APP_AUTHOR = "Martin Rotter" APP_AUTHOR = "Martin Rotter"
APP_COPYRIGHT = "(C) 2011-2020 $$APP_AUTHOR" APP_COPYRIGHT = "(C) 2011-2020 $$APP_AUTHOR"
APP_VERSION = "3.6.3" APP_VERSION = "3.7.0"
APP_LONG_NAME = "$$APP_NAME $$APP_VERSION" APP_LONG_NAME = "$$APP_NAME $$APP_VERSION"
APP_EMAIL = "rotter.martinos@gmail.com" APP_EMAIL = "rotter.martinos@gmail.com"
APP_URL = "https://github.com/martinrotter/rssguard" APP_URL = "https://github.com/martinrotter/rssguard"

View File

@ -31,7 +31,7 @@ bool FeedDownloader::isUpdateRunning() const {
return !m_feeds.isEmpty(); return !m_feeds.isEmpty();
} }
void FeedDownloader::updateAvailableFeeds(const QList<MessageFilter*>& msg_filters) { void FeedDownloader::updateAvailableFeeds() {
for (const Feed* feed : m_feeds) { for (const Feed* feed : m_feeds) {
auto* cache = dynamic_cast<CacheForServiceRoot*>(feed->getParentServiceRoot()); auto* cache = dynamic_cast<CacheForServiceRoot*>(feed->getParentServiceRoot());
@ -42,11 +42,11 @@ void FeedDownloader::updateAvailableFeeds(const QList<MessageFilter*>& msg_filte
} }
while (!m_feeds.isEmpty()) { while (!m_feeds.isEmpty()) {
updateOneFeed(m_feeds.takeFirst(), msg_filters); updateOneFeed(m_feeds.takeFirst());
} }
} }
void FeedDownloader::updateFeeds(const QList<Feed*>& feeds, const QList<MessageFilter*>& msg_filters) { void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
QMutexLocker locker(m_mutex); QMutexLocker locker(m_mutex);
if (feeds.isEmpty()) { if (feeds.isEmpty()) {
@ -62,7 +62,7 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds, const QList<MessageF
// Job starts now. // Job starts now.
emit updateStarted(); emit updateStarted();
updateAvailableFeeds(msg_filters); updateAvailableFeeds();
} }
finalizeUpdate(); finalizeUpdate();
@ -73,7 +73,7 @@ void FeedDownloader::stopRunningUpdate() {
m_feedsOriginalCount = m_feedsUpdated = 0; m_feedsOriginalCount = m_feedsUpdated = 0;
} }
void FeedDownloader::updateOneFeed(Feed* feed, const QList<MessageFilter*>& msg_filters) { void FeedDownloader::updateOneFeed(Feed* feed) {
qDebug().nospace() << "Downloading new messages for feed ID " qDebug().nospace() << "Downloading new messages for feed ID "
<< feed->customId() << " URL: " << feed->url() << " title: " << feed->title() << " in thread: \'" << feed->customId() << " URL: " << feed->url() << " title: " << feed->title() << " in thread: \'"
<< QThread::currentThreadId() << "\'."; << QThread::currentThreadId() << "\'.";
@ -101,7 +101,7 @@ void FeedDownloader::updateOneFeed(Feed* feed, const QList<MessageFilter*>& msg_
.remove(QRegularExpression(QSL("([\\n\\r])|(^\\s)"))); .remove(QRegularExpression(QSL("([\\n\\r])|(^\\s)")));
} }
if (!msg_filters.isEmpty()) { if (!feed->filters().isEmpty()) {
// Perform per-message filtering. // Perform per-message filtering.
QJSEngine filter_engine; QJSEngine filter_engine;
@ -117,7 +117,19 @@ void FeedDownloader::updateOneFeed(Feed* feed, const QList<MessageFilter*>& msg_
// Attach live message object to wrapper. // Attach live message object to wrapper.
msg_obj.setMessage(&msgs[i]); msg_obj.setMessage(&msgs[i]);
for (MessageFilter* msg_filter : msg_filters) { auto feed_filters = feed->filters();
for (int i = 0; i < feed_filters.size(); i++) {
QPointer<MessageFilter> filter = feed_filters.at(i);
if (filter.isNull()) {
qWarning("Message filter was probably deleted, removing its pointer from list of filters.");
feed_filters.removeAt(i--);
continue;
}
MessageFilter* msg_filter = filter.data();
// Call the filtering logic, given function must return integer value from // Call the filtering logic, given function must return integer value from
// FilteringAction enumeration. // FilteringAction enumeration.
// //
@ -129,10 +141,12 @@ void FeedDownloader::updateOneFeed(Feed* feed, const QList<MessageFilter*>& msg_
switch (decision) { switch (decision) {
case FilteringAction::Accept: case FilteringAction::Accept:
// Message is normally accepted, it could be tweaked by the filter. // Message is normally accepted, it could be tweaked by the filter.
continue; continue;
case FilteringAction::Ignore: case FilteringAction::Ignore:
// Remove the message, we do not want it. // Remove the message, we do not want it.
msgs.removeAt(i--); msgs.removeAt(i--);
break; break;

View File

@ -41,7 +41,7 @@ class FeedDownloader : public QObject {
bool isUpdateRunning() const; bool isUpdateRunning() const;
public slots: public slots:
void updateFeeds(const QList<Feed*>& feeds, const QList<MessageFilter*>& msg_filters); void updateFeeds(const QList<Feed*>& feeds);
void stopRunningUpdate(); void stopRunningUpdate();
signals: signals:
@ -50,8 +50,8 @@ class FeedDownloader : public QObject {
void updateProgress(const Feed* feed, int current, int total); void updateProgress(const Feed* feed, int current, int total);
private: private:
void updateOneFeed(Feed* feed, const QList<MessageFilter*>& msg_filters); void updateOneFeed(Feed* feed);
void updateAvailableFeeds(const QList<MessageFilter*>& msg_filters); void updateAvailableFeeds();
void finalizeUpdate(); void finalizeUpdate();
QList<Feed*> m_feeds; QList<Feed*> m_feeds;

View File

@ -229,7 +229,7 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const {
QDateTime dt = TextFactory::parseDateTime(QSqlQueryModel::data(idx, role).value<qint64>()).toLocalTime(); QDateTime dt = TextFactory::parseDateTime(QSqlQueryModel::data(idx, role).value<qint64>()).toLocalTime();
if (m_customDateFormat.isEmpty()) { if (m_customDateFormat.isEmpty()) {
return dt.toString(Qt::DefaultLocaleShortDate); return QLocale().toString(dt, QLocale::FormatType::ShortFormat);
} }
else { else {
return dt.toString(m_customDateFormat); return dt.toString(m_customDateFormat);

View File

@ -72,8 +72,8 @@ void FormAbout::loadLicenseAndInformation() {
m_ui.m_lblDesc->setText(tr("<b>%8</b><br>" "<b>Version:</b> %1 (built on %2/%3)<br>" "<b>Revision:</b> %4<br>" "<b>Build date:</b> %5<br>" m_ui.m_lblDesc->setText(tr("<b>%8</b><br>" "<b>Version:</b> %1 (built on %2/%3)<br>" "<b>Revision:</b> %4<br>" "<b>Build date:</b> %5<br>"
"<b>Qt:</b> %6 (compiled against %7)<br>").arg( "<b>Qt:</b> %6 (compiled against %7)<br>").arg(
qApp->applicationVersion(), APP_SYSTEM_NAME, APP_SYSTEM_VERSION, APP_REVISION, qApp->applicationVersion(), APP_SYSTEM_NAME, APP_SYSTEM_VERSION, APP_REVISION,
TextFactory::parseDateTime(QString("%1 %2").arg(__DATE__, QLocale().toString(TextFactory::parseDateTime(QString("%1 %2").arg(__DATE__, __TIME__)),
__TIME__)).toString(Qt::DefaultLocaleShortDate), QLocale::FormatType::ShortFormat),
qVersion(), QT_VERSION_STR, qVersion(), QT_VERSION_STR,
APP_NAME)); APP_NAME));
m_ui.m_txtInfo->setText(tr("<body>%5 is a (very) tiny feed reader." m_ui.m_txtInfo->setText(tr("<body>%5 is a (very) tiny feed reader."

View File

@ -127,7 +127,7 @@ void WebViewer::loadMessages(const QList<Message>& messages, RootItem* root) {
message.m_author), message.m_author),
message.m_url, message.m_url,
message.m_contents, message.m_contents,
message.m_created.toString(Qt::DefaultLocaleShortDate), QLocale().toString(message.m_created, QLocale::FormatType::ShortFormat),
enclosures, enclosures,
message.m_isRead ? "mark-unread" : "mark-read", message.m_isRead ? "mark-unread" : "mark-read",
message.m_isImportant ? "mark-unstarred" : "mark-starred", message.m_isImportant ? "mark-unstarred" : "mark-starred",
@ -201,11 +201,11 @@ bool WebViewer::eventFilter(QObject* object, QEvent* event) {
QWheelEvent* wh_event = static_cast<QWheelEvent*>(event); QWheelEvent* wh_event = static_cast<QWheelEvent*>(event);
if ((wh_event->modifiers() & Qt::KeyboardModifier::ControlModifier) > 0) { if ((wh_event->modifiers() & Qt::KeyboardModifier::ControlModifier) > 0) {
if (wh_event->delta() > 0) { if (wh_event->angleDelta().y() > 0) {
increaseWebPageZoom(); increaseWebPageZoom();
return true; return true;
} }
else if (wh_event->delta() < 0) { else if (wh_event->angleDelta().y() < 0) {
decreaseWebPageZoom(); decreaseWebPageZoom();
return true; return true;
} }

View File

@ -10,7 +10,7 @@ class ExternalTool {
public: public:
explicit ExternalTool(); explicit ExternalTool();
ExternalTool(const ExternalTool& other); ExternalTool(const ExternalTool& other);
explicit ExternalTool(QString executable, QStringList parameters); explicit ExternalTool(QString executable, QStringList parameters);
QString toString(); QString toString();
QString executable() const; QString executable() const;

View File

@ -75,7 +75,6 @@ void FeedReader::updateFeeds(const QList<Feed*>& feeds) {
m_feedDownloader = new FeedDownloader(); m_feedDownloader = new FeedDownloader();
// Downloader setup. // Downloader setup.
qRegisterMetaType<QList<MessageFilter*>>("QList<MessageFilter*>");
qRegisterMetaType<QList<Feed*>>("QList<Feed*>"); qRegisterMetaType<QList<Feed*>>("QList<Feed*>");
m_feedDownloader->moveToThread(m_feedDownloaderThread); m_feedDownloader->moveToThread(m_feedDownloaderThread);
@ -92,8 +91,7 @@ void FeedReader::updateFeeds(const QList<Feed*>& feeds) {
QMetaObject::invokeMethod(m_feedDownloader, "updateFeeds", QMetaObject::invokeMethod(m_feedDownloader, "updateFeeds",
Qt::ConnectionType::QueuedConnection, Qt::ConnectionType::QueuedConnection,
Q_ARG(QList<Feed*>, feeds), Q_ARG(QList<Feed*>, feeds));
Q_ARG(QList<MessageFilter*>, m_messageFilters));
} }
void FeedReader::updateAutoUpdateStatus() { void FeedReader::updateAutoUpdateStatus() {
@ -130,6 +128,12 @@ int FeedReader::autoUpdateInitialInterval() const {
return m_globalAutoUpdateInitialInterval; return m_globalAutoUpdateInitialInterval;
} }
void FeedReader::loadSaveMessageFilters() {
// TODO: Load all message filters from database.
// All plugin services will hook active filters to
// all feeds.
}
void FeedReader::updateAllFeeds() { void FeedReader::updateAllFeeds() {
updateFeeds(m_feedsModel->rootItem()->getSubTreeFeeds()); updateFeeds(m_feedsModel->rootItem()->getSubTreeFeeds());
} }

View File

@ -26,8 +26,7 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject {
explicit FeedReader(QObject* parent = nullptr); explicit FeedReader(QObject* parent = nullptr);
virtual ~FeedReader(); virtual ~FeedReader();
// List of all installed "feed service plugins", including obligatory // List of all installed "feed service plugins".
// "standard" service entry point.
QList<ServiceEntryPoint*> feedServices(); QList<ServiceEntryPoint*> feedServices();
// Access to DB cleaner. // Access to DB cleaner.
@ -51,6 +50,8 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject {
int autoUpdateRemainingInterval() const; int autoUpdateRemainingInterval() const;
int autoUpdateInitialInterval() const; int autoUpdateInitialInterval() const;
void loadSaveMessageFilters();
public slots: public slots:
void updateAllFeeds(); void updateAllFeeds();
void stopRunningFeedUpdate(); void stopRunningFeedUpdate();

View File

@ -499,7 +499,7 @@ void AdBlockRule::parseFilter() {
void AdBlockRule::parseDomains(const QString& domains, const QChar& separator) { void AdBlockRule::parseDomains(const QString& domains, const QChar& separator) {
QStringList domainsList = domains.split(separator, QString::SkipEmptyParts); QStringList domainsList = domains.split(separator, QString::SkipEmptyParts);
for (const QString domain : domainsList) { for (const QString& domain : domainsList) {
if (domain.isEmpty()) { if (domain.isEmpty()) {
continue; continue;
} }
@ -619,6 +619,7 @@ QString AdBlockRule::createRegExpFromFilter(const QString& filter) const {
QList<QStringMatcher> AdBlockRule::createStringMatchers(const QStringList& filters) const { QList<QStringMatcher> AdBlockRule::createStringMatchers(const QStringList& filters) const {
QList<QStringMatcher> matchers; QList<QStringMatcher> matchers;
matchers.reserve(filters.size()); matchers.reserve(filters.size());
for (const QString& filter : filters) { for (const QString& filter : filters) {

View File

@ -18,7 +18,8 @@
Feed::Feed(RootItem* parent) Feed::Feed(RootItem* parent)
: RootItem(parent), m_url(QString()), m_status(Normal), m_autoUpdateType(DefaultAutoUpdate), : RootItem(parent), m_url(QString()), m_status(Normal), m_autoUpdateType(DefaultAutoUpdate),
m_autoUpdateInitialInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_autoUpdateRemainingInterval(DEFAULT_AUTO_UPDATE_INTERVAL) { m_autoUpdateInitialInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_autoUpdateRemainingInterval(DEFAULT_AUTO_UPDATE_INTERVAL),
m_filters(QList<QPointer<MessageFilter>>()) {
setKind(RootItemKind::Feed); setKind(RootItemKind::Feed);
} }
@ -51,6 +52,7 @@ Feed::Feed(const Feed& other) : RootItem(other) {
setAutoUpdateType(other.autoUpdateType()); setAutoUpdateType(other.autoUpdateType());
setAutoUpdateInitialInterval(other.autoUpdateInitialInterval()); setAutoUpdateInitialInterval(other.autoUpdateInitialInterval());
setAutoUpdateRemainingInterval(other.autoUpdateRemainingInterval()); setAutoUpdateRemainingInterval(other.autoUpdateRemainingInterval());
setFilters(other.filters());
} }
Feed::~Feed() = default; Feed::~Feed() = default;
@ -241,9 +243,11 @@ QString Feed::getAutoUpdateStatusDescription() const {
case DefaultAutoUpdate: case DefaultAutoUpdate:
//: Describes feed auto-update status. //: Describes feed auto-update status.
auto_update_string = tr("uses global settings (%n minute(s) to next auto-update)", auto_update_string = qApp->feedReader()->autoUpdateEnabled()
nullptr, ? tr("uses global settings (%n minute(s) to next auto-update)",
qApp->feedReader()->autoUpdateRemainingInterval()); nullptr,
qApp->feedReader()->autoUpdateRemainingInterval())
: tr("uses global settings (global feed auto-updating is disabled)");
break; break;
case SpecificAutoUpdate: case SpecificAutoUpdate:
@ -276,7 +280,18 @@ QString Feed::getStatusDescription() const {
} }
} }
QList<QPointer<MessageFilter>> Feed::filters() const {
return m_filters;
}
void Feed::setFilters(const QList<QPointer<MessageFilter>>& filters) {
m_filters = filters;
}
QString Feed::additionalTooltip() const { QString Feed::additionalTooltip() const {
return tr("Auto-update status: %1\n" return tr("Auto-update status: %1\n"
"Status: %2").arg(getAutoUpdateStatusDescription(), getStatusDescription()); "Active message filters: %2\n"
"Status: %3").arg(getAutoUpdateStatusDescription(),
QString::number(m_filters.size()),
getStatusDescription());
} }

View File

@ -6,7 +6,9 @@
#include "services/abstract/rootitem.h" #include "services/abstract/rootitem.h"
#include "core/message.h" #include "core/message.h"
#include "core/messagefilter.h"
#include <QPointer>
#include <QVariant> #include <QVariant>
// Base class for "feed" nodes. // Base class for "feed" nodes.
@ -67,6 +69,9 @@ class Feed : public RootItem {
QString url() const; QString url() const;
void setUrl(const QString& url); void setUrl(const QString& url);
QList<QPointer<MessageFilter>> filters() const;
void setFilters(const QList<QPointer<MessageFilter>>& filters);
bool markAsReadUnread(ReadStatus status); bool markAsReadUnread(ReadStatus status);
bool cleanMessages(bool clean_read_only); bool cleanMessages(bool clean_read_only);
@ -88,6 +93,7 @@ class Feed : public RootItem {
int m_autoUpdateRemainingInterval{}; int m_autoUpdateRemainingInterval{};
int m_totalCount{}; int m_totalCount{};
int m_unreadCount{}; int m_unreadCount{};
QList<QPointer<MessageFilter>> m_filters;
}; };
Q_DECLARE_METATYPE(Feed::AutoUpdateType) Q_DECLARE_METATYPE(Feed::AutoUpdateType)

View File

@ -163,9 +163,9 @@ QString TtRssServiceRoot::additionalTooltip() const {
"Last error: %3\nLast login on: %4").arg(m_network->username(), "Last error: %3\nLast login on: %4").arg(m_network->username(),
m_network->url(), m_network->url(),
NetworkFactory::networkErrorText(m_network->lastError()), NetworkFactory::networkErrorText(m_network->lastError()),
m_network->lastLoginTime().isValid() ? m_network->lastLoginTime().isValid()
m_network->lastLoginTime().toString(Qt::DefaultLocaleShortDate) : ? QLocale().toString(m_network->lastLoginTime(), QLocale::FormatType::ShortFormat)
QSL("-")); : QSL("-"));
} }
TtRssNetworkFactory* TtRssServiceRoot::network() const { TtRssNetworkFactory* TtRssServiceRoot::network() const {

View File

@ -77,6 +77,7 @@ int main(int argc, char* argv[]) {
qApp->loadDynamicShortcuts(); qApp->loadDynamicShortcuts();
qApp->hideOrShowMainForm(); qApp->hideOrShowMainForm();
qApp->feedReader()->loadSaveMessageFilters();
qApp->feedReader()->feedsModel()->loadActivatedServiceAccounts(); qApp->feedReader()->feedsModel()->loadActivatedServiceAccounts();
qApp->showTrayIcon(); qApp->showTrayIcon();
qApp->offerChanges(); qApp->offerChanges();