Skip to content

Commit

Permalink
experimental ability to purge articles from individual feeds - availa…
Browse files Browse the repository at this point in the history
…ble with feed context menu and main menu Feeds submenu
  • Loading branch information
martinrotter committed Jan 7, 2025
1 parent a352b75 commit 7722065
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/librssguard/database/databasecleaner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,58 +15,69 @@ void DatabaseCleaner::purgeDatabaseData(CleanerOrders which_data) {

// Inform everyone about the start of the process.
emit purgeStarted();

bool result = true;
const int difference = 99 / 12;
int progress = 0;
QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className());

if (which_data.m_removeReadMessages) {
progress += difference;

emit purgeProgress(progress, tr("Removing read articles..."));

// Remove read messages.
result &= purgeReadMessages(database);
progress += difference;

emit purgeProgress(progress, tr("Read articles purged..."));
}

if (which_data.m_removeRecycleBin) {
progress += difference;

emit purgeProgress(progress, tr("Purging recycle bin..."));

// Remove read messages.
result &= purgeRecycleBin(database);
progress += difference;

emit purgeProgress(progress, tr("Recycle bin purged..."));
}

if (which_data.m_removeOldMessages) {
progress += difference;

emit purgeProgress(progress, tr("Removing old articles..."));

// Remove old messages.
result &= purgeOldMessages(database, which_data.m_barrierForRemovingOldMessagesInDays);
progress += difference;

emit purgeProgress(progress, tr("Old articles purged..."));
}

if (which_data.m_removeStarredMessages) {
progress += difference;

emit purgeProgress(progress, tr("Removing starred articles..."));

// Remove old messages.
result &= purgeStarredMessages(database);
progress += difference;

emit purgeProgress(progress, tr("Starred articles purged..."));
}

if (which_data.m_shrinkDatabase) {
progress += difference;

emit purgeProgress(progress, tr("Shrinking database file..."));

// Call driver-specific vacuuming function.
result &= qApp->database()->driver()->vacuumDatabase();
progress += difference;

emit purgeProgress(progress, tr("Database file shrinked..."));
}

Expand Down
21 changes: 21 additions & 0 deletions src/librssguard/database/databasequeries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,27 @@ bool DatabaseQueries::removeUnwantedArticlesFromFeed(const QSqlDatabase& db,
return rows_deleted > 0;
}

bool DatabaseQueries::purgeFeedMessages(const QSqlDatabase& database, const Feed* feed) {
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"));

q.bindValue(QSL(":feed"), feed->customId());
q.bindValue(QSL(":account_id"), feed->getParentServiceRoot()->accountId());

if (!q.exec()) {
throw ApplicationException(q.lastError().text());
}
else {
return q.numRowsAffected() > 0;
}
}

bool DatabaseQueries::purgeMessage(const QSqlDatabase& db, int message_id) {
QSqlQuery q(db);

Expand Down
1 change: 1 addition & 0 deletions src/librssguard/database/databasequeries.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +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 purgeMessage(const QSqlDatabase& db, int message_id);
static bool purgeImportantMessages(const QSqlDatabase& db);
static bool purgeReadMessages(const QSqlDatabase& db);
Expand Down
7 changes: 7 additions & 0 deletions src/librssguard/gui/dialogs/formmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ QList<QAction*> FormMain::allActions() const {
actions << m_ui->m_actionMarkSelectedItemsAsRead;
actions << m_ui->m_actionMarkSelectedItemsAsUnread;
actions << m_ui->m_actionClearSelectedItems;
actions << m_ui->m_actionPurgeSelectedItems;
actions << m_ui->m_actionClearAllItems;
actions << m_ui->m_actionShowOnlyUnreadItems;
actions << m_ui->m_actionSortFeedsAlphabetically;
Expand Down Expand Up @@ -499,6 +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_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));
Expand Down Expand Up @@ -605,6 +607,7 @@ void FormMain::setupIcons() {
m_ui->m_actionUpdateSelectedItemsWithCustomTimers->setIcon(icon_theme_factory->fromTheme(QSL("download"),
QSL("browser-download")));
m_ui->m_actionClearSelectedItems->setIcon(icon_theme_factory->fromTheme(QSL("mail-mark-junk")));
m_ui->m_actionPurgeSelectedItems->setIcon(icon_theme_factory->fromTheme(QSL("edit-clear")));
m_ui->m_actionClearAllItems->setIcon(icon_theme_factory->fromTheme(QSL("mail-mark-junk")));
m_ui->m_actionDeleteSelectedItem->setIcon(icon_theme_factory->fromTheme(QSL("list-remove")));
m_ui->m_actionDeleteSelectedMessages->setIcon(icon_theme_factory->fromTheme(QSL("mail-mark-junk")));
Expand Down Expand Up @@ -925,6 +928,10 @@ void FormMain::createConnections() {
&QAction::triggered,
tabWidget()->feedMessageViewer()->feedsView(),
&FeedsView::clearSelectedItems);
connect(m_ui->m_actionPurgeSelectedItems,
&QAction::triggered,
tabWidget()->feedMessageViewer()->feedsView(),
&FeedsView::purgeSelectedFeeds);
connect(m_ui->m_actionClearAllItems,
&QAction::triggered,
tabWidget()->feedMessageViewer()->feedsView(),
Expand Down
6 changes: 6 additions & 0 deletions src/librssguard/gui/dialogs/formmain.ui
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
<addaction name="m_actionCopyUrlSelectedFeed"/>
<addaction name="m_actionMarkSelectedItemsAsRead"/>
<addaction name="m_actionMarkSelectedItemsAsUnread"/>
<addaction name="m_actionPurgeSelectedItems"/>
<addaction name="m_actionClearSelectedItems"/>
<addaction name="separator"/>
<addaction name="m_actionFocusSearchFeeds"/>
Expand Down Expand Up @@ -960,6 +961,11 @@
<string>&amp;Pause automatic feed fetching</string>
</property>
</action>
<action name="m_actionPurgeSelectedItems">
<property name="text">
<string>&amp;Purge selected feeds</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
Expand Down
17 changes: 17 additions & 0 deletions src/librssguard/gui/feedsview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,23 @@ void FeedsView::clearSelectedItems() {
}
}

void FeedsView::purgeSelectedFeeds() {
if (MsgBox::show(nullptr,
QMessageBox::Icon::Question,
tr("Are you sure?"),
tr("Do you really want to purge all non-starred articles from selected feeds?"),
{},
{},
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No,
QMessageBox::StandardButton::No) != QMessageBox::StandardButton::Yes) {
return;
}

for (auto* it : selectedFeeds(true)) {
it->purgeArticles();
}
}

void FeedsView::clearAllItems() {
if (MsgBox::show(nullptr,
QMessageBox::Icon::Question,
Expand Down
1 change: 1 addition & 0 deletions src/librssguard/gui/feedsview.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class RSSGUARD_DLLSPEC FeedsView : public BaseTreeView {
// Feed clearers.
void clearSelectedItems();
void clearAllItems();
void purgeSelectedFeeds();

// Base manipulators.
void editItems(const QList<RootItem*>& items);
Expand Down
18 changes: 18 additions & 0 deletions src/librssguard/services/abstract/feed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,24 @@ 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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/librssguard/services/abstract/feed.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ 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);

Expand Down

0 comments on commit 7722065

Please sign in to comment.