From 882deab455fb7b6ca020391a33bff24e088c62bf Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Sat, 14 Sep 2024 23:11:10 +0200 Subject: Allow SimplePie updates with composer (#4374) * rename lib/SimplePie to lib/CustomSimplePie * add test for autoloading SimplePie with PSR-0 * install SimplePie 1.6.0 * Add SimplePie CHANGELOG.md, ignore irrelevant files * remove unmodified custom classes * rename all customized SimplePie classes * Add autoloading for SimplePie PSR-0 and CustomSimplePie classes * let CustomSimplePie extends SimplePie, remove unchanged code * let CustomSimplePieMisc extends SimplePie\Misc, remove unchanged code * Add tests for autoloading * let CustomSimplePieContentTypeSniffer extends Sniffer, remove unchanged code * remove unchanged CustomSimplePieEnclosure class The fixed typos are commited to SimplePie See https://github.com/simplepie/simplepie/pull/722/commits/133eac158cddaf5d2ddf9d9e5f42d92f944f885d * let CustomSimplePieFile extends SimplePie\File, remove unchanged code * let CustomSimplePieParser extends SimplePie\Parser, remove unchanged code * let CustomSimplePieSanitize extends SimplePie\Sanitize, remove unchanged code * let CustomSimplePieHttpParser extends SimplePie\HTTP\Parser, remove unchanged code * Remove CustomSimplePie * Switch SimplePie repo to https://github.com/FreshRSS/simplepie.git * move to latest branch, update all SimplePie source files * Use namespaced SimplePie classes, remove SimplePie library folder * Update to latest SimplePie version with FreshRSS modifications * Bump SimplePie Tests expected to fail due to missing a backport of functionalities * Add fork-specific readme * Re-implement initial syslog SimplePie GET https://github.com/FreshRSS/FreshRSS/pull/815 Lacks https://github.com/FreshRSS/FreshRSS/pull/6061 * Closer backport of syslog SimplePie GET https://github.com/FreshRSS/FreshRSS/pull/6061 But the requests logs will be in the wrong order in case of redirections * Fixes * lib update * SimplePie include a few more files * Try with cache-hash branch * Point to newer commit * Point to newer commit * Finalise logs * Finalise * Bump SimplePie commit * Bump SimplePie commit * Readme SimplePie fork * Bump SimplePie commit * Better logging * Bump SimplePie commit * Reworked approach to work with SimplePie cache Simpler FreshRSS patches * Bump SimplePie commit https://github.com/FreshRSS/simplepie/pull/22 * Simplepie846 https://github.com/FreshRSS/simplepie/pull/23 And additional fixes * Remove log * Cherry pick relevant unmerged SimplePie PRs --------- Co-authored-by: Alexandre Alapetite --- app/Controllers/feedController.php | 16 +++++++++++----- app/Models/Category.php | 4 ++-- app/Models/Entry.php | 2 +- app/Models/Feed.php | 33 +++++++++++++++++---------------- app/Models/SimplePieResponse.php | 10 ++++++++++ app/Services/ImportService.php | 2 +- 6 files changed, 42 insertions(+), 25 deletions(-) mode change 100644 => 100755 app/Controllers/feedController.php create mode 100644 app/Models/SimplePieResponse.php (limited to 'app') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php old mode 100644 new mode 100755 index 3f4ed3149..9c4860521 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -385,7 +385,8 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { * list of feeds for which a cache refresh is needed * @throws FreshRSS_BadUrl_Exception */ - public static function actualizeFeeds(?int $feed_id = null, ?string $feed_url = null, ?int $maxFeeds = null, ?SimplePie $simplePiePush = null): array { + public static function actualizeFeeds(?int $feed_id = null, ?string $feed_url = null, ?int $maxFeeds = null, + ?\SimplePie\SimplePie $simplePiePush = null): array { if (function_exists('set_time_limit')) { @set_time_limit(300); } @@ -443,6 +444,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { } $url = $feed->url(); //For detection of HTTP 301 + $oldSimplePieHash = $feed->attributeString('SimplePieHash'); $pubSubHubbubEnabled = $pubsubhubbubEnabledGeneral && $feed->pubSubHubbubEnabled(); if ($simplePiePush === null && $feed_id === null && $pubSubHubbubEnabled && ($feed->lastUpdate() > $pshbMinAge)) { @@ -619,7 +621,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { if ($pubSubHubbubEnabled && $simplePiePush === null) { //We use push, but have discovered an article by pull! $text = 'An article was discovered by pull although we use PubSubHubbub!: Feed ' . - SimplePie_Misc::url_remove_credentials($url) . + \SimplePie\Misc::url_remove_credentials($url) . ' GUID ' . $entry->guid(); Minz_Log::warning($text, PSHB_LOG); Minz_Log::warning($text); @@ -657,6 +659,9 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { } $feedProperties = []; + if ($oldSimplePieHash !== $feed->attributeString('SimplePieHash')) { + $feedProperties['attributes'] = $feed->attributes(); + } if ($pubsubhubbubEnabledGeneral && $feed->hubUrl() !== '' && $feed->selfUrl() !== '') { //selfUrl has priority for WebSub if ($feed->selfUrl() !== $url) { // https://github.com/pubsubhubbub/PubSubHubbub/wiki/Moving-Feeds-or-changing-Hubs @@ -672,8 +677,8 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { } } } elseif ($feed->url() !== $url) { // HTTP 301 Moved Permanently - Minz_Log::notice('Feed ' . SimplePie_Misc::url_remove_credentials($url) . - ' moved permanently to ' . SimplePie_Misc::url_remove_credentials($feed->url(false))); + Minz_Log::notice('Feed ' . \SimplePie\Misc::url_remove_credentials($url) . + ' moved permanently to ' . \SimplePie\Misc::url_remove_credentials($feed->url(false))); $feedProperties['url'] = $feed->url(); } @@ -798,7 +803,8 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { * list of feeds for which a cache refresh is needed * @throws FreshRSS_BadUrl_Exception */ - public static function actualizeFeedsAndCommit(?int $feed_id = null, ?string $feed_url = null, ?int $maxFeeds = null, ?SimplePie $simplePiePush = null): array { + public static function actualizeFeedsAndCommit(?int $feed_id = null, ?string $feed_url = null, ?int $maxFeeds = null, + ?SimplePie\SimplePie $simplePiePush = null): array { $entryDAO = FreshRSS_Factory::createEntryDao(); [$nbUpdatedFeeds, $feed, $nbNewArticles, $feedsCacheToRefresh] = FreshRSS_feed_Controller::actualizeFeeds($feed_id, $feed_url, $maxFeeds, $simplePiePush); if ($nbNewArticles > 0) { diff --git a/app/Models/Category.php b/app/Models/Category.php index 691ac1066..5c346844a 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -181,7 +181,7 @@ class FreshRSS_Category extends Minz_Model { $opml = httpGet($url, $cachePath, 'opml', $this->attributes(), $this->curlOptions()); if ($opml == '') { Minz_Log::warning('Error getting dynamic OPML for category ' . $this->id() . '! ' . - SimplePie_Misc::url_remove_credentials($url)); + \SimplePie\Misc::url_remove_credentials($url)); $ok = false; } else { $dryRunCategory = new FreshRSS_Category(); @@ -229,7 +229,7 @@ class FreshRSS_Category extends Minz_Model { } else { $ok = false; Minz_Log::warning('Error loading dynamic OPML for category ' . $this->id() . '! ' . - SimplePie_Misc::url_remove_credentials($url)); + \SimplePie\Misc::url_remove_credentials($url)); } } diff --git a/app/Models/Entry.php b/app/Models/Entry.php index c1ae66f65..fe6702bcd 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -830,7 +830,7 @@ HTML; foreach ($metas as $meta) { if ($meta instanceof DOMElement && strtolower(trim($meta->getAttribute('http-equiv'))) === 'refresh') { $refresh = preg_replace('/^[0-9.; ]*\s*(url\s*=)?\s*/i', '', trim($meta->getAttribute('content'))); - $refresh = SimplePie_Misc::absolutize_url($refresh, $url); + $refresh = is_string($refresh) ? \SimplePie\Misc::absolutize_url($refresh, $url) : false; if ($refresh != false && $refresh !== $url) { return $this->getContentByParsing($refresh, $maxRedirs - 1); } diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 37f1d8cd4..7b6fda7b6 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -95,7 +95,7 @@ class FreshRSS_Feed extends Minz_Model { } public function url(bool $includeCredentials = true): string { - return $includeCredentials ? $this->url : SimplePie_Misc::url_remove_credentials($this->url); + return $includeCredentials ? $this->url : \SimplePie\Misc::url_remove_credentials($this->url); } public function selfUrl(): string { return $this->selfUrl; @@ -343,7 +343,7 @@ class FreshRSS_Feed extends Minz_Model { * @throws Minz_FileNotExistException * @throws FreshRSS_Feed_Exception */ - public function load(bool $loadDetails = false, bool $noCache = false): ?SimplePie { + public function load(bool $loadDetails = false, bool $noCache = false): ?\SimplePie\SimplePie { if ($this->url != '') { /** * @throws Minz_FileNotExistException @@ -362,16 +362,16 @@ class FreshRSS_Feed extends Minz_Model { } $simplePie->set_feed_url($url); if (!$loadDetails) { //Only activates auto-discovery when adding a new feed - $simplePie->set_autodiscovery_level(SIMPLEPIE_LOCATOR_NONE); + $simplePie->set_autodiscovery_level(\SimplePie\SimplePie::LOCATOR_NONE); } if ($this->attributeBoolean('clear_cache')) { // Do not use `$simplePie->enable_cache(false);` as it would prevent caching in multiuser context $this->clearCache(); } Minz_ExtensionManager::callHook('simplepie_before_init', $simplePie, $this); - $mtime = $simplePie->init(); + $simplePieResult = $simplePie->init(); - if ((!$mtime) || !empty($simplePie->error())) { + if ($simplePieResult === false || $simplePie->get_hash() === '' || !empty($simplePie->error())) { $errorMessage = $simplePie->error(); if (empty($errorMessage)) { $errorMessage = ''; @@ -380,7 +380,7 @@ class FreshRSS_Feed extends Minz_Model { } throw new FreshRSS_Feed_Exception( ($errorMessage == '' ? 'Unknown error for feed' : $errorMessage) . - ' [' . $this->url . ']', + ' [' . \SimplePie\Misc::url_remove_credentials($this->url) . ']', $simplePie->status_code() ); } @@ -410,16 +410,17 @@ class FreshRSS_Feed extends Minz_Model { $subscribe_url = $simplePie->subscribe_url(true) ?? ''; } - $clean_url = SimplePie_Misc::url_remove_credentials($subscribe_url); + $clean_url = \SimplePie\Misc::url_remove_credentials($subscribe_url); if ($subscribe_url !== '' && $subscribe_url !== $url) { $this->_url($clean_url); } - if (($mtime === true) || ($mtime > $this->lastUpdate) || $noCache) { - //Minz_Log::debug('FreshRSS no cache ' . $mtime . ' > ' . $this->lastUpdate . ' for ' . $clean_url); + if ($noCache || $simplePie->get_hash() !== $this->attributeString('SimplePieHash')) { + // syslog(LOG_DEBUG, 'FreshRSS no cache ' . $simplePie->get_hash() . ' !== ' . $this->attributeString('SimplePieHash') . ' for ' . $clean_url); + $this->_attribute('SimplePieHash', $simplePie->get_hash()); return $simplePie; } - //Minz_Log::debug('FreshRSS use cache for ' . $clean_url); + syslog(LOG_DEBUG, 'FreshRSS SimplePie uses cache for ' . $clean_url); } } return null; @@ -428,7 +429,7 @@ class FreshRSS_Feed extends Minz_Model { /** * @return array */ - public function loadGuids(SimplePie $simplePie): array { + public function loadGuids(\SimplePie\SimplePie $simplePie): array { $hasUniqueGuids = true; $testGuids = []; $guids = []; @@ -468,7 +469,7 @@ class FreshRSS_Feed extends Minz_Model { } /** @return Traversable */ - public function loadEntries(SimplePie $simplePie): Traversable { + public function loadEntries(\SimplePie\SimplePie $simplePie): Traversable { $hasBadGuids = $this->attributeBoolean('hasBadGuids'); $items = $simplePie->get_items(); @@ -575,7 +576,7 @@ class FreshRSS_Feed extends Minz_Model { if (is_array($authors)) { foreach ($authors as $author) { $authorName = $author->name != '' ? $author->name : $author->email; - if ($authorName != '') { + if (is_string($authorName) && $authorName !== '') { $authorNames .= escapeToUnicodeAlternative(strip_tags($authorName), true) . '; '; } } @@ -609,7 +610,7 @@ class FreshRSS_Feed extends Minz_Model { * returns a SimplePie initialized already with that content * @param string $feedContent the content of the feed, typically generated via FreshRSS_View::renderToString() */ - private function simplePieFromContent(string $feedContent): SimplePie { + private function simplePieFromContent(string $feedContent): \SimplePie\SimplePie { $simplePie = customSimplePie(); $simplePie->set_raw_data($feedContent); $simplePie->init(); @@ -637,7 +638,7 @@ class FreshRSS_Feed extends Minz_Model { ]; } - public function loadJson(): ?SimplePie { + public function loadJson(): ?\SimplePie\SimplePie { if ($this->url == '') { return null; } @@ -669,7 +670,7 @@ class FreshRSS_Feed extends Minz_Model { return $this->simplePieFromContent($feedContent); } - public function loadHtmlXpath(): ?SimplePie { + public function loadHtmlXpath(): ?\SimplePie\SimplePie { if ($this->url == '') { return null; } diff --git a/app/Models/SimplePieResponse.php b/app/Models/SimplePieResponse.php new file mode 100644 index 000000000..17c954e8c --- /dev/null +++ b/app/Models/SimplePieResponse.php @@ -0,0 +1,10 @@ +get_status_code() . ' ' . \SimplePie\Misc::url_remove_credentials($this->get_final_requested_uri())); + } +} diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php index 9ec36b61c..1871c37e0 100644 --- a/app/Services/ImportService.php +++ b/app/Services/ImportService.php @@ -316,7 +316,7 @@ class FreshRSS_Import_Service { $this->lastStatus = false; } - $clean_url = SimplePie_Misc::url_remove_credentials($url); + $clean_url = \SimplePie\Misc::url_remove_credentials($url); self::log("Cannot create {$clean_url} feed in category {$category->name()}"); return null; } -- cgit v1.2.3