From 450d01e714efbaa1968efc47fa054814c0e70713 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 16 Jan 2024 10:38:38 +0100 Subject: [PATCH] working limitting --- src/librssguard/core/feeddownloader.cpp | 3 - src/librssguard/database/databasequeries.cpp | 79 ++++++++++++++++++- src/librssguard/database/databasequeries.h | 3 +- .../gui/reusable/articleamountcontrol.cpp | 5 +- src/librssguard/services/abstract/feed.cpp | 4 +- src/librssguard/services/abstract/feed.h | 2 +- .../services/abstract/serviceroot.cpp | 22 +++--- 7 files changed, 96 insertions(+), 22 deletions(-) diff --git a/src/librssguard/core/feeddownloader.cpp b/src/librssguard/core/feeddownloader.cpp index 55c8df043..cfa1637cf 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -232,9 +232,6 @@ void FeedDownloader::updateOneFeed(ServiceRoot* acc, try { QSqlDatabase database = qApp->database()->driver()->threadSafeConnection(metaObject()->className()); - - feed->removeUnwantedArticles(database); - QList msgs = feed->getParentServiceRoot()->obtainNewMessages(feed, stated_messages, tagged_messages); qDebugNN << LOGSEC_FEEDDOWNLOADER << "Downloaded" << NONQUOTE_W_SPACE(msgs.size()) << "messages for feed ID" diff --git a/src/librssguard/database/databasequeries.cpp b/src/librssguard/database/databasequeries.cpp index 513e0d686..8ff884fd3 100644 --- a/src/librssguard/database/databasequeries.cpp +++ b/src/librssguard/database/databasequeries.cpp @@ -546,13 +546,86 @@ bool DatabaseQueries::restoreBin(const QSqlDatabase& db, int account_id) { return q.exec(); } -void DatabaseQueries::removeUnwantedArticlesFromFeed(const QSqlDatabase& db, +bool DatabaseQueries::removeUnwantedArticlesFromFeed(const QSqlDatabase& db, + const Feed* feed, const Feed::ArticleIgnoreLimit& feed_setup, const Feed::ArticleIgnoreLimit& app_setup) { // Feed setup has higher preference. - int amount_to_remove = + int amount_to_keep = feed_setup.m_keepCountOfArticles > 0 ? feed_setup.m_keepCountOfArticles : app_setup.m_keepCountOfArticles; - // bool dont_remove_unread = feed_setup.m_doNotRemoveUnread + bool dont_remove_unread = + feed_setup.m_customizeLimitting ? feed_setup.m_doNotRemoveUnread : app_setup.m_doNotRemoveUnread; + bool dont_remove_starred = + feed_setup.m_customizeLimitting ? feed_setup.m_doNotRemoveStarred : app_setup.m_doNotRemoveStarred; + bool recycle_dont_purge = + feed_setup.m_customizeLimitting ? feed_setup.m_moveToBinDontPurge : app_setup.m_moveToBinDontPurge; + + if (amount_to_keep <= 0) { + // No articles will be removed, quitting. + return false; + } + // We find datetime stamp of oldest article which will be NOT moved/removed. + QSqlQuery q(db); + + q.setForwardOnly(true); + q.prepare(QSL("SELECT Messages.date_created " + "FROM Messages " + "WHERE " + " Messages.feed = :feed AND " + " Messages.is_deleted = 0 AND " + " Messages.is_pdeleted = 0 " + "ORDER BY Messages.date_created DESC " + "LIMIT 1 OFFSET :offset;")); + q.bindValue(QSL(":offset"), amount_to_keep - 1); + q.bindValue(QSL(":feed"), feed->customId()); + + if (!q.exec()) { + throw ApplicationException(q.lastError().text()); + } + + if (!q.next()) { + return false; + } + + qlonglong last_kept_stamp = q.value(0).toLongLong(); + + if (recycle_dont_purge) { + // We mark all older articles as deleted. + q.prepare(QSL("UPDATE Messages " + "SET is_deleted = 1 " + "WHERE " + " Messages.feed = :feed AND " + " Messages.is_deleted = 0 AND " + " Messages.is_pdeleted = 0 AND " + " Messages.is_important != :is_important AND " + " Messages.is_read != :is_read AND " + " Messages.date_created < :stamp")); + } + else { + // We purge all older articles. + q.prepare(QSL("DELETE FROM Messages " + "WHERE " + " Messages.feed = :feed AND " + " (Messages.is_deleted = 1 OR Messages.is_important != :is_important) AND " + " (Messages.is_deleted = 1 OR Messages.is_read != :is_read) AND " + " Messages.date_created < :stamp")); + } + + q.bindValue(QSL(":is_important"), dont_remove_starred ? 1 : 2); + q.bindValue(QSL(":is_read"), dont_remove_unread ? 0 : 2); + q.bindValue(QSL(":feed"), feed->customId()); + q.bindValue(QSL(":stamp"), last_kept_stamp); + + if (!q.exec()) { + throw ApplicationException(q.lastError().text()); + } + + int rows_deleted = q.numRowsAffected(); + + qDebugNN << LOGSEC_DB << "Feed cleanup has recycled/purged" << NONQUOTE_W_SPACE(rows_deleted) + << "old articles from feed" << QUOTE_W_SPACE_DOT(feed->customId()); + + return rows_deleted > 0; } bool DatabaseQueries::purgeMessage(const QSqlDatabase& db, int message_id) { diff --git a/src/librssguard/database/databasequeries.h b/src/librssguard/database/databasequeries.h index b7fc59c0c..1ddae7c8d 100644 --- a/src/librssguard/database/databasequeries.h +++ b/src/librssguard/database/databasequeries.h @@ -72,7 +72,8 @@ class DatabaseQueries { static bool restoreBin(const QSqlDatabase& db, int account_id); // Purge database. - static void removeUnwantedArticlesFromFeed(const QSqlDatabase& db, + static bool removeUnwantedArticlesFromFeed(const QSqlDatabase& db, + const Feed* feed, const Feed::ArticleIgnoreLimit& feed_setup, const Feed::ArticleIgnoreLimit& app_setup); diff --git a/src/librssguard/gui/reusable/articleamountcontrol.cpp b/src/librssguard/gui/reusable/articleamountcontrol.cpp index 50e044086..5e357d029 100644 --- a/src/librssguard/gui/reusable/articleamountcontrol.cpp +++ b/src/librssguard/gui/reusable/articleamountcontrol.cpp @@ -13,8 +13,9 @@ ArticleAmountControl::ArticleAmountControl(QWidget* parent) : QWidget(parent) { "accepts particular article, it can still subsequently ignored and not added to database.") .arg(QSL(APP_NAME)), false); - m_ui.m_helpLimit->setHelpText(tr("All excessive articles are removed automatically by the application, usually when " - "particular feed is fetched. Articles are either completely purged from internal " + m_ui.m_helpLimit->setHelpText(tr("All excessive articles are removed automatically by the application, usually after " + "particular feed is fetched. Articles are either completely purged (including " + "articles from recycle bin) from internal " "database or are just moved to recycle bin."), false); diff --git a/src/librssguard/services/abstract/feed.cpp b/src/librssguard/services/abstract/feed.cpp index 95ca0ad5b..21c76cfab 100644 --- a/src/librssguard/services/abstract/feed.cpp +++ b/src/librssguard/services/abstract/feed.cpp @@ -201,11 +201,11 @@ void Feed::setIsRtl(bool rtl) { m_isRtl = rtl; } -void Feed::removeUnwantedArticles(QSqlDatabase& db) { +bool Feed::removeUnwantedArticles(QSqlDatabase& db) { Feed::ArticleIgnoreLimit feed_setup = articleIgnoreLimit(); Feed::ArticleIgnoreLimit app_setup = Feed::ArticleIgnoreLimit::fromSettings(); - DatabaseQueries::removeUnwantedArticlesFromFeed(db, feed_setup, app_setup); + return DatabaseQueries::removeUnwantedArticlesFromFeed(db, this, feed_setup, app_setup); } void Feed::appendMessageFilter(MessageFilter* filter) { diff --git a/src/librssguard/services/abstract/feed.h b/src/librssguard/services/abstract/feed.h index 461e7aaa4..38b80c643 100644 --- a/src/librssguard/services/abstract/feed.h +++ b/src/librssguard/services/abstract/feed.h @@ -108,7 +108,7 @@ class Feed : public RootItem { bool isRtl() const; void setIsRtl(bool rtl); - void removeUnwantedArticles(QSqlDatabase& db); + bool removeUnwantedArticles(QSqlDatabase& db); ArticleIgnoreLimit& articleIgnoreLimit(); const ArticleIgnoreLimit& articleIgnoreLimit() const; diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index 989d6ab1e..b20ef343a 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -1277,20 +1277,22 @@ ServiceRoot::LabelOperation operator&(ServiceRoot::LabelOperation lhs, ServiceRo UpdatedArticles ServiceRoot::updateMessages(QList& messages, Feed* feed, bool force_update, QMutex* db_mutex) { UpdatedArticles updated_messages; - - if (messages.isEmpty()) { - qDebugNN << "No messages to be updated/added in DB for feed" << QUOTE_W_SPACE_DOT(feed->customId()); - return updated_messages; - } - - bool ok = false; QSqlDatabase database = qApp->database()->driver()->threadSafeConnection(metaObject()->className()); - qDebugNN << LOGSEC_CORE << "Updating messages in DB."; + if (!messages.isEmpty()) { + bool ok = false; - updated_messages = DatabaseQueries::updateMessages(database, messages, feed, force_update, db_mutex, &ok); + qDebugNN << LOGSEC_CORE << "Updating messages in DB."; - if (!updated_messages.m_unread.isEmpty() || !updated_messages.m_all.isEmpty()) { + updated_messages = DatabaseQueries::updateMessages(database, messages, feed, force_update, db_mutex, &ok); + } + else { + qDebugNN << "No messages to be updated/added in DB for feed" << QUOTE_W_SPACE_DOT(feed->customId()); + } + + bool anything_removed = feed->removeUnwantedArticles(database); + + if (anything_removed || !updated_messages.m_unread.isEmpty() || !updated_messages.m_all.isEmpty()) { QMutexLocker lck(db_mutex); // Something was added or updated in the DB, update numbers.