diff options
| author | 2015-05-16 13:05:43 +0200 | |
|---|---|---|
| committer | 2015-05-16 13:05:43 +0200 | |
| commit | 3adab4b70fab858048bd68ed72e71676c4d5badf (patch) | |
| tree | d920a83bc8aaca915bdde358e24ee84f52c3b139 /app | |
| parent | 0163564b9e02bc399c26d3083048f38d3374cbd7 (diff) | |
More PubSubHubbub
https://github.com/FreshRSS/FreshRSS/issues/312
Show whether PubSubHubbub is enabled in the Web interface of feed
configuration.
When PubSubHubbub is used, do not pull refresh so often (hard-coded to
max once per 24h for now).
Improved logic for lease renewal, and some detection of lease problems.
Updated read-me and changelog.
Diffstat (limited to 'app')
| -rwxr-xr-x | app/Controllers/feedController.php | 36 | ||||
| -rw-r--r-- | app/Models/Feed.php | 59 | ||||
| -rw-r--r-- | app/i18n/cz/conf.php | 1 | ||||
| -rw-r--r-- | app/i18n/cz/sub.php | 1 | ||||
| -rw-r--r-- | app/i18n/de/sub.php | 1 | ||||
| -rw-r--r-- | app/i18n/en/sub.php | 1 | ||||
| -rw-r--r-- | app/i18n/fr/sub.php | 1 | ||||
| -rw-r--r-- | app/views/helpers/feed/update.phtml | 8 |
8 files changed, 87 insertions, 21 deletions
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index ab73879d0..dfdf0dc16 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -268,7 +268,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { * 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. */ - public function actualizeAction($simplePie = null) { + public function actualizeAction($simplePiePush = null) { @set_time_limit(300); $feedDAO = FreshRSS_Factory::createFeedDao(); @@ -295,10 +295,16 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // Calculate date of oldest entries we accept in DB. $nb_month_old = max(FreshRSS_Context::$user_conf->old_entries, 1); $date_min = time() - (3600 * 24 * 30 * $nb_month_old); + $pshbMinAge = time() - (3600 * 24); //TODO: Make a configuration. $updated_feeds = 0; $is_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0; foreach ($feeds as $feed) { + $pubSubHubbubEnabled = $feed->pubSubHubbubEnabled(); + if ((!$simplePiePush) && (!$id) && (!$force) && $pubSubHubbubEnabled && ($feed->lastUpdate() > $pshbMinAge)) { + continue; //When PubSubHubbub is used, do not pull refresh so often + } + if (!$feed->lock()) { Minz_Log::notice('Feed already being actualized: ' . $feed->url()); continue; @@ -306,8 +312,8 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $url = $feed->url(); //For detection of HTTP 301 try { - if ($simplePie) { - $feed->loadEntries($simplePie); //Used by PubSubHubbub + if ($simplePiePush) { + $feed->loadEntries($simplePiePush); //Used by PubSubHubbub } else { $feed->load(false); } @@ -374,6 +380,14 @@ class FreshRSS_feed_Controller extends Minz_ActionController { continue; } + if ($pubSubHubbubEnabled && !$simplePiePush) { //We use push, but have discovered an article by pull! + $text = 'An article was discovered by pull although we use PubSubHubbub!: Feed ' . $url . ' GUID ' . $entry->guid(); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . $text . "\n", FILE_APPEND); + Minz_Log::warning($text); + $pubSubHubbubEnabled = false; + $feed->pubSubHubbubEnabled(false); //To force the renewal of our lease + } + if (!$entryDAO->hasTransaction()) { $entryDAO->beginTransaction(); } @@ -423,15 +437,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feedDAO->updateFeed($feed->id(), array('url' => $feed->url())); } - if ($simplePie === null) { - $feed->faviconPrepare(); - if (in_array($feed->url(), array('http://push-pub.appspot.com/feed'))) { //TODO: Remove white-list after testing - Minz_Log::debug('PubSubHubbub match ' . $feed->url()); - if ($feed->pubSubHubbubPrepare()) { - Minz_Log::notice('PubSubHubbub subscribe ' . $feed->url()); - if (!$feed->pubSubHubbubSubscribe(true)) { //Subscribe - Minz_Log::warning('Error while PubSubHubbub subscribing to ' . $feed->url()); - } + $feed->faviconPrepare(); + if (in_array($feed->url(), array('http://push-pub.appspot.com/feed'))) { //TODO: Remove white-list after testing + Minz_Log::debug('PubSubHubbub match ' . $feed->url()); + if ($feed->pubSubHubbubPrepare()) { + Minz_Log::notice('PubSubHubbub subscribe ' . $feed->url()); + if (!$feed->pubSubHubbubSubscribe(true)) { //Subscribe + Minz_Log::warning('Error while PubSubHubbub subscribing to ' . $feed->url()); } } } diff --git a/app/Models/Feed.php b/app/Models/Feed.php index d2b552265..7bc60dfc9 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -104,6 +104,16 @@ class FreshRSS_Feed extends Minz_Model { public function ttl() { return $this->ttl; } + // public function ttlExpire() { + // $ttl = $this->ttl; + // if ($ttl == -2) { //Default + // $ttl = FreshRSS_Context::$user_conf->ttl_default; + // } + // if ($ttl == -1) { //Never + // $ttl = 64000000; //~2 years. Good enough for PubSubHubbub logic + // } + // return $this->lastUpdate + $ttl; + // } public function nbEntries() { if ($this->nbEntries < 0) { $feedDAO = FreshRSS_Factory::createFeedDao(); @@ -349,18 +359,42 @@ class FreshRSS_Feed extends Minz_Model { //<PubSubHubbub> + function pubSubHubbubEnabled($keep = true) { + $url = $this->selfUrl ? $this->selfUrl : $this->url; + $hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($url) . '/!hub.json'; + if ($hubFile = @file_get_contents($hubFilename)) { + $hubJson = json_decode($hubFile, true); + if (!$keep) { + $hubJson['lease_end'] = time() - 60; + file_put_contents($hubFilename, json_encode($hubJson)); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" + . 'Force expire lease for ' . $url . "\n", FILE_APPEND); + } elseif ($hubJson && (empty($hubJson['lease_end']) || $hubJson['lease_end'] > time())) { + return true; + } + } + return false; + } + function pubSubHubbubPrepare() { $key = ''; if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl) { $path = PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl); - if ($hubFile = @file_get_contents($path . '/!hub.json')) { + $hubFilename = $path . '/!hub.json'; + if ($hubFile = @file_get_contents($hubFilename)) { $hubJson = json_decode($hubFile, true); if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) { - Minz_Log::warning('Invalid JSON for PubSubHubbub: ' . $this->url); + $text = 'Invalid JSON for PubSubHubbub: ' . $this->url; + Minz_Log::warning($text); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . $text . "\n", FILE_APPEND); return false; } - if (empty($hubJson['lease_end']) || $hubJson['lease_end'] <= time()) { - Minz_Log::warning('PubSubHubbub lease expired: ' . $this->url); + if (empty($hubJson['lease_end']) || ($hubJson['lease_end'] <= (time() + (3600 * 24)))) { //TODO: Make a better policy + $text = 'PubSubHubbub lease ends at ' + . date('c', empty($hubJson['lease_end']) ? time() : $hubJson['lease_end']) + . ' and needs renewal: ' . $this->url; + Minz_Log::warning($text); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . $text . "\n", FILE_APPEND); $key = $hubJson['key']; //To renew our lease } } else { @@ -370,12 +404,12 @@ class FreshRSS_Feed extends Minz_Model { 'hub' => $this->hubUrl, 'key' => $key, ); - file_put_contents($path . '/!hub.json', json_encode($hubJson)); + file_put_contents($hubFilename, json_encode($hubJson)); @mkdir(PSHB_PATH . '/keys/'); file_put_contents(PSHB_PATH . '/keys/' . $key . '.txt', base64url_encode($this->selfUrl)); - Minz_Log::debug('PubSubHubbub prepared for ' . $this->url); - file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . - 'PubSubHubbub prepared for ' . $this->url . "\n", FILE_APPEND); + $text = 'PubSubHubbub prepared for ' . $this->url; + Minz_Log::debug($text); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . $text . "\n", FILE_APPEND); } $currentUser = Minz_Session::param('currentUser'); if (ctype_alnum($currentUser) && !file_exists($path . '/' . $currentUser . '.txt')) { @@ -388,7 +422,8 @@ class FreshRSS_Feed extends Minz_Model { //Parameter true to subscribe, false to unsubscribe. function pubSubHubbubSubscribe($state) { if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl) { - $hubFile = @file_get_contents(PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl) . '/!hub.json'); + $hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl) . '/!hub.json'; + $hubFile = @file_get_contents($hubFilename); if ($hubFile === false) { Minz_Log::warning('JSON not found for PubSubHubbub: ' . $this->url); return false; @@ -421,6 +456,12 @@ class FreshRSS_Feed extends Minz_Model { file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . 'PubSubHubbub ' . ($state ? 'subscribe' : 'unsubscribe') . ' to ' . $this->selfUrl . ' with callback ' . $callbackUrl . ': ' . $info['http_code'] . ' ' . $response . "\n", FILE_APPEND); + + if (!$state) { //unsubscribe + $hubJson['lease_end'] = time() - 60; + file_put_contents($hubFilename, json_encode($hubJson)); + } + return substr($info['http_code'], 0, 1) == '2'; } return false; diff --git a/app/i18n/cz/conf.php b/app/i18n/cz/conf.php index 29fb1e4d4..9518df66d 100644 --- a/app/i18n/cz/conf.php +++ b/app/i18n/cz/conf.php @@ -84,6 +84,7 @@ return array( 'articles_per_page' => 'Počet článků na stranu', 'auto_load_more' => 'Načítat další články dole na stránce', 'auto_remove_article' => 'Po přečtení články schovat', + 'mark_updated_article_unread' => 'Označte aktualizované položky jako nepřečtené', 'confirm_enabled' => 'Vyžadovat potvrzení pro akci “označit vše jako přečtené”', 'display_articles_unfolded' => 'Ve výchozím stavu zobrazovat články otevřené', 'display_categories_unfolded' => 'Ve výchozím stavu zobrazovat kategorie zavřené', diff --git a/app/i18n/cz/sub.php b/app/i18n/cz/sub.php index 78712506c..cea0541e3 100644 --- a/app/i18n/cz/sub.php +++ b/app/i18n/cz/sub.php @@ -37,6 +37,7 @@ return array( 'url' => 'URL kanálu', 'validator' => 'Zkontrolovat platnost kanálu', 'website' => 'URL webové stránky', + 'pubsubhubbub' => 'Okamžité oznámení s PubSubHubbub', ), 'import_export' => array( 'export' => 'Export', diff --git a/app/i18n/de/sub.php b/app/i18n/de/sub.php index 0479b8f46..7433bd61c 100644 --- a/app/i18n/de/sub.php +++ b/app/i18n/de/sub.php @@ -37,6 +37,7 @@ return array( 'url' => 'Feed-URL', 'validator' => 'Überprüfen Sie die Gültigkeit des Feeds', 'website' => 'Webseiten-URL', + 'pubsubhubbub' => 'Sofortige Benachrichtigung mit PubSubHubbub', ), 'import_export' => array( 'export' => 'Exportieren', diff --git a/app/i18n/en/sub.php b/app/i18n/en/sub.php index 2b62e4775..d8b5ced04 100644 --- a/app/i18n/en/sub.php +++ b/app/i18n/en/sub.php @@ -37,6 +37,7 @@ return array( 'url' => 'Feed URL', 'validator' => 'Check the validity of the feed', 'website' => 'Website URL', + 'pubsubhubbub' => 'Instant notification with PubSubHubbub', ), 'import_export' => array( 'export' => 'Export', diff --git a/app/i18n/fr/sub.php b/app/i18n/fr/sub.php index a3f7c4d6d..0a1a03e41 100644 --- a/app/i18n/fr/sub.php +++ b/app/i18n/fr/sub.php @@ -37,6 +37,7 @@ return array( 'url' => 'URL du flux', 'validator' => 'Vérifier la valididé du flux', 'website' => 'URL du site', + 'pubsubhubbub' => 'Notification instantanée par PubSubHubbub', ), 'import_export' => array( 'export' => 'Exporter', diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml index 0b08d036c..b2cf9f93c 100644 --- a/app/views/helpers/feed/update.phtml +++ b/app/views/helpers/feed/update.phtml @@ -126,6 +126,14 @@ ?></select> </div> </div> + <div class="form-group"> + <label class="group-name" for="pubsubhubbub"><?php echo _t('sub.feed.pubsubhubbub'); ?></label> + <div class="group-controls"> + <label class="checkbox" for="pubsubhubbub"> + <input type="checkbox" name="pubsubhubbub" id="pubsubhubbub" disabled="disabled" value="1"<?php echo $this->feed->pubSubHubbubEnabled() ? ' checked="checked"' : ''; ?> /> + </label> + </div> + </div> <div class="form-group form-actions"> <div class="group-controls"> <button class="btn btn-important"><?php echo _t('gen.action.submit'); ?></button> |
