aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2015-05-16 13:05:43 +0200
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2015-05-16 13:05:43 +0200
commit3adab4b70fab858048bd68ed72e71676c4d5badf (patch)
treed920a83bc8aaca915bdde358e24ee84f52c3b139 /app
parent0163564b9e02bc399c26d3083048f38d3374cbd7 (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-xapp/Controllers/feedController.php36
-rw-r--r--app/Models/Feed.php59
-rw-r--r--app/i18n/cz/conf.php1
-rw-r--r--app/i18n/cz/sub.php1
-rw-r--r--app/i18n/de/sub.php1
-rw-r--r--app/i18n/en/sub.php1
-rw-r--r--app/i18n/fr/sub.php1
-rw-r--r--app/views/helpers/feed/update.phtml8
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>