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

Improve markAsReadUponGone (#5315)

* Improve markAsReadUponGone
Fix case  when the uptream feed has zero article, then old articles would never be automatically marked as read with the "mark as read when gone" policy, which was only based on the timestamp of new articles from the uptream feed.

* Fix typo

* Simplify request
Needs to be re-tested with SQLite + MySQL

* While waiting to check syntax on all database types

* Fix multiple errors
In the case of WebSub, and in the case of invalid GUIDs
Alexandre Alapetite 3 лет назад
Родитель
Сommit
8abe53d879
3 измененных файлов с 25 добавлено и 13 удалено
  1. 4 1
      app/Controllers/feedController.php
  2. 10 8
      app/Models/Feed.php
  3. 11 4
      app/Models/FeedDAO.php

+ 4 - 1
app/Controllers/feedController.php

@@ -531,7 +531,10 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 
 			$feedDAO->updateLastUpdate($feed->id(), false, $mtime);
 			$needFeedCacheRefresh |= ($feed->keepMaxUnread() != false);
-			$needFeedCacheRefresh |= ($feed->markAsReadUponGone() != false);
+			if (!$simplePiePush) {
+				// Do not call for WebSub events, as we do not know the list of articles still on the upstream feed.
+				$needFeedCacheRefresh |= ($feed->markAsReadUponGone() != false);
+			}
 			if ($needFeedCacheRefresh) {
 				$feedDAO->updateCachedValues($feed->id());
 			}

+ 10 - 8
app/Models/Feed.php

@@ -278,7 +278,7 @@ class FreshRSS_Feed extends Minz_Model {
 		if ($validate) {
 			$url = checkUrl($url);
 		}
-		if ($url == '') {
+		if ($url == false) {
 			throw new FreshRSS_BadUrl_Exception($value);
 		}
 		$this->url = $url;
@@ -306,7 +306,7 @@ class FreshRSS_Feed extends Minz_Model {
 		if ($validate) {
 			$value = checkUrl($value);
 		}
-		if ($value == '') {
+		if ($value == false) {
 			$value = '';
 		}
 		$this->website = $value;
@@ -448,7 +448,8 @@ class FreshRSS_Feed extends Minz_Model {
 		$hasUniqueGuids = true;
 		$testGuids = [];
 		$guids = [];
-		$hasBadGuids = $this->attributes('hasBadGuids');
+		$links = [];
+		$hadBadGuids = $this->attributes('hasBadGuids');
 
 		$items = $simplePie->get_items();
 		if (empty($items)) {
@@ -463,19 +464,20 @@ class FreshRSS_Feed extends Minz_Model {
 			$hasUniqueGuids &= empty($testGuids['_' . $guid]);
 			$testGuids['_' . $guid] = true;
 			$guids[] = $guid;
+			$links[] = $item->get_permalink();
 		}
 
-		if ($hasBadGuids != !$hasUniqueGuids) {
-			$hasBadGuids = !$hasUniqueGuids;
-			if ($hasBadGuids) {
+		if ($hadBadGuids != !$hasUniqueGuids) {
+			if ($hadBadGuids) {
 				Minz_Log::warning('Feed has invalid GUIDs: ' . $this->url);
 			} else {
 				Minz_Log::warning('Feed has valid GUIDs again: ' . $this->url);
 			}
 			$feedDAO = FreshRSS_Factory::createFeedDao();
-			$feedDAO->updateFeedAttribute($this, 'hasBadGuids', $hasBadGuids);
+			$feedDAO->updateFeedAttribute($this, 'hasBadGuids', !$hasUniqueGuids);
 		}
-		return $guids;
+
+		return $hasUniqueGuids ? $guids : $links;
 	}
 
 	/** @return iterable<FreshRSS_Entry> */

+ 11 - 4
app/Models/FeedDAO.php

@@ -69,7 +69,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo {
 		);
 
 		if ($stm && $stm->execute($values)) {
-			return $this->pdo->lastInsertId('`_feed_id_seq`');
+			return (int)($this->pdo->lastInsertId('`_feed_id_seq`'));
 		} else {
 			$info = $stm == null ? $this->pdo->errorInfo() : $stm->errorInfo();
 			if ($this->autoUpdateDb($info)) {
@@ -355,7 +355,7 @@ SQL;
 	}
 
 	/**
-	 * Use $defaultCacheDuration == -1 to return all feeds, without filtering them by TTL.
+	 * @param int $defaultCacheDuration Use -1 to return all feeds, without filtering them by TTL.
 	 * @return array<FreshRSS_Feed>
 	 */
 	public function listFeedsOrderUpdate(int $defaultCacheDuration = 3600, int $limit = 0): array {
@@ -496,13 +496,20 @@ SQL;
 		//Double SELECT for MySQL workaround ERROR 1093 (HY000)
 		$sql = <<<'SQL'
 UPDATE `_entry` SET is_read=1
-WHERE id_feed=:id_feed1 AND is_read=0 AND `lastSeen` < (SELECT e3.maxlastseen FROM (
-	SELECT MAX(e2.`lastSeen`) AS maxlastseen FROM `_entry` e2 WHERE e2.id_feed = :id_feed2) e3)
+WHERE id_feed=:id_feed1 AND is_read=0 AND (
+	`lastSeen` + 60 < (SELECT s1.maxlastseen FROM (
+		SELECT MAX(e2.`lastSeen`) AS maxlastseen FROM `_entry` e2 WHERE e2.id_feed = :id_feed2
+	) s1)
+	OR `lastSeen` + 60 < (SELECT s2.lastcorrectupdate FROM (
+		SELECT f2.`lastUpdate` AS lastcorrectupdate FROM `_feed` f2 WHERE f2.id = :id_feed3 AND f2.error = 0
+	) s2)
+)
 SQL;
 
 		if (($stm = $this->pdo->prepare($sql)) &&
 			$stm->bindParam(':id_feed1', $id, PDO::PARAM_INT) &&
 			$stm->bindParam(':id_feed2', $id, PDO::PARAM_INT) &&
+			$stm->bindParam(':id_feed3', $id, PDO::PARAM_INT) &&
 			$stm->execute()) {
 			return $stm->rowCount();
 		} else {