Ajout d'options multiples pour les méta-données.
Ajout d'un bridge de démonstration, DemoBridge. Ajout d'un début de documentation pour créer un bridge dans CREATE_BRIDGE.md
This commit is contained in:
parent
c204b9d914
commit
1c869631d6
7 changed files with 179 additions and 81 deletions
23
CREATE_BRIDGE.md
Normal file
23
CREATE_BRIDGE.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Howto create a bridge
|
||||||
|
|
||||||
|
A bridge is an interface that allows rss-bridge to create a RSS feed from a website.
|
||||||
|
The bridge is a PHP file, located in the `bridges/` folder.
|
||||||
|
|
||||||
|
##Specifications
|
||||||
|
|
||||||
|
A rss bridge must extend the `BridgeAbstract` class, and implement the following functions :
|
||||||
|
|
||||||
|
* The `loadMetadatas` function, described below,
|
||||||
|
* The `getCacheDuration` function, describing the time during which rss-bridge will output cached values instead of re-generating a RSS feed.
|
||||||
|
* The `collectData` function, also described below.
|
||||||
|
|
||||||
|
##The `collectData` function
|
||||||
|
|
||||||
|
This function takes as a parameter an array called `$param`, that is automatically filled with values from the user, according to the values setted in `loadMetadatas`.
|
||||||
|
This function is the place where all the website scrapping and the RSS feed generation process will go.
|
||||||
|
|
||||||
|
The RSS elements are stored in the class variable `items[]`.
|
||||||
|
|
||||||
|
Every RSS element is an instance of the `Item` class.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* 2014-05-25
|
*
|
||||||
* @name Acrimed Bridge
|
* @name Acrimed Bridge
|
||||||
* @homepage http://www.acrimed.org/
|
* @homepage http://www.acrimed.org/
|
||||||
* @description Returns the newest articles.
|
* @description Returns the newest articles.
|
||||||
|
@ -8,7 +8,16 @@
|
||||||
*/
|
*/
|
||||||
class AcrimedBridge extends BridgeAbstract{
|
class AcrimedBridge extends BridgeAbstract{
|
||||||
|
|
||||||
public function collectData(array $param){
|
public function loadMetadatas() {
|
||||||
|
|
||||||
|
$this->maintainer = "qwertygc";
|
||||||
|
$this->name = "Acrimed Bridge";
|
||||||
|
$this->uri = "http://www.acrimed.org/";
|
||||||
|
$this->description = "Returns the newest articles.";
|
||||||
|
$this->update = "2014-05-25";
|
||||||
|
|
||||||
|
}
|
||||||
|
public function collectData(array $param){
|
||||||
|
|
||||||
function StripCDATA($string) {
|
function StripCDATA($string) {
|
||||||
$string = str_replace('<![CDATA[', '', $string);
|
$string = str_replace('<![CDATA[', '', $string);
|
||||||
|
@ -37,13 +46,6 @@ class AcrimedBridge extends BridgeAbstract{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getName(){
|
|
||||||
return 'Acrimed Bridge';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getURI(){
|
|
||||||
return 'http://acrimed.org/';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCacheDuration(){
|
public function getCacheDuration(){
|
||||||
return 3600*2; // 2 hours
|
return 3600*2; // 2 hours
|
||||||
|
|
|
@ -12,6 +12,46 @@
|
||||||
*/
|
*/
|
||||||
class Arte7Bridge extends BridgeAbstract{
|
class Arte7Bridge extends BridgeAbstract{
|
||||||
|
|
||||||
|
public function loadMetadatas() {
|
||||||
|
|
||||||
|
$this->maintainer = "mitsukarenai";
|
||||||
|
$this->name = "Arte +7";
|
||||||
|
$this->uri = "http://www.arte.tv/";
|
||||||
|
$this->description = "Returns newest videos from ARTE +7";
|
||||||
|
$this->update = "2015-10-31";
|
||||||
|
$this->parameters["Catégorie (Français)"] =
|
||||||
|
'[
|
||||||
|
{
|
||||||
|
"type" : "list",
|
||||||
|
"identifier" : "catfr",
|
||||||
|
"name" : "Catégorie",
|
||||||
|
"values" : [
|
||||||
|
{
|
||||||
|
"name" : "Toutes les vidéos (français)",
|
||||||
|
"value" : "toutes-les-videos"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "Actu & société",
|
||||||
|
"value" : "actu-société"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "Séries & fiction",
|
||||||
|
"value" : "séries-fiction"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "Cinéma",
|
||||||
|
"value" : "cinéma"
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
]';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function collectData(array $param){
|
public function collectData(array $param){
|
||||||
|
|
||||||
function extractVideoset($category='toutes-les-videos', $lang='fr')
|
function extractVideoset($category='toutes-les-videos', $lang='fr')
|
||||||
|
|
72
bridges/DemoBridge.php
Normal file
72
bridges/DemoBridge.php
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ABCTabsBridge
|
||||||
|
* Returns the newest tabs
|
||||||
|
*
|
||||||
|
* @name ABC Tabs Bridge
|
||||||
|
* @homepage http://www.abc-tabs.com/
|
||||||
|
* @description Returns 22 newest tabs
|
||||||
|
* @maintainer kranack
|
||||||
|
* @update 2014-07-23
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DemoBridge extends BridgeAbstract{
|
||||||
|
|
||||||
|
public function loadMetadatas() {
|
||||||
|
|
||||||
|
$this->maintainer = "teromene";
|
||||||
|
$this->name = "DemoBridge";
|
||||||
|
$this->uri = "http://github.com/sebsauvage/rss-bridge";
|
||||||
|
$this->description = "Bridge used for demos";
|
||||||
|
$this->update = "2015-11-03";
|
||||||
|
|
||||||
|
$this->parameters['testCheckbox'] =
|
||||||
|
'[
|
||||||
|
{
|
||||||
|
"type" : "checkbox",
|
||||||
|
"identifier" : "testCheckbox",
|
||||||
|
"name" : "test des checkbox"
|
||||||
|
}
|
||||||
|
|
||||||
|
]';
|
||||||
|
|
||||||
|
$this->parameters['testList'] =
|
||||||
|
'[
|
||||||
|
{
|
||||||
|
"type" : "list",
|
||||||
|
"identifier" : "testList",
|
||||||
|
"name" : "test des listes",
|
||||||
|
"values" : [
|
||||||
|
{
|
||||||
|
"name" : "Test",
|
||||||
|
"value" : "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "Test 2",
|
||||||
|
"value" : "test2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]';
|
||||||
|
$this->parameters['testNumber'] =
|
||||||
|
'[
|
||||||
|
{
|
||||||
|
"type" : "number",
|
||||||
|
"identifier" : "testNumber",
|
||||||
|
"name" : "test des numéros",
|
||||||
|
"exampleValue" : "1515632"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
]';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collectData(array $param){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCacheDuration(){
|
||||||
|
return 3600; // 1 hour
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
*/
|
*/
|
||||||
class FacebookBridge extends BridgeAbstract{
|
class FacebookBridge extends BridgeAbstract{
|
||||||
|
|
||||||
private $name;
|
|
||||||
|
|
||||||
public function collectData(array $param){
|
public function collectData(array $param){
|
||||||
|
|
||||||
|
|
26
index.php
26
index.php
|
@ -96,14 +96,14 @@ try{
|
||||||
$bridge->setCache($cache); // just add disable cache to your query to disable caching
|
$bridge->setCache($cache); // just add disable cache to your query to disable caching
|
||||||
}
|
}
|
||||||
$bridge->setDatas($_REQUEST);
|
$bridge->setDatas($_REQUEST);
|
||||||
|
$bridge->loadMetadatas();
|
||||||
// Data transformation
|
// Data transformation
|
||||||
$format = Format::create($format);
|
$format = Format::create($format);
|
||||||
$format
|
$format
|
||||||
->setDatas($bridge->getDatas())
|
->setDatas($bridge->getDatas())
|
||||||
->setExtraInfos(array(
|
->setExtraInfos(array(
|
||||||
'name' => $bridge->getName(),
|
'name' => $bridge->name,
|
||||||
'uri' => $bridge->getURI(),
|
'uri' => $bridge->uri,
|
||||||
))
|
))
|
||||||
->display();
|
->display();
|
||||||
die;
|
die;
|
||||||
|
@ -143,7 +143,7 @@ function displayBridgeCard($bridgeName, $formats, $isActive = true)
|
||||||
$bridgeElement = Bridge::create($bridgeName);
|
$bridgeElement = Bridge::create($bridgeName);
|
||||||
$bridgeElement->loadMetadatas();
|
$bridgeElement->loadMetadatas();
|
||||||
|
|
||||||
$name = '<a href="'.$bridgeElement->homepage.'">'.$bridgeElement->name.'</a>';
|
$name = '<a href="'.$bridgeElement->uri.'">'.$bridgeElement->name.'</a>';
|
||||||
$description = $bridgeElement->description;
|
$description = $bridgeElement->description;
|
||||||
|
|
||||||
$card = <<<CARD
|
$card = <<<CARD
|
||||||
|
@ -157,7 +157,7 @@ CARD;
|
||||||
// If we don't have any parameter for the bridge, we print a generic form to load it.
|
// If we don't have any parameter for the bridge, we print a generic form to load it.
|
||||||
if(count($bridgeElement->parameters) == 0) {
|
if(count($bridgeElement->parameters) == 0) {
|
||||||
|
|
||||||
$card .= '<form method="GET" action="?">
|
$card .= '<form method="POST" action="?">
|
||||||
<input type="hidden" name="action" value="display" />
|
<input type="hidden" name="action" value="display" />
|
||||||
<input type="hidden" name="bridge" value="' . $bridgeName . '" />' . PHP_EOL;
|
<input type="hidden" name="bridge" value="' . $bridgeName . '" />' . PHP_EOL;
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ CARD;
|
||||||
{
|
{
|
||||||
$card .= '<ol class="list-use">' . PHP_EOL;
|
$card .= '<ol class="list-use">' . PHP_EOL;
|
||||||
$card .= '<h5>'.$parameterName.'</h5>' . PHP_EOL;
|
$card .= '<h5>'.$parameterName.'</h5>' . PHP_EOL;
|
||||||
$card .= '<form method="GET" action="?">
|
$card .= '<form method="POST" action="?">
|
||||||
<input type="hidden" name="action" value="display" />
|
<input type="hidden" name="action" value="display" />
|
||||||
<input type="hidden" name="bridge" value="' . $bridgeName . '" />' . PHP_EOL;
|
<input type="hidden" name="bridge" value="' . $bridgeName . '" />' . PHP_EOL;
|
||||||
|
|
||||||
|
@ -193,6 +193,18 @@ CARD;
|
||||||
$card .= '<input id="' . $idArg . '" type="text" value="" placeholder="' . $inputEntry['exampleValue'] . '" name="' . $inputEntry['identifier'] . '" /><br />' . PHP_EOL;
|
$card .= '<input id="' . $idArg . '" type="text" value="" placeholder="' . $inputEntry['exampleValue'] . '" name="' . $inputEntry['identifier'] . '" /><br />' . PHP_EOL;
|
||||||
} else if($inputEntry['type'] == 'number') {
|
} else if($inputEntry['type'] == 'number') {
|
||||||
$card .= '<input id="' . $idArg . '" type="number" value="" placeholder="' . $inputEntry['exampleValue'] . '" name="' . $inputEntry['identifier'] . '" /><br />' . PHP_EOL;
|
$card .= '<input id="' . $idArg . '" type="number" value="" placeholder="' . $inputEntry['exampleValue'] . '" name="' . $inputEntry['identifier'] . '" /><br />' . PHP_EOL;
|
||||||
|
} else if($inputEntry['type'] == 'list') {
|
||||||
|
$card .= '<select id="' . $idArg . '" name="' . $inputEntry['name'] . '" >';
|
||||||
|
foreach($inputEntry['values'] as $listValues) {
|
||||||
|
|
||||||
|
$card .= "<option value='" . $listValues['value'] . "'>" . $listValues['name'] . "</option>";
|
||||||
|
|
||||||
|
}
|
||||||
|
$card .= '</select><br >';
|
||||||
|
} else if($inputEntry['type'] == 'checkbox') {
|
||||||
|
|
||||||
|
$card .= '<input id="' . $idArg . '" type="checkbox" name="' . $inputEntry['identifier'] . '" /><br />' . PHP_EOL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -240,7 +252,7 @@ $formats = Format::searchInformation();
|
||||||
$activeFoundBridgeCount = 0;
|
$activeFoundBridgeCount = 0;
|
||||||
$showInactive = isset($_REQUEST['show_inactive']) && $_REQUEST['show_inactive'] == 1;
|
$showInactive = isset($_REQUEST['show_inactive']) && $_REQUEST['show_inactive'] == 1;
|
||||||
$inactiveBridges = '';
|
$inactiveBridges = '';
|
||||||
foreach($whitelist_selection as $bridgeName)
|
foreach(Bridge::listBridges() as $bridgeName)
|
||||||
{
|
{
|
||||||
if(BridgeWhitelist($whitelist_selection, $bridgeName))
|
if(BridgeWhitelist($whitelist_selection, $bridgeName))
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
|
|
||||||
interface BridgeInterface{
|
interface BridgeInterface{
|
||||||
public function collectData(array $param);
|
public function collectData(array $param);
|
||||||
public function getName();
|
|
||||||
public function getURI();
|
|
||||||
public function getCacheDuration();
|
public function getCacheDuration();
|
||||||
public function loadMetadatas();
|
public function loadMetadatas();
|
||||||
}
|
}
|
||||||
|
@ -18,7 +16,7 @@ abstract class BridgeAbstract implements BridgeInterface{
|
||||||
protected $items = array();
|
protected $items = array();
|
||||||
|
|
||||||
public $name = "Bridge sans nom";
|
public $name = "Bridge sans nom";
|
||||||
public $homepage = "";
|
public $uri = "";
|
||||||
public $description = 'No description provided';
|
public $description = 'No description provided';
|
||||||
public $maintainer = 'No maintainer';
|
public $maintainer = 'No maintainer';
|
||||||
public $parameters = array();
|
public $parameters = array();
|
||||||
|
@ -257,74 +255,25 @@ class Bridge{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read bridge dir and catch informations about each bridge depending annotation
|
* Lists the available bridges.
|
||||||
* @return array Informations about each bridge
|
* @return array List of the bridges
|
||||||
*/
|
*/
|
||||||
static public function searchInformation(){
|
static public function listBridges() {
|
||||||
|
|
||||||
$pathDirBridge = self::getDir();
|
$pathDirBridge = self::getDir();
|
||||||
|
|
||||||
$listBridge = array();
|
$listBridge = array();
|
||||||
|
$dirFiles = scandir($pathDirBridge);
|
||||||
|
|
||||||
$searchCommonPattern = array('maintainer', 'description', 'homepage', 'name');
|
|
||||||
|
|
||||||
$dirFiles = scandir($pathDirBridge);
|
|
||||||
if( $dirFiles !== false ){
|
if( $dirFiles !== false ){
|
||||||
foreach( $dirFiles as $fileName ){
|
foreach( $dirFiles as $fileName ){
|
||||||
if( preg_match('@([^.]+)\.php@U', $fileName, $out) ){ // Is PHP file ?
|
if( preg_match('@([^.]+)\.php@U', $fileName, $out) ){
|
||||||
$infos = array(); // Information about the bridge
|
$listBridge[] = $out[1];
|
||||||
$resParse = token_get_all(file_get_contents($pathDirBridge . $fileName)); // 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".
|
return $listBridge;
|
||||||
|
}
|
||||||
|
|
||||||
if( isset($outComment['args']) && is_array($outComment['args']) ){
|
|
||||||
$infos['use'] = array();
|
|
||||||
|
|
||||||
foreach($outComment['args'] as $num => $args){ // Each use
|
|
||||||
|
|
||||||
preg_match_all('#(?<type>[a-z]+)\|(?<name>[a-z]+)="(?<value>.*)"(?:,|$)#U', $args, $outArg); // Catch arguments for current use
|
|
||||||
|
|
||||||
if(!isset($outArg['name']) || count($outArg['name']) == 0) {
|
|
||||||
preg_match_all('#(?<name>[a-z]+)="(?<value>.*)"(?:,|$)#U', $args, $outArg); // Catch arguments
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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] = array();
|
|
||||||
|
|
||||||
$infos['use'][$usePos][$name]['query-name'] = $name;
|
|
||||||
$infos['use'][$usePos][$name]['value'] = $outArg['value'][$numArg];
|
|
||||||
$infos['use'][$usePos][$name]['type'] = $outArg['type'][$numArg];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( isset($infos['name']) ){ // If informations containt at least a name
|
|
||||||
$listBridge[$out[1]] = $infos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $listBridge;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue