Quellcode durchsuchen

Improve feed refresh (#6117)

* Improve feed refresh
Better account for some edge cases for cron and automatic labels
fix https://github.com/FreshRSS/FreshRSS/issues/6089
fix https://github.com/FreshRSS/FreshRSS/issues/6109

* Apply labels also to new entries already marked as read

* Add case most relevant for cron
Alexandre Alapetite vor 2 Jahren
Ursprung
Commit
bfd277065c

+ 14 - 10
app/Controllers/feedController.php

@@ -742,11 +742,12 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 	}
 
 	/**
-	 * @param array<int,int> $newUnreadEntriesPerFeed
 	 * @return int|false The number of articles marked as read, of false if error
 	 */
-	private static function keepMaxUnreads(array $newUnreadEntriesPerFeed) {
+	private static function keepMaxUnreads() {
 		$affected = 0;
+		$entryDAO = FreshRSS_Factory::createEntryDao();
+		$newUnreadEntriesPerFeed = $entryDAO->newUnreadEntriesPerFeed();
 		$feedDAO = FreshRSS_Factory::createFeedDao();
 		$feeds = $feedDAO->listFeedsOrderUpdate(-1);
 		foreach ($feeds as $feed) {
@@ -801,26 +802,23 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 		return $tagDAO->tagEntries($applyLabels);
 	}
 
-	public static function commitNewEntries(): bool {
+	public static function commitNewEntries(): void {
 		$entryDAO = FreshRSS_Factory::createEntryDao();
-		$newUnreadEntriesPerFeed = $entryDAO->newUnreadEntriesPerFeed();
-		$nbNewEntries = array_sum($newUnreadEntriesPerFeed);
+		['all' => $nbNewEntries, 'unread' => $nbNewUnreadEntries] = $entryDAO->countNewEntries();
 		if ($nbNewEntries > 0) {
 			if (!$entryDAO->inTransaction()) {
 				$entryDAO->beginTransaction();
 			}
 			if ($entryDAO->commitNewEntries()) {
-				self::keepMaxUnreads($newUnreadEntriesPerFeed);
 				self::applyLabelActions($nbNewEntries);
+				if ($nbNewUnreadEntries > 0) {
+					self::keepMaxUnreads();
+				}
 			}
 			if ($entryDAO->inTransaction()) {
 				$entryDAO->commit();
 			}
 		}
-
-		$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
-		$databaseDAO->minorDbMaintenance();
-		return true;
 	}
 
 	/**
@@ -846,6 +844,12 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 			self::commitNewEntries();
 		} else {
 			if ($id === 0 && $url === '') {
+				// Case of a batch refresh (e.g. cron)
+				$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
+				$databaseDAO->minorDbMaintenance();
+				Minz_ExtensionManager::callHookVoid('freshrss_user_maintenance');
+
+				FreshRSS_feed_Controller::commitNewEntries();
 				FreshRSS_category_Controller::refreshDynamicOpmls();
 			}
 			[$updated_feeds, $feed, $nbNewArticles] = self::actualizeFeeds($id, $url, $maxFeeds);

+ 4 - 0
app/Controllers/javascriptController.php

@@ -20,6 +20,10 @@ class FreshRSS_javascript_Controller extends FreshRSS_ActionController {
 		header('Content-Type: application/json; charset=UTF-8');
 		Minz_Session::_param('actualize_feeds', false);
 
+		$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
+		$databaseDAO->minorDbMaintenance();
+		Minz_ExtensionManager::callHookVoid('freshrss_user_maintenance');
+
 		$catDAO = FreshRSS_Factory::createCategoryDao();
 		$this->view->categories = $catDAO->listCategoriesOrderUpdate(FreshRSS_Context::userConf()->dynamic_opml_ttl_default);
 

+ 23 - 1
app/Models/EntryDAO.php

@@ -274,7 +274,29 @@ SQL;
 	}
 
 	/**
-	 * Count the number of new entries in the temporary table (which have not yet been committed), grouped by feed ID.
+	 * Count the number of new entries in the temporary table (which have not yet been committed), grouped by read / unread.
+	 * @return array{'all':int,'unread':int,'read':int}
+	 */
+	public function countNewEntries(): array {
+		$sql = <<<'SQL'
+		SELECT is_read, COUNT(id) AS nb_entries FROM `_entrytmp`
+		GROUP BY is_read
+		SQL;
+		$lines = $this->fetchAssoc($sql) ?? [];
+		$nbRead = 0;
+		$nbUnread = 0;
+		foreach ($lines as $line) {
+			if (empty($line['is_read'])) {
+				$nbUnread = (int)($line['nb_entries'] ?? 0);
+			} else {
+				$nbRead = (int)($line['nb_entries'] ?? 0);
+			}
+		}
+		return ['all' => $nbRead + $nbUnread, 'unread' => $nbUnread, 'read' => $nbRead];
+	}
+
+	/**
+	 * Count the number of new unread entries in the temporary table (which have not yet been committed), grouped by feed ID.
 	 * @return array<int,int>
 	 */
 	public function newUnreadEntriesPerFeed(): array {

+ 0 - 1
app/actualize_script.php

@@ -103,7 +103,6 @@ foreach ($users as $user) {
 
 	notice('FreshRSS actualize ' . $user . '…');
 	echo $user, ' ';	//Buffered
-	Minz_ExtensionManager::callHookVoid('freshrss_user_maintenance');
 	$app->run();
 
 	if (!invalidateHttpCache()) {

+ 4 - 2
cli/actualize-user.php

@@ -20,11 +20,13 @@ if (!empty($options['invalid']) || empty($options['valid']['user']) || !is_strin
 }
 
 $username = cliInitUser($options['valid']['user']);
+fwrite(STDERR, 'FreshRSS actualizing user “' . $username . "”…\n");
 
+$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
+$databaseDAO->minorDbMaintenance();
 Minz_ExtensionManager::callHookVoid('freshrss_user_maintenance');
 
-fwrite(STDERR, 'FreshRSS actualizing user “' . $username . "”…\n");
-
+FreshRSS_feed_Controller::commitNewEntries();
 $result = FreshRSS_category_Controller::refreshDynamicOpmls();
 if (!empty($result['errors'])) {
 	$errors = $result['errors'];