From 07740a03286ca30c37b814bc4fb43620b1220012 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Wed, 8 Jan 2025 10:16:23 +0100 Subject: [PATCH] option to purge individual feeds --- src/librssguard/core/feedsmodel.cpp | 20 +++++++++++++++ src/librssguard/core/feedsmodel.h | 1 + src/librssguard/database/databasequeries.cpp | 27 +++++++++++++------- src/librssguard/database/databasequeries.h | 2 +- src/librssguard/gui/dialogs/formmain.cpp | 2 +- src/librssguard/gui/feedsview.cpp | 5 ++-- src/librssguard/services/abstract/feed.cpp | 18 ------------- src/librssguard/services/abstract/feed.h | 2 -- 8 files changed, 43 insertions(+), 34 deletions(-) diff --git a/src/librssguard/core/feedsmodel.cpp b/src/librssguard/core/feedsmodel.cpp index 49fde2715..1d3bbdb2f 100644 --- a/src/librssguard/core/feedsmodel.cpp +++ b/src/librssguard/core/feedsmodel.cpp @@ -529,6 +529,26 @@ bool FeedsModel::markItemCleared(RootItem* item, bool clean_read_only) { return true; } +bool FeedsModel::purgeArticles(const QList& feeds) { + auto database = qApp->database()->driver()->connection(metaObject()->className()); + + try { + bool anything_purged = DatabaseQueries::purgeFeedArticles(database, feeds); + + if (anything_purged) { + reloadCountsOfWholeModel(); + emit reloadMessageListRequested(false); + return true; + } + } + catch (const ApplicationException& ex) { + qCriticalNN << LOGSEC_CORE + << "Purging of articles from feeds failed with error:" << QUOTE_W_SPACE_DOT(ex.message()); + } + + return false; +} + QVariant FeedsModel::data(const QModelIndex& index, int role) const { switch (role) { case Qt::ItemDataRole::FontRole: { diff --git a/src/librssguard/core/feedsmodel.h b/src/librssguard/core/feedsmodel.h index ce71524dd..29b12364c 100644 --- a/src/librssguard/core/feedsmodel.h +++ b/src/librssguard/core/feedsmodel.h @@ -111,6 +111,7 @@ class RSSGUARD_DLLSPEC FeedsModel : public QAbstractItemModel { // Feeds operations. bool markItemRead(RootItem* item, RootItem::ReadStatus read); bool markItemCleared(RootItem* item, bool clean_read_only); + bool purgeArticles(const QList &feeds); // Signals that properties (probably counts) // of ALL items have changed. diff --git a/src/librssguard/database/databasequeries.cpp b/src/librssguard/database/databasequeries.cpp index eea1d04d5..ea932eb63 100644 --- a/src/librssguard/database/databasequeries.cpp +++ b/src/librssguard/database/databasequeries.cpp @@ -634,18 +634,27 @@ bool DatabaseQueries::removeUnwantedArticlesFromFeed(const QSqlDatabase& db, return rows_deleted > 0; } -bool DatabaseQueries::purgeFeedMessages(const QSqlDatabase& database, const Feed* feed) { +bool DatabaseQueries::purgeFeedArticles(const QSqlDatabase& database, const QList& feeds) { QSqlQuery q(database); - q.setForwardOnly(true); - q.prepare(QSL("DELETE FROM Messages " - "WHERE " - " Messages.account_id = :account_id AND " - " Messages.feed = :feed AND " - " Messages.is_important = 0")); + auto feed_clauses = boolinq::from(feeds) + .select([](Feed* feed) { + return QSL("(" + "Messages.feed = '%1' AND " + "Messages.account_id = %2 AND " + "Messages.is_important = 0" + ")") + .arg(feed->customId(), QString::number(feed->getParentServiceRoot()->accountId())); + }) + .toStdList(); - q.bindValue(QSL(":feed"), feed->customId()); - q.bindValue(QSL(":account_id"), feed->getParentServiceRoot()->accountId()); + qDebugNN << feed_clauses; + + QStringList feed_str_clauses = FROM_STD_LIST(QStringList, feed_clauses); + QString feed_clause = feed_str_clauses.join(QSL(" OR ")); + + q.setForwardOnly(true); + q.prepare(QSL("DELETE FROM Messages WHERE %1;").arg(feed_clause)); if (!q.exec()) { throw ApplicationException(q.lastError().text()); diff --git a/src/librssguard/database/databasequeries.h b/src/librssguard/database/databasequeries.h index 1fdf7475a..7bac62947 100644 --- a/src/librssguard/database/databasequeries.h +++ b/src/librssguard/database/databasequeries.h @@ -76,7 +76,7 @@ class RSSGUARD_DLLSPEC DatabaseQueries { const Feed::ArticleIgnoreLimit& feed_setup, const Feed::ArticleIgnoreLimit& app_setup); - static bool purgeFeedMessages(const QSqlDatabase& database, const Feed* feed); + static bool purgeFeedArticles(const QSqlDatabase& database, const QList& feeds); static bool purgeMessage(const QSqlDatabase& db, int message_id); static bool purgeImportantMessages(const QSqlDatabase& db); static bool purgeReadMessages(const QSqlDatabase& db); diff --git a/src/librssguard/gui/dialogs/formmain.cpp b/src/librssguard/gui/dialogs/formmain.cpp index fa071ead7..c39d908b9 100644 --- a/src/librssguard/gui/dialogs/formmain.cpp +++ b/src/librssguard/gui/dialogs/formmain.cpp @@ -500,7 +500,7 @@ void FormMain::updateFeedButtonsAvailability() { m_ui->m_actionBackupDatabaseSettings->setEnabled(!critical_action_running); m_ui->m_actionCleanupDatabase->setEnabled(!critical_action_running); m_ui->m_actionClearSelectedItems->setEnabled(anything_selected); - m_ui->m_actionPurgeSelectedItems->setEnabled(feed_selected); + m_ui->m_actionPurgeSelectedItems->setEnabled(feed_selected || category_selected || service_selected); m_ui->m_actionDeleteSelectedItem->setEnabled(!critical_action_running && anything_selected); m_ui->m_actionEditSelectedItem->setEnabled(!critical_action_running && anything_selected); m_ui->m_actionEditChildFeeds->setEnabled(!critical_action_running && (service_selected || category_selected)); diff --git a/src/librssguard/gui/feedsview.cpp b/src/librssguard/gui/feedsview.cpp index 75e06e964..296b688e0 100644 --- a/src/librssguard/gui/feedsview.cpp +++ b/src/librssguard/gui/feedsview.cpp @@ -266,9 +266,7 @@ void FeedsView::purgeSelectedFeeds() { return; } - for (auto* it : selectedFeeds(true)) { - it->purgeArticles(); - } + m_sourceModel->purgeArticles(selectedFeeds(true)); } void FeedsView::clearAllItems() { @@ -989,6 +987,7 @@ QMenu* FeedsView::initializeContextMenuFeeds(RootItem* clicked_item) { << qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed << qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead << qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread + << qApp->mainForm()->m_ui->m_actionPurgeSelectedItems << qApp->mainForm()->m_ui->m_actionDeleteSelectedItem); auto cat_add = clicked_item->getParentServiceRoot()->supportsCategoryAdding(); diff --git a/src/librssguard/services/abstract/feed.cpp b/src/librssguard/services/abstract/feed.cpp index 515f3d7e2..9d3e971bf 100644 --- a/src/librssguard/services/abstract/feed.cpp +++ b/src/librssguard/services/abstract/feed.cpp @@ -113,24 +113,6 @@ QVariant Feed::data(int column, int role) const { } } -void Feed::purgeArticles() { - auto database = qApp->database()->driver()->connection(metaObject()->className()); - - try { - bool anything_purged = DatabaseQueries::purgeFeedMessages(database, this); - - if (anything_purged) { - getParentServiceRoot()->updateCounts(true); - getParentServiceRoot()->itemChanged(getParentServiceRoot()->getSubTree()); - getParentServiceRoot()->requestReloadMessageList(false); - } - } - catch (const ApplicationException& ex) { - qCriticalNN << LOGSEC_CORE << "Purging of articles from feed" << QUOTE_W_SPACE(customId()) - << "failed with error:" << QUOTE_W_SPACE_DOT(ex.message()); - } -} - int Feed::autoUpdateInterval() const { return m_autoUpdateInterval; } diff --git a/src/librssguard/services/abstract/feed.h b/src/librssguard/services/abstract/feed.h index 6111872a3..787e4ece9 100644 --- a/src/librssguard/services/abstract/feed.h +++ b/src/librssguard/services/abstract/feed.h @@ -71,8 +71,6 @@ class RSSGUARD_DLLSPEC Feed : public RootItem { virtual bool isFetching() const; virtual QVariant data(int column, int role) const; - void purgeArticles(); - void setCountOfAllMessages(int count_all_messages); void setCountOfUnreadMessages(int count_unread_messages);