Просмотр исходного кода

Rework keepmax (#5905)

* Rework keepmax
fix https://github.com/FreshRSS/FreshRSS/issues/5702
fix https://github.com/FreshRSS/FreshRSS/issues/5870

* More WIP

* Minor progress

* Progress

* Beta

* Improved debug message

* Revert noCommit

* Fix variable reset

* Remove debug syslogs
Alexandre Alapetite 2 лет назад
Родитель
Сommit
f0d4f2762d

+ 85 - 65
app/Controllers/feedController.php

@@ -105,7 +105,10 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 		$feed->_id($id);
 
 		// Ok, feed has been added in database. Now we have to refresh entries.
-		self::actualizeFeed($id, $url, false, null);
+		[, , $nb_new_articles] = self::actualizeFeeds($id, $url);
+		if ($nb_new_articles > 0) {
+			self::commitNewEntries();
+		}
 
 		return $feed;
 	}
@@ -327,42 +330,46 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 	}
 
 	/**
-	 * @return array{0:int,1:FreshRSS_Feed|false,2:int}
+	 * @return array{0:int,1:FreshRSS_Feed|null,2:int} Number of updated feeds, first feed or null, number of new articles
 	 * @throws FreshRSS_BadUrl_Exception
 	 */
-	public static function actualizeFeed(int $feed_id, string $feed_url, bool $force, ?SimplePie $simplePiePush = null,
-		bool $noCommit = false, int $maxFeeds = 10): array {
+	public static function actualizeFeeds(?int $feed_id = null, ?string $feed_url = null, ?int $maxFeeds = null, ?SimplePie $simplePiePush = null): array {
 		if (function_exists('set_time_limit')) {
 			@set_time_limit(300);
 		}
 
+		if (!is_int($feed_id) || $feed_id <= 0) {
+			$feed_id = null;
+		}
+		if (!is_string($feed_url) || trim($feed_url) === '') {
+			$feed_url = null;
+		}
+		if (!is_int($maxFeeds) || $maxFeeds <= 0) {
+			$maxFeeds = PHP_INT_MAX;
+		}
+
 		$feedDAO = FreshRSS_Factory::createFeedDao();
 		$entryDAO = FreshRSS_Factory::createEntryDao();
 
 		// Create a list of feeds to actualize.
-		// If feed_id is set and valid, corresponding feed is added to the list but
-		// alone in order to automatize further process.
 		$feeds = [];
-		if ($feed_id > 0 || $feed_url) {
-			$feed = $feed_id > 0 ? $feedDAO->searchById($feed_id) : $feedDAO->searchByUrl($feed_url);
-			if ($feed) {
+		if ($feed_id !== null || $feed_url !== null) {
+			$feed = $feed_id !== null ? $feedDAO->searchById($feed_id) : $feedDAO->searchByUrl($feed_url);
+			if ($feed !== null && $feed->id() > 0) {
 				$feeds[] = $feed;
+				$feed_id = $feed->id();
 			}
 		} else {
 			$feeds = $feedDAO->listFeedsOrderUpdate(-1);
 		}
 
-		// Set maxFeeds to a minimum of 10
-		if ($maxFeeds < 10) {
-			$maxFeeds = 10;
-		}
-
 		// WebSub (PubSubHubbub) support
 		$pubsubhubbubEnabledGeneral = FreshRSS_Context::$system_conf->pubsubhubbub_enabled;
 		$pshbMinAge = time() - (3600 * 24);  //TODO: Make a configuration.
 
 		$updated_feeds = 0;
 		$nb_new_articles = 0;
+
 		foreach ($feeds as $feed) {
 			/** @var FreshRSS_Feed|null $feed */
 			$feed = Minz_ExtensionManager::callHook('feed_before_actualize', $feed);
@@ -373,7 +380,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 			$url = $feed->url();	//For detection of HTTP 301
 
 			$pubSubHubbubEnabled = $pubsubhubbubEnabledGeneral && $feed->pubSubHubbubEnabled();
-			if ($simplePiePush === null && $feed_id === 0 && $pubSubHubbubEnabled && ($feed->lastUpdate() > $pshbMinAge)) {
+			if ($simplePiePush === null && $feed_id === null && $pubSubHubbubEnabled && ($feed->lastUpdate() > $pshbMinAge)) {
 				//$text = 'Skip pull of feed using PubSubHubbub: ' . $url;
 				//Minz_Log::debug($text);
 				//Minz_Log::debug($text, PSHB_LOG);
@@ -388,7 +395,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 			if ($ttl === FreshRSS_Feed::TTL_DEFAULT) {
 				$ttl = FreshRSS_Context::$user_conf->ttl_default;
 			}
-			if ($simplePiePush === null && $feed_id === 0 && (time() <= $feed->lastUpdate() + $ttl)) {
+			if ($simplePiePush === null && $feed_id === null && (time() <= $feed->lastUpdate() + $ttl)) {
 				//Too early to refresh from source, but check whether the feed was updated by another user
 				$ε = 10;	// negligible offset errors in seconds
 				if ($mtime <= 0 ||
@@ -452,6 +459,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 			}
 
 			$needFeedCacheRefresh = false;
+			$nbMarkedUnread = 0;
 
 			if (count($newGuids) > 0) {
 				$titlesAsRead = [];
@@ -499,8 +507,8 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 							}
 
 							if (!$entry->isRead()) {
-								$needFeedCacheRefresh = true;
-								$feed->incPendingUnread();	//Maybe
+								$needFeedCacheRefresh = true;	//Maybe
+								$nbMarkedUnread++;
 							}
 
 							// If the entry has changed, there is a good chance for the full content to have changed as well.
@@ -540,9 +548,6 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 						}
 						$entryDAO->addEntry($entry->toArray(), true);
 
-						if (!$entry->isRead()) {
-							$feed->incPendingUnread();
-						}
 						$nb_new_articles++;
 					}
 				}
@@ -568,7 +573,11 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 			}
 
 			$feedDAO->updateLastUpdate($feed->id(), false, $mtime);
-			$needFeedCacheRefresh |= ($feed->keepMaxUnread() != false);
+			if ($feed->keepMaxUnread() !== null && ($feed->nbNotRead() + $nbMarkedUnread > $feed->keepMaxUnread())) {
+				Minz_Log::debug('Existing unread entries (' . ($feed->nbNotRead() + $nbMarkedUnread) . ') exceeding max number of ' .
+					$feed->keepMaxUnread() .  ' for [' . $feed->url(false) . ']');
+				$needFeedCacheRefresh |= ($feed->markAsReadMaxUnread() != false);
+			}
 			if ($simplePiePush === null) {
 				// Do not call for WebSub events, as we do not know the list of articles still on the upstream feed.
 				$needFeedCacheRefresh |= ($feed->markAsReadUponGone($feedIsEmpty, $mtime) != false);
@@ -644,62 +653,72 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 			unset($feed);
 			gc_collect_cycles();
 
-			// No more than $maxFeeds feeds unless $force is true to avoid overloading
-			// the server.
-			if ($updated_feeds >= $maxFeeds && !$force) {
+			if ($updated_feeds >= $maxFeeds) {
 				break;
 			}
 		}
-		if (!$noCommit && ($nb_new_articles > 0 || $updated_feeds > 0)) {
-			if (!$entryDAO->inTransaction()) {
-				$entryDAO->beginTransaction();
+		return [$updated_feeds, reset($feeds) ?: null, $nb_new_articles];
+	}
+
+	public static function commitNewEntries(): bool {
+		$entryDAO = FreshRSS_Factory::createEntryDao();
+		if (!$entryDAO->inTransaction()) {
+			$entryDAO->beginTransaction();
+		}
+
+		$newUnreadEntriesPerFeed = $entryDAO->newUnreadEntriesPerFeed();
+		if ($entryDAO->commitNewEntries()) {
+			$feedDAO = FreshRSS_Factory::createFeedDao();
+			$feeds = $feedDAO->listFeedsOrderUpdate(-1);
+			foreach ($feeds as $feed) {
+				if (!empty($newUnreadEntriesPerFeed[$feed->id()]) && $feed->keepMaxUnread() !== null &&
+					($feed->nbNotRead() + $newUnreadEntriesPerFeed[$feed->id()] > $feed->keepMaxUnread())) {
+					Minz_Log::debug('New unread entries (' . ($feed->nbNotRead() + $newUnreadEntriesPerFeed[$feed->id()]) . ') exceeding max number of ' .
+						$feed->keepMaxUnread() .  ' for [' . $feed->url(false) . ']');
+					$feed->markAsReadMaxUnread();
+				}
 			}
-			$entryDAO->commitNewEntries();
 			$feedDAO->updateCachedValues();
-			if ($entryDAO->inTransaction()) {
-				$entryDAO->commit();
-			}
+		}
 
-			$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
-			$databaseDAO->minorDbMaintenance();
+		if ($entryDAO->inTransaction()) {
+			$entryDAO->commit();
 		}
-		return [$updated_feeds, reset($feeds), $nb_new_articles];
+
+		$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
+		$databaseDAO->minorDbMaintenance();
+		return true;
 	}
 
 	/**
 	 * This action actualizes entries from one or several feeds.
 	 *
 	 * Parameters are:
-	 *   - id (default: false): Feed ID
-	 *   - url (default: false): Feed URL
-	 *   - force (default: false)
+	 *   - id (default: null): Feed ID, or set to -1 to commit new articles to the main database
+	 *   - url (default: null): Feed URL (instead of feed ID)
+	 *   - maxFeeds (default: 10): Max number of feeds to refresh
 	 *   - noCommit (default: 0): Set to 1 to prevent committing the new articles to the main database
-	 * If id and url are not specified, all the feeds are actualized. But if force is
-	 * false, process stops at 10 feeds to avoid time execution problem.
+	 * If id and url are not specified, all the feeds are actualized, within the limits of maxFeeds.
 	 */
 	public function actualizeAction(): int {
 		Minz_Session::_param('actualize_feeds', false);
 		$id = Minz_Request::paramInt('id');
 		$url = Minz_Request::paramString('url');
-		$force = Minz_Request::paramBoolean('force');
-		$maxFeeds = Minz_Request::paramInt('maxFeeds');
+		$maxFeeds = Minz_Request::paramInt('maxFeeds') ?: 10;
 		$noCommit = ($_POST['noCommit'] ?? 0) == 1;
-		$feed = null;
 
-		if ($id == -1 && !$noCommit) {	//Special request only to commit & refresh DB cache
+		if ($id === -1 && !$noCommit) {	//Special request only to commit & refresh DB cache
 			$updated_feeds = 0;
-			$entryDAO = FreshRSS_Factory::createEntryDao();
-			$feedDAO = FreshRSS_Factory::createFeedDao();
-			$entryDAO->beginTransaction();
-			$entryDAO->commitNewEntries();
-			$feedDAO->updateCachedValues();
-			$entryDAO->commit();
-
-			$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
-			$databaseDAO->minorDbMaintenance();
+			$feed = null;
+			self::commitNewEntries();
 		} else {
-			FreshRSS_category_Controller::refreshDynamicOpmls();
-			[$updated_feeds, $feed] = self::actualizeFeed($id, $url, $force, null, $noCommit, $maxFeeds);
+			if ($id === 0 && $url === '') {
+				FreshRSS_category_Controller::refreshDynamicOpmls();
+			}
+			[$updated_feeds, $feed, $nbNewArticles] = self::actualizeFeeds($id, $url, $maxFeeds);
+			if (!$noCommit && $nbNewArticles > 0) {
+				FreshRSS_feed_Controller::commitNewEntries();
+			}
 		}
 
 		if (Minz_Request::paramBoolean('ajax')) {
@@ -711,15 +730,13 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 			$this->view->_layout(null);
 		} elseif ($feed instanceof FreshRSS_Feed) {
 			// Redirect to the main page with correct notification.
-			if ($updated_feeds === 1) {
-				Minz_Request::good(_t('feedback.sub.feed.actualized', $feed->name()), [
-					'params' => ['get' => 'f_' . $feed->id()]
-				]);
-			} elseif ($updated_feeds > 1) {
-				Minz_Request::good(_t('feedback.sub.feed.n_actualized', $updated_feeds), []);
-			} else {
-				Minz_Request::good(_t('feedback.sub.feed.no_refresh'), []);
-			}
+			Minz_Request::good(_t('feedback.sub.feed.actualized', $feed->name()), [
+				'params' => ['get' => 'f_' . $id]
+			]);
+		} elseif ($updated_feeds >= 1) {
+			Minz_Request::good(_t('feedback.sub.feed.n_actualized', $updated_feeds), []);
+		} else {
+			Minz_Request::good(_t('feedback.sub.feed.no_refresh'), []);
 		}
 		return $updated_feeds;
 	}
@@ -899,7 +916,10 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 
 		//Re-fetch articles as if the feed was new.
 		$feedDAO->updateFeed($feed->id(), [ 'lastUpdate' => 0 ]);
-		self::actualizeFeed($feed_id, '', false);
+		[, , $nb_new_articles] = self::actualizeFeeds($feed_id);
+		if ($nb_new_articles > 0) {
+			FreshRSS_feed_Controller::commitNewEntries();
+		}
 
 		//Extract all feed entries from database, load complete content and store them back in database.
 		$entries = $entryDAO->listWhere('f', $feed_id, FreshRSS_Entry::STATE_ALL, 'DESC', $limit);

+ 2 - 2
app/Controllers/subscriptionController.php

@@ -124,8 +124,8 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
 			$feed->_attributes('read_upon_reception', Minz_Request::paramTernary('read_upon_reception'));
 			$feed->_attributes('clear_cache', Minz_Request::paramTernary('clear_cache'));
 
-			$keep_max_n_unread = Minz_Request::paramInt('keep_max_n_unread');
-			$feed->_attributes('keep_max_n_unread', $keep_max_n_unread > 0 ? $keep_max_n_unread : null);
+			$keep_max_n_unread = Minz_Request::paramTernary('keep_max_n_unread') === true ? Minz_Request::paramInt('keep_max_n_unread') : null;
+			$feed->_attributes('keep_max_n_unread', $keep_max_n_unread >= 0 ? $keep_max_n_unread : null);
 
 			$read_when_same_title_in_feed = Minz_Request::paramString('read_when_same_title_in_feed');
 			if ($read_when_same_title_in_feed === '') {

+ 20 - 0
app/Models/EntryDAO.php

@@ -273,6 +273,26 @@ SQL;
 		}
 	}
 
+	/**
+	 * Count the number of new entries in the temporary table (which have not yet been committed), grouped by feed ID.
+	 * @return array<int,int>
+	 */
+	public function newUnreadEntriesPerFeed(): array {
+		$sql = <<<'SQL'
+		SELECT id_feed, COUNT(id) AS nb_entries FROM `_entrytmp`
+		WHERE is_read = 0
+		GROUP BY id_feed
+		SQL;
+		$lines = $this->fetchAssoc($sql) ?? [];
+		$result = [];
+		foreach ($lines as $line) {
+			if (!empty($line['id_feed'])) {
+				$result[(int)$line['id_feed']] = (int)($line['nb_entries'] ?? 0);
+			}
+		}
+		return $result;
+	}
+
 	/**
 	 * Toggle favorite marker on one or more article
 	 *

+ 19 - 16
app/Models/Feed.php

@@ -46,7 +46,6 @@ class FreshRSS_Feed extends Minz_Model {
 	private ?FreshRSS_Category $category;
 	private int $nbEntries = -1;
 	private int $nbNotRead = -1;
-	private int $nbPendingNotRead = 0;
 	private string $name = '';
 	private string $website = '';
 	private string $description = '';
@@ -211,13 +210,13 @@ class FreshRSS_Feed extends Minz_Model {
 
 		return $this->nbEntries;
 	}
-	public function nbNotRead(bool $includePending = false): int {
+	public function nbNotRead(): int {
 		if ($this->nbNotRead < 0) {
 			$feedDAO = FreshRSS_Factory::createFeedDao();
 			$this->nbNotRead = $feedDAO->countNotRead($this->id());
 		}
 
-		return $this->nbNotRead + ($includePending ? $this->nbPendingNotRead : 0);
+		return $this->nbNotRead;
 	}
 
 	public function faviconPrepare(): void {
@@ -750,15 +749,7 @@ class FreshRSS_Feed extends Minz_Model {
 	}
 
 	/**
-	 * To keep track of some new potentially unread articles since last commit+fetch from database
-	 */
-	public function incPendingUnread(int $n = 1): void {
-		$this->nbPendingNotRead += $n;
-	}
-
-	/**
-	 * Remember to call updateCachedValue($id_feed) or updateCachedValues() just after.
-	 * @return int|false the number of lines affected, or false if not applicable
+	 * @return int|null The max number of unread articles to keep, or null if disabled.
 	 * @throws JsonException
 	 */
 	public function keepMaxUnread() {
@@ -766,11 +757,23 @@ class FreshRSS_Feed extends Minz_Model {
 		if ($keepMaxUnread === null) {
 			$keepMaxUnread = FreshRSS_Context::$user_conf->mark_when['max_n_unread'];
 		}
-		$keepMaxUnread = (int)$keepMaxUnread;
-		if ($keepMaxUnread > 0 && $this->nbNotRead(false) + $this->nbPendingNotRead > $keepMaxUnread) {
-			return FreshRSS_Factory::createFeedDao()->keepMaxUnread($this->id(), max(0, $keepMaxUnread - $this->nbPendingNotRead));
+		return is_int($keepMaxUnread) && $keepMaxUnread >= 0 ? $keepMaxUnread : null;
+	}
+
+	/**
+	 * @return int|false The number of articles marked as read, of false if error
+	 */
+	public function markAsReadMaxUnread() {
+		$keepMaxUnread = $this->keepMaxUnread();
+		if ($keepMaxUnread === null) {
+			return false;
 		}
-		return false;
+		$feedDAO = FreshRSS_Factory::createFeedDao();
+		$affected = $feedDAO->markAsReadMaxUnread($this->id(), $keepMaxUnread);
+		if ($affected > 0) {
+			Minz_Log::debug(__METHOD__ . " $affected items [" . $this->url(false) . ']');
+		}
+		return $affected;
 	}
 
 	/**

+ 4 - 4
app/Models/FeedDAO.php

@@ -373,7 +373,7 @@ SQL;
 	 * @return array<FreshRSS_Feed>
 	 */
 	public function listFeedsOrderUpdate(int $defaultCacheDuration = 3600, int $limit = 0): array {
-		$sql = 'SELECT id, url, kind, name, website, `lastUpdate`, `pathEntries`, `httpAuth`, ttl, attributes '
+		$sql = 'SELECT id, url, kind, name, website, `lastUpdate`, `pathEntries`, `httpAuth`, ttl, attributes, `cache_nbEntries`, `cache_nbUnreads` '
 			. 'FROM `_feed` '
 			. ($defaultCacheDuration < 0 ? '' : 'WHERE ttl >= ' . FreshRSS_Feed::TTL_DEFAULT
 				. ' AND `lastUpdate` < (' . (time() + 60)
@@ -468,7 +468,7 @@ SQL;
 	 * Remember to call updateCachedValues() after calling this function
 	 * @return int|false number of lines affected or false in case of error
 	 */
-	public function keepMaxUnread(int $id, int $n) {
+	public function markAsReadMaxUnread(int $id, int $n) {
 		//Double SELECT for MySQL workaround ERROR 1093 (HY000)
 		$sql = <<<'SQL'
 UPDATE `_entry` SET is_read=1
@@ -610,8 +610,8 @@ SQL;
 			$myFeed->_error($dao['error'] ?? 0);
 			$myFeed->_ttl($dao['ttl'] ?? FreshRSS_Feed::TTL_DEFAULT);
 			$myFeed->_attributes('', $dao['attributes'] ?? '');
-			$myFeed->_nbNotRead($dao['cache_nbUnreads'] ?? 0);
-			$myFeed->_nbEntries($dao['cache_nbEntries'] ?? 0);
+			$myFeed->_nbNotRead($dao['cache_nbUnreads'] ?? -1);
+			$myFeed->_nbEntries($dao['cache_nbEntries'] ?? -1);
 			if (isset($dao['id'])) {
 				$myFeed->_id($dao['id']);
 			}

+ 1 - 1
app/Models/UserConfiguration.php

@@ -34,7 +34,7 @@ declare(strict_types=1);
  * @property bool $lazyload
  * @property string $mail_login
  * @property bool $mark_updated_article_unread
- * @property array<string,bool> $mark_when
+ * @property array<string,bool|int> $mark_when
  * @property int $max_posts_per_rss
  * @property-read array<string,int> $limits
  * @property int|null $old_entries

+ 1 - 1
app/actualize_script.php

@@ -13,7 +13,7 @@ $begin_date = date_create('now');
 $_GET['c'] = 'feed';
 $_GET['a'] = 'actualize';
 $_GET['ajax'] = 1;
-$_GET['force'] = true;
+$_GET['maxFeeds'] = PHP_INT_MAX;
 $_SERVER['HTTP_HOST'] = '';
 
 $app = new FreshRSS();

+ 4 - 1
cli/actualize-user.php

@@ -31,7 +31,10 @@ if (!empty($result['successes'])) {
 	echo "FreshRSS refreshed $successes dynamic OPMLs for $username\n";
 }
 
-list($nbUpdatedFeeds, $feed, $nbNewArticles) = FreshRSS_feed_Controller::actualizeFeed(0, '', true);
+[$nbUpdatedFeeds, , $nbNewArticles] = FreshRSS_feed_Controller::actualizeFeeds();
+if ($nbNewArticles > 0) {
+	FreshRSS_feed_Controller::commitNewEntries();
+}
 
 echo "FreshRSS actualized $nbUpdatedFeeds feeds for $username ($nbNewArticles new articles)\n";
 

+ 4 - 8
docs/en/users/09_refreshing_feeds.md

@@ -58,19 +58,15 @@ To do so, you need to create a scheduled task, which need to call a specific URL
 
 Special parameters to configure the script - all parameters can be combined:
 
-- Parameter "force"
-<https://freshrss.example.net/i/?c=feed&a=actualize&force=1>
-If *force* is set to 1 all feeds will be refreshed at once.
-
-- Parameter "ajax"
+- Parameter `ajax`
 <https://freshrss.example.net/i/?c=feed&a=actualize&ajax=1>
 Only a status site is returned and not a complete website. Example: "OK"
 
-- Parameter "maxFeeds"
+- Parameter `maxFeeds`
 <https://freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=30>
-If *maxFeeds* is set the configured amount of feeds is refreshed at once. The default setting is "10".
+If *maxFeeds* is set the configured amount of feeds is refreshed at once. The default setting is `10`.
 
-- Parameter "token"
+- Parameter `token`
 <https://freshrss.example.net/i/?c=feed&a=actualize&token=542345872345734>
 Security parameter to prevent unauthorized refreshes. For detailed Documentation see "Form authentication".
 

+ 4 - 8
docs/fr/users/03_Main_view.md

@@ -45,19 +45,15 @@ toutes les heures.
 « Paramètres de configuration du script; Ils sont utilisables simultanément
 : »
 
-* Parameter "force"
-<https://freshrss.example.net/i/?c=feed&a=actualize&force=1> If *force* is set
-to 1 all feeds will be refreshed at once.
-
-* Parameter "ajax" <https://freshrss.example.net/i/?c=feed&a=actualize&ajax=1>
+* Parameter `ajax` <https://freshrss.example.net/i/?c=feed&a=actualize&ajax=1>
 Only a status site is returned and not a complete website. Example: "OK"
 
-* Parameter "maxFeeds"
+* Parameter `maxFeeds`
 <https://freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=30> If *maxFeeds*
 is set the configured amount of feeds is refreshed at once. The default
-setting is "10".
+setting is `10`.
 
-* Parameter "token"
+* Parameter `token`
 <https://freshrss.example.net/i/?c=feed&a=actualize&token=542345872345734>
 Security parameter to prevent unauthorized refreshes. For detailed
 Documentation see "Form authentication".

+ 0 - 8
docs/i18n/freshrss.fr.po

@@ -8386,14 +8386,6 @@ msgstr ""
 "« Paramètres de configuration du script; Ils sont utilisables "
 "simultanément : »"
 
-#. type: Plain text
-#: en/./users/09_refreshing_feeds.md:64
-msgid ""
-"- Parameter \"force\" <https://freshrss.example.net/i/?"
-"c=feed&a=actualize&force=1> If *force* is set to 1 all feeds will be "
-"refreshed at once."
-msgstr ""
-
 #. type: Plain text
 #: en/./users/09_refreshing_feeds.md:68
 msgid ""

+ 0 - 9
docs/i18n/templates/freshrss.pot

@@ -7879,15 +7879,6 @@ msgstr ""
 msgid "Special parameters to configure the script - all parameters can be combined:"
 msgstr ""
 
-#. type: Plain text
-#: en/./users/09_refreshing_feeds.md:64
-#, markdown-text
-msgid ""
-"- Parameter \"force\" "
-"<https://freshrss.example.net/i/?c=feed&a=actualize&force=1> If *force* is "
-"set to 1 all feeds will be refreshed at once."
-msgstr ""
-
 #. type: Plain text
 #: en/./users/09_refreshing_feeds.md:68
 #, markdown-text

+ 4 - 1
p/api/greader.php

@@ -327,7 +327,10 @@ final class GReaderAPI {
 		$importService = new FreshRSS_Import_Service($user);
 		$importService->importOpml($opml);
 		if ($importService->lastStatus()) {
-			FreshRSS_feed_Controller::actualizeFeed(0, '', true);
+			[, , $nb_new_articles] = FreshRSS_feed_Controller::actualizeFeeds();
+			if ($nb_new_articles > 0) {
+				FreshRSS_feed_Controller::commitNewEntries();
+			}
 			invalidateHttpCache($user);
 			exit('OK');
 		} else {

+ 5 - 2
p/api/pshb.php

@@ -133,8 +133,11 @@ foreach ($users as $userFilename) {
 		Minz_ExtensionManager::enableByList(FreshRSS_Context::$user_conf->extensions_enabled, 'user');
 		Minz_Translate::reset(FreshRSS_Context::$user_conf->language);
 
-		list($updated_feeds, $feed, $nb_new_articles) = FreshRSS_feed_Controller::actualizeFeed(0, $self, false, $simplePie);
-		if ($updated_feeds > 0 || $feed != false) {
+		[$updated_feeds, , $nb_new_articles] = FreshRSS_feed_Controller::actualizeFeeds(null, $self, null, $simplePie);
+		if ($nb_new_articles > 0) {
+			FreshRSS_feed_Controller::commitNewEntries();
+		}
+		if ($updated_feeds > 0) {
 			$nb++;
 		} else {
 			Minz_Log::warning('Warning: User ' . $username . ' does not subscribe anymore to ' . $self, PSHB_LOG);