|
|
|
@ -19,6 +19,8 @@ class FreshRSS_Feed extends Minz_Model { |
|
|
|
|
private $ttl = -2; |
|
|
|
|
private $hash = null; |
|
|
|
|
private $lockPath = ''; |
|
|
|
|
private $hubUrl = ''; |
|
|
|
|
private $selfUrl = ''; |
|
|
|
|
|
|
|
|
|
public function __construct($url, $validate=true) { |
|
|
|
|
if ($validate) { |
|
|
|
@ -49,6 +51,12 @@ class FreshRSS_Feed extends Minz_Model { |
|
|
|
|
public function url() { |
|
|
|
|
return $this->url; |
|
|
|
|
} |
|
|
|
|
public function selfUrl() { |
|
|
|
|
return $this->selfUrl; |
|
|
|
|
} |
|
|
|
|
public function hubUrl() { |
|
|
|
|
return $this->hubUrl; |
|
|
|
|
} |
|
|
|
|
public function category() { |
|
|
|
|
return $this->category; |
|
|
|
|
} |
|
|
|
@ -96,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(); |
|
|
|
@ -226,6 +244,11 @@ class FreshRSS_Feed extends Minz_Model { |
|
|
|
|
throw new FreshRSS_Feed_Exception(($errorMessage == '' ? 'Feed error' : $errorMessage) . ' [' . $url . ']'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$links = $feed->get_links('self'); |
|
|
|
|
$this->selfUrl = isset($links[0]) ? $links[0] : null; |
|
|
|
|
$links = $feed->get_links('hub'); |
|
|
|
|
$this->hubUrl = isset($links[0]) ? $links[0] : null; |
|
|
|
|
|
|
|
|
|
if ($loadDetails) { |
|
|
|
|
// si on a utilisé l'auto-discover, notre url va avoir changé |
|
|
|
|
$subscribe_url = $feed->subscribe_url(false); |
|
|
|
@ -259,7 +282,7 @@ class FreshRSS_Feed extends Minz_Model { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function loadEntries($feed) { |
|
|
|
|
public function loadEntries($feed) { |
|
|
|
|
$entries = array(); |
|
|
|
|
|
|
|
|
|
foreach ($feed->get_items() as $item) { |
|
|
|
@ -333,4 +356,129 @@ class FreshRSS_Feed extends Minz_Model { |
|
|
|
|
function unlock() { |
|
|
|
|
@unlink($this->lockPath); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//<PubSubHubbub> |
|
|
|
|
|
|
|
|
|
function pubSubHubbubEnabled() { |
|
|
|
|
$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 ($hubJson && empty($hubJson['error']) && |
|
|
|
|
(empty($hubJson['lease_end']) || $hubJson['lease_end'] > time())) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function pubSubHubbubError($error = true) { |
|
|
|
|
$url = $this->selfUrl ? $this->selfUrl : $this->url; |
|
|
|
|
$hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($url) . '/!hub.json'; |
|
|
|
|
$hubFile = @file_get_contents($hubFilename); |
|
|
|
|
$hubJson = $hubFile ? json_decode($hubFile, true) : array(); |
|
|
|
|
if (!isset($hubJson['error']) || $hubJson['error'] !== (bool)$error) { |
|
|
|
|
$hubJson['error'] = (bool)$error; |
|
|
|
|
file_put_contents($hubFilename, json_encode($hubJson)); |
|
|
|
|
file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" |
|
|
|
|
. 'Set error to ' . ($error ? 1 : 0) . ' for ' . $url . "\n", FILE_APPEND); |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function pubSubHubbubPrepare() { |
|
|
|
|
$key = ''; |
|
|
|
|
if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl && @is_dir(PSHB_PATH)) { |
|
|
|
|
$path = PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl); |
|
|
|
|
$hubFilename = $path . '/!hub.json'; |
|
|
|
|
if ($hubFile = @file_get_contents($hubFilename)) { |
|
|
|
|
$hubJson = json_decode($hubFile, true); |
|
|
|
|
if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) { |
|
|
|
|
$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() + (3600 * 23)))) { //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 |
|
|
|
|
} elseif (((!empty($hubJson['error'])) || empty($hubJson['lease_end'])) && |
|
|
|
|
(empty($hubJson['lease_start']) || $hubJson['lease_start'] < time() - (3600 * 23))) { //Do not renew too often |
|
|
|
|
$key = $hubJson['key']; //To renew our lease |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
@mkdir($path, 0777, true); |
|
|
|
|
$key = sha1($path . FreshRSS_Context::$system_conf->salt . uniqid(mt_rand(), true)); |
|
|
|
|
$hubJson = array( |
|
|
|
|
'hub' => $this->hubUrl, |
|
|
|
|
'key' => $key, |
|
|
|
|
); |
|
|
|
|
file_put_contents($hubFilename, json_encode($hubJson)); |
|
|
|
|
@mkdir(PSHB_PATH . '/keys/'); |
|
|
|
|
file_put_contents(PSHB_PATH . '/keys/' . $key . '.txt', base64url_encode($this->selfUrl)); |
|
|
|
|
$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')) { |
|
|
|
|
touch($path . '/' . $currentUser . '.txt'); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return $key; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//Parameter true to subscribe, false to unsubscribe. |
|
|
|
|
function pubSubHubbubSubscribe($state) { |
|
|
|
|
if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl) { |
|
|
|
|
$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; |
|
|
|
|
} |
|
|
|
|
$hubJson = json_decode($hubFile, true); |
|
|
|
|
if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) { |
|
|
|
|
Minz_Log::warning('Invalid JSON for PubSubHubbub: ' . $this->url); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
$callbackUrl = checkUrl(FreshRSS_Context::$system_conf->base_url . 'api/pshb.php?k=' . $hubJson['key']); |
|
|
|
|
if ($callbackUrl == '') { |
|
|
|
|
Minz_Log::warning('Invalid callback for PubSubHubbub: ' . $this->url); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
$ch = curl_init(); |
|
|
|
|
curl_setopt_array($ch, array( |
|
|
|
|
CURLOPT_URL => $this->hubUrl, |
|
|
|
|
CURLOPT_FOLLOWLOCATION => true, |
|
|
|
|
CURLOPT_RETURNTRANSFER => true, |
|
|
|
|
CURLOPT_USERAGENT => _t('gen.freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ')', |
|
|
|
|
CURLOPT_POSTFIELDS => 'hub.verify=sync' |
|
|
|
|
. '&hub.mode=' . ($state ? 'subscribe' : 'unsubscribe') |
|
|
|
|
. '&hub.topic=' . urlencode($this->selfUrl) |
|
|
|
|
. '&hub.callback=' . urlencode($callbackUrl) |
|
|
|
|
) |
|
|
|
|
); |
|
|
|
|
$response = curl_exec($ch); |
|
|
|
|
$info = curl_getinfo($ch); |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//</PubSubHubbub> |
|
|
|
|
} |
|
|
|
|