new page entrance + new dedicated dir for bridges + some fixe, optimizations
This commit is contained in:
parent
2797336bbe
commit
50b87448c6
6 changed files with 250 additions and 90 deletions
|
@ -43,6 +43,9 @@ I'm sebsauvage, webmaster of [sebsauvage.net](http://sebsauvage.net), author of
|
||||||
|
|
||||||
Thanks to [Mitsukarenai](https://github.com/Mitsukarenai) for the inspiration.
|
Thanks to [Mitsukarenai](https://github.com/Mitsukarenai) for the inspiration.
|
||||||
|
|
||||||
|
Patch :
|
||||||
|
- Yves ASTIER (Draeli) : PHP optimizations, minor fixes, dynamic brigde list with all stuff behind
|
||||||
|
|
||||||
Licence
|
Licence
|
||||||
===
|
===
|
||||||
Code is public domain.
|
Code is public domain.
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
require_once('rss-bridge-lib.php');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RssBridgeFlickrExplore
|
* RssBridgeFlickrExplore
|
||||||
* Returns the newest interesting images from http://www.flickr.com/explore
|
* Returns the newest interesting images from http://www.flickr.com/explore
|
||||||
|
*
|
||||||
|
* @name Flickr Explore
|
||||||
|
* @description Returns the latest interesting images from Flickr
|
||||||
*/
|
*/
|
||||||
class RssBridgeFlickrExplore extends RssBridgeAbstractClass
|
class RssBridgeFlickrExplore extends RssBridgeAbstractClass
|
||||||
{
|
{
|
||||||
|
@ -12,7 +13,7 @@ class RssBridgeFlickrExplore extends RssBridgeAbstractClass
|
||||||
protected $bridgeDescription = 'Returns the latest interesting images from Flickr';
|
protected $bridgeDescription = 'Returns the latest interesting images from Flickr';
|
||||||
protected $cacheDuration = 360; // 6 hours. No need to get more.
|
protected $cacheDuration = 360; // 6 hours. No need to get more.
|
||||||
protected function collectData($request) {
|
protected function collectData($request) {
|
||||||
$html = file_get_html('http://www.flickr.com/explore') or $this->returnError('404 Not Found', 'ERROR: could not request Flickr.');
|
$html = file_get_html('http://www.flickr.com/explore') or $this->returnError(404, 'could not request Flickr.');
|
||||||
$this->items = Array();
|
$this->items = Array();
|
||||||
foreach($html->find('span.photo_container') as $element) {
|
foreach($html->find('span.photo_container') as $element) {
|
||||||
$item['uri'] = 'http://flickr.com'.$element->find('a',0)->href;
|
$item['uri'] = 'http://flickr.com'.$element->find('a',0)->href;
|
||||||
|
@ -26,4 +27,3 @@ class RssBridgeFlickrExplore extends RssBridgeAbstractClass
|
||||||
|
|
||||||
$bridge = new RssBridgeFlickrExplore();
|
$bridge = new RssBridgeFlickrExplore();
|
||||||
$bridge->process();
|
$bridge->process();
|
||||||
?>
|
|
|
@ -1,16 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
require_once('rss-bridge-lib.php');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RssBridgeGoogleMostRecent
|
* RssBridgeGoogleMostRecent
|
||||||
* Search Google for most recent pages regarding a specific topic.
|
* Search Google for most recent pages regarding a specific topic.
|
||||||
* Returns the 100 most recent links in results in past year,
|
* Returns the 100 most recent links in results in past year, sorting by date (most recent first).
|
||||||
* sorting by date (most recent first).
|
|
||||||
* Example:
|
* Example:
|
||||||
* http://www.google.com/search?q=sebsauvage&num=100&complete=0&tbs=qdr:y,sbd:1
|
* http://www.google.com/search?q=sebsauvage&num=100&complete=0&tbs=qdr:y,sbd:1
|
||||||
* complete=0&num=100 : get 100 results
|
* complete=0&num=100 : get 100 results
|
||||||
* qdr:y : in past year
|
* qdr:y : in past year
|
||||||
* sbd:1 : sort by date (will only work if qdr: is specified)
|
* sbd:1 : sort by date (will only work if qdr: is specified)
|
||||||
|
*
|
||||||
|
* @name Google search
|
||||||
|
* @description Returns most recent results from Google search.
|
||||||
|
* @use1(q="keyword search")
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class RssBridgeGoogleSearch extends RssBridgeAbstractClass
|
class RssBridgeGoogleSearch extends RssBridgeAbstractClass
|
||||||
|
@ -22,9 +23,9 @@ class RssBridgeGoogleSearch extends RssBridgeAbstractClass
|
||||||
protected function collectData($request) {
|
protected function collectData($request) {
|
||||||
$html = '';
|
$html = '';
|
||||||
if (isset($request['q'])) { /* keyword search mode */
|
if (isset($request['q'])) { /* keyword search mode */
|
||||||
$html = file_get_html('http://www.google.com/search?q='.urlencode($request['q']).'&num=100&complete=0&tbs=qdr:y,sbd:1') or $this->returnError('404 Not Found', 'ERROR: no results for this query.');
|
$html = file_get_html('http://www.google.com/search?q='.urlencode($request['q']).'&num=100&complete=0&tbs=qdr:y,sbd:1') or $this->returnError(404, 'no results for this query.');
|
||||||
} else {
|
} else {
|
||||||
$this->returnError('400 Bad Request', 'ERROR: You must specify a keyword (?q=...).');
|
$this->returnError(400, 'You must specify a keyword (?q=...).');
|
||||||
}
|
}
|
||||||
$this->items = Array();
|
$this->items = Array();
|
||||||
foreach($html->find('div[id=ires]',0)->find('li[class=g]') as $element) {
|
foreach($html->find('div[id=ires]',0)->find('li[class=g]') as $element) {
|
||||||
|
@ -38,4 +39,3 @@ class RssBridgeGoogleSearch extends RssBridgeAbstractClass
|
||||||
|
|
||||||
$bridge = new RssBridgeGoogleSearch();
|
$bridge = new RssBridgeGoogleSearch();
|
||||||
$bridge->process();
|
$bridge->process();
|
||||||
?>
|
|
|
@ -1,9 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
require_once('rss-bridge-lib.php');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RssBridgeTwitter
|
* RssBridgeTwitter
|
||||||
* Based on https://github.com/mitsukarenai/twitterbridge-noapi
|
* Based on https://github.com/mitsukarenai/twitterbridge-noapi
|
||||||
|
*
|
||||||
|
* @name Twitter Bridge
|
||||||
|
* @description Returns user timelines or keyword search from http://twitter.com without using their API.
|
||||||
|
* @use1(q="keyword search")
|
||||||
|
* @use2(u="user timeline mode")
|
||||||
*/
|
*/
|
||||||
class RssBridgeTwitter extends RssBridgeAbstractClass
|
class RssBridgeTwitter extends RssBridgeAbstractClass
|
||||||
{
|
{
|
||||||
|
@ -14,11 +17,11 @@ class RssBridgeTwitter extends RssBridgeAbstractClass
|
||||||
protected function collectData($request) {
|
protected function collectData($request) {
|
||||||
$html = '';
|
$html = '';
|
||||||
if (isset($request['q'])) { /* keyword search mode */
|
if (isset($request['q'])) { /* keyword search mode */
|
||||||
$html = file_get_html('http://twitter.com/search/realtime?q='.urlencode($request['q']).'+include:retweets&src=typd') or $this->returnError('404 Not Found', 'ERROR: no results for this query.');
|
$html = file_get_html('http://twitter.com/search/realtime?q='.urlencode($request['q']).'+include:retweets&src=typd') or $this->returnError(404, 'no results for this query.');
|
||||||
} elseif (isset($request['u'])) { /* user timeline mode */
|
} elseif (isset($request['u'])) { /* user timeline mode */
|
||||||
$html = file_get_html('http://twitter.com/'.urlencode($request['u'])) or $this->returnError('404 Not Found', 'ERROR: requested username can\'t be found.');
|
$html = file_get_html('http://twitter.com/'.urlencode($request['u'])) or $this->returnError(404, 'requested username can\'t be found.');
|
||||||
} else {
|
} else {
|
||||||
$this->returnError('400 Bad Request', 'ERROR: You must specify a keyword (?q=...) or a Twitter username (?u=...).');
|
$this->returnError(400, 'You must specify a keyword (?q=...) or a Twitter username (?u=...).');
|
||||||
}
|
}
|
||||||
$this->items = Array();
|
$this->items = Array();
|
||||||
foreach($html->find('div.tweet') as $tweet) {
|
foreach($html->find('div.tweet') as $tweet) {
|
||||||
|
@ -37,4 +40,3 @@ class RssBridgeTwitter extends RssBridgeAbstractClass
|
||||||
|
|
||||||
$bridge = new RssBridgeTwitter();
|
$bridge = new RssBridgeTwitter();
|
||||||
$bridge->process();
|
$bridge->process();
|
||||||
?>
|
|
148
index.php
Normal file
148
index.php
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
<?php
|
||||||
|
require_once('rss-bridge-lib.php');
|
||||||
|
|
||||||
|
define('PATH_BRIDGES_RELATIVE', 'bridges/');
|
||||||
|
define('PATH_BRIDGES', __DIR__ . DIRECTORY_SEPARATOR . 'bridges' . DIRECTORY_SEPARATOR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO :
|
||||||
|
- gérer la détection du SSL
|
||||||
|
- faire la création de l'objet en dehors du bridge
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read bridge dir and catch informations about each bridge
|
||||||
|
* @param string @pathDirBridge Dir to the bridge path
|
||||||
|
* @return array Informations about each bridge
|
||||||
|
*/
|
||||||
|
function searchBridgeInformation($pathDirBridge){
|
||||||
|
$searchCommonPattern = array('description', 'name');
|
||||||
|
$listBridge = array();
|
||||||
|
if($handle = opendir($pathDirBridge)) {
|
||||||
|
while(false !== ($entry = readdir($handle))) {
|
||||||
|
if( preg_match('@([^.]+)\.php@U', $entry, $out) ){ // Is PHP file ?
|
||||||
|
$infos = array(); // Information about the bridge
|
||||||
|
$resParse = token_get_all(file_get_contents($pathDirBridge . $entry)); // Parse PHP file
|
||||||
|
foreach($resParse as $v){
|
||||||
|
if( is_array($v) && $v[0] == T_DOC_COMMENT ){ // Lexer node is COMMENT ?
|
||||||
|
$commentary = $v[1];
|
||||||
|
foreach( $searchCommonPattern as $name){ // Catch information with common pattern
|
||||||
|
preg_match('#@' . preg_quote($name, '#') . '\s+(.+)#', $commentary, $outComment);
|
||||||
|
if( isset($outComment[1]) ){
|
||||||
|
$infos[$name] = $outComment[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
preg_match_all('#@use(?<num>[1-9][0-9]*)\s?\((?<args>.+)\)(?:\r|\n)#', $commentary, $outComment); // Catch specific information about "use".
|
||||||
|
if( isset($outComment['args']) && is_array($outComment['args']) ){
|
||||||
|
$infos['use'] = array();
|
||||||
|
foreach($outComment['args'] as $num => $args){ // Each use
|
||||||
|
preg_match_all('#(?<name>[a-z]+)="(?<value>.*)"(?:,|$)#U', $args, $outArg); // Catch arguments for current use
|
||||||
|
if( isset($outArg['name']) ){
|
||||||
|
$usePos = $outComment['num'][$num]; // Current use name
|
||||||
|
if( !isset($infos['use'][$usePos]) ){ // Not information actually for this "use" ?
|
||||||
|
$infos['use'][$usePos] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($outArg['name'] as $numArg => $name){ // Each arguments
|
||||||
|
$infos['use'][$usePos][$name] = $outArg['value'][$numArg];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isset($infos['name']) ){ // If informations containt at least a name
|
||||||
|
// $listBridge
|
||||||
|
$listBridge[$out[1]] = $infos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir($handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $listBridge;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createNetworkLink($bridgeName, $arguments){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isset($_REQUEST) && isset($_REQUEST['action']) ){
|
||||||
|
switch($_REQUEST['action']){
|
||||||
|
case 'create':
|
||||||
|
if( isset($_REQUEST['bridge']) ){
|
||||||
|
unset($_REQUEST['action']);
|
||||||
|
$bridge = $_REQUEST['bridge'];
|
||||||
|
unset($_REQUEST['bridge']);
|
||||||
|
// var_dump($_REQUEST);die;
|
||||||
|
$pathBridge = PATH_BRIDGES_RELATIVE . $bridge . '.php';
|
||||||
|
if( file_exists($pathBridge) ){
|
||||||
|
require $pathBridge;
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$listBridge = searchBridgeInformation(PATH_BRIDGES);
|
||||||
|
// echo '<pre>';
|
||||||
|
// var_dump($listBridge);
|
||||||
|
// echo '</pre>';
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Rss-bridge - Create your own network !</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta name="description" content="Rss-bridge" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul class="list-bridge">
|
||||||
|
<?php foreach($listBridge as $bridgeReference => $bridgeInformations): ?>
|
||||||
|
<li id="bridge-<?php echo $bridgeReference ?>" data-ref="<?php echo $bridgeReference ?>">
|
||||||
|
<div class="name"><?php echo $bridgeInformations['name'] ?></div>
|
||||||
|
<div class="informations">
|
||||||
|
<p class="description">
|
||||||
|
<?php echo isset($bridgeInformations['description']) ? $bridgeInformations['description'] : 'No description provide' ?>
|
||||||
|
</p>
|
||||||
|
<?php if( isset($bridgeInformations['use']) && count($bridgeInformations['use']) > 0 ): ?>
|
||||||
|
<ol class="list-use">
|
||||||
|
<?php foreach($bridgeInformations['use'] as $anUseNum => $anUse): ?>
|
||||||
|
<li data-use="<?php echo $anUseNum ?>">
|
||||||
|
<form method="POST" action="?">
|
||||||
|
<input type="hidden" name="action" value="create" />
|
||||||
|
<input type="hidden" name="bridge" value="<?php echo $bridgeReference ?>" />
|
||||||
|
<?php foreach($anUse as $argName => $argDescription): ?>
|
||||||
|
<?php
|
||||||
|
$idArg = 'arg-' . $bridgeReference . '-' . $anUseNum . '-' . $argName;
|
||||||
|
?>
|
||||||
|
<label for="<?php echo $idArg ?>"><?php echo $argDescription ?></label><input id="<?php echo $idArg ?>" type="text" value="" name="<?php echo $argName ?>" /><br />
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<button type="submit" name="format" value="json">Json</button>
|
||||||
|
<button type="submit" name="format" value="plaintext">Text</button>
|
||||||
|
<button type="submit" name="format" value="html">HTML</button>
|
||||||
|
<button type="submit" name="format" value="atom">ATOM</button>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ol>
|
||||||
|
<?php else: ?>
|
||||||
|
<form method="POST" action="?">
|
||||||
|
<input type="hidden" name="action" value="create" />
|
||||||
|
<input type="hidden" name="bridge" value="<?php echo $bridgeReference ?>" />
|
||||||
|
<button type="submit" name="format" value="json">Json</button>
|
||||||
|
<button type="submit" name="format" value="plaintext">Text</button>
|
||||||
|
<button type="submit" name="format" value="html">HTML</button>
|
||||||
|
<button type="submit" name="format" value="atom">ATOM</button>
|
||||||
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -7,32 +7,34 @@
|
||||||
ini_set('user_agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0');
|
ini_set('user_agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0');
|
||||||
date_default_timezone_set('UTC');
|
date_default_timezone_set('UTC');
|
||||||
error_reporting(0);
|
error_reporting(0);
|
||||||
//ini_set('display_errors','1'); error_reporting(E_ALL); // For debugging only.
|
ini_set('display_errors','1'); error_reporting(E_ALL); // For debugging only.
|
||||||
define('CACHEDIR','cache/'); // Directory containing cache files. Do not forget trailing slash.
|
define('CACHEDIR','cache/'); // Directory containing cache files. Do not forget trailing slash.
|
||||||
|
define('CHARSET', 'UTF-8');
|
||||||
|
define('SimpleDomLib', 'vendor/simplehtmldom/simple_html_dom.php');
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
// Create cache directory if it does not exist.
|
// Create cache directory if it does not exist.
|
||||||
if (!is_dir(CACHEDIR)) { mkdir(CACHEDIR,0705); chmod(CACHEDIR,0705); }
|
if (!is_dir(CACHEDIR)) { mkdir(CACHEDIR,0705); chmod(CACHEDIR,0705); }
|
||||||
|
|
||||||
// Import DOM library.
|
// Import DOM library.
|
||||||
if (!file_exists('simple_html_dom.php'))
|
if (!file_exists(SimpleDomLib))
|
||||||
{
|
{
|
||||||
header('HTTP/1.1 500 Internal Server Error');
|
header('HTTP/1.1 500 Internal Server Error');
|
||||||
header('Content-Type: text/plain');
|
header('Content-Type: text/plain');
|
||||||
die('"PHP Simple HTML DOM Parser" is missing. Get it from http://simplehtmldom.sourceforge.net/ and place the script "simple_html_dom.php" in the same folder to allow me to work.');
|
die('"PHP Simple HTML DOM Parser" is missing. Get it from http://simplehtmldom.sourceforge.net and place the script "simple_html_dom.php" in the same folder to allow me to work.');
|
||||||
}
|
}
|
||||||
require_once('simple_html_dom.php');
|
require_once(SimpleDomLib);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract RSSBridge class on which all bridges are build upon.
|
* Abstract RSSBridge class on which all bridges are build upon.
|
||||||
* It provides utility methods (cache, ATOM feed building...)
|
* It provides utility methods (cache, ATOM feed building...)
|
||||||
*/
|
*/
|
||||||
abstract class RssBridgeAbstractClass
|
abstract class RssBridgeAbstractClass {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* $items is an array of dictionnaries. Each subclass must fill this array when collectData() is called.
|
* $items is an array of dictionnaries. Each subclass must fill this array when collectData() is called.
|
||||||
* eg. $items = Array( Array('uri'=>'http://foo.bar', 'title'=>'My beautiful foobar', 'content'='Hello, <b>world !</b>','timestamp'=>'1375864834'),
|
* eg. $items = array( array('uri'=>'http://foo.bar', 'title'=>'My beautiful foobar', 'content'='Hello, <b>world !</b>','timestamp'=>'1375864834'),
|
||||||
* Array('uri'=>'http://toto.com', 'title'=>'Welcome to toto', 'content'='What is this website about ?','timestamp'=>'1375868313')
|
* array('uri'=>'http://toto.com', 'title'=>'Welcome to toto', 'content'='What is this website about ?','timestamp'=>'1375868313')
|
||||||
* )
|
* )
|
||||||
* Keys in dictionnaries:
|
* Keys in dictionnaries:
|
||||||
* uri (string;mandatory) = The URI the item points to.
|
* uri (string;mandatory) = The URI the item points to.
|
||||||
|
@ -42,82 +44,83 @@ abstract class RssBridgeAbstractClass
|
||||||
* Other keys can be added, but will be ignored.
|
* Other keys can be added, but will be ignored.
|
||||||
* $items will be used to build the ATOM feed, json and other outputs.
|
* $items will be used to build the ATOM feed, json and other outputs.
|
||||||
*/
|
*/
|
||||||
var $items;
|
public $items;
|
||||||
|
|
||||||
private $contentType; // MIME type returned to browser.
|
private $contentType; // MIME type returned to browser.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the content-type returns to browser.
|
* Sets the content-type returns to browser.
|
||||||
* Example: $this->setContentType('text/html; charset=UTF-8')
|
*
|
||||||
|
* @param string Content-type returns to browser - Example: $this->setContentType('text/html; charset=UTF-8')
|
||||||
|
* @return this
|
||||||
*/
|
*/
|
||||||
private function setContentType($value)
|
private function setContentType($value){
|
||||||
{
|
|
||||||
$this->contentType = $value;
|
$this->contentType = $value;
|
||||||
header('Content-Type: '.$value);
|
header('Content-Type: '.$value);
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* collectData() will be called to ask the bridge to go collect data on the net.
|
* collectData() will be called to ask the bridge to go collect data on the net.
|
||||||
* All derived classes must implement this method.
|
* All derived classes must implement this method.
|
||||||
* This method must fill $this->items with collected items.
|
* This method must fill $this->items with collected items.
|
||||||
* Input: $request : The incoming request (=$_GET). This can be used or ignored by the bridge.
|
* @param mixed $request : The incoming request (=$_GET). This can be used or ignored by the bridge.
|
||||||
*/
|
*/
|
||||||
abstract protected function collectData($request);
|
abstract protected function collectData($request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a HTTP error to user, with a message.
|
* Returns a HTTP error to user, with a message.
|
||||||
* Example: $this->returnError('404 Not Found', 'ERROR: no results.');
|
* Example: $this->returnError(404, 'no results.');
|
||||||
|
* @param integer $code
|
||||||
|
* @param string $message
|
||||||
*/
|
*/
|
||||||
protected function returnError($code, $message)
|
protected function returnError($code, $message){
|
||||||
{
|
$errors = array(
|
||||||
header("HTTP/1.1 $code"); header('Content-Type: text/plain;charset=UTF-8');
|
400 => 'Bad Request',
|
||||||
die($message);
|
404 => 'Not Found',
|
||||||
|
501 => 'Not Implemented',
|
||||||
|
);
|
||||||
|
|
||||||
|
header('HTTP/1.1 ' . $code . ( isset($errors[$code]) ? ' ' . $errors[$code] : ''));
|
||||||
|
header('Content-Type: text/plain;charset=' . CHARSET);
|
||||||
|
die('ERROR : ' . $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds an ATOM feed from $this->items and return it to browser.
|
* Builds an ATOM feed from $this->items and return it to browser.
|
||||||
*/
|
*/
|
||||||
private function returnATOM()
|
private function returnATOM(){
|
||||||
{
|
$this->setContentType('application/atom+xml; charset=' . CHARSET);
|
||||||
$this->setContentType('application/atom+xml; charset=UTF-8');
|
|
||||||
|
$https = ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '' );
|
||||||
|
$httpHost = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
|
||||||
|
$httpInfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
|
||||||
|
|
||||||
echo '<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:lang="en-US">'."\n";
|
echo '<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:lang="en-US">'."\n";
|
||||||
|
|
||||||
echo '<title type="text">'.htmlspecialchars($this->bridgeName).'</title>'."\n";
|
echo '<title type="text">'.htmlspecialchars($this->bridgeName).'</title>'."\n";
|
||||||
echo '<id>http'.(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '')."://{$_SERVER['HTTP_HOST']}{$_SERVER['PATH_INFO']}".'/</id>'."\n";
|
echo '<id>http' . $https . '://' . $httpHost . $httpInfo . './</id>'."\n";
|
||||||
echo '<updated></updated>'."\n"; // FIXME
|
echo '<updated></updated>'."\n"; // FIXME
|
||||||
echo '<link rel="alternate" type="text/html" href="'.htmlspecialchars($this->bridgeURI).'" />'."\n";
|
echo '<link rel="alternate" type="text/html" href="'.htmlspecialchars($this->bridgeURI).'" />'."\n";
|
||||||
echo '<link rel="self" href="http'.(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '')."://{$_SERVER['HTTP_HOST']}".htmlentities($_SERVER['REQUEST_URI']).'" />'."\n"."\n";
|
echo '<link rel="self" href="http'.$https.'://' . $httpHost . htmlentities($_SERVER['REQUEST_URI']).'" />'."\n"."\n";
|
||||||
|
|
||||||
foreach($this->items as $item) {
|
foreach($this->items as $item) {
|
||||||
echo '<entry><author><name>'.htmlspecialchars($this->bridgeName).'</name><uri>'.htmlspecialchars($this->bridgeURI).'</uri></author>'."\n";
|
echo '<entry><author><name>'.htmlspecialchars($this->bridgeName).'</name><uri>'.htmlspecialchars($this->bridgeURI).'</uri></author>'."\n";
|
||||||
echo '<title type="html"><![CDATA['.$item['title'].']]></title>'."\n";
|
echo '<title type="html"><![CDATA['.$item['title'].']]></title>'."\n";
|
||||||
echo '<link rel="alternate" type="text/html" href="'.$item['uri'].'" />'."\n";
|
echo '<link rel="alternate" type="text/html" href="'.$item['uri'].'" />'."\n";
|
||||||
echo '<id>'.$item['uri'].'</id>'."\n";
|
echo '<id>'.$item['uri'].'</id>'."\n";
|
||||||
if (isset($item['timestamp']))
|
echo '<updated>' . ( isset($item['timestamp']) ? date(DATE_ATOM, $item['timestamp']) : '' ) . '</updated>'."\n";
|
||||||
{
|
echo '<content type="html">' . ( isset($item['content']) ? '<![CDATA[' . $item['content'] . ']]>' : '') . '</content>'."\n";
|
||||||
echo '<updated>'.date(DATE_ATOM, $item['timestamp']).'</updated>'."\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo '<updated></updated>'."\n";
|
|
||||||
}
|
|
||||||
if (isset($item['content']))
|
|
||||||
{
|
|
||||||
echo '<content type="html"><![CDATA['.$item['content'].']]></content>'."\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo '<content type="html"></content>'."\n";
|
|
||||||
}
|
|
||||||
// FIXME: Security: Disable Javascript ?
|
// FIXME: Security: Disable Javascript ?
|
||||||
echo '</entry>'."\n\n";
|
echo '</entry>'."\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '</feed>';
|
echo '</feed>';
|
||||||
}
|
}
|
||||||
|
|
||||||
private function returnHTML()
|
private function returnHTML(){
|
||||||
{
|
$this->setContentType('text/html; charset=' . CHARSET);
|
||||||
$this->setContentType('text/html; charset=UTF-8');
|
|
||||||
echo '<html><head><title>'.htmlspecialchars($this->bridgeName).'</title>';
|
echo '<html><head><title>'.htmlspecialchars($this->bridgeName).'</title>';
|
||||||
echo '<style>body{font-family:"Trebuchet MS",Verdana,Arial,Helvetica,sans-serif;font-size:10pt;background-color:#aaa;}div.rssitem{border:1px solid black;padding:5px;margin:10px;background-color:#fff;}</style></head><body>';
|
echo '<style>body{font-family:"Trebuchet MS",Verdana,Arial,Helvetica,sans-serif;font-size:10pt;background-color:#aaa;}div.rssitem{border:1px solid black;padding:5px;margin:10px;background-color:#fff;}</style></head><body>';
|
||||||
echo '<h1>'.htmlspecialchars($this->bridgeName).'</h1>';
|
echo '<h1>'.htmlspecialchars($this->bridgeName).'</h1>';
|
||||||
|
@ -134,8 +137,7 @@ abstract class RssBridgeAbstractClass
|
||||||
/**
|
/**
|
||||||
* Builds a JSON string from $this->items and return it to browser.
|
* Builds a JSON string from $this->items and return it to browser.
|
||||||
*/
|
*/
|
||||||
private function returnJSON()
|
private function returnJSON(){
|
||||||
{
|
|
||||||
$this->setContentType('application/json');
|
$this->setContentType('application/json');
|
||||||
echo json_encode($this->items);
|
echo json_encode($this->items);
|
||||||
}
|
}
|
||||||
|
@ -143,25 +145,23 @@ abstract class RssBridgeAbstractClass
|
||||||
/**
|
/**
|
||||||
* Returns $this->items as raw php data.
|
* Returns $this->items as raw php data.
|
||||||
*/
|
*/
|
||||||
private function returnPlaintext()
|
private function returnPlaintext(){
|
||||||
{
|
$this->setContentType('text/plain;charset=' . CHARSET);
|
||||||
$this->setContentType('text/plain;charset=UTF-8');
|
|
||||||
print_r($this->items);
|
print_r($this->items);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start processing request and return response to browser.
|
* Start processing request and return response to browser.
|
||||||
*/
|
*/
|
||||||
public function process()
|
public function process(){
|
||||||
{
|
|
||||||
$this->serveCachedVersion();
|
$this->serveCachedVersion();
|
||||||
|
|
||||||
// Cache file does not exists or has expired: We re-fetch the results and cache it.
|
// Cache file does not exists or has expired: We re-fetch the results and cache it.
|
||||||
$this->collectData($_GET);
|
$this->collectData($_REQUEST);
|
||||||
if (empty($this->items)) { $this->returnError('404 Not Found', 'ERROR: no results.'); }
|
|
||||||
|
|
||||||
$format = 'atom';
|
if (empty($this->items)) { $this->returnError(404, 'no results.'); }
|
||||||
if (!empty($_GET['format'])) { $format = $_GET['format']; }
|
|
||||||
|
$format = isset($_REQUEST['format']) ? $_REQUEST['format'] : 'atom';
|
||||||
switch($format) {
|
switch($format) {
|
||||||
case 'plaintext':
|
case 'plaintext':
|
||||||
$this->returnPlaintext();
|
$this->returnPlaintext();
|
||||||
|
@ -179,15 +179,23 @@ abstract class RssBridgeAbstractClass
|
||||||
$this->storeReponseInCache();
|
$this->storeReponseInCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getCacheName(){
|
||||||
|
if( !isset($_REQUEST) ){
|
||||||
|
$this->returnError(501, 'WTF ?');
|
||||||
|
}
|
||||||
|
|
||||||
|
$stringToEncode = $_SERVER['REQUEST_URI'] . http_build_query($_REQUEST);
|
||||||
|
return CACHEDIR.hash('sha1',$stringToEncode).'.cache';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cached version of current request URI directly to the browser
|
* Returns the cached version of current request URI directly to the browser
|
||||||
* if it exists and if cache has not expired.
|
* if it exists and if cache has not expired.
|
||||||
* Continues execution no cached version available.
|
* Continues execution no cached version available.
|
||||||
*/
|
*/
|
||||||
private function serveCachedVersion()
|
private function serveCachedVersion(){
|
||||||
{
|
|
||||||
// See if cache exists for this request
|
// See if cache exists for this request
|
||||||
$cachefile = CACHEDIR.hash('sha1',$_SERVER['REQUEST_URI']).'.cache'; // Cache path and filename
|
$cachefile = $this->getCacheName(); // Cache path and filename
|
||||||
if (file_exists($cachefile)) { // The cache file exists.
|
if (file_exists($cachefile)) { // The cache file exists.
|
||||||
if (time() - ($this->cacheDuration*60) < filemtime($cachefile)) { // Cache file has not expired. Serve it.
|
if (time() - ($this->cacheDuration*60) < filemtime($cachefile)) { // Cache file has not expired. Serve it.
|
||||||
$data = json_decode(file_get_contents($cachefile),true);
|
$data = json_decode(file_get_contents($cachefile),true);
|
||||||
|
@ -201,14 +209,13 @@ abstract class RssBridgeAbstractClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores currently generated page in cache.
|
* Stores currently generated page in cache.
|
||||||
|
* @return this
|
||||||
*/
|
*/
|
||||||
private function storeReponseInCache()
|
private function storeReponseInCache(){
|
||||||
{
|
$cachefile = $this->getCacheName(); // Cache path and filename
|
||||||
$cachefile = CACHEDIR.hash('sha1',$_SERVER['REQUEST_URI']).'.cache'; // Cache path and filename
|
$data = array('data'=>ob_get_contents(), 'Content-Type'=>$this->contentType);
|
||||||
$data = Array('data'=>ob_get_contents(), 'Content-Type'=>$this->contentType);
|
|
||||||
file_put_contents($cachefile,json_encode($data));
|
file_put_contents($cachefile,json_encode($data));
|
||||||
ob_end_flush();
|
ob_end_flush();
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
Loading…
Reference in a new issue