1
0
Fork 0
forked from blallo/rss-bridge

Merge remote-tracking branch 'upstream/master'

Conflicts:
	bridges/Sexactu.php
This commit is contained in:
unknown 2015-04-06 14:52:04 +02:00
commit a5f52b8789
100 changed files with 6776 additions and 158 deletions

6
.gitignore vendored
View file

@ -166,6 +166,11 @@ UpgradeLog*.htm
App_Data/*.mdf
App_Data/*.ldf
#################
## Other ide stuff
#################
.idea/*
#############
## Windows detritus
#############
@ -219,3 +224,4 @@ pip-log.txt
## RSS-Bridge
##############
/cache
/whitelist.txt

View file

@ -1,31 +1,31 @@
rss-bridge
===
rss-bridge is a php script capable of generating ATOM feed for specific pages which don't have one.
rss-bridge is a PHP project capable of generating ATOM feeds for websites which don't have one.
Supported sites/pages
Supported sites/pages (main)
===
* `FlickrExplore` : [Latest interesting images](http://www.flickr.com/explore) from Flickr.
* `GoogleSearch` : Most recent results from Google Search.
* `Twitter` : Can return keyword/hashtag search or user timeline.
* `Identi.ca` : Identica user timeline (Should be compatible with other Pump.io instances).
* `YouTube` : YouTube user channel feed.
* `Cryptome` : Returns the most recent documents from Cryptome.org.
* `Futurasciences` : Returns the most recent articles from futura-sciences.com.
* `GuruMed`: Returns the most recent articles for gurumed.org
* `DansTonChat`: Most recent quotes from danstonchat.com
* `DuckDuckGo`: Most recent results from DuckDuckGo.com
* `FSBridge`: Most recent article (full text) from futura-sciences.com
* `GuruMed`: Most recent entries (full text) from gurumed.org
* `Instagram`: Most recent photos from an instagram.com user.
* `OpenClassrooms`: Lastest tutorials from fr.openclassrooms.com.
* `Pinterest`: Most recent photos from user or search.
* `ScmbBridge`: Newest stories from secouchermoinsbete.fr
* `WikipediaENLatest`: highlighted articles from Wikipedia in English.
* `WikipediaFRLatest`: highlighted articles from Wikipedia in French.
* `WikipediaEOLatest`: highlighted articles from Wikipedia in Esperanto.
* `FlickrExplore` : [Latest interesting images](http://www.flickr.com/explore) from Flickr
* `GoogleSearch` : Most recent results from Google Search
* `GooglePlus` : Most recent posts of user timeline
* `Twitter` : Return keyword/hashtag search or user timeline
* `Identi.ca` : Identica user timeline (Should be compatible with other Pump.io instances)
* `YouTube` : YouTube user channel, playlist or search
* `Cryptome` : Returns the most recent documents from [Cryptome.org](http://cryptome.org/)
* `DansTonChat`: Most recent quotes from [danstonchat.com](http://danstonchat.com/)
* `DuckDuckGo`: Most recent results from [DuckDuckGo.com](https://duckduckgo.com/)
* `Instagram`: Most recent photos from an Instagram user
* `OpenClassrooms`: Lastest tutorials from [fr.openclassrooms.com](http://fr.openclassrooms.com/)
* `Pinterest`: Most recent photos from user or search
* `ScmbBridge`: Newest stories from [secouchermoinsbete.fr](http://secouchermoinsbete.fr/)
* `WikipediaENLatest`: highlighted articles from Wikipedia in English
* `WikipediaFRLatest`: highlighted articles from Wikipedia in French
* `WikipediaEOLatest`: highlighted articles from Wikipedia in Esperanto
* `Bandcamp` : Returns last release from [bandcamp](https://bandcamp.com/) for a tag
* `ThePirateBay` : Returns the newest indexed torrents from [The Pirate Bay](https://thepiratebay.se/) with keywords
Plus [many other bridges](bridges/) to enable, thanks to the community
Output format
===
@ -50,10 +50,17 @@ Minecraft hashtag (#Minecraft) search on Twitter, in ATOM format (as displayed b
Requirements
===
* php 5.3
* [PHP Simple HTML DOM Parser](http://simplehtmldom.sourceforge.net). (Put `simple_html_dom.php` in `vendor/simplehtmldom/`).
* Ssl lib activated in PHP config
* PHP 5.3
* `openssl` extension enabled in PHP config (`php.ini`)
Enabling/Disabling bridges
===
By default, the script creates `whitelist.txt` and adds the main bridges (see above). `whitelist.txt` is ignored by git, you can edit it:
* to enable extra bridges (one bridge per line)
* to disable main bridges (remove the line)
New bridges are disabled by default, so make sure to check regularly what's new and whitelist what you want !
Author
===
@ -62,22 +69,40 @@ I'm sebsauvage, webmaster of [sebsauvage.net](http://sebsauvage.net), author of
Patch/contributors :
* Yves ASTIER ([Draeli](https://github.com/Draeli)) : PHP optimizations, fixes, dynamic brigde/format list with all stuff behind and extend cache system. Mail : contact@yves-astier.com
* [Mitsukarenai](https://github.com/Mitsukarenai) : Initial inspiration, TwitterBridge, IdenticaBridge, YoutubeBridge.
* [Mitsukarenai](https://github.com/Mitsukarenai) : Initial inspiration, collaborator
* [ArthurHoaro](https://github.com/ArthurHoaro)
* [BoboTiG](https://github.com/BoboTiG)
* [Astalaseven](https://github.com/Astalaseven)
* [qwertygc](https://github.com/qwertygc)
* [Djuuu](https://github.com/Djuuu)
* [Anadrark](https://github.com/Anadrark])
* [Grummfy](https://github.com/Grummfy)
* [Polopollo](https://github.com/Polopollo)
* [16mhz](https://github.com/16mhz)
* [kranack](https://github.com/kranack)
Licence
License
===
Code is public domain.
Code is [Public Domain](UNLICENSE).
Including `PHP Simple HTML DOM Parser` under the [MIT License](http://opensource.org/licenses/MIT)
Technical notes
===
* There is a cache so that source services won't ban you even if you hammer the rss-bridge with requests. Each bridge has a different duration for the cache. The `cache` subdirectory will be automatically created. You can purge it whenever you want.
* To implement a new rss-bridge, create a new class in `bridges` subdirectory. Look at existing bridges for examples. For items you generate in `$this->items`, only `uri` and `title` are mandatory in each item. `timestamp` and `content` are optional but recommended. Any additional key will be ignored by ATOM feed (but outputed to jSon).
* To implement a new rss-bridge, create a new class in `bridges` subdirectory. Look at existing bridges for examples and the guidelines below. For items you generate in `$this->items`, only `uri` and `title` are mandatory in each item. `timestamp` and `content` are optional but recommended. Any additional key will be ignored by ATOM feed (but outputed to json).
### Bridge guidelines
* metatags: `@name` {Name of service}, `@homepage` {URL to homepage}, `@description`, `@update` {YYYY-MM-DD}, `@maintainer` {Github username or nickname}
* scripts (eg. Javascript) must be stripped out. Make good use of `strip_tags()` and `preg_replace()`
* bridge must present data within 8 seconds (adjust iterators accordingly)
* cache timeout must be fine-tuned so that each refresh can provide 1 or 2 new elements on busy periods
* `<audio>` and `<video>` must not autoplay. Seriously.
* do everything you can to extract valid timestamps. Translate formats, use API, exploit sitemap, whatever. Free the data!
* don't create duplicates. If the website runs on WordPress, use the generic WordPress bridge if possible.
* maintain efficient and well-commented code :wink:
Rant
===
@ -86,10 +111,10 @@ Rant
Your catchword is "share", but you don't want us to share. You want to keep us within your walled gardens. That's why you've been removing RSS links from webpages, hiding them deep on your website, or removed RSS entirely, replacing it with crippled or demented proprietary API. **FUCK YOU.**
You're not social when you hamper sharing by removing RSS. You're happy to have customers create content for your ecosystem, but you don't want this content out - a content you do not even own. Google Takeout is just a gimmick. We want our data to flow, we want RSS.
You're not social when you hamper sharing by removing RSS. You're happy to have customers creating content for your ecosystem, but you don't want this content out - a content you do not even own. Google Takeout is just a gimmick. We want our data to flow, we want RSS.
We want to share with friends, using open protocols: RSS, XMPP, whatever. Because no one wants to have *your* service with *your* applications using *your* API forced-feeded to them. Friends must be free to choose whatever software and service they want.
We want to share with friends, using open protocols: RSS, XMPP, whatever. Because no one wants to have *your* service with *your* applications using *your* API force-feeding them. Friends must be free to choose whatever software and service they want.
We are rebuilding bridges your have wilfully destroyed.
We are rebuilding bridges you have wilfully destroyed.
Get your shit together: Put RSS back in.

25
UNLICENSE Normal file
View file

@ -0,0 +1,25 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org>

44
bridges/ABCTabsBridge.php Normal file
View file

@ -0,0 +1,44 @@
<?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 ABCTabsBridge extends BridgeAbstract{
private $request;
public function collectData(array $param){
$html = '';
$html = file_get_html('http://www.abc-tabs.com/tablatures/nouveautes.html') or $this->returnError('No results for this query.', 404);
$table = $html->find('table#myTable', 0)->children(1);
foreach ($table->find('tr') as $tab)
{
$item = new \Item();
$item->name = $tab->find('td', 1)->plaintext . ' - ' . $tab->find('td', 2)->plaintext;
$item->title = $tab->find('td', 1)->plaintext . ' - ' . $tab->find('td', 2)->plaintext;
$item->content = 'Le ' . $tab->find('td', 0)->plaintext . '<br> Par: ' . $tab->find('td', 5)->plaintext . '<br> Type: ' . $tab->find('td', 3)->plaintext;
$item->id = 'http://www.abc-tabs.com' . $tab->find('td', 2)->find('a', 0)->getAttribute('href');
$item->uri = 'http://www.abc-tabs.com' . $tab->find('td', 2)->find('a', 0)->getAttribute('href');
$this->items[] = $item;
}
}
public function getName(){
return 'ABC Tabs Bridge';
}
public function getURI(){
return 'http://www.abc-tabs.com/';
}
public function getCacheDuration(){
return 3600; // 1 hour
}
}

52
bridges/AcrimedBridge.php Normal file
View file

@ -0,0 +1,52 @@
<?php
/**
* 2014-05-25
* @name Acrimed Bridge
* @homepage http://www.acrimed.org/
* @description Returns the newest articles.
* @maintainer qwertygc
*/
class AcrimedBridge extends BridgeAbstract{
public function collectData(array $param){
function StripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function ExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.texte', 0)->innertext;
return $text;
}
$html = file_get_html('http://www.acrimed.org/spip.php?page=backend') or $this->returnError('Could not request Acrimed.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 10) {
$item = new \Item();
$item->title = StripCDATA($element->find('title', 0)->innertext);
$item->uri = StripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = ExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Acrimed Bridge';
}
public function getURI(){
return 'http://acrimed.org/';
}
public function getCacheDuration(){
return 3600*2; // 2 hours
// return 0; // 2 hours
}
}

View file

@ -0,0 +1,55 @@
<?php
/**
*
* @name Allo Cine : Faux Raccord
* @homepage http://www.allocine.fr/video/programme-12284/saison-24580/
* @description Allo Cine : Faux Raccord
* @update 07/11/2013
* initial maintainer: superbaillot.net
*/
class AllocineFRBridge extends BridgeAbstract{
private $_URL = "http://www.allocine.fr/video/programme-12284/saison-24580/";
private $_NOM = "Faux Raccord";
public function collectData(array $param){
$html = file_get_html($this->_URL) or $this->returnError('Could not request Allo cine.', 404);
foreach($html->find('figure.media-meta-fig') as $element)
{
$item = new Item();
$titre = $element->find('div.titlebar h3.title a', 0);
$content = trim($element->innertext);
$figCaption = strpos($content, $this->_NOM);
if($figCaption !== false)
{
$content = str_replace('src="/', 'src="http://www.allocine.fr/',$content);
$content = str_replace('href="/', 'href="http://www.allocine.fr/',$content);
$content = str_replace('src=\'/', 'src=\'http://www.allocine.fr/',$content);
$content = str_replace('href=\'/', 'href=\'http://www.allocine.fr/',$content);
$item->content = $content;
$item->title = trim($titre->innertext);
$item->uri = "http://www.allocine.fr" . $titre->href;
$this->items[] = $item;
}
}
}
public function getName(){
return 'Allo Cine : ' . $this->_NOM;
}
public function getURI(){
return $this->_URL;
}
public function getCacheDuration(){
return 25200; // 7 hours
}
public function getDescription(){
return "Allo Cine : " . $this->_NOM . " via rss-bridge";
}
}
?>

View file

@ -0,0 +1,55 @@
<?php
/**
*
* @name Allo Cine : Top 5
* @homepage http://www.allocine.fr/video/programme-12299/saison-22542/
* @description Allo Cine : Top 5 via rss-bridge
* @update 07/11/2013
* initial maintainer: superbaillot.net
*/
class AllocineT5Bridge extends BridgeAbstract{
private $_URL = "http://www.allocine.fr/video/programme-12299/saison-22542/";
private $_NOM = "Top 5";
public function collectData(array $param){
$html = file_get_html($this->_URL) or $this->returnError('Could not request Allo cine.', 404);
foreach($html->find('figure.media-meta-fig') as $element)
{
$item = new Item();
$titre = $element->find('div.titlebar h3.title a', 0);
$content = trim($element->innertext);
$figCaption = strpos($content, $this->_NOM);
if($figCaption !== false)
{
$content = str_replace('src="/', 'src="http://www.allocine.fr/',$content);
$content = str_replace('href="/', 'href="http://www.allocine.fr/',$content);
$content = str_replace('src=\'/', 'src=\'http://www.allocine.fr/',$content);
$content = str_replace('href=\'/', 'href=\'http://www.allocine.fr/',$content);
$item->content = $content;
$item->title = trim($titre->innertext);
$item->uri = "http://www.allocine.fr" . $titre->href;
$this->items[] = $item;
}
}
}
public function getName(){
return 'Allo Cine : ' . $this->_NOM;
}
public function getURI(){
return $this->_URL;
}
public function getCacheDuration(){
return 25200; // 7 hours
}
public function getDescription(){
return "Allo Cine : " . $this->_NOM . " via rss-bridge";
}
}
?>

View file

@ -0,0 +1,55 @@
<?php
/**
*
* @name Allo Cine : Tueurs En Serie
* @homepage http://www.allocine.fr/video/programme-12286/saison-22938/
* @description Allo Cine : Tueurs En Serie
* @update 12/11/2013
* initial maintainer: superbaillot.net
*/
class AllocineTueursEnSerieBridge extends BridgeAbstract{
private $_URL = "http://www.allocine.fr/video/programme-12286/saison-22938/";
private $_NOM = "Tueurs en Séries";
public function collectData(array $param){
$html = file_get_html($this->_URL) or $this->returnError('Could not request Allo cine.', 404);
foreach($html->find('figure.media-meta-fig') as $element)
{
$item = new Item();
$titre = $element->find('div.titlebar h3.title a', 0);
$content = trim($element->innertext);
$figCaption = strpos($content, $this->_NOM);
if($figCaption !== false)
{
$content = str_replace('src="/', 'src="http://www.allocine.fr/',$content);
$content = str_replace('href="/', 'href="http://www.allocine.fr/',$content);
$content = str_replace('src=\'/', 'src=\'http://www.allocine.fr/',$content);
$content = str_replace('href=\'/', 'href=\'http://www.allocine.fr/',$content);
$item->content = $content;
$item->title = trim($titre->innertext);
$item->uri = "http://www.allocine.fr" . $titre->href;
$this->items[] = $item;
}
}
}
public function getName(){
return 'Allo Cine : ' . $this->_NOM;
}
public function getURI(){
return $this->_URL;
}
public function getCacheDuration(){
return 25200; // 7 hours
}
public function getDescription(){
return "Allo Cine : " . $this->_NOM . " via rss-bridge";
}
}
?>

78
bridges/Arte7deBridge.php Normal file
View file

@ -0,0 +1,78 @@
<?php
/**
* RssBridgeArte7de
* Returns images from given page and tags
* 2014-05-25
*
* @name Arte +7 DE
* @homepage http://www.arte.tv/guide/de/
* @description Returns newest videos from ARTE +7 (german)
* @maintainer mitsukarenai
*/
class Arte7deBridge extends BridgeAbstract{
public function collectData(array $param){
$input_json = json_decode(file_get_contents('http://www.arte.tv/guide/de/plus7.json'), TRUE) or $this->returnError('Could not request ARTE.', 404);
foreach($input_json['videos'] as $element) {
$item = new \Item();
$item->uri = 'http://www.arte.tv'.$element['url'];
$item->postid = $item->uri;
$date = $element['airdate_long'];
$date = explode(' ', $date);
$day = (int)$date['1'];
$month=FALSE;
switch ($date['2']) {
case 'Januar':
$month=1;break;
case 'Februar':
$month=2;break;
case 'März':
$month=3;break;
case 'April':
$month=4;break;
case 'Mai':
$month=5;break;
case 'Juni':
$month=6;break;
case 'Juli':
$month=7;break;
case 'August':
$month=8;break;
case 'September':
$month=9;break;
case 'Oktober':
$month=10;break;
case 'November':
$month=11;break;
case 'Dezember':
$month=12;break;
}
$year=(int)date('Y');
$heure=explode(':', $date['4']);
$hour=(int)$heure['0'];
$minute=(int)$heure['1'];
$item->timestamp = mktime($hour, $minute, 0, $month, $day, $year);
$item->thumbnailUri = $element['image_url'];
$item->title = $element['title'];
$item->content = $element['desc'].'<br><br>'.$element['video_channels'].', '.$element['duration'].'min<br><img src="' . $item->thumbnailUri . '" />';
$this->items[] = $item;
}
}
public function getName(){
return 'Arte7de';
}
public function getURI(){
return 'http://www.arte.tv/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

78
bridges/Arte7frBridge.php Normal file
View file

@ -0,0 +1,78 @@
<?php
/**
* RssBridgeArte7fr
* Returns images from given page and tags
* 2014-05-25
*
* @name Arte +7 FR
* @homepage http://www.arte.tv/guide/fr/
* @description Returns newest videos from ARTE +7 (french)
* @maintainer mitsukarenai
*/
class Arte7frBridge extends BridgeAbstract{
public function collectData(array $param){
$input_json = json_decode(file_get_contents('http://www.arte.tv/guide/fr/plus7.json'), TRUE) or $this->returnError('Could not request ARTE.', 404);
foreach($input_json['videos'] as $element) {
$item = new \Item();
$item->uri = 'http://www.arte.tv'.$element['url'];
$item->postid = $item->uri;
$date = $element['airdate_long'];
$date = explode(' ', $date);
$day = (int)$date['1'];
$month=FALSE;
switch ($date['2']) {
case 'janvier':
$month=1;break;
case 'février':
$month=2;break;
case 'mars':
$month=3;break;
case 'avril':
$month=4;break;
case 'mai':
$month=5;break;
case 'juin':
$month=6;break;
case 'juillet':
$month=7;break;
case 'août':
$month=8;break;
case 'septembre':
$month=9;break;
case 'octobre':
$month=10;break;
case 'novembre':
$month=11;break;
case 'décembre':
$month=12;break;
}
$year=(int)date('Y');
$heure=explode('h', $date['4']);
$hour=(int)$heure['0'];
$minute=(int)$heure['1'];
$item->timestamp = mktime($hour, $minute, 0, $month, $day, $year);
$item->thumbnailUri = $element['image_url'];
$item->title = $element['title'];
$item->content = $element['desc'].'<br><br>'.$element['video_channels'].', '.$element['duration'].'min<br><img src="' . $item->thumbnailUri . '" />';
$this->items[] = $item;
}
}
public function getName(){
return 'Arte7fr';
}
public function getURI(){
return 'http://www.arte.tv/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -0,0 +1,48 @@
<?php
/**
* BandcampTagRSS
* 2014-05-25
*
* @name Bandcamp Tag
* @homepage http://bandcamp.com/
* @description New bandcamp release by tag
* @maintainer sebsauvage
* @use1(tag="tag")
*/
class BandcampBridge extends BridgeAbstract{
private $request;
public function collectData(array $param){
$html = '';
if (isset($param['tag'])) {
$this->request = $param['tag'];
$html = file_get_html('http://bandcamp.com/tag/'.urlencode($this->request).'?sort_field=date') or $this->returnError('No results for this query.', 404);
}
else {
$this->returnError('You must specify tag (/tag/...)', 400);
}
foreach($html->find('li.item') as $release) {
$item = new \Item();
$item->name = $release->find('div.itemsubtext',0)->plaintext . ' - ' . $release->find('div.itemtext',0)->plaintext;
$item->title = $release->find('div.itemsubtext',0)->plaintext . ' - ' . $release->find('div.itemtext',0)->plaintext;
$item->content = '<img src="' . $release->find('img.art',0)->src . '"/><br/>' . $release->find('div.itemsubtext',0)->plaintext . ' - ' . $release->find('div.itemtext',0)->plaintext;
$item->id = $release->find('a',0)->getAttribute('href');
$item->uri = $release->find('a',0)->getAttribute('href');
$this->items[] = $item;
}
}
public function getName(){
return (!empty($this->request) ? $this->request .' - ' : '') .'Bandcamp Tag';
}
public function getURI(){
return 'http://bandcamp.com';
}
public function getCacheDuration(){
return 600; // 10 minutes
}
}

51
bridges/BastaBridge.php Normal file
View file

@ -0,0 +1,51 @@
<?php
/**
* RssBridgeBastabag
* Returns the newest articles
* 2014-05-25
*
* @name Bastamag Bridge
* @homepage http://www.bastamag.net/
* @description Returns the newest articles.
* @maintainer qwertygc
*/
class BastaBridge extends BridgeAbstract{
public function collectData(array $param){
function BastaExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.texte', 0)->innertext;
return $text;
}
$html = file_get_html('http://www.bastamag.net/spip.php?page=backend') or $this->returnError('Could not request Bastamag.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 10) {
$item = new \Item();
$item->title = $element->find('title', 0)->innertext;
$item->uri = $element->find('guid', 0)->plaintext;
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = BastaExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Bastamag Bridge';
}
public function getURI(){
return 'http://bastamag.net/';
}
public function getCacheDuration(){
return 3600*2; // 2 hours
// return 0; // 2 hours
}
}

View file

@ -0,0 +1,48 @@
<?php
/**
*
* @name Blagues De Merde
* @homepage http://www.blaguesdemerde.fr/
* @description Blagues De Merde
* @update 16/10/2013
* initial maintainer: superbaillot.net
*/
class BlaguesDeMerdeBridge extends BridgeAbstract{
public function collectData(array $param){
$html = file_get_html('http://www.blaguesdemerde.fr/') or $this->returnError('Could not request BDM.', 404);
foreach($html->find('article.joke_contener') as $element) {
$item = new Item();
$temp = $element->find('a');
if(isset($temp[2]))
{
$item->content = trim($element->find('div.joke_text_contener', 0)->innertext);
$uri = $temp[2]->href;
$item->uri = $uri;
$item->title = substr($uri, (strrpos($uri, "/") + 1));
$date = $element->find("li.bdm_date",0)->innertext;
$time = mktime(0, 0, 0, substr($date, 3, 2), substr($date, 0, 2), substr($date, 6, 4));
$item->timestamp = $time;
$item->name = $element->find("li.bdm_pseudo",0)->innertext;;
$this->items[] = $item;
}
}
}
public function getName(){
return 'blaguesdemerde';
}
public function getURI(){
return 'http://www.blaguesdemerde.fr/';
}
public function getCacheDuration(){
return 7200; // 2h hours
}
public function getDescription(){
return "Blagues De Merde via rss-bridge";
}
}
?>

View file

@ -0,0 +1,55 @@
<?php
/**
* RssBridgeBooruproject
* Returns images from given page
* 2014-05-25
*
* @name Booruproject
* @homepage http://booru.org/
* @description Returns images from given page and booruproject instance (****.booru.org)
* @maintainer mitsukarenai
* @use1(i="instance (required)", p="page", t="tags")
*/
class BooruprojectBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0; $tags = '';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
$page = $page - 1;
$page = $page * 20;
}
if (isset($param['t'])) {
$tags = '&tags='.urlencode($param['t']);
}
if (empty($param['i'])) {
$this->returnError('Please enter a ***.booru.org instance.', 404);
}
$html = file_get_html("http://".$param['i'].".booru.org/index.php?page=post&s=list&pid=".$page.$tags) or $this->returnError('Could not request Booruproject.', 404);
foreach($html->find('div[class=content] span') as $element) {
$item = new \Item();
$item->uri = 'http://'.$param['i'].'.booru.org/'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->find('a', 0)->getAttribute('id'));
$item->timestamp = time();
$item->thumbnailUri = $element->find('img', 0)->src;
$item->tags = $element->find('img', 0)->getAttribute('title');
$item->title = 'Booruproject '.$param['i'].' | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Booruproject';
}
public function getURI(){
return 'http://booru.org/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -0,0 +1,56 @@
<?php
/**
* RssBridgeCoinDesk
* Returns the 5 newest posts from coindesk.com (full text)
*
* @name CoinDesk
* @homepage http://www.coindesk.com/
* @description Returns the 5 newest posts from CoinDesk (full text)
* @maintainer mitsukarenai
* @update 2014-05-30
*/
class CoinDeskBridge extends BridgeAbstract{
public function collectData(array $param){
function CoinDeskStripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function CoinDeskExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.single-content', 0)->innertext;
$text = strip_tags($text, '<p><a><img>');
return $text;
}
$html = file_get_html('http://www.coindesk.com/feed/atom/') or $this->returnError('Could not request CoinDesk.', 404);
$limit = 0;
foreach($html->find('entry') as $element) {
if($limit < 5) {
$item = new \Item();
$item->title = CoinDeskStripCDATA($element->find('title', 0)->innertext);
$item->author = $element->find('author', 0)->plaintext;
$item->uri = $element->find('link', 0)->href;
$item->timestamp = strtotime($element->find('published', 0)->plaintext);
$item->content = CoinDeskExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'CoinDesk';
}
public function getURI(){
return 'http://www.coindesk.com/';
}
public function getCacheDuration(){
return 1800; // 30min
}
}

View file

@ -0,0 +1,41 @@
<?php
/**
* RssBridgeCollegeDeFrance
* Returns the 10 newest posts from http://www.college-de-france.fr
*
* @name CollegeDeFrance
* @homepage http://www.college-de-france.fr/
* @description Returns the 10 newest posts from CollegeDeFrance
* @maintainer pit-fgfjiudghdf
* @update 2014-05-26
*/
class CollegeDeFranceBridge extends BridgeAbstract{
public function collectData(array $param){
$find = array('janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'novembre', 'décembre');
$replace = array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
$html = file_get_html('http://www.college-de-france.fr/site/audio-video/_audiovideos.jsp?index=0&prompt=&fulltextdefault=mots-cles...&fulltext=mots-cles...&fields=TYPE2_ACTIVITY&fieldsdefault=0_0&TYPE2=0') or $this->returnError('Could not request CollegeDeFrance.', 404);
$limit = 0;
foreach($html->find('li.audio') as $element) {
if($limit < 10) {
$item = new \Item();
$item->title = $element->find('span.title', 0)->plaintext;
$item->timestamp = strtotime(str_replace($find, $replace, $element->find('span.date', 0)->plaintext));
$item->content = $element->find('span.lecturer', 0)->innertext . ' - ' . $element->find('span.title', 0)->innertext;
$item->uri = $element->find('a', 0)->href;
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'CollegeDeFrance';
}
public function getURI(){
return 'http://www.college-de-france.fr/';
}
public function getCacheDuration(){
return 3600*3; // 3 hour
}
}

View file

@ -0,0 +1,59 @@
<?php
/**
*
* @name CopieDouble
* @homepage http://www.copie-double.com/
* @description CopieDouble
* @update 12/12/2013
* initial maintainer: superbaillot.net
*/
class CopieDoubleBridge extends BridgeAbstract{
public function collectData(array $param){
$html = file_get_html('http://www.copie-double.com/') or $this->returnError('Could not request CopieDouble.', 404);
$table = $html->find('table table', 2);
foreach($table->find('tr') as $element)
{
$td = $element->find('td', 0);
$cpt++;
if($td->class == "couleur_1")
{
$item = new Item();
$title = $td->innertext;
$pos = strpos($title, "<a");
$title = substr($title, 0, $pos);
$item->title = $title;
}
elseif(strpos($element->innertext, "/images/suivant.gif") === false)
{
$a=$element->find("a", 0);
$item->uri = "http://www.copie-double.com" . $a->href;
$content = str_replace('src="/', 'src="http://www.copie-double.com/',$element->find("td", 0)->innertext);
$content = str_replace('href="/', 'href="http://www.copie-double.com/',$content);
$item->content = $content;
$this->items[] = $item;
}
}
}
public function getName(){
return 'CopieDouble';
}
public function getURI(){
return 'http://www.copie-double.com';
}
public function getDescription(){
return 'CopieDouble via rss-bridge';
}
public function getCacheDuration(){
return 14400; // 4 hours
}
}
?>

View file

@ -3,25 +3,29 @@
* RssBridgeCryptome
* Retrieve lastest documents from Cryptome.
* Returns the N most recent documents, sorting by date (most recent first).
* 2014-05-25
*
* @name Cryptome
* @homepage http://cryptome.org/
* @description Returns the N most recent documents.
* @maintainer BoboTiG
* @use1(n="number")
*/
class CryptomeBridge extends BridgeAbstract{
public function collectData(array $param){
$html = '';
$num = 90;
$num = 20;
$link = 'http://cryptome.org/';
// If you want HTTPS access instead, uncomment the following line:
//$link = 'https://secure.netsolhost.com/cryptome.org/';
$html = file_get_html($link) or $this->returnError('Could not request Cryptome.', 404);
if (isset($param['n'])) { /* number of documents */
if (!empty($param['n'])) { /* number of documents */
$num = min(max(1, $param['n']+0), $num);
}
foreach($html->find('pre') as $element) {
for ( $i = 0; $i < $num; ++$i ) {
$item = new \Item();

View file

@ -0,0 +1,81 @@
<?php
/**
* RssBridgeDailymotion
* Returns the newest videos
*
* @name Dailymotion Bridge
* @homepage https://www.dailymotion.com/
* @description Returns the 5 newest videos by username/playlist or search
* @maintainer mitsukarenai
* @update 2014-11-18
* @use1(u="username")
* @use2(p="playlist id")
* @use3(s="search keyword",pa="page")
*
*/
class DailymotionBridge extends BridgeAbstract{
private $request;
public function collectData(array $param){
function getMetadata($id) {
$metadata=array();
$html2 = file_get_html('http://www.dailymotion.com/video/'.$id) or $this->returnError('Could not request Dailymotion.', 404);
$metadata['title'] = $html2->find('meta[property=og:title]', 0)->getAttribute('content');
$metadata['timestamp'] = strtotime($html2->find('meta[property=video:release_date]', 0)->getAttribute('content') );
$metadata['thumbnailUri'] = $html2->find('meta[property=og:image]', 0)->getAttribute('content');
$metadata['uri'] = $html2->find('meta[property=og:url]', 0)->getAttribute('content');
return $metadata;
}
$html = '';
$limit = 5;
$count = 0;
if (isset($param['u'])) { // user timeline mode
$this->request = $param['u'];
$html = file_get_html('http://www.dailymotion.com/user/'.urlencode($this->request).'/1') or $this->returnError('Could not request Dailymotion.', 404);
}
else if (isset($param['p'])) { // playlist mode
$this->request = strtok($param['p'], '_');
$html = file_get_html('http://www.dailymotion.com/playlist/'.urlencode($this->request).'') or $this->returnError('Could not request Dailymotion.', 404);
}
else if (isset($param['s'])) { // search mode
$this->request = $param['s']; $page = 1; if (isset($param['pa'])) $page = (int)preg_replace("/[^0-9]/",'', $param['pa']);
$html = file_get_html('http://www.dailymotion.com/search/'.urlencode($this->request).'/'.$page.'') or $this->returnError('Could not request Dailymotion.', 404);
}
else {
$this->returnError('You must either specify a Dailymotion username (?u=...) or a playlist id (?p=...) or search (?s=...)', 400);
}
foreach($html->find('div.media a.preview_link') as $element) {
if($count < $limit) {
$item = new \Item();
$item->id = str_replace('/video/', '', strtok($element->href, '_'));
$metadata = getMetadata($item->id);
$item->uri = $metadata['uri'];
$item->thumbnailUri = $metadata['thumbnailUri'];
$item->title = $metadata['title'];
$item->timestamp = $metadata['timestamp'];
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br><a href="' . $item->uri . '">' . $item->title . '</a>';
$this->items[] = $item;
$count++;
}
}
}
public function getName(){
return (!empty($this->request) ? $this->request .' - ' : '') .'Dailymotion Bridge';
}
public function getURI(){
return 'https://www.dailymotion.com/';
}
public function getCacheDuration(){
return 3600*3; // 3 hours
}
}

View file

@ -0,0 +1,48 @@
<?php
/**
* RssBridgeDanbooru
* Returns images from given page
* 2014-05-25
*
* @name Danbooru
* @homepage http://donmai.us/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page", t="tags")
*/
class DanbooruBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 1;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://donmai.us/posts?&page=$page&tags=$tags") or $this->returnError('Could not request Danbooru.', 404);
foreach($html->find('div[id=posts] article') as $element) {
$item = new \Item();
$item->uri = 'http://donmai.us'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->getAttribute('data-id'));
$item->timestamp = time();
$item->thumbnailUri = 'http://donmai.us'.$element->find('img', 0)->src;
$item->tags = $element->find('img', 0)->getAttribute('alt');
$item->title = 'Danbooru | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Danbooru';
}
public function getURI(){
return 'http://donmai.us/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -3,9 +3,12 @@
* RssBridgeDansTonChat
* Retrieve lastest quotes from DansTonChat.
* Returns the most recent quotes, sorting by date (most recent first).
* 2014-05-25
*
* @name DansTonChat Bridge
* @homepage http://danstonchat.com/latest.html
* @description Returns latest quotes from DansTonChat.
* @maintainer Astalaseven
*/
class DansTonChatBridge extends BridgeAbstract{

View file

@ -0,0 +1,55 @@
<?php
/**
* @name DauphineLibereBridge Bridge
* @homepage http://www.ledauphine.com/
* @description Returns the newest articles. For choice « à la une » leave empty the input. For « France-Monde » input "france-monde". For « Faits Divers » input "faits-divers". For « Economie et Finance » input "economie-et-finance". For « Politique » input "politique". For « Sport » input "sport". For « Ain » input "ain". For « Alpes-de-Haute-Provence » input "haute-provence". For « Hautes-Alpes » input "hautes-alpes". For « Ardèche » input "ardeche". For « Drôme » input "drome". For « Isere Sud » input "isere-sud". For « Isere Nord » input "isere-nord". For « Savoie » input "savoie". For « Haute-Savoie » input "haute-savoie". For « Vaucluse » input "vaucluse".
* @maintainer qwertygc
* @use1(u="edition")
*/
class DauphineLibereBridge extends BridgeAbstract{
public function collectData(array $param){
function ExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.column', 0)->innertext;
$text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);
return $text;
}
if (isset($param['u'])) { /* user timeline mode */
$this->request = $param['u'];
$html = file_get_html('http://www.ledauphine.com/'.$this->request.'/rss') or $this->returnError('Could not request DauphineLibere.', 404);
}
else {
$html = file_get_html('http://www.ledauphine.com/rss') or $this->returnError('Could not request DauphineLibere.', 404);
}
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 10) {
$item = new \Item();
$item->title = $element->find('title', 0)->innertext;
$item->uri = $element->find('guid', 0)->plaintext;
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = ExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Dauphine Bridge';
}
public function getURI(){
return 'http://ledauphine.com/';
}
public function getCacheDuration(){
return 3600*2; // 2 hours
// return 0; // 2 hours
}
}

View file

@ -0,0 +1,75 @@
<?php
/**
* RssBridgeDeveloppezDotCom
* Returns the 15 newest posts from http://www.developpez.com (full text)
* 2014-07-14
*
* @name Developpez.com Actus (FR)
* @homepage http://www.developpez.com/
* @description Returns the 15 newest posts from DeveloppezDotCom (full text).
* @maintainer polopollo
*/
class DeveloppezDotComBridge extends BridgeAbstract{
public function collectData(array $param){
function DeveloppezDotComStripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function convert_smart_quotes($string)//F***ing quotes from Microsoft Word badly encoded, here was the trick: http://stackoverflow.com/questions/1262038/how-to-replace-microsoft-encoded-quotes-in-php
{
$search = array(chr(145),
chr(146),
chr(147),
chr(148),
chr(151));
$replace = array("'",
"'",
'"',
'"',
'-');
return str_replace($search, $replace, $string);
}
function DeveloppezDotComExtractContent($url) {
$articleHTMLContent = file_get_html($url);
$text = convert_smart_quotes($articleHTMLContent->find('div.content', 0)->innertext);
$text = utf8_encode($text);
return trim($text);
}
$rssFeed = file_get_html('http://www.developpez.com/index/rss') or $this->returnError('Could not request http://www.developpez.com/index/rss', 404);
$limit = 0;
foreach($rssFeed->find('item') as $element) {
if($limit < 10) {
$item = new \Item();
$item->title = DeveloppezDotComStripCDATA($element->find('title', 0)->innertext);
$item->uri = DeveloppezDotComStripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$content = DeveloppezDotComExtractContent($item->uri);
$item->content = strlen($content) ? $content : $element->description;//In case of it is a tutorial, we just keep the original description
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'DeveloppezDotCom';
}
public function getURI(){
return 'http://www.developpez.com/';
}
public function getCacheDuration(){
return 1800; // 30min
}
}

44
bridges/DilbertBridge.php Normal file
View file

@ -0,0 +1,44 @@
<?php
/**
*
* @name Dilbert Daily Strip
* @homepage http://dilbert.com/strips/
* @description The Unofficial Dilbert Daily Comic Strip
* @update 30/01/2015
* initial maintainer: superbaillot.net
* @maintainer kranack
*/
class DilbertBridge extends BridgeAbstract{
public function collectData(array $param){
$html = file_get_html('http://dilbert.com/strips/') or $this->returnError('Could not request Dilbert.', 404);
foreach($html->find('section.comic-item') as $element) {
$comic = $element->find('img', 0);
$item = new Item();
$item->uri = $element->find('a',0)->href;
$item->content = '<img src="'. $comic->src . '" alt="' . $comic->alt . '" />';
$item->title = $comic->alt;
$item->timestamp = strtotime($element->find('h3', 0)->plaintext);
$this->items[] = $item;
}
}
public function getName(){
return 'Dilbert';
}
public function getURI(){
return 'http://dilbert.com';
}
public function getDescription(){
return 'Dilbert via rss-bridge';
}
public function getCacheDuration(){
return 14400; // 4 hours
}
}
?>

View file

@ -0,0 +1,50 @@
<?php
/**
* RssBridgeDollbooru
* Returns images from given page
* 2015-01-20
*
* @name Dollbooru
* @homepage http://dollbooru.org/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page", t="tags")
*/
class DollbooruBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://dollbooru.org/post/list/$tags/$page") or $this->returnError('Could not request Dollbooru.', 404);
foreach($html->find('div[class=shm-image-list] a') as $element) {
$item = new \Item();
$item->uri = 'http://dollbooru.org'.$element->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->getAttribute('data-post-id'));
$item->timestamp = time();
$item->thumbnailUri = 'http://dollbooru.org'.$element->find('img', 0)->src;
$item->tags = $element->getAttribute('data-tags');
$item->title = 'Dollbooru | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Dollbooru';
}
public function getURI(){
return 'http://dollbooru.org/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -3,16 +3,19 @@
* RssBridgeDuckDuckGo
* Search DuckDuckGo for most recent pages regarding a specific topic.
* Returns the most recent links in results, sorting by date (most recent first).
* 2014-05-25
*
* @name DuckDuckGo
* @homepage https://duckduckgo.com/
* @description Returns most recent results from DuckDuckGo.
* @maintainer Astalaseven
* @use1(u="keyword")
*/
class DuckDuckGoBridge extends BridgeAbstract{
public function collectData(array $param){
$html = '';
$link = 'https://duckduckgo.com/html/?q='.$param[u].'+sort:date';
$link = 'http://duckduckgo.com/html/?q='.$param[u].'+sort:date';
$html = file_get_html($link) or $this->returnError('Could not request DuckDuckGo.', 404);

81
bridges/EZTVBridge.php Normal file
View file

@ -0,0 +1,81 @@
<?php
/**
* RssBridgeEZTV
* Monitor torrent for shows on EZTV
* 2015-01-20
*
* @name EZTV
* @homepage https://eztv.ch/
* @description Returns list of *recent* torrents for a specific show on EZTV. Get showID from URLs in https://eztv.ch/shows/showID/show-full-name.
* @maintainer alexAubin
* @update 2014-01-20
* @use1(i="showID1,showID2,...")
*/
class EZTVBridge extends BridgeAbstract{
public function collectData(array $param){
// Make timestamp from relative released time in table
function makeTimestamp($relativeReleaseTime){
$relativeDays = 0;
$relativeHours = 0;
foreach (explode(" ",$relativeReleaseTime) as $relativeTimeElement) {
if (substr($relativeTimeElement,-1) == "d") $relativeDays = substr($relativeTimeElement,0,-1);
if (substr($relativeTimeElement,-1) == "h") $relativeHours = substr($relativeTimeElement,0,-1);
}
return mktime(date('h')-$relativeHours,0,0,date('m'),date('d')-$relativeDays,date('Y'));
}
// Check for ID provided
if (!isset($param['i']))
$this->returnError('You must provide a list of ID (?i=showID1,showID2,...)', 400);
// Loop on show ids
$showList = explode(",",$param['i']);
foreach($showList as $showID){
// Get show page
$html = file_get_html('https://eztv.ch/shows/'.rawurlencode($showID).'/') or $this->returnError('Could not request EZTV for id "'.$showID.'"', 404);
// Loop on each element that look like an episode entry...
foreach($html->find('.forum_header_border') as $element) {
// Filter entries that are not episode entries
$ep = $element->find('td',1);
if (empty($ep)) continue;
$epinfo = $ep->find('.epinfo',0);
$released = $element->find('td',3);
if (empty($epinfo)) continue;
if (empty($released->plaintext)) continue;
// Filter entries that are older than 1 week
if ($released->plaintext == '&gt;1 week') continue;
// Fill item
$item = new \Item();
$item->uri = 'https://eztv.ch/'.$epinfo->href;
$item->id = $item->uri;
$item->timestamp = makeTimestamp($released->plaintext);
$item->title = $epinfo->plaintext;
$item->content = $epinfo->alt;
if(!empty($item->title))
$this->items[] = $item;
}
}
}
public function getName(){
return 'EZTV';
}
public function getURI(){
return 'https://eztv.ch/';
}
public function getCacheDuration(){
return 3600; // 1 hour
}
}

View file

@ -4,7 +4,10 @@
* Returns the 5 newest posts from http://www.futura-sciences.com (full text)
*
* @name Futurasciences
* @description Returns the 20 newest posts from FS (full text)
* @description Returns the 5 newest posts from FS (full text)
* @homepage http://www.futura-sciences.com
*@maintainer qwertygc
*/
class FSBridge extends BridgeAbstract{
@ -22,13 +25,14 @@ class FSBridge extends BridgeAbstract{
function FS_ExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.fiche-actualite', 0)->innertext;
$text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);
return $text;
}
$html = file_get_html('http://www.futura-sciences.com/rss/actualites.xml') or $this->returnError('Could not request Futura Sciences.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 20) {
if($limit < 5) {
$item = new \Item();
$item->title = FS_StripCDATA($element->find('title', 0)->innertext);
$item->uri = FS_StripCDATA($element->find('guid', 0)->plaintext);
@ -50,7 +54,7 @@ class FSBridge extends BridgeAbstract{
}
public function getCacheDuration(){
// return 3600; // 1 hour
return 0; // 1 hour
return 3600; // 1 hour
// return 0; // 1 hour
}
}

View file

@ -2,9 +2,12 @@
/**
* RssBridgeFlickrExplore
* Returns the newest interesting images from http://www.flickr.com/explore
* 2014-05-25
*
* @name Flickr Explore
* @homepage http://www.flickr.com/explore
* @description Returns the latest interesting images from Flickr
* @maintainer sebsauvage
*/
class FlickrExploreBridge extends BridgeAbstract{
@ -32,4 +35,4 @@ class FlickrExploreBridge extends BridgeAbstract{
public function getCacheDuration(){
return 21600; // 6 hours
}
}
}

View file

@ -0,0 +1,53 @@
<?php
/**
* RssBridgeFlickrTagUser
* Returns the tagged images from http://www.flickr.com/
* 2014-05-26
*
* @name Flickr TagUser
* @homepage http://www.flickr.com/
* @description Returns the tagged or user images from Flickr
* @maintainer erwang
* @use1(q="keyword")
* @use2(u="username")
*/
class FlickrTagBridge extends BridgeAbstract{
public function collectData(array $param){
$html = file_get_html('http://www.flickr.com/search/?q=vendee&s=rec') or $this->returnError('Could not request Flickr.', 404);
if (isset($param['q'])) { /* keyword search mode */
$this->request = $param['q'];
$html = file_get_html('http://www.flickr.com/search/?q='.urlencode($this->request).'&s=rec') or $this->returnError('No results for this query.', 404);
}
elseif (isset($param['u'])) { /* user timeline mode */
$this->request = $param['u'];
$html = file_get_html('http://www.flickr.com/photos/'.urlencode($this->request).'/') or $this->returnError('Requested username can\'t be found.', 404);
}
else {
$this->returnError('You must specify a keyword or a Flickr username.', 400);
}
foreach($html->find('span.photo_container') as $element) {
$item = new \Item();
$item->uri = 'http://flickr.com'.$element->find('a',0)->href;
$item->thumbnailUri = $element->find('img',0)->getAttribute('data-defer-src');
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a>'; // FIXME: Filter javascript ?
$item->title = $element->find('a',0)->title;
$this->items[] = $item;
}
}
public function getName(){
return 'Flickr Tag';
}
public function getURI(){
return 'http://www.flickr.com/search/';
}
public function getCacheDuration(){
return 21600; // 6 hours
}
}

58
bridges/FootitoBridge.php Normal file
View file

@ -0,0 +1,58 @@
<?php
/**
*
* @name Footito
* @homepage http://www.footito.fr/
* @description Footito
* @update 21/11/2013
* initial maintainer: superbaillot.net
*/
class FootitoBridge extends BridgeAbstract{
public function collectData(array $param){
$html = file_get_html('http://www.footito.fr/') or $this->returnError('Could not request Footito.', 404);
foreach($html->find('div.post') as $element) {
$item = new Item();
$content = trim($element->innertext);
$content = str_replace("<img", "<img style='float : left;'", $content );
$content = str_replace("class=\"logo\"", "style='float : left;'", $content );
$content = str_replace("class=\"contenu\"", "style='margin-left : 60px;'", $content );
$content = str_replace("class=\"responsive-comment\"", "style='border-top : 1px #DDD solid; background-color : white; padding : 10px;'", $content );
$content = str_replace("class=\"jaime\"", "style='display : none;'", $content );
$content = str_replace("class=\"auteur-event responsive\"", "style='display : none;'", $content );
$content = str_replace("class=\"report-abuse-button\"", "style='display : none;'", $content );
$content = str_replace("class=\"reaction clearfix\"", "style='margin : 10px 0px; padding : 5px; border-bottom : 1px #DDD solid;'", $content );
$content = str_replace("class=\"infos\"", "style='font-size : 0.7em;'", $content );
$item->content = $content;
$title = $element->find('.contenu .texte ', 0)->plaintext;
$item->title = $title;
$info = $element->find('div.infos', 0);
$item->timestamp = strtotime($info->find('time', 0)->datetime);
$item->name = $info->find('a.auteur', 0)->plaintext;
$this->items[] = $item;
}
}
public function getName(){
return 'footito';
}
public function getURI(){
return 'http://www.footito.fr/';
}
public function getCacheDuration(){
return 3600; // 1h hours
}
public function getDescription(){
return "Footito via rss-bridge";
}
}
?>

View file

@ -0,0 +1,66 @@
<?php
/**
* RssBridge4chan
* @name 4chan
* @homepage https://www.4chan.org/
* @description Returns posts from the specified thread
* @maintainer mitsukarenai
* @update 2015-02-01
* @use1(t="Thread URL")
*/
class FourchanBridge extends BridgeAbstract{
public function collectData(array $param){
if (!isset($param['t']))
$this->returnError('You must specify the thread URL (?t=...)', 400);
$thread = parse_url($param['t']) or $this->returnError('This URL seems malformed, please check it.', 400);
if($thread['host'] !== 'boards.4chan.org')
$this->returnError('4chan thread URL only.', 400);
if(strpos($thread['path'], 'thread/') === FALSE)
$this->returnError('You must specify the thread URL.', 400);
$url = 'https://boards.4chan.org'.$thread['path'].'';
$html = file_get_html($url) or $this->returnError("Could not request 4chan, thread not found", 404);
foreach($html->find('div.postContainer') as $element) {
$item = new \Item();
$item->id = $element->find('.post', 0)->getAttribute('id');
$item->uri = $url.'#'.$item->id;
$item->timestamp = $element->find('span.dateTime', 0)->getAttribute('data-utc');
$item->author = $element->find('span.name', 0)->plaintext;
if(!empty($element->find('.file', 0) ) ) {
$item->image = $element->find('.file a', 0)->href;
$item->imageThumb = $element->find('.file img', 0)->src;
if(empty($item->imageThumb) and strpos($item->image, '.swf') !== FALSE)
$item->imageThumb = 'http://i.imgur.com/eO0cxf9.jpg';
}
if(!empty($element->find('span.subject', 0)->innertext )) {
$item->subject = $element->find('span.subject', 0)->innertext;
}
$item->title = (!empty($item->subject) ? $item->subject.' - ' : '' ) . 'reply '.$item->id.' | '.$item->author;
$item->content = (!empty($item->image) ? '<a href="'.$item->image.'"><img alt="'.$item->id.'" src="'.$item->imageThumb.'" /></a><br>' : '') . '<span id="'.$item->id.'">'.$element->find('.postMessage', 0)->innertext.'</span>';
$this->items[] = $item;
}
$this->items = array_reverse($this->items);
}
public function getName(){
return '4chan';
}
public function getURI(){
return 'https://www.4chan.org/';
}
public function getCacheDuration(){
return 300; // 5min
}
}

View file

@ -0,0 +1,70 @@
<?php
/**
* RssBridgeFrandroid
* Returns the RSS feed from Frandroid (full text articles)
*
* @name Frandroid
* @homepage http://www.frandroid.com/
* @description Returns the RSS feed from Frandroid (full text articles)
* @maintainer Daiyousei
* @update 2015-03-05
*/
class FrandroidBridge extends BridgeAbstract
{
public function collectData(array $param)
{
function FrandroidStripCDATA($string)
{
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function FrandroidExtractContent($url)
{
$html2 = file_get_html($url);
$html3 = $html2->find('div.post-content', 0);
$html3->find('div.no-sidebar-ad-top', 0)->outertext = '';
$ret = $html3->find('div.shortcode-container');
foreach ($ret as $value) {
$value->outertext = '';
}
$html3->find('div#hrr-link', 0)->outertext = '';
$text = $html3->innertext;
$text = strip_tags($text, '<h1><span><h2><p><b><a><blockquote><img><em><ul><ol>');
return $text;
}
$html = file_get_html('http://feeds.feedburner.com/Frandroid?format=xml') or $this->returnError('Could not request Frandroid.', 404);
$limit = 0;
foreach ($html->find('item') as $element) {
if ($limit < 5) {
$item = new \Item();
$item->title = FrandroidStripCDATA($element->find('title', 0)->innertext);
$item->uri = FrandroidStripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = FrandroidExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName()
{
return 'Frandroid';
}
public function getURI()
{
return 'http://www.frandroid.com/';
}
public function getCacheDuration()
{
return 300; // 5min
}
}

View file

@ -0,0 +1,52 @@
<?php
/**
* RssBridgeGelbooru
* Returns images from given page
* 2014-05-25
*
* @name Gelbooru
* @homepage http://gelbooru.com/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page", t="tags")
*/
class GelbooruBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0;
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
$page = $page - 1;
$page = $page * 63;
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://gelbooru.com/index.php?page=post&s=list&tags=$tags&pid=$page") or $this->returnError('Could not request Gelbooru.', 404);
foreach($html->find('div[class=content] span') as $element) {
$item = new \Item();
$item->uri = 'http://gelbooru.com/'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->getAttribute('id'));
$item->timestamp = time();
$item->thumbnailUri = $element->find('img', 0)->src;
$item->tags = $element->find('img', 0)->getAttribute('alt');
$item->title = 'Gelbooru | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Gelbooru';
}
public function getURI(){
return 'http://gelbooru.com/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

86
bridges/GiphyBridge.php Normal file
View file

@ -0,0 +1,86 @@
<?php
/**
* RssBridgeGiphy
* Based on https://github.com/mitsukarenai/twitterbridge-noapi
* 2014-12-05
*
* @name Giphy Bridge
* @homepage http://giphy.com/
* @description Bridge for giphy.com
* @maintainer kraoc
* @use1(s="search tag")
* @use2(n="max number of returned items")
*/
define(GIPHY_LIMIT, 10);
class GiphyBridge extends BridgeAbstract{
public function collectData(array $param){
$html = '';
$base_url = 'http://giphy.com';
if (isset($param['s'])) { /* keyword search mode */
$html = file_get_html($base_url.'/search/'.urlencode($param['s'].'/')) or $this->returnError('No results for this query.', 404);
}
else {
$this->returnError('You must specify a search worf (?s=...).', 400);
}
$max = GIPHY_LIMIT;
if (isset($param['n'])) {
$max = (integer) $param['n'];
}
$limit = 0;
$kw = urlencode($param['s']);
foreach($html->find('div.hoverable-gif') as $entry) {
if($limit < $max) {
$node = $entry->first_child();
$href = $node->getAttribute('href');
$html2 = file_get_html($base_url . $href) or $this->returnError('No results for this query.', 404);
$figure = $html2->getElementByTagName('figure');
$img = $figure->firstChild();
$caption = $figure->lastChild();
$item = new \Item();
$item->id = $img->getAttribute('data-gif_id');
$item->uri = $img->getAttribute('data-bitly_gif_url');
$item->username = 'Giphy - '.ucfirst($kw);
$title = $caption->innertext();
$title = preg_replace('/\s+/', ' ',$title);
$title = str_replace('animated GIF', '', $title);
$title = str_replace($kw, '', $title);
$title = preg_replace('/\s+/', ' ',$title);
$title = trim($title);
if (strlen($title) <= 0) {
$title = $item->id;
}
$item->title = trim($title);
$item->content =
'<a href="'.$item->uri.'">'
.'<img src="'.$img->getAttribute('src').'" width="'.$img->getAttribute('data-original-width').'" height="'.$img->getAttribute('data-original-height').'" />'
.'</a>';
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Giphy Bridge';
}
public function getURI(){
return 'http://giphy.com/';
}
public function getCacheDuration(){
return 300; // 5 minutes
}
public function getUsername(){
return $this->items[0]->username;
}
}

View file

@ -0,0 +1,57 @@
<?php
/**
* RssBridgeGizmodoFR
* Returns the 15 newest posts from http://www.gizmodo.fr (full text)
* 2014-07-14
*
* @name GizmodoFR
* @homepage http://www.gizmodo.fr/
* @description Returns the 15 newest posts from GizmodoFR (full text).
* @maintainer polopollo
*/
class GizmodoFRBridge extends BridgeAbstract{
public function collectData(array $param){
function GizmodoFRExtractContent($url) {
$articleHTMLContent = file_get_html($url);
$text = $articleHTMLContent->find('div.entry-thumbnail', 0)->innertext;
$text = $text.$articleHTMLContent->find('div.entry-excerpt', 0)->innertext;
$text = $text.$articleHTMLContent->find('div.entry-content', 0)->innertext;
foreach($articleHTMLContent->find('pagespeed_iframe') as $element) {
$text = $text.'<p>link to a iframe (could be a video): <a href="'.$element->src.'">'.$element->src.'</a></p><br>';
}
$text = strip_tags($text, '<p><b><a><blockquote><img><em>');
return $text;
}
$rssFeed = file_get_html('http://www.gizmodo.fr/feed') or $this->returnError('Could not request http://www.gizmodo.fr/feed', 404);
$limit = 0;
foreach($rssFeed->find('item') as $element) {
if($limit < 15) {
$item = new \Item();
$item->title = $element->find('title', 0)->innertext;
$item->uri = $element->find('guid', 0)->plaintext;
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = GizmodoFRExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'GizmodoFR';
}
public function getURI(){
return 'http://www.gizmodo.fr/';
}
public function getCacheDuration(){
return 1800; // 30min
}
}

View file

@ -0,0 +1,125 @@
<?php
/**
* Google Plus Post Bridge
* Freely inspired by tweeter bridge
* 2014-07-20
*
* @name Google Plus Post Bridge
* @homepage http://plus.google.com/
* @description Returns user public post (without API).
* @maintainer Grummfy
* @use1(username="usernameOrId")
*/
class GooglePlusPostBridge extends BridgeAbstract
{
protected $_title;
protected $_url;
const GOOGLE_PLUS_BASE_URL = 'https://plus.google.com/';
public function collectData(array $param)
{
if (!isset($param['username']))
{
$this->returnError('You must specify a username (?username=...).', 400);
}
$this->request = $param['username'];
// get content parsed
// $html = file_get_html(__DIR__ . '/../posts2.html'
$html = file_get_html(self::GOOGLE_PLUS_BASE_URL . urlencode($this->request) . '/posts'
// force language
, false, stream_context_create(array('http'=> array(
'header' => 'Accept-Language: fr,fr-be,fr-fr;q=0.8,en;q=0.4,en-us;q=0.2;*' . "\r\n"
)))
) OR $this->returnError('No results for this query.', 404);
// get title, url, ... there is a lot of intresting stuff in meta
$this->_title = $html->find('meta[property]', 0)->getAttribute('content');
$this->_url = $html->find('meta[itemprop=url]', 0)->getAttribute('content');
// foreach ($html->find('meta') as $e)
// {
// $item = new \Item();
// $item->content = var_export($e->attr, true);
// $this->items[] = $item;
// }
// div[jsmodel=XNmfOc]
foreach($html->find('div.yt') as $post)
{
$item = new \Item();
// $item->content = $post->find('div.Al', 0)->innertext;
$item->username = $item->fullname = $post->find('header.lea h3 a', 0)->innertext;
$item->id = $post->getAttribute('id');
// $item->title = $item->fullname = $post->find('header.lea', 0)->plaintext;
$item->avatar = $post->find('div.ys img', 0)->src;
// var_dump((($post->find('a.o-U-s', 0)->getAllAttributes())));
$item->uri = $post->find('a.o-U-s', 0)->href;
$item->timestamp = strtotime($post->find('a.o-U-s', 0)->plaintext);
$this->items[] = $item;
// hashtag to treat : https://plus.google.com/explore/tag
$hashtags = array();
foreach($post->find('a.d-s') as $hashtag)
{
$hashtags[ trim($hashtag->plaintext) ] = self::GOOGLE_PLUS_BASE_URL . $hashtag->href;
}
$item->content = '';
// avatar display
$item->content .= '<div style="float:left; margin: 0 0.5em 0.5em 0;"><a href="' . self::GOOGLE_PLUS_BASE_URL . urlencode($this->request);
$item->content .= '"><img align="top" alt="avatar" src="' . $item->avatar.'" />' . $item->username . '</a></div>';
$content = $post->find('div.Al', 0);
// alter link
// $content = $content->innertext;
// $content = str_replace('href="./', 'href="' . self::GOOGLE_PLUS_BASE_URL, $content);
// $content = str_replace('href="photos', 'href="' . self::GOOGLE_PLUS_BASE_URL . 'photos', $content);
// XXX ugly but I don't have any idea how to do a better stuff, str_replace on link doesn't work as expected and ask too many checks
foreach($content->find('a') as $link)
{
$hasHttp = strpos($link->href, 'http');
$hasDoubleSlash = strpos($link->href, '//');
if ((!$hasHttp && !$hasDoubleSlash)
|| (false !== $hasHttp && strpos($link->href, 'http') != 0)
|| (false === $hasHttp && false !== $hasDoubleSlash && $hasDoubleSlash != 0))
{
// skipp bad link, for some hashtag or other stuff
if (strpos($link->href, '/') == 0)
{
$link->href = substr($link->href, 1);
}
$link->href = self::GOOGLE_PLUS_BASE_URL . $link->href;
}
}
$content = $content->innertext;
$item->content .= '<div style="margin-top: -1.5em">' . $content . '</div>';
// extract plaintext
$item->content_simple = $post->find('div.Al', 0)->plaintext;
}
// $html->save(__DIR__ . '/../posts2.html');
}
public function getName()
{
return $this->_title ?: 'Google Plus Post Bridge';
}
public function getURI()
{
return $this->_url ?: 'http://plus.google.com/';
}
public function getCacheDuration()
{
return 1; // 600; // 10 minutes
}
}

View file

@ -8,9 +8,12 @@
* complete=0&num=100 : get 100 results
* qdr:y : in past year
* sbd:1 : sort by date (will only work if qdr: is specified)
* 2014-05-25
*
* @name Google search
* @homepage https://www.google.com/
* @description Returns most recent results from Google search.
* @maintainer sebsauvage
* @use1(q="keyword")
*/
class GoogleSearchBridge extends BridgeAbstract{
@ -22,7 +25,7 @@ class GoogleSearchBridge extends BridgeAbstract{
if (isset($param['q'])) { /* keyword search mode */
$this->request = $param['q'];
$html = file_get_html('http://www.google.com/search?q=' . urlencode($this->request) . '&num=100&complete=0&tbs=qdr:y,sbd:1') or $this->returnError('No results for this query.', 404);
$html = file_get_html('https://www.google.com/search?q=' . urlencode($this->request) . '&num=100&complete=0&tbs=qdr:y,sbd:1') or $this->returnError('No results for this query.', 404);
}
else{
$this->returnError('You must specify a keyword (?q=...).', 400);
@ -35,7 +38,7 @@ class GoogleSearchBridge extends BridgeAbstract{
// Extract direct URL from google href (eg. /url?q=...)
$t = $element->find('a[href]',0)->href;
$item->uri = 'http://google.com'.$t;
$item->uri = ''.$t;
parse_str(parse_url($t, PHP_URL_QUERY),$parameters);
if (isset($parameters['q'])) { $item->uri = $parameters['q']; }
$item->title = $element->find('h3',0)->plaintext;
@ -56,4 +59,4 @@ class GoogleSearchBridge extends BridgeAbstract{
public function getCacheDuration(){
return 1800; // 30 minutes
}
}
}

View file

@ -1,10 +1,12 @@
<?php
/**
* RssBridgeGuruMed
* Returns the 10 newest posts from http://www.gurumed.org (full text)
* Returns the 5 newest posts from http://www.gurumed.org (full text)
*
* @name GuruMed
* @description Returns the 20 newest posts from Gurumed (full text)
* @description Returns the 5 newest posts from Gurumed (full text)
* @homepage http://www.gurumed.org
*@maintainer qwertygc
*/
class GuruMedBridge extends BridgeAbstract{
@ -28,7 +30,7 @@ class GuruMedBridge extends BridgeAbstract{
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 10) {
if($limit < 5) {
$item = new \Item();
$item->title = GurumedStripCDATA($element->find('title', 0)->innertext);
$item->uri = GurumedStripCDATA($element->find('guid', 0)->plaintext);

View file

@ -0,0 +1,62 @@
<?php
/**
* RssBridgeHumbleStoreDiscount
* Returns the 10 first sales from the Humble Store
* Enjoy your indie games :)
*
* @name Humble Store Discount Bridge
* @homepage https://www.humblebundle.com/store
* @description Returns the 10 first sales from the Humble Store
* @maintainer 16mhz
* @update 2014-07-18
*/
class HumbleStoreDiscountBridge extends BridgeAbstract{
public function collectData(array $param){
$result = file_get_html('https://www.humblebundle.com/store/api/humblebundle?request=2&page_size=20&sort=discount&page=0')
or $this->returnError('Could not request the Humble Store.', 404);
$string = json_decode($result, true);
$items = $string['results'];
$store_link = 'https://www.humblebundle.com/store/p/';
$limit = 0;
foreach ($items as $key => $value) {
if ($limit < 10) {
$new_price = $value['current_price'][0] . ' ' . $value['current_price'][1];
$full_price = $value['full_price'][0] . ' ' . $value['full_price'][1];
$product_name = $value['human_name'];
$sale_end = (int)$value['sale_end'];
$product_uri = $store_link . $value['machine_name'];
$platforms = str_replace('\'', '', implode("','", $value['platforms']));
$delivery_methods = str_replace('\'', '', implode("','", $value['delivery_methods']));
$thumbnail = 'https://www.humblebundle.com' . $value['storefront_featured_image_small'];
$content = '<img src="' . $thumbnail . '" alt="' . $value['storefront_featured_image_small'] . '"><br/><br/><b>' . $product_name
. '</b><br/><br/><b>Current price:</b> ' . $new_price . '<br/><b>Full price:</b> ' . $full_price .'<br/><b>Sale ends:</b> '. date(DATE_ATOM, $sale_end)
. '<br/><b>Developer:</b> ' . $value['developer_name'] . '<br/><b>Delivery methods:</b> ' . $delivery_methods
. '<br/><b>Platforms:</b> ' . $platforms . '<br/>' . $value['description'];
$item = new \Item();
$item->title = $product_name . ' - ' . $new_price;
$item->uri = $product_uri;
$item->timestamp = $sale_end - 10*24*3600; // just a hack, stamping game as 10 days before sales end (better than no timestamp)
$item->content = $content;
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'HumbleStoreDiscount';
}
public function getURI(){
return 'https://www.humblebundle.com/store';
}
public function getCacheDuration(){
return 21600; // 6 hours
}
}

View file

@ -1,9 +1,12 @@
<?php
/**
* RssBridgeIdentica
* 2014-05-25
*
* @name Identica Bridge
* @homepage https://identi.ca/
* @description Returns user timelines
* @maintainer mitsukarenai
* @use1(u="username")
*/
class IdenticaBridge extends BridgeAbstract{

View file

@ -2,9 +2,12 @@
/**
* RssBridgeInstagram
* Returns the newest photos
* 2014-05-25
*
* @name Instagram Bridge
* @homepage http://instagram.com/
* @description Returns the newest images
* @maintainer pauder
* @use1(u="username")
*/
class InstagramBridge extends BridgeAbstract{

View file

@ -0,0 +1,54 @@
<?php
/**
* RssBridgeKonachan
* Returns images from given page
* 2014-05-25
*
* @name Konachan
* @homepage http://konachan.com/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page",t="tags")
*/
class KonachanBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 1;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://konachan.com/post?page=$page&tags=$tags") or $this->returnError('Could not request Konachan.', 404);
$input_json = explode('Post.register(', $html);
foreach($input_json as $element)
$data[] = preg_replace('/}\)(.*)/', '}', $element);
unset($data[0]);
foreach($data as $datai) {
$json = json_decode($datai, TRUE);
$item = new \Item();
$item->uri = 'http://konachan.com/post/show/'.$json['id'];
$item->postid = $json['id'];
$item->timestamp = $json['created_at'];
$item->imageUri = $json['file_url'];
$item->thumbnailUri = $json['preview_url'];
$item->title = 'Konachan | '.$json['id'];
$item->content = '<a href="' . $item->imageUri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$json['tags'];
$this->items[] = $item;
}
}
public function getName(){
return 'Konachan';
}
public function getURI(){
return 'http://konachan.com/post';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

56
bridges/KoreusBridge.php Normal file
View file

@ -0,0 +1,56 @@
<?php
/**
* RssBridgeKoreus
* Returns the 5 newest posts from Koreus (full text)
*
* @name Koreus
* @homepage http://www.koreus.com/
* @description Returns the 5 newest posts from Koreus (full text)
* @maintainer pit-fgfjiudghdf
* @update 2014-05-26
*/
class KoreusBridge extends BridgeAbstract{
public function collectData(array $param){
function KoreusStripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function KoreusExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('p[class=itemText]', 0)->innertext;
$text = utf8_encode(preg_replace('/(Sur le m.+?)+$/i','',$text));
return $text;
}
$html = file_get_html('http://feeds.feedburner.com/Koreus-articles') or $this->returnError('Could not request Koreus.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 5) {
$item = new \Item();
$item->title = KoreusStripCDATA($element->find('title', 0)->innertext);
$item->uri = KoreusStripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = KoreusExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Koreus';
}
public function getURI(){
return 'http://www.koreus.com/';
}
public function getCacheDuration(){
return 3600; // 1 hour
}
}

61
bridges/LeBonCoinBridge.php Executable file
View file

@ -0,0 +1,61 @@
<?php
/**
* RssBridgeLeBonCoin
* Search LeBonCoin for most recent ads in a specific region and topic.
* Returns the most recent classified ads in results, sorting by date (most recent first).
* Region identifiers : alsace, aquitaine, auvergne, basse_normandie, bourgogne, bretagne, centre,
* champagne_ardenne, corse, franche_comte, haute_normandie, ile_de_france, languedoc_roussillon,
* limousin, lorraine, midi_pyrenees, nord_pas_de_calais, pays_de_la_loire, picardie,
* poitou_charentes, provence_alpes_cote_d_azur, rhone_alpes, guadeloupe, martinique, guyane, reunion.
* 2014-07-22
*
* @name LeBonCoin
* @homepage http://www.leboncoin.fr
* @description Returns most recent results from LeBonCoin for a region and a keyword.
* @maintainer 16mhz
* @use1(r="Region identifier", k="Keyword")
*/
class LeBonCoinBridge extends BridgeAbstract{
public function collectData(array $param){
$html = '';
$link = 'http://www.leboncoin.fr/annonces/offres/' . $param[r] . '/?f=a&th=1&q=' . $param[k];
$html = file_get_html($link) or $this->returnError('Could not request LeBonCoin.', 404);
$list = $html->find('.list-lbc', 0);
$tags = $list->find('a');
foreach($tags as $element) {
$item = new \Item();
$item->uri = $element->href;
$title = $element->getAttribute('title');
$content = '<img src="' . $element->find('div.image', 0)->find('img', 0)->getAttribute('src') . '" alt="thumbnail">';
$date = $element->find('div.date', 0)->find('div', 0) . $element->find('div.date', 0)->find('div', 1) . '<br/>';
$detailsList = $element->find('div.detail', 0);
for ($i = 1; $i < 4; $i++) {
$line = $detailsList->find('div', $i);
$content .= $line;
}
$item->title = $title . ' - ' . $detailsList->find('div', 3);
$item->content = $content . $date;
$this->items[] = $item;
}
}
public function getName(){
return 'LeBonCoin';
}
public function getURI(){
return 'http://www.leboncoin.fr';
}
public function getCacheDuration(){
return 3600; // 1 hour
}
}

View file

@ -0,0 +1,69 @@
<?php
/**
* RssBridgeLeJournalDuGeek
* Returns the 15 newest posts from http://www.journaldugeek.com (full text)
* 2014-07-14
*
* @name journaldugeek.com (FR)
* @homepage http://www.journaldugeek.com/
* @description Returns the 5 newest posts from LeJournalDuGeek (full text).
* @maintainer polopollo
*/
class LeJournalDuGeekBridge extends BridgeAbstract{
public function collectData(array $param){
function LeJournalDuGeekStripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function LeJournalDuGeekExtractContent($url) {
$articleHTMLContent = file_get_html($url);
$text = $text.$articleHTMLContent->find('div.post-content', 0)->innertext;
foreach($articleHTMLContent->find('a.more') as $element) {
if ($element->innertext == "Source") {
$text = $text.'<p><a href="'.$element->href.'">Source : '.$element->href.'</a></p>';
break;
}
}
foreach($articleHTMLContent->find('iframe') as $element) {
if (preg_match("/youtube/i", $element->src)) {
$text = $text.'// An IFRAME to Youtube was included in the article: <a href="'.$element->src.'">'.$element->src.'</a><br>';
}
}
$text = strip_tags($text, '<p><b><a><blockquote><img><em><br/><br><ul><li>');
return $text;
}
$rssFeed = file_get_html('http://www.journaldugeek.com/rss') or $this->returnError('Could not request http://www.journaldugeek.com/rss', 404);
$limit = 0;
foreach($rssFeed->find('item') as $element) {
if($limit < 5) {
$item = new \Item();
$item->title = LeJournalDuGeekStripCDATA($element->find('title', 0)->innertext);
$item->uri = LeJournalDuGeekStripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = LeJournalDuGeekExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'LeJournalDuGeek';
}
public function getURI(){
return 'http://www.journaldugeek.com/';
}
public function getCacheDuration(){
return 1800; // 30min
}
}

View file

@ -0,0 +1,52 @@
<?php
/**
* 2014-05-25
* @name LeMotDuJour Bridge
* @homepage http://www.lemotdujour.com/
* @description Returns the newest articles.
* @maintainer qwertygc
*/
class LeMotDuJourBridge extends BridgeAbstract{
public function collectData(array $param){
function StripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function ExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.single-contenu', 0)->innertext;
return $text;
}
$html = file_get_html('http://feeds2.feedburner.com/lemotdujour/lemotdujour') or $this->returnError('Could not request LeMotDuJour.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 10) {
$item = new \Item();
$item->title = StripCDATA($element->find('title', 0)->innertext);
$item->uri = StripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = ExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'LeMotDuJour Bridge';
}
public function getURI(){
return 'http://lemotdujour.com/';
}
public function getCacheDuration(){
return 3600*2; // 2 hours
// return 0; // 2 hours
}
}

View file

@ -0,0 +1,65 @@
<?php
/**
*
* @name Les Joies Du Code
* @homepage http://lesjoiesducode.fr/
* @description LesJoiesDuCode
* @update 04/02/2015
* initial maintainer: superbaillot.net
*/
class LesJoiesDuCodeBridge extends BridgeAbstract{
public function collectData(array $param){
$html = file_get_html('http://lesjoiesducode.fr/') or $this->returnError('Could not request LesJoiesDuCode.', 404);
foreach($html->find('div.post') as $element) {
$item = new Item();
$temp = $element->find('h3 a', 0);
$titre = $temp->innertext;
$url = $temp->href;
$temp = $element->find('div.bodytype', 0);
// retrieve .gif instead of static .jpg
$images = $temp->find('p.e img');
foreach($images as $image){
$img_src = str_replace(".jpg",".gif",$image->src);
$image->src = $img_src;
}
$content = $temp->innertext;
$auteur = $temp->find('i', 0);
$pos = strpos($auteur->innertext, "by");
if($pos > 0)
{
$auteur = trim(str_replace("*/", "", substr($auteur->innertext, ($pos + 2))));
$item->name = $auteur;
}
$item->content .= trim($content);
$item->uri = $url;
$item->title = trim($titre);
$this->items[] = $item;
}
}
public function getName(){
return 'Les Joies Du Code';
}
public function getURI(){
return 'http://lesjoiesducode.fr/';
}
public function getCacheDuration(){
return 7200; // 2h hours
}
public function getDescription(){
return "Les Joies Du Code via rss-bridge";
}
}
?>

View file

@ -0,0 +1,54 @@
<?php
/**
* RssBridgeLolibooru
* Returns images from given page and tags
*
* @name Lolibooru
* @homepage http://lolibooru.moe/
* @description Returns images from given page and tags
* @maintainer mitsukarenai
* @update 2015-03-21
* @use1(p="page", t="tags")
*/
class LolibooruBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 1; $tags = '';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://lolibooru.moe/post?page=$page&tags=$tags") or $this->returnError('Could not request Lolibooru.', 404);
$input_json = explode('Post.register(', $html);
foreach($input_json as $element)
$data[] = preg_replace('/}\)(.*)/', '}', $element);
unset($data[0]);
foreach($data as $datai) {
$json = json_decode($datai, TRUE);
$item = new \Item();
$item->uri = 'http://lolibooru.moe/post/show/'.$json['id'];
$item->postid = $json['id'];
$item->timestamp = $json['created_at'];
$item->imageUri = $json['file_url'];
$item->thumbnailUri = $json['preview_url'];
$item->title = 'Lolibooru | '.$json['id'];
$item->content = '<a href="' . $item->imageUri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$json['tags'];
$this->items[] = $item;
}
}
public function getName(){
return 'Lolibooru';
}
public function getURI(){
return 'http://lolibooru.moe/post';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

60
bridges/MalikiBridge.php Normal file
View file

@ -0,0 +1,60 @@
<?php
/**
* RssBridgeMaliki
* Returns Maliki's newest strips
*
* @name Maliki
* @homepage http://www.maliki.com/
* @description Returns Maliki's newest strips
* @maintainer mitsukarenai
* @update 2014-05-30
*/
class MalikiBridge extends BridgeAbstract{
public function collectData(array $param){
$html = file_get_html('http://www.maliki.com/') or $this->returnError('Could not request Maliki.', 404);
$count=0;
$latest=1; $latest_title="";
$latest = $html->find('div.conteneur_page a', 1)->href;
$latest_title = $html->find('div.conteneur_page img', 0)->title;
function MalikiExtractContent($url) {
$html2 = file_get_html($url);
$text = 'http://www.maliki.com/'.$html2->find('img', 0)->src;
$text = '<img alt="" src="'.$text.'"/><br>'.$html2->find('div.imageetnews', 0)->plaintext;
return $text;
}
$item = new \Item();
$item->uri = 'http://www.maliki.com/'.$latest;
$item->title = $latest_title;
$item->timestamp = time();
$item->content = MalikiExtractContent($item->uri);
$this->items[] = $item;
foreach($html->find('div.boite_strip') as $element) {
if(!empty($element->find('a',0)->href) and $count < 3) {
$item = new \Item();
$item->uri = 'http://www.maliki.com/'.$element->find('a',0)->href;
$item->title = $element->find('img',0)->title;
$item->timestamp = strtotime(str_replace('/', '-', $element->find('span.stylepetit', 0)->innertext));
$item->content = MalikiExtractContent($item->uri);
$this->items[] = $item;
$count++;
}
}
}
public function getName(){
return 'Maliki';
}
public function getURI(){
return 'http://www.maliki.com/';
}
public function getCacheDuration(){
return 86400*6; // 6 days
}
}

View file

@ -0,0 +1,55 @@
<?php
/**
* @name MemoLinux
* @homepage http://memo-linux.com/
* @description Returns the 10 newest posts from MemoLinux (full text)
* @maintainer qwertygc
* @update 2015-01-30
*/
class MemoLinuxBridge extends BridgeAbstract{
public function collectData(array $param){
function StripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function ExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.entry-content', 0)->innertext;
$text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);
$text = preg_replace('@<div[^>]*?>.*?</div>@si', '', $text);
$text = preg_replace("/<h1.*/", '', $text);
return $text;
}
$html = file_get_html('http://memo-linux.com/feed/') or $this->returnError('Could not request MemoLinux.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 10) {
$item = new \Item();
$item->title = StripCDATA($element->find('title', 0)->innertext);
$item->uri = StripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = ExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'MemoLinux';
}
public function getURI(){
return 'http://memo-linux.com/feed/';
}
public function getCacheDuration(){
return 3600*12; // 12 hours
}
}

View file

@ -0,0 +1,50 @@
<?php
/**
* RssBridgeMilbooru
* Returns images from given page
* 2014-05-25
*
* @name Milbooru
* @homepage http://sheslostcontrol.net/moe/shimmie/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page",t="tags")
*/
class MilbooruBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://sheslostcontrol.net/moe/shimmie/index.php?q=/post/list/$tags/$page") or $this->returnError('Could not request Milbooru.', 404);
foreach($html->find('div[class=shm-image-list] span[class=thumb]') as $element) {
$item = new \Item();
$item->uri = 'http://sheslostcontrol.net/moe/shimmie/'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->find('a', 0)->getAttribute('data-post-id'));
$item->timestamp = time();
$item->thumbnailUri = 'http://sheslostcontrol.net/moe/shimmie/'.$element->find('img', 0)->src;
$item->tags = $element->find('a', 0)->getAttribute('data-tags');
$item->title = 'Milbooru | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Milbooru';
}
public function getURI(){
return 'http://sheslostcontrol.net/moe/shimmie/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -0,0 +1,62 @@
<?php
/**
* RssBridgeMondeDiplo
* Search MondeDiplo for most recent pages.
* Returns the most recent links in results.
* 2014-07-22
*
* @name MondeDiplo
* @homepage http://www.monde-diplomatique.fr
* @description Returns most recent results from MondeDiplo.
* @maintainer Pitchoule
*/
class MondeDiploBridge extends BridgeAbstract{
public function collectData(array $param){
$link = 'http://www.monde-diplomatique.fr';
$html = file_get_html($link) or $this->returnError('Could not request MondeDiplo. for : ' . $link , 404);
foreach($html->find('div.laune') as $element) {
$item = new Item();
$item->uri = 'http://www.monde-diplomatique.fr'.$element->find('a', 0)->href;
$item->title = $element->find('h3', 0)->plaintext;
$item->content = $element->find('div.dates_auteurs', 0)->plaintext. '<br>' .strstr($element->find('div', 0)->plaintext, $element->find('div.dates_auteurs', 0)->plaintext, true);
$this->items[] = $item;
}
$liste = $html->find('div.listes', 0); // First list
foreach ($liste->find('li') as $e) {
$item = new Item();
$item->uri = 'http://www.monde-diplomatique.fr' . $e->find('a', 0)->href;
$item->title = $e->find('a', 0)->plaintext;
$item->content = $e->find('div.dates_auteurs', 0)->plaintext;
$this->items[] = $item;
}
foreach($html->find('div.liste ul li') as $element) {
if ($element->getAttribute('class') != 'intrapub') {
$item = new Item();
$item->uri = 'http://www.monde-diplomatique.fr'.$element->find('a', 0)->href;
$item->title = $element->find('h3', 0)->plaintext;
$item->content = $element->find('div.dates_auteurs', 0)->plaintext . ' <br> ' . $element->find('div.intro', 0)->plaintext;
$this->items[] = $item;
}
}
}
public function getName(){
return 'Monde Diplomatique';
}
public function getURI(){
return 'http://www.monde-diplomatique.fr';
}
public function getCacheDuration(){
return 21600; // 6 hours
}
}

View file

@ -0,0 +1,47 @@
<?php
/**
* RssBridgeMsnMonde
* Returns the 10 newest posts from MSN Actualités (full text)
*
* @name MSN Actu Monde
* @homepage http://www.msn.com/fr-fr/actualite/monde
* @description Returns the 10 newest posts from MSN Actualités (full text)
* @maintainer kranack
* @update 2015-01-30
*/
class MsnMondeBridge extends BridgeAbstract{
public function collectData(array $param){
function MsnMondeExtractContent($url, &$item) {
$html2 = file_get_html($url);
$item->content = $html2->find('#content', 0)->find('article', 0)->find('section', 0)->plaintext;
$item->timestamp = strtotime($html2->find('.authorinfo-txt', 0)->find('time', 0)->datetime);
}
$html = file_get_html('http://www.msn.com/fr-fr/actualite/monde') or $this->returnError('Could not request MsnMonde.', 404);
$limit = 0;
foreach($html->find('.smalla') as $article) {
if($limit < 10) {
$item = new \Item();
$item->title = utf8_decode($article->find('h4', 0)->innertext);
$item->uri = "http://www.msn.com" . utf8_decode($article->find('a', 0)->href);
MsnMondeExtractContent($item->uri, $item);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'MSN Actu Monde';
}
public function getURI(){
return 'http://www.msn.com/fr-fr/actualite/monde';
}
public function getCacheDuration(){
return 3600; // 1 hour
}
}

View file

@ -0,0 +1,52 @@
<?php
/**
* RssBridgeMspabooru
* Returns images from given page
* 2014-05-25
*
* @name Mspabooru
* @homepage http://mspabooru.com/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page",t="tags")
*/
class MspabooruBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
$page = $page - 1;
$page = $page * 50;
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://mspabooru.com/index.php?page=post&s=list&tags=$tags&pid=$page") or $this->returnError('Could not request Mspabooru.', 404);
foreach($html->find('div[class=content] span') as $element) {
$item = new \Item();
$item->uri = 'http://mspabooru.com/'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->getAttribute('id'));
$item->timestamp = time();
$item->thumbnailUri = $element->find('img', 0)->src;
$item->tags = $element->find('img', 0)->getAttribute('alt');
$item->title = 'Mspabooru | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Mspabooru';
}
public function getURI(){
return 'http://mspabooru.com/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -0,0 +1,56 @@
<?php
/**
* 2014-08-27
* @name NASA APOD Bridge
* @homepage http://apod.nasa.gov/apod/astropix.html
* @description Returns the 3 latest NASA APOD pictures and explanations
* @maintainer corenting
*/
class NasaApodBridge extends BridgeAbstract{
public function collectData(array $param) {
$html = file_get_html('http://apod.nasa.gov/apod/archivepix.html') or $this->returnError('Error while downloading the website content', 404);
$list = explode("<br>", $html->find('b', 0)->innertext);
for($i = 0; $i < 3;$i++)
{
$line = $list[$i];
$item = new \Item();
$uri_page = $html->find('a',$i + 3)->href;
$uri = 'http://apod.nasa.gov/apod/'.$uri_page;
$item->uri = $uri;
$picture_html = file_get_html($uri);
$picture_html_string = $picture_html->innertext;
//Extract image and explanation
$media = $picture_html->find('p',1)->innertext;
$media = strstr($media, '<br>');
$media = preg_replace('/<br>/', '', $media, 1);
$explanation = $picture_html->find('p',2)->innertext;
//Extract date from the picture page
$date = explode(" ", $picture_html->find('p',1)->innertext);
$item->timestamp = strtotime($date[4].$date[3].$date[2]);
//Other informations
$item->content = $media.'<br />'.$explanation;
$item->title = $picture_html->find('b',0)->innertext;
$this->items[] = $item;
}
}
public function getName(){
return 'NASA APOD';
}
public function getURI(){
return 'http://apod.nasa.gov/apod/astropix.html';
}
public function getCacheDuration(){
return 3600*12; // 12 hours
}
}

View file

@ -0,0 +1,56 @@
<?php
/**
* RssBridgeNextinpact
* Returns the newest articles
* 2014-05-25
*
* @name Nextinpact Bridge
* @homepage http://www.nextinpact.com/
* @description Returns the newest articles.
* @maintainer qwertygc
*/
class NextInpactBridge extends BridgeAbstract{
public function collectData(array $param){
function StripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function ExtractContent($url) {
$html2 = file_get_html($url);
$text = '<h2>'.$html2->find('div#actu_entete > h2', 0)->innertext.'</h2><br><br>';
$text = $text.$html2->find('div[itemprop=articleBody]', 0)->innertext;
return $text;
}
$html = file_get_html('http://www.nextinpact.com/rss/news.xml') or $this->returnError('Could not request Nextinpact.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 3) {
$item = new \Item();
$item->title = StripCDATA($element->find('title', 0)->innertext);
$item->uri = StripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = ExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Nextinpact Bridge';
}
public function getURI(){
return 'http://www.nextinpact.com/';
}
public function getCacheDuration(){
return 3600; // 1 hour
// return 0;
}
}

View file

@ -0,0 +1,62 @@
<?php
/**
* RssBridgeNiceMatin
* Returns the 10 newest posts from Nice Matin (full text)
*
* @name NiceMatin
* @homepage http://www.nicematin.com/
* @description Returns the 10 newest posts from NiceMatin (full text)
* @maintainer pit-fgfjiudghdf
* @update 2014-05-26
*/
class NiceMatinBridge extends BridgeAbstract{
public function collectData(array $param){
function NiceMatinUrl($string) {
$string = str_replace('</link>', '', $string);
//$string = str_replace('.+', '', $string);
$string = preg_replace('/html.*http.*/i','html',$string);
$string = preg_replace('/.*http/i','http',$string);
return $string;
}
function NiceMatinExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('figure[itemprop=associatedMedia]', 0)->innertext;
$text .= $html2->find('div[id=content-article]', 0)->innertext;
return $text;
}
$html = file_get_html('http://www.nicematin.com/derniere-minute/rss') or $this->returnError('Could not request NiceMatin.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 10) {
$item = new \Item();
//$item->title = NiceMatinStripCDATA($element->find('title', 0)->innertext);
$item->title = $element->find('title', 0)->innertext;
$item->uri = NiceMatinUrl($element->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = NiceMatinExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'NiceMatin';
}
public function getURI(){
return 'http://www.nicematin.com/';
}
public function getCacheDuration(){
return 3600; // 1 hour
}
}

View file

@ -0,0 +1,56 @@
<?php
/**
* RssBridgeNumerama
* Returns the 5 newest posts from http://www.numerama.com (full text)
* 2014-05-25
*
* @name Numerama
* @homepage http://www.numerama.com/
* @description Returns the 5 newest posts from Numerama (full text)
* @maintainer mitsukarenai
*/
class NumeramaBridge extends BridgeAbstract{
public function collectData(array $param){
function NumeramaStripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function NumeramaExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('h2.intro', 0)->innertext;
$text = $text.$html2->find('div.content', 0)->innertext;
$text = strip_tags($text, '<p><b><a><blockquote><img><em><ul><ol>');
return $text;
}
$html = file_get_html('http://www.numerama.com/rss/news.rss') or $this->returnError('Could not request Numerama.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 5) {
$item = new \Item();
$item->title = NumeramaStripCDATA($element->find('title', 0)->innertext);
$item->uri = NumeramaStripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = NumeramaExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Numerama';
}
public function getURI(){
return 'http://www.numerama.com/';
}
public function getCacheDuration(){
return 1800; // 30min
}
}

View file

@ -3,16 +3,24 @@
* RssBridgeOpenClassrooms
* Retrieve lastest tutorials from OpenClassrooms.
* Returns the most recent tutorials, sorting by date (most recent first).
* 2014-05-25
*
* @name OpenClassrooms Bridge
* @homepage http://fr.openclassrooms.com/
* @description Returns latest tutorials from OpenClassrooms.
* @maintainer sebsauvage
* @use1(u="informatique or sciences")
*/
class OpenClassroomsBridge extends BridgeAbstract{
public function collectData(array $param){
if ($param['u']!='informatique' && $param['u']!='sciences')
{
$this->returnError('Error: You must chose "informatique" or "science".', 404);
}
$html = '';
$link = 'http://fr.openclassrooms.com/'.$param[u].'/cours?title=&sort=updatedAt+desc';
$link = 'http://fr.openclassrooms.com/'.$param['u'].'/cours?title=&sort=updatedAt+desc';
$html = file_get_html($link) or $this->returnError('Could not request OpenClassrooms.', 404);

View file

@ -0,0 +1,59 @@
<?php
/**
* RssBridgeOpenTheory
* Returns the 5 newest posts from http://open1theory.com (full text)
*
* @name Opentheory
* @description Returns the 5 newest posts from OpenTheory (full text)
* @homepage http://open1theory.com
*@maintainer qwertygc
*/
class OpenTheoryBridge extends BridgeAbstract{
public function collectData(array $param){
function StripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function ExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.entry-content', 0)->innertext;
$text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);
return $text;
}
$html = file_get_html('http://open1theory.com/feed') or $this->returnError('Could not request OpenTheory.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 5) {
$item = new \Item();
$item->title = StripCDATA($element->find('title', 0)->innertext);
$item->uri = StripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = ExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'OpenTheory';
}
public function getURI(){
return 'http://open1theory.com/feed';
}
public function getCacheDuration(){
return 3600; // 1 hour
// return 0; // 1 hour
}
}

View file

@ -0,0 +1,84 @@
<?php
/**
* RssBridge Paru Vendu Immo
* Retrieve lastest documents from http://www.paruvendu.fr/immobilier/.
*
* @name Paru Vendu Immobilier
* @homepage http://www.paruvendu.fr/immobilier/
* @description Returns the ads from the first page of search result.
* @maintainer polo2ro
* @update 2015-02-02
* @use1(minarea="Min surface m²",maxprice="Max price",pa="Country code (ex: FR)",lo="department numbers or postal codes, comma-separated")
*/
class ParuVenduImmoBridge extends BridgeAbstract
{
private $request = '';
public function collectData(array $param)
{
$html = '';
$num = 20;
$appartment = '&tbApp=1&tbDup=1&tbChb=1&tbLof=1&tbAtl=1&tbPla=1';
$maison = '&tbMai=1&tbVil=1&tbCha=1&tbPro=1&tbHot=1&tbMou=1&tbFer=1';
$link = $this->getURI().'/immobilier/annonceimmofo/liste/listeAnnonces?tt=1'.$appartment.$maison;
if (isset($param['minarea'])) {
$this->request .= ' '.$param['minarea'].' m2';
$link .= '&sur0='.urlencode($param['minarea']);
}
if (isset($param['maxprice'])) {
$link .= '&px1='.urlencode($param['maxprice']);
}
if (isset($param['pa'])) {
$link .= '&pa='.urlencode($param['pa']);
}
if (isset($param['lo'])) {
$this->request .= ' In: '.$param['lo'];
$link .= '&lo='.urlencode($param['lo']);
}
$html = file_get_html($link) or $this->returnError('Could not request paruvendu.', 404);
foreach($html->find('div.annonce a') as $element) {
if (!$element->title) {
continue;
}
$img ='';
foreach($element->find('span.img img') as $img) {
if ($img->original) {
$img = '<img src="'.$img->original.'" />';
}
}
$desc = $element->find('span.desc')[0]->innertext;
$desc = str_replace("voir l'annonce", '', $desc);
$price = $element->find('span.price')[0]->innertext;
$item = new \Item();
$item->uri = $this->getURI().$element->href;
$item->title = $element->title;
$item->content = $img.$desc.$price;
$this->items[] = $item;
}
}
public function getName(){
return 'Paru Vendu Immobilier'.$this->request;
}
public function getURI(){
return 'http://www.paruvendu.fr';
}
public function getCacheDuration(){
return 10800; // 3 hours
}
}

View file

@ -2,9 +2,12 @@
/**
* RssBridgePinterest
* Returns the newest photos on a board
* 2014-05-25
*
* @name Pinterest Bridge
* @homepage http://www.pinterest.com/
* @description Returns the newest images on a board
* @maintainer pauder
* @use1(u="username",b="board")
* @use2(q="keyword")
*/
@ -16,7 +19,18 @@ class PinterestBridge extends BridgeAbstract{
public function collectData(array $param){
$html = '';
if (isset($param['u']) && isset($param['b'])) {
if (isset($param['u']) || isset($param['b'])) {
if (empty($param['u']))
{
$this->returnError('You must specify a Pinterest username (?u=...).', 400);
}
if (empty($param['b']))
{
$this->returnError('You must specify a Pinterest board for this username (?b=...).', 400);
}
$this->username = $param['u'];
$this->board = $param['b'];
$html = file_get_html($this->getURI().'/'.urlencode($this->username).'/'.urlencode($this->board)) or $this->returnError('Could not request Pinterest.', 404);
@ -39,7 +53,7 @@ class PinterestBridge extends BridgeAbstract{
$item = new \Item();
$item->uri = $this->getURI().$a->getAttribute('href');
$item->content = '<img src="' . htmlentities($img->getAttribute('src')) . '" alt="" />';
$item->content = '<img src="' . htmlentities(str_replace('/236x/', '/736x/', $img->getAttribute('src'))) . '" alt="" />';
if (isset($this->query))
@ -54,13 +68,9 @@ class PinterestBridge extends BridgeAbstract{
$item->content .= '<br /><img align="left" style="margin: 2px 4px;" src="'.htmlentities($item->avatar).'" /> <strong>'.$item->username.'</strong>';
$item->content .= '<br />'.$item->fullname;
} else {
$credit = $div->find('a.creditItem',0);
$item->content .= '<br />'.$credit->innertext;
}
$item->title = basename($img->getAttribute('alt'));
$item->title = $img->getAttribute('alt');
//$item->timestamp = $media->created_time;
$this->items[] = $item;
@ -83,6 +93,6 @@ class PinterestBridge extends BridgeAbstract{
}
public function getCacheDuration(){
return 0;
return 3600;
}
}

View file

@ -0,0 +1,45 @@
<?php
/**
* RssBridgePlanetLibre
* Returns the 5 newest posts from PlanetLibre (full text)
*
* @name PlanetLibre
* @homepage http://www.planet-libre.org
* @description Returns the 5 newest posts from PlanetLibre (full text)
* @maintainer pit-fgfjiudghdf
* @update 2014-05-26
*/
class PlanetLibreBridge extends BridgeAbstract{
public function collectData(array $param){
function PlanetLibreExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div[class="post-text"]', 0)->innertext;
return $text;
}
$html = file_get_html('http://www.planet-libre.org/') or $this->returnError('Could not request PlanetLibre.', 404);
$limit = 0;
foreach($html->find('div.post') as $element) {
if($limit < 5) {
$item = new \Item();
$item->title = $element->find('h1', 0)->plaintext;
$item->uri = $element->find('a', 0)->href;
$item->timestamp = strtotime(str_replace('/', '-', $element->find('div[class="post-date"]', 0)->plaintext));
$item->content = PlanetLibreExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'PlanetLibre';
}
public function getURI(){
return 'http://www.planet-libre.org/';
}
public function getCacheDuration(){
return 3600*2; // 1 hour
}
}

View file

@ -0,0 +1,43 @@
<?php
/**
* 2014-08-27
* @name Project M Game Bridge
* @homepage http://projectmgame.com/en/
* @description Returns the newest articles.
* @maintainer corenting
*/
class ProjectMGameBridge extends BridgeAbstract{
public function collectData(array $param){
$html = '';
$html = file_get_html('http://projectmgame.com/en/') or $this->returnError('Error while downloading the Project M homepage', 404);
foreach($html->find('article') as $article) {
$item = new \Item();
$item->uri = 'http://projectmgame.com/en/'.$article->find('section div.info_block a',0)->href;
$item->title = $article->find('h1 p',0)->innertext;
$p_list = $article->find('section p');
$content = '';
foreach($p_list as $p) $content .= $p->innertext;
$item->content = $content;
// get publication date
$str_date = $article->find('section div.info_block a',0)->innertext;
$item->timestamp = strtotime($str_date);
$this->items[] = $item;
}
}
public function getName(){
return 'Project M Game Bridge';
}
public function getURI(){
return 'http://projectmgame.com/en/';
}
public function getCacheDuration(){
return 10800; //3 hours
}
}

52
bridges/RaymondBridge.php Normal file
View file

@ -0,0 +1,52 @@
<?php
/**
* RssBridgeRaymond
* Returns the 3 newest posts from Raymond.cc (full text)
*
* @name Raymond
* @homepage http://www.raymond.cc
* @description Returns the 3 newest posts from Raymond.cc (full text)
* @maintainer pit-fgfjiudghdf
* @update 2014-05-26
*/
class RaymondBridge extends BridgeAbstract{
public function collectData(array $param){
function raymondStripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function raymondExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.entry-content', 0)->innertext;
$text = preg_replace('/class="ad".*/', '', $text);
$text = strip_tags($text, '<p><a><i><strong><em><img>');
$text = str_replace('(adsbygoogle = window.adsbygoogle || []).push({});', '', $text);
return $text;
}
$html = file_get_html('http://www.raymond.cc/blog/feed') or $this->returnError('Could not request raymond.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 3) {
$item = new \Item();
$item->title = raymondStripCDATA($element->find('title', 0)->innertext);
$item->uri = raymondStripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = raymondExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'raymond';
}
public function getURI(){
return 'http://www.raymond.cc/blog';
}
public function getCacheDuration(){
return 3600*12; // 12 hour
}
}

58
bridges/Rue89Bridge.php Normal file
View file

@ -0,0 +1,58 @@
<?php
/**
* RssBridgeRue89
* Returns the 5 newest posts from http://rue89.nouvelobs.com/ (full text)
*
* @name Rue89
* @description Returns the 5 newest posts from Rue89 (full text)
* @update 2015-01-30
* @maintainer pit-fgfjiudghdf
*/
class Rue89Bridge extends BridgeAbstract{
public function collectData(array $param){
function Rue89StripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function Rue89ExtractContent($url) {
$html2 = file_get_html($url);
//$text = $html2->find('div[class=text]', 0)->innertext;
foreach($html2->find('img') as $image) {
$image->src = $image->getAttribute('data-src');
}
$text = $html2->find('div.content', 0)->innertext;
$text = str_replace('href="/', 'href="http://rue89.nouvelobs.com/', $text);
$text = str_replace('src="/', 'src="http://rue89.nouvelobs.com/', $text);
$text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);
$text = strip_tags($text, '<h1><h2><strong><p><b><a><blockquote><img><em><ul><ol>');
return $text;
}
$html = file_get_html('http://rue89.feedsportal.com/c/33822/f/608948/index.rss') or $this->returnError('Could not request Rue89.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 5) {
$item = new \Item();
$item->title = Rue89StripCDATA($element->find('title', 0)->innertext);
$item->uri = str_replace('#commentaires', '', Rue89StripCDATA($element->find('comments', 0)->plaintext));
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = Rue89ExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Rue89';
}
public function getURI(){
return 'http://rue89.nouvelobs.com/';
}
public function getCacheDuration(){
return 3600; // 1 hour
}
}

52
bridges/Rule34Bridge.php Normal file
View file

@ -0,0 +1,52 @@
<?php
/**
* RssBridgeRule34
* Returns images from given page
* 2014-05-25
*
* @name Rule34
* @homepage http://rule34.xxx/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page",t="tags")
*/
class Rule34Bridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
$page = $page - 1;
$page = $page * 50;
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://rule34.xxx/index.php?page=post&s=list&tags=$tags&pid=$page") or $this->returnError('Could not request Rule34.', 404);
foreach($html->find('div[class=content] span') as $element) {
$item = new \Item();
$item->uri = 'http://rule34.xxx/'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->getAttribute('id'));
$item->timestamp = time();
$item->thumbnailUri = $element->find('img', 0)->src;
$item->tags = $element->find('img', 0)->getAttribute('alt');
$item->title = 'Rule34 | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Rule34';
}
public function getURI(){
return 'http://rule34.xxx/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -0,0 +1,50 @@
<?php
/**
* RssBridgeRule34paheal
* Returns images from given page
* 2014-05-25
*
* @name Rule34paheal
* @homepage http://rule34.paheal.net/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page",t='tags")
*/
class Rule34pahealBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://rule34.paheal.net/post/list/$tags/$page") or $this->returnError('Could not request Rule34paheal.', 404);
foreach($html->find('div[class=shm-image-list] div[class=shm-thumb]') as $element) {
$item = new \Item();
$item->uri = 'http://rule34.paheal.net'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->find('img', 0)->getAttribute('id'));
$item->timestamp = time();
$item->thumbnailUri = $element->find('img', 0)->src;
$item->tags = $element->getAttribute('data-tags');
$item->title = 'Rule34paheal | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Rule34paheal';
}
public function getURI(){
return 'http://rule34.paheal.net/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -0,0 +1,52 @@
<?php
/**
* RssBridgeSafebooru
* Returns images from given page
* 2014-05-25
*
* @name Safebooru
* @homepage http://safebooru.org/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page",t="tags")
*/
class SafebooruBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
$page = $page - 1;
$page = $page * 40;
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://safebooru.org/index.php?page=post&s=list&tags=$tags&pid=$page") or $this->returnError('Could not request Safebooru.', 404);
foreach($html->find('div[class=content] span') as $element) {
$item = new \Item();
$item->uri = 'http://safebooru.org/'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->getAttribute('id'));
$item->timestamp = time();
$item->thumbnailUri = $element->find('img', 0)->src;
$item->tags = $element->find('img', 0)->getAttribute('alt');
$item->title = 'Safebooru | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Safebooru';
}
public function getURI(){
return 'http://safebooru.org/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -0,0 +1,54 @@
<?php
/**
* RssBridgeSakugabooru
* Returns images from given page
* 2014-05-25
*
* @name Sakugabooru
* @homepage http://sakuga.yshi.org/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page",t="tags")
*/
class SakugabooruBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 1;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://sakuga.yshi.org/post?page=$page&tags=$tags") or $this->returnError('Could not request Sakugabooru.', 404);
$input_json = explode('Post.register(', $html);
foreach($input_json as $element)
$data[] = preg_replace('/}\)(.*)/', '}', $element);
unset($data[0]);
foreach($data as $datai) {
$json = json_decode($datai, TRUE);
$item = new \Item();
$item->uri = 'http://sakuga.yshi.org/post/show/'.$json['id'];
$item->postid = $json['id'];
$item->timestamp = $json['created_at'];
$item->imageUri = $json['file_url'];
$item->thumbnailUri = $json['preview_url'];
$item->title = 'Sakugabooru | '.$json['id'];
$item->content = '<a href="' . $item->imageUri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$json['tags'];
$this->items[] = $item;
}
}
public function getName(){
return 'Sakugabooru';
}
public function getURI(){
return 'http://sakuga.yshi.org/post';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

54
bridges/ScilogsBridge.php Normal file
View file

@ -0,0 +1,54 @@
<?php
/**
* RssBridgeScilogs
* Returns the newest articles
* 2014-05-25
*
* @name Scilogs Bridge
* @homepage http://www.scilogs.fr/
* @description Returns the newest articles.
* @maintainer qwertygc
*/
class ScilogsBridge extends BridgeAbstract{
public function collectData(array $param){
function ScilogsStripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function ScilogsExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.entrybody', 0)->innertext;
return $text;
}
$html = file_get_html('http://www.scilogs.fr/?wpmu-feed=posts') or $this->returnError('Could not request Scilogs.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 10) {
$item = new \Item();
$item->title = ScilogsStripCDATA($element->find('title', 0)->innertext);
$item->uri = ScilogsStripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = ScilogsExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Scilogs Bridge';
}
public function getURI(){
return 'http://scilogs.fr/';
}
public function getCacheDuration(){
return 3600*2; // 2 hours
}
}

View file

@ -2,9 +2,12 @@
/**
* RssBridgeSeCoucherMoinsBete
* Returns the newest anecdotes
* 2014-05-25
*
* @name Se Coucher Moins Bête Bridge
* @homepage http://secouchermoinsbete.fr/
* @description Returns the newest anecdotes.
* @maintainer Astalaseven
*/
class ScmbBridge extends BridgeAbstract{

48
bridges/ScoopItBridge.php Normal file
View file

@ -0,0 +1,48 @@
<?php
/**
* RssBridgeScoopIt
* Search DScoopIt for most recent pages regarding a specific topic.
* Returns the most recent links in results, sorting by date (most recent first).
* 2014-06-13
*
* @name ScoopIt
* @homepage http://www.scoop.it
* @description Returns most recent results from ScoopIt.
* @maintainer Pitchoule
* @use1(u="keyword")
*/
class ScoopItBridge extends BridgeAbstract{
public function collectData(array $param){
$html = '';
if ($param['u'] != '') {
$this->request = $param['u'];
$link = 'http://scoop.it/search?q=' .urlencode($this->request);
$html = file_get_html($link) or $this->returnError('Could not request ScoopIt. for : ' . $link , 404);
foreach($html->find('div.post-view') as $element) {
$item = new Item();
$item->uri = $element->find('a', 0)->href;
$item->title = preg_replace('~[[:cntrl:]]~', '', $element->find('div.tCustomization_post_title',0)->plaintext);
$item->content = preg_replace('~[[:cntrl:]]~', '', $element->find('div.tCustomization_post_description', 0)->plaintext);
$this->items[] = $item;
}
} else {
$this->returnError('You must specify a keyword', 404);
}
}
public function getName(){
return 'ScooptIt';
}
public function getURI(){
return 'http://Scoop.it';
}
public function getCacheDuration(){
return 21600; // 6 hours
}
}

View file

@ -0,0 +1,56 @@
<?php
/**
* @name SegfaultMint
* @homepage http://segfault.linuxmint.com/
* @description Returns the 5 newest posts from SegfaultMint (full text)
* @maintainer qwertygc
* @update 2014-07-05
*/
class SegfaultMintBridge extends BridgeAbstract{
public function collectData(array $param){
function StripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function ExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.post-bodycopy', 0)->innertext;
$text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);
return $text;
}
$html = file_get_html('http://segfault.linuxmint.com/feed/') or $this->returnError('Could not request segfault.', 404);
$limit = 0;
foreach($html->find('item') as $element) {
if($limit < 5) {
$item = new \Item();
$item->title = StripCDATA($element->find('title', 0)->innertext);
$item->uri = StripCDATA($element->find('guid', 0)->plaintext);
$item->timestamp = strtotime($element->find('pubDate', 0)->plaintext);
$item->content = ExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Segfault Mint';
}
public function getURI(){
return 'http://segfault.linuxmint.com/feed/';
}
public function getCacheDuration(){
return 3600*24; // 24 hours
}
}

View file

@ -0,0 +1,55 @@
<?php
/**
* SoundcloudBridge
* Returns the newest music from user
*
* @name Soundcloud Bridge
* @homepage http://www.soundcloud.com/
* @description Returns 10 newest music from user profile
* @maintainer kranack
* @update 2014-07-24
* @use1(u="username")
*
*/
class SoundCloudBridge extends BridgeAbstract{
private $request;
private $name;
public function collectData(array $param){
if (isset($param['u']) && !empty($param['u']))
{
$this->request = $param['u'];
$res = json_decode(file_get_contents('http://api.soundcloud.com/resolve.json?url=http://www.soundcloud.com/'. urlencode($this->request) .'&consumer_key=apigee')) or $this->returnError('No results for this query', 404);
$tracks = json_decode(file_get_contents('http://api.soundcloud.com/users/'. urlencode($res->id) .'/tracks.json?consumer_key=apigee')) or $this->returnError('No results for this user', 404);
}
else
{
$this->returnError('You must specify username', 400);
}
for ($i=0; $i < 10; $i++) {
$item = new \Item();
$item->name = $tracks[$i]->user->username .' - '. $tracks[$i]->title;
$item->title = $tracks[$i]->user->username .' - '. $tracks[$i]->title;
$item->content = '<audio src="'. $tracks[$i]->uri .'/stream?consumer_key=apigee">';
$item->id = 'https://soundcloud.com/'. urlencode($this->request) .'/'. urlencode($tracks[$i]->permalink);
$item->uri = 'https://soundcloud.com/'. urlencode($this->request) .'/'. urlencode($tracks[$i]->permalink);
$this->items[] = $item;
}
}
public function getName(){
return (!empty($this->name) ? $this->name .' - ' : '') .'Soundcloud Bridge';
}
public function getURI(){
return 'http://www.soundcloud.com/';
}
public function getCacheDuration(){
return 600; // 10 minutes
}
}

View file

@ -0,0 +1,50 @@
<?php
/**
* RssBridgeTagBoard
* Search TagBoard for most recent pages regarding a specific topic.
* Returns the most recent links in results, sorting by date (most recent first).
* 2014-09-10
*
* @name TagBoard
* @homepage http://www.TagBoard.com
* @description Returns most recent results from TagBoard.
* @maintainer Pitchoule
* @use1(u="keyword")
*/
class TagBoardBridge extends BridgeAbstract{
public function collectData(array $param){
$html = '';
$this->request = $param['u'];
$link = 'https://post-cache.tagboard.com/search/' .$this->request;
$html = file_get_html($link) or $this->returnError('Could not request TagBoard for : ' . $link , 404);
$parsed_json = json_decode($html);
foreach($parsed_json->{'posts'} as $element) {
$item = new Item();
$item->uri = $element->{'permalink'};
$item->title = $element->{'text'};
$item->thumbnailUri = $element->{'photos'}[0]->{'m'};
if (isset($item->thumbnailUri)) {
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a>';
}else{
$item->content = $element->{'html'};
}
$this->items[] = $item;
}
}
public function getName(){
return 'tagboard - ' .$this->request;
}
public function getURI(){
return 'http://TagBoard.com';
}
public function getCacheDuration(){
return 21600; // 6 hours
}
}

52
bridges/TbibBridge.php Normal file
View file

@ -0,0 +1,52 @@
<?php
/**
* RssBridgeTbib
* Returns images from given page
* 2014-05-25
*
* @name Tbib
* @homepage http://tbib.org/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page",t="tags")
*/
class TbibBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
$page = $page - 1;
$page = $page * 50;
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://tbib.org/index.php?page=post&s=list&tags=$tags&pid=$page") or $this->returnError('Could not request Tbib.', 404);
foreach($html->find('div[class=content] span') as $element) {
$item = new \Item();
$item->uri = 'http://tbib.org/'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->getAttribute('id'));
$item->timestamp = time();
$item->thumbnailUri = $element->find('img', 0)->src;
$item->tags = $element->find('img', 0)->getAttribute('alt');
$item->title = 'Tbib | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Tbib';
}
public function getURI(){
return 'http://tbib.org/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -0,0 +1,65 @@
<?php
/**
*
* @name The Coding Love
* @homepage http://thecodinglove.com/
* @description The Coding Love
* @update 04/02/2015
* initial maintainer: superbaillot.net
*/
class TheCodingLoveBridge extends BridgeAbstract{
public function collectData(array $param){
$html = file_get_html('http://thecodinglove.com/') or $this->returnError('Could not request The Coding Love.', 404);
foreach($html->find('div.post') as $element) {
$item = new Item();
$temp = $element->find('h3 a', 0);
$titre = $temp->innertext;
$url = $temp->href;
$temp = $element->find('div.bodytype', 0);
// retrieve .gif instead of static .jpg
$images = $temp->find('p.e img');
foreach($images as $image){
$img_src = str_replace(".jpg",".gif",$image->src);
$image->src = $img_src;
}
$content = $temp->innertext;
$auteur = $temp->find('i', 0);
$pos = strpos($auteur->innertext, "by");
if($pos > 0)
{
$auteur = trim(str_replace("*/", "", substr($auteur->innertext, ($pos + 2))));
$item->name = $auteur;
}
$item->content .= trim($content);
$item->uri = $url;
$item->title = trim($titre);
$this->items[] = $item;
}
}
public function getName(){
return 'The Coding Love';
}
public function getURI(){
return 'http://thecodinglove.com/';
}
public function getCacheDuration(){
return 7200; // 2h hours
}
public function getDescription(){
return "The Coding Love via rss-bridge";
}
}
?>

View file

@ -0,0 +1,90 @@
<?php
/**
* RssBridgeThePirateBay
* Returns results for the keywords. You can put several list of keywords by separating them with a semicolon (e.g. "one show;another show")
* 2014-05-25
*
* @name The Pirate Bay
* @homepage https://thepiratebay.se/
* @description Returns results for the keywords. You can put several list of keywords by separating them with a semicolon (e.g. "one show;another show")
* @maintainer mitsukarenai
* @update 2014-05-26
* @use1(q="first list;second list;...")
*/
class ThePirateBayBridge extends BridgeAbstract{
public function collectData(array $param){
function parseDateTimestamp($element){
$guessedDate = $element->find('font',0)->plaintext;
$guessedDate = explode("Uploaded ",$guessedDate)[1];
$guessedDate = explode(",",$guessedDate)[0];
if (count(explode(":",$guessedDate)) == 1)
{
$guessedDate = strptime($guessedDate, '%m-%d&nbsp;%Y');
$timestamp = mktime(0, 0, 0,
$guessedDate['tm_mon'] + 1, $guessedDate['tm_mday'], 1900+$guessedDate['tm_year']);
}
else if (explode("&nbsp;",$guessedDate)[0] == 'Today')
{
$guessedDate = strptime(explode("&nbsp;",$guessedDate)[1], '%H:%M');
$timestamp = mktime($guessedDate['tm_hour'], $guessedDate['tm_min'], 0,
date('m'), date('d'), date('Y'));
}
else if (explode("&nbsp;",$guessedDate)[0] == 'Y-day')
{
$guessedDate = strptime(explode("&nbsp;",$guessedDate)[1], '%H:%M');
$timestamp = mktime($guessedDate['tm_hour'], $guessedDate['tm_min'], 0,
date('m',time()-24*60*60), date('d',time()-24*60*60), date('Y',time()-24*60*60));
}
else
{
$guessedDate = strptime($guessedDate, '%m-%d&nbsp;%H:%M');
$timestamp = mktime($guessedDate['tm_hour'], $guessedDate['tm_min'], 0,
$guessedDate['tm_mon'] + 1, $guessedDate['tm_mday'], date('Y'));
}
return $timestamp;
}
if (!isset($param['q']))
$this->returnError('You must specify keywords (?q=...)', 400);
$keywordsList = explode(";",$param['q']);
foreach($keywordsList as $keywords){
$html = file_get_html('https://thepiratebay.se/search/'.rawurlencode($keywords).'/0/3/0') or $this->returnError('Could not request TPB.', 404);
if ($html->find('table#searchResult', 0) == FALSE)
$this->returnError('No result for query '.$keywords, 404);
foreach($html->find('tr') as $element) {
$item = new \Item();
$item->uri = 'https://thepiratebay.se/'.$element->find('a.detLink',0)->href;
$item->id = $item->uri;
$item->timestamp = parseDateTimestamp($element);
$item->title = $element->find('a.detLink',0)->plaintext;
$item->seeders = (int)$element->find('td',2)->plaintext;
$item->leechers = (int)$element->find('td',3)->plaintext;
$item->content = $element->find('font',0)->plaintext.'<br>seeders: '.$item->seeders.' | leechers: '.$item->leechers.'<br><a href="'.$element->find('a',3)->href.'">download</a>';
if(!empty($item->title))
$this->items[] = $item;
}
}
}
public function getName(){
return 'The Pirate Bay';
}
public function getURI(){
return 'https://thepiratebay.se/';
}
public function getCacheDuration(){
return 3600; // 1 hour
}
}

View file

@ -0,0 +1,62 @@
<?php
/**
*
* @name Tuxboard
* @homepage http://www.tuxboard.com/
* @description Tuxboard
* @update 2014-07-08
* initial maintainer: superbaillot.net
*/
class TuxboardBridge extends BridgeAbstract{
public function collectData(array $param){
function StripCDATA($string) {
$string = str_replace('<![CDATA[', '', $string);
$string = str_replace(']]>', '', $string);
return $string;
}
function ExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('article#page', 0)->innertext;
$text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);
return $text;
}
$html = file_get_html('http://www.tuxboard.com/feed/atom/') or $this->returnError('Could not request Tuxboard.', 404);
$limit = 0;
foreach($html->find('entry') as $element) {
if($limit < 10) {
$item = new \Item();
$item->title = StripCDATA($element->find('title', 0)->innertext);
$item->uri = $element->find('link', 0)->href;
$item->timestamp = strtotime($element->find('published', 0)->plaintext);
$item->content = ExtractContent($item->uri);
$this->items[] = $item;
$limit++;
}
}
}
public function getName(){
return 'Tuxboard';
}
public function getURI(){
return 'http://www.tuxboard.com';
}
public function getDescription(){
return 'Tuxboard via rss-bridge';
}
public function getCacheDuration(){
return 3600; // 1 hour
}
}
?>

View file

@ -2,9 +2,12 @@
/**
* RssBridgeTwitter
* Based on https://github.com/mitsukarenai/twitterbridge-noapi
* 2014-05-25
*
* @name Twitter Bridge
* @homepage http://twitter.com/
* @description Returns user timelines or keyword/hashtag search results (without using their API).
* @maintainer mitsukarenai
* @use1(q="keyword or #hashtag")
* @use2(u="username")
*/
@ -26,15 +29,27 @@ class TwitterBridge extends BridgeAbstract{
$this->returnError('You must specify a keyword (?q=...) or a Twitter username (?u=...).', 400);
}
foreach($html->find('div.tweet') as $tweet) {
foreach($html->find('div.js-stream-tweet') as $tweet) {
$item = new \Item();
$item->username = trim(substr($tweet->find('span.username', 0)->plaintext, 1)); // extract username and sanitize
$item->username = $tweet->getAttribute('data-screen-name'); // extract username and sanitize
$item->fullname = $tweet->getAttribute('data-name'); // extract fullname (pseudonym)
$item->avatar = $tweet->find('img', 0)->src; // get avatar link
$item->id = $tweet->getAttribute('data-tweet-id'); // get TweetID
$item->uri = 'https://twitter.com'.$tweet->find('a.details', 0)->getAttribute('href'); // get tweet link
$item->timestamp = $tweet->find('span._timestamp', 0)->getAttribute('data-time'); // extract tweet timestamp
$item->content = str_replace('href="/', 'href="https://twitter.com/', strip_tags($tweet->find('p.tweet-text', 0)->innertext, '<a>')); // extract tweet text
$item->uri = 'https://twitter.com'.$tweet->find('a.js-permalink', 0)->getAttribute('href'); // get tweet link
$item->timestamp = $tweet->find('span.js-short-timestamp', 0)->getAttribute('data-time'); // extract tweet timestamp
// processing content links
foreach($tweet->find('a') as $link) {
if($link->hasAttribute('data-expanded-url') ) {
$link->href = $link->getAttribute('data-expanded-url');
}
$link->removeAttribute('data-expanded-url');
$link->removeAttribute('data-query-source');
$link->removeAttribute('rel');
$link->removeAttribute('class');
$link->removeAttribute('target');
$link->removeAttribute('title');
}
$item->content = str_replace('href="/', 'href="https://twitter.com/', strip_tags($tweet->find('p.js-tweet-text', 0)->innertext, '<a>')); // extract tweet text
$item->title = $item->fullname . ' (@'. $item->username . ') | ' . $item->content;
$this->items[] = $item;
}

View file

@ -0,0 +1,70 @@
<?php
/**
* RssBridgeTwitterClean
* Based on https://github.com/mitsukarenai/twitterbridge-noapi
*
* @name Twitter Bridge Clean
* @homepage http://twitter.com/
* @description Returns user timelines without username in title or search results for keywords/hashtags (without using their API).
* @maintainer vinzv
* @update 2015-03-07
* @use1(q="keyword or #hashtag")
* @use2(u="username")
*/
class TwitterBridgeClean extends BridgeAbstract{
private $request;
public function collectData(array $param){
$html = '';
if (isset($param['q'])) { /* keyword search mode */
$this->request = $param['q'];
$html = file_get_html('http://twitter.com/search/realtime?q='.urlencode($this->request).'+include:retweets&src=typd') or $this->returnError('No results for this query.', 404);
}
elseif (isset($param['u'])) { /* user timeline mode */
$this->request = $param['u'];
$html = file_get_html('http://twitter.com/'.urlencode($this->request)) or $this->returnError('Requested username can\'t be found.', 404);
}
else {
$this->returnError('You must specify a keyword (?q=...) or a Twitter username (?u=...).', 400);
}
foreach($html->find('div.js-stream-tweet') as $tweet) {
$item = new \Item();
$item->username = $tweet->getAttribute('data-screen-name'); // extract username and sanitize
$item->fullname = $tweet->getAttribute('data-name'); // extract fullname (pseudonym)
$item->avatar = $tweet->find('img', 0)->src; // get avatar link
$item->id = $tweet->getAttribute('data-tweet-id'); // get TweetID
$item->uri = 'https://twitter.com'.$tweet->find('a.js-permalink', 0)->getAttribute('href'); // get tweet link
$item->timestamp = $tweet->find('span.js-short-timestamp', 0)->getAttribute('data-time'); // extract tweet timestamp
// processing content links
foreach($tweet->find('a') as $link) {
if($link->hasAttribute('data-expanded-url') ) {
$link->href = $link->getAttribute('data-expanded-url');
}
$link->removeAttribute('data-expanded-url');
$link->removeAttribute('data-query-source');
$link->removeAttribute('rel');
$link->removeAttribute('class');
$link->removeAttribute('target');
$link->removeAttribute('title');
$link->removeAttribute('dir');
}
$item->content = str_replace('pic.twitter.com', 'https://pic.twitter.com', strip_tags($tweet->find('p.js-tweet-text', 0)->innertext)); // extract tweet text
$item->title = $item->content;
$this->items[] = $item;
}
}
public function getName(){
return (!empty($this->request) ? $this->request .' - ' : '') .'Twitter Bridge';
}
public function getURI(){
return 'http://twitter.com';
}
public function getCacheDuration(){
return 300; // 5 minutes
}
}

View file

@ -0,0 +1,78 @@
<?php
/**
* RssBridgeTwitter
* Based on https://github.com/mitsukarenai/twitterbridge-noapi
* 2014-05-25
*
* @name Twitter Bridge Extended
* @homepage https://twitter.com/
* @description (same as Twitter Bridge, but with avatar, replies and RTs)
* @maintainer mitsukarenai
* @use1(q="keyword or hashtag")
* @use2(u="username")
*/
class TwitterBridgeExtended extends BridgeAbstract{
public function collectData(array $param){
$html = '';
if (isset($param['q'])) { /* keyword search mode */
$html = file_get_html('https://twitter.com/search/realtime?q='.urlencode($param['q']).'+include:retweets&src=typd') or $this->returnError('No results for this query.', 404);
}
elseif (isset($param['u'])) { /* user timeline mode */
$html = file_get_html('https://twitter.com/'.urlencode($param['u']).'/with_replies') or $this->returnError('Requested username can\'t be found.', 404);
}
else {
$this->returnError('You must specify a keyword (?q=...) or a Twitter username (?u=...).', 400);
}
foreach($html->find('div.js-stream-tweet') as $tweet) {
$item = new \Item();
// extract username and sanitize
$item->username = $tweet->getAttribute('data-screen-name');
// extract fullname (pseudonym)
$item->fullname = $tweet->getAttribute('data-name');
// get avatar link
$item->avatar = $tweet->find('img', 0)->src;
// get TweetID
$item->id = $tweet->getAttribute('data-tweet-id');
// get tweet link
$item->uri = 'https://twitter.com'.$tweet->find('a.js-permalink', 0)->getAttribute('href');
// extract tweet timestamp
$item->timestamp = $tweet->find('span.js-short-timestamp', 0)->getAttribute('data-time');
// extract plaintext
$item->content_simple = str_replace('href="/', 'href="https://twitter.com/', html_entity_decode(strip_tags($tweet->find('p.js-tweet-text', 0)->innertext, '<a>')));
// processing content links
foreach($tweet->find('a') as $link) {
if($link->hasAttribute('data-expanded-url') ) {
$link->href = $link->getAttribute('data-expanded-url');
}
$link->removeAttribute('data-expanded-url');
$link->removeAttribute('data-query-source');
$link->removeAttribute('rel');
$link->removeAttribute('class');
$link->removeAttribute('target');
$link->removeAttribute('title');
}
// get tweet text
$item->content = '<a href="https://twitter.com/'.$item->username.'"><img style="align:top;width:75px;" alt="avatar" src="'.$item->avatar.'" />'.$item->username.'</a> '.$item->fullname.'<br/><blockquote>'.str_replace('href="/', 'href="https://twitter.com/', $tweet->find('p.js-tweet-text', 0)->innertext).'</blockquote>';
// generate the title
$item->title = $item->fullname . ' (@'. $item->username . ') | ' . $item->content_simple;
// put out
$this->items[] = $item;
}
}
public function getName(){
return 'Twitter Bridge Extended';
}
public function getURI(){
return 'http://twitter.com';
}
public function getCacheDuration(){
return 300; // 5 minutes
}
}

View file

@ -0,0 +1,152 @@
<?php
/**
* RssBridgeTwitter
* Based on https://github.com/mitsukarenai/twitterbridge-noapi
* 2014-12-05
*
* @name Twitter Bridge Tweaked
* @homepage https://twitter.com/
* @description (same as Twitter Bridge Extended, but with cleaned title & content)
* @maintainer kraoc
* @use1(q="keyword or hashtag")
* @use2(u="username")
*/
class TwitterBridgeTweaked extends BridgeAbstract{
private function containsTLD($string) {
preg_match(
"/(AC($|\/)|\.AD($|\/)|\.AE($|\/)|\.AERO($|\/)|\.AF($|\/)|\.AG($|\/)|\.AI($|\/)|\.AL($|\/)|\.AM($|\/)|\.AN($|\/)|\.AO($|\/)|\.AQ($|\/)|\.AR($|\/)|\.ARPA($|\/)|\.AS($|\/)|\.ASIA($|\/)|\.AT($|\/)|\.AU($|\/)|\.AW($|\/)|\.AX($|\/)|\.AZ($|\/)|\.BA($|\/)|\.BB($|\/)|\.BD($|\/)|\.BE($|\/)|\.BF($|\/)|\.BG($|\/)|\.BH($|\/)|\.BI($|\/)|\.BIZ($|\/)|\.BJ($|\/)|\.BM($|\/)|\.BN($|\/)|\.BO($|\/)|\.BR($|\/)|\.BS($|\/)|\.BT($|\/)|\.BV($|\/)|\.BW($|\/)|\.BY($|\/)|\.BZ($|\/)|\.CA($|\/)|\.CAT($|\/)|\.CC($|\/)|\.CD($|\/)|\.CF($|\/)|\.CG($|\/)|\.CH($|\/)|\.CI($|\/)|\.CK($|\/)|\.CL($|\/)|\.CM($|\/)|\.CN($|\/)|\.CO($|\/)|\.COM($|\/)|\.COOP($|\/)|\.CR($|\/)|\.CU($|\/)|\.CV($|\/)|\.CX($|\/)|\.CY($|\/)|\.CZ($|\/)|\.DE($|\/)|\.DJ($|\/)|\.DK($|\/)|\.DM($|\/)|\.DO($|\/)|\.DZ($|\/)|\.EC($|\/)|\.EDU($|\/)|\.EE($|\/)|\.EG($|\/)|\.ER($|\/)|\.ES($|\/)|\.ET($|\/)|\.EU($|\/)|\.FI($|\/)|\.FJ($|\/)|\.FK($|\/)|\.FM($|\/)|\.FO($|\/)|\.FR($|\/)|\.GA($|\/)|\.GB($|\/)|\.GD($|\/)|\.GE($|\/)|\.GF($|\/)|\.GG($|\/)|\.GH($|\/)|\.GI($|\/)|\.GL($|\/)|\.GM($|\/)|\.GN($|\/)|\.GOV($|\/)|\.GP($|\/)|\.GQ($|\/)|\.GR($|\/)|\.GS($|\/)|\.GT($|\/)|\.GU($|\/)|\.GW($|\/)|\.GY($|\/)|\.HK($|\/)|\.HM($|\/)|\.HN($|\/)|\.HR($|\/)|\.HT($|\/)|\.HU($|\/)|\.ID($|\/)|\.IE($|\/)|\.IL($|\/)|\.IM($|\/)|\.IN($|\/)|\.INFO($|\/)|\.INT($|\/)|\.IO($|\/)|\.IQ($|\/)|\.IR($|\/)|\.IS($|\/)|\.IT($|\/)|\.JE($|\/)|\.JM($|\/)|\.JO($|\/)|\.JOBS($|\/)|\.JP($|\/)|\.KE($|\/)|\.KG($|\/)|\.KH($|\/)|\.KI($|\/)|\.KM($|\/)|\.KN($|\/)|\.KP($|\/)|\.KR($|\/)|\.KW($|\/)|\.KY($|\/)|\.KZ($|\/)|\.LA($|\/)|\.LB($|\/)|\.LC($|\/)|\.LI($|\/)|\.LK($|\/)|\.LR($|\/)|\.LS($|\/)|\.LT($|\/)|\.LU($|\/)|\.LV($|\/)|\.LY($|\/)|\.MA($|\/)|\.MC($|\/)|\.MD($|\/)|\.ME($|\/)|\.MG($|\/)|\.MH($|\/)|\.MIL($|\/)|\.MK($|\/)|\.ML($|\/)|\.MM($|\/)|\.MN($|\/)|\.MO($|\/)|\.MOBI($|\/)|\.MP($|\/)|\.MQ($|\/)|\.MR($|\/)|\.MS($|\/)|\.MT($|\/)|\.MU($|\/)|\.MUSEUM($|\/)|\.MV($|\/)|\.MW($|\/)|\.MX($|\/)|\.MY($|\/)|\.MZ($|\/)|\.NA($|\/)|\.NAME($|\/)|\.NC($|\/)|\.NE($|\/)|\.NET($|\/)|\.NF($|\/)|\.NG($|\/)|\.NI($|\/)|\.NL($|\/)|\.NO($|\/)|\.NP($|\/)|\.NR($|\/)|\.NU($|\/)|\.NZ($|\/)|\.OM($|\/)|\.ORG($|\/)|\.PA($|\/)|\.PE($|\/)|\.PF($|\/)|\.PG($|\/)|\.PH($|\/)|\.PK($|\/)|\.PL($|\/)|\.PM($|\/)|\.PN($|\/)|\.PR($|\/)|\.PRO($|\/)|\.PS($|\/)|\.PT($|\/)|\.PW($|\/)|\.PY($|\/)|\.QA($|\/)|\.RE($|\/)|\.RO($|\/)|\.RS($|\/)|\.RU($|\/)|\.RW($|\/)|\.SA($|\/)|\.SB($|\/)|\.SC($|\/)|\.SD($|\/)|\.SE($|\/)|\.SG($|\/)|\.SH($|\/)|\.SI($|\/)|\.SJ($|\/)|\.SK($|\/)|\.SL($|\/)|\.SM($|\/)|\.SN($|\/)|\.SO($|\/)|\.SR($|\/)|\.ST($|\/)|\.SU($|\/)|\.SV($|\/)|\.SY($|\/)|\.SZ($|\/)|\.TC($|\/)|\.TD($|\/)|\.TEL($|\/)|\.TF($|\/)|\.TG($|\/)|\.TH($|\/)|\.TJ($|\/)|\.TK($|\/)|\.TL($|\/)|\.TM($|\/)|\.TN($|\/)|\.TO($|\/)|\.TP($|\/)|\.TR($|\/)|\.TRAVEL($|\/)|\.TT($|\/)|\.TV($|\/)|\.TW($|\/)|\.TZ($|\/)|\.UA($|\/)|\.UG($|\/)|\.UK($|\/)|\.US($|\/)|\.UY($|\/)|\.UZ($|\/)|\.VA($|\/)|\.VC($|\/)|\.VE($|\/)|\.VG($|\/)|\.VI($|\/)|\.VN($|\/)|\.VU($|\/)|\.WF($|\/)|\.WS($|\/)|\.XN--0ZWM56D($|\/)|\.XN--11B5BS3A9AJ6G($|\/)|\.XN--80AKHBYKNJ4F($|\/)|\.XN--9T4B11YI5A($|\/)|\.XN--DEBA0AD($|\/)|\.XN--G6W251D($|\/)|\.XN--HGBK6AJ7F53BBA($|\/)|\.XN--HLCJ6AYA9ESC7A($|\/)|\.XN--JXALPDLP($|\/)|\.XN--KGBECHTV($|\/)|\.XN--ZCKZAH($|\/)|\.YE($|\/)|\.YT($|\/)|\.YU($|\/)|\.ZA($|\/)|\.ZM($|\/)|\.ZW)/i",
$string,
$M
);
$has_tld = (count($M) > 0) ? true : false;
return $has_tld;
}
private function cleaner($url) {
$U = explode(' ', $url);
$W =array();
foreach ($U as $k => $u) {
if (stristr($u,".")) { //only preg_match if there is a dot
if ($this->containsTLD($u) === true) {
unset($U[$k]);
return $this->cleaner( implode(' ', $U) );
}
}
}
return implode(' ', $U);
}
// (c) Kraoc / urlclean
// https://github.com/kraoc/Leed-market/blob/master/urlclean/urlclean.plugin.disabled.php
private function resolve_url($link) {
// fallback to crawl to real url (slowest method and unsecure to privacy)
if (function_exists('curl_init') && !ini_get('safe_mode')) {
curl_setopt($ch, CURLOPT_USERAGENT, $ua);
curl_setopt($ch, CURLOPT_URL, $link);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// >>> anonimization
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_REFERER, '');
// <<< anonimization
$ch = curl_init();
$ua = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.16 (KHTML, like Gecko) Chrome/24.0.1304.0 Safari/537.16';
$a = curl_exec($ch);
$link = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
}
$link = preg_replace("/[&#?]xtor=(.)+/", "", $link); // remove: xtor
$link = preg_replace("/utm_([^&#]|(&amp;))+&*/", "", $link); // remove: utm_
// cleanup end of url
$link = preg_replace("/\?&/", "", $link);
if (isset($link[strlen($link) -1])){
if ($link[strlen($link) -1] == '?')
$link = substr($link, 0, strlen($link) -1);
}
return $link;
}
public function collectData(array $param){
$html = '';
if (isset($param['q'])) { /* keyword search mode */
$html = file_get_html('https://twitter.com/search/realtime?q='.urlencode($param['q']).'+include:retweets&src=typd') or $this->returnError('No results for this query.', 404);
}
elseif (isset($param['u'])) { /* user timeline mode */
$html = file_get_html('https://twitter.com/'.urlencode($param['u']).'/with_replies') or $this->returnError('Requested username can\'t be found.', 404);
}
else {
$this->returnError('You must specify a keyword (?q=...) or a Twitter username (?u=...).', 400);
}
foreach($html->find('div.js-stream-tweet') as $tweet) {
$item = new \Item();
// extract username and sanitize
$item->username = $tweet->getAttribute('data-screen-name');
// extract fullname (pseudonym)
$item->fullname = $tweet->getAttribute('data-name');
// get avatar link
$item->avatar = $tweet->find('img', 0)->src;
// get TweetID
$item->id = $tweet->getAttribute('data-tweet-id');
// get tweet link
$item->uri = 'https://twitter.com'.$tweet->find('a.js-permalink', 0)->getAttribute('href');
// extract tweet timestamp
$item->timestamp = $tweet->find('span.js-short-timestamp', 0)->getAttribute('data-time');
// extract plaintext
$item->content_simple = str_replace('href="/', 'href="https://twitter.com/', html_entity_decode(strip_tags($tweet->find('p.js-tweet-text', 0)->innertext, '<a>')));
// processing content links
foreach($tweet->find('a') as $link) {
if($link->hasAttribute('data-expanded-url') ) {
$link->href = $link->getAttribute('data-expanded-url');
}
$link->removeAttribute('data-expanded-url');
$link->removeAttribute('data-query-source');
$link->removeAttribute('rel');
$link->removeAttribute('class');
$link->removeAttribute('target');
$link->removeAttribute('title');
}
// get tweet text
$item->content = '<a href="https://twitter.com/'.$item->username.'"><img style="align:top;width:75px;" alt="avatar" src="'.$item->avatar.'" />'.$item->username.'</a> '.$item->fullname.'<br/><blockquote>'.str_replace('href="/', 'href="https://twitter.com/', $tweet->find('p.js-tweet-text', 0)->innertext).'</blockquote>';
// generate the title
// $item->title = $item->fullname . ' (@'. $item->username . ') | ' . $item->content_simple;
$item->title = $item->content_simple;
$item->title = preg_replace('|https?://www\.[a-z\.0-9]+|i', '', $item->title); // remove http(s) links
$item->title = preg_replace('|www\.[a-z\.0-9]+|i', '', $item->title); // remove www. links
$item->title = $this->cleaner($item->title); // remove all remaining links
$item->title = trim($item->title); // remove extra spaces at beginning and end
// convert all content links to real ones
$regex = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
$item->content = preg_replace_callback($regex, function($url) {
// do stuff with $url[0] here
return $this->resolve_url($url[0]);
}, $item->content);
// put out
$this->items[] = $item;
}
}
public function getName(){
return 'Twitter Bridge Tweaked';
}
public function getURI(){
return 'http://twitter.com';
}
public function getCacheDuration(){
return 300; // 5 minutes
}
public function getUsername(){
return $this->items[0]->username;
}
}

66
bridges/WhydBridge.php Normal file
View file

@ -0,0 +1,66 @@
<?php
/**
* WhydBridge
* Returns the newest music from user
*
* @name Whyd Bridge
* @homepage http://www.whyd.com/
* @description Returns 10 newest music from user profile
* @maintainer kranack
* @update 2014-07-18
* @use1(u="username/id")
*
*/
class WhydBridge extends BridgeAbstract{
private $request;
private $name;
public function collectData(array $param){
$html = '';
if (isset($param['u']))
{
$this->request = $param['u'];
if (strlen(preg_replace("/[^0-9a-f]/",'', $this->request)) == 24) { // is input the userid ?
$html = file_get_html('http://www.whyd.com/u/'.preg_replace("/[^0-9a-f]/",'', $this->request)) or $this->returnError('No results for this query.', 404);
} else { // input may be the username
$html = file_get_html('http://www.whyd.com/search?q='.urlencode($this->request)) or $this->returnError('No results for this query.', 404);
for ($j = 0; $j < 5; $j++) {
if (strtolower($html->find('div.user', $j)->find('a',0)->plaintext) == strtolower($this->request)) {
$html = file_get_html('http://www.whyd.com' . $html->find('div.user', $j)->find('a', 0)->getAttribute('href')) or $this->returnError('No results for this query', 404);
break;
}
}
}
$this->name = $html->find('div#profileTop', 0)->find('h1', 0)->plaintext;
}
else
{
$this->returnError('You must specify username', 400);
}
for($i = 0; $i < 10; $i++) {
$track = $html->find('div.post', $i);
$item = new \Item();
$item->name = $track->find('h2', 0)->plaintext;
$item->title = $track->find('h2', 0)->plaintext;
$item->content = $track->find('a.thumb',0) . '<br/>' . $track->find('h2', 0)->plaintext;
$item->id = 'http://www.whyd.com' . $track->find('a.no-ajaxy',0)->getAttribute('href');
$item->uri = 'http://www.whyd.com' . $track->find('a.no-ajaxy',0)->getAttribute('href');
$this->items[] = $item;
}
}
public function getName(){
return (!empty($this->name) ? $this->name .' - ' : '') .'Whyd Bridge';
}
public function getURI(){
return 'http://www.whyd.com/';
}
public function getCacheDuration(){
return 600; // 10 minutes
}
}

3
bridges/WikipediaENBridge.php Executable file → Normal file
View file

@ -2,9 +2,12 @@
/**
* RssBridgeWikipediaEN
* Retrieve latest highlighted articles from Wikipedia in English.
* 2014-05-25
*
* @name Wikipedia EN "Today's Featured Article..."
* @homepage https://en.wikipedia.org/
* @description Returns the highlighted en.wikipedia.org article.
* @maintainer gsurrel
*/
class WikipediaENBridge extends BridgeAbstract{

View file

@ -2,9 +2,12 @@
/**
* RssBridgeWikipediaEO
* Retrieve latest highlighted articles from Wikipedia in Esperanto.
* 2014-05-25
*
* @name Wikipedia EO "Artikolo de la semajno"
* @homepage https://eo.wikipedia.org/
* @description Returns the highlighted eo.wikipedia.org article.
* @maintainer gsurrel
*/
class WikipediaEOBridge extends BridgeAbstract{

3
bridges/WikipediaFRBridge.php Executable file → Normal file
View file

@ -2,9 +2,12 @@
/**
* RssBridgeWikipediaFR
* Retrieve latest highlighted articles from Wikipedia in French.
* 2014-05-25
*
* @name Wikipedia FR "Lumière sur..."
* @homepage https://fr.wikipedia.org/
* @description Returns the highlighted fr.wikipedia.org article.
* @maintainer gsurrel
*/
class WikipediaFRBridge extends BridgeAbstract{

View file

@ -0,0 +1,95 @@
<?php
/**
* RssBridgeWordpress
* Returns the 3 newest full posts of a Wordpress blog
*
* @name Wordpress Bridge
* @homepage https://wordpress.com/
* @description Returns the 3 newest full posts of a Wordpress blog
* @maintainer aledeg
* @update 2014-05-26
* @use1(url="blog URL (required)", name="blog name")
*/
class WordPressBridge extends BridgeAbstract {
private $url;
private $name;
public function collectData(array $param) {
$this->processParams($param);
if (!$this->hasUrl()) {
$this->returnError('You must specify a URL', 400);
}
$html = file_get_html($this->url) or $this->returnError("Could not request {$this->url}.", 404);
$posts = $html->find('.post');
if(!empty($posts) ) {
$i=0;
foreach ($html->find('.post') as $article) {
if($i < 3) {
$uri = $article->find('a', 0)->href;
$this->items[] = $this->getDetails($uri);
$i++;
}
}
}
else {
$this->returnError("Sorry, {$this->url} doesn't seem to be a Wordpress blog.", 404);
}
}
private function getDetails($uri) {
$html = file_get_html($uri) or exit;
$item = new \Item();
$article = $html->find('.post', 0);
$item->uri = $uri;
$item->title = $article->find('h1', 0)->innertext;
$item->content = $this->clearContent($article->find('.entry-content,.entry', 0)->innertext);
$item->timestamp = $this->getDate($uri);
return $item;
}
private function clearContent($content) {
$content = preg_replace('/<script.*\/script>/', '', $content);
$content = preg_replace('/<div class="wpa".*/', '', $content);
return $content;
}
private function getDate($uri) {
preg_match('/\d{4}\/\d{2}\/\d{2}/', $uri, $matches);
$date = new \DateTime($matches[0]);
return $date->format('U');
}
public function getName() {
return "{$this->name} - Wordpress Bridge";
}
public function getURI() {
return $this->url;
}
public function getCacheDuration() {
return 3600*3; // 3 hours
}
private function hasUrl() {
if (empty($this->url)) {
return false;
}
return true;
}
private function processParams($param) {
$this->url = $param['url'];
$this->name = $param['name'];
}
}

52
bridges/XbooruBridge.php Normal file
View file

@ -0,0 +1,52 @@
<?php
/**
* RssBridgeXbooru
* Returns images from given page
* 2014-05-25
*
* @name Xbooru
* @homepage http://xbooru.com/
* @description Returns images from given page
* @maintainer mitsukarenai
* @use1(p="page",t="tags")
*/
class XbooruBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 0;$tags='';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
$page = $page - 1;
$page = $page * 50;
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("http://xbooru.com/index.php?page=post&s=list&tags=$tags&pid=$page") or $this->returnError('Could not request Xbooru.', 404);
foreach($html->find('div[class=content] span') as $element) {
$item = new \Item();
$item->uri = 'http://xbooru.com/'.$element->find('a', 0)->href;
$item->postid = (int)preg_replace("/[^0-9]/",'', $element->getAttribute('id'));
$item->timestamp = time();
$item->thumbnailUri = $element->find('img', 0)->src;
$item->tags = $element->find('img', 0)->getAttribute('alt');
$item->title = 'Xbooru | '.$item->postid;
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$item->tags;
$this->items[] = $item;
}
}
public function getName(){
return 'Xbooru';
}
public function getURI(){
return 'http://xbooru.com/';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

54
bridges/YandereBridge.php Normal file
View file

@ -0,0 +1,54 @@
<?php
/**
* RssBridgeYandere
* Returns images from given page and tags
* 2014-05-25
*
* @name Yande.re
* @homepage https://yande.re/
* @description Returns images from given page and tags
* @maintainer mitsukarenai
* @use1(p="page", t="tags")
*/
class YandereBridge extends BridgeAbstract{
public function collectData(array $param){
$page = 1; $tags = '';
if (isset($param['p'])) {
$page = (int)preg_replace("/[^0-9]/",'', $param['p']);
}
if (isset($param['t'])) {
$tags = urlencode($param['t']);
}
$html = file_get_html("https://yande.re/post?page=$page&tags=$tags") or $this->returnError('Could not request Yandere.', 404);
$input_json = explode('Post.register(', $html);
foreach($input_json as $element)
$data[] = preg_replace('/}\)(.*)/', '}', $element);
unset($data[0]);
foreach($data as $datai) {
$json = json_decode($datai, TRUE);
$item = new \Item();
$item->uri = 'http://yande.re/post/show/'.$json['id'];
$item->postid = $json['id'];
$item->timestamp = $json['created_at'];
$item->imageUri = $json['file_url'];
$item->thumbnailUri = $json['preview_url'];
$item->title = 'Yandere | '.$json['id'];
$item->content = '<a href="' . $item->imageUri . '"><img src="' . $item->thumbnailUri . '" /></a><br>Tags: '.$json['tags'];
$this->items[] = $item;
}
}
public function getName(){
return 'Yande.re';
}
public function getURI(){
return 'http://yande.re/post';
}
public function getCacheDuration(){
return 1800; // 30 minutes
}
}

View file

@ -4,43 +4,130 @@
* Returns the newest videos
*
* @name Youtube Bridge
* @description Returns the newest videos
* @homepage https://www.youtube.com/
* @description Returns the 10 newest videos by username/channel/playlist or search
* @maintainer mitsukarenai
* @update 2014-06-20
* @use1(u="username")
* @use2(c="channel id")
* @use3(p="playlist id")
* @use4(s="search keyword",pa="page")
*
* WARNING: to parse big playlists (over ~90 videos), you need to edit simple_html_dom.php:
* change: define('MAX_FILE_SIZE', 600000);
* into: define('MAX_FILE_SIZE', 900000); (or more)
*/
class YoutubeBridge extends BridgeAbstract{
private $request;
private $request;
public function collectData(array $param){
$html = '';
if (isset($param['u'])) { /* user timeline mode */
$this->request = $param['u'];
$html = file_get_html('https://www.youtube.com/user/'.urlencode($this->request).'/videos') or $this->returnError('Could not request Youtube.', 404);
}
else {
$this->returnError('You must specify a Youtbe username (?u=...).', 400);
}
foreach($html->find('li.channels-content-item') as $element) {
$item = new \Item();
$item->uri = 'https://www.youtube.com'.$element->find('a',0)->href;
$item->thumbnailUri = 'https:'.$element->find('img',0)->src;
$item->title = trim($element->find('h3',0)->plaintext);
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br><a href="' . $item->uri . '">' . $item->title . '</a>';
$this->items[] = $item;
}
}
public function collectData(array $param){
public function getName(){
return (!empty($this->request) ? $this->request .' - ' : '') .'Youtube Bridge';
}
function getPublishDate($id) {
// relies on Youtube API; deprecated
$json = json_decode(file_get_contents("https://gdata.youtube.com/feeds/api/videos/$id?v=2&alt=json"), TRUE);
$timestamp = strtotime($json['entry']['published']['$t']);
return $timestamp;
}
public function getURI(){
return 'https://www.youtube.com/';
}
public function getCacheDuration(){
return 21600; // 6 hours
}
$html = '';
$limit = 10;
$count = 0;
if (isset($param['u'])) { /* user timeline mode */
$this->request = $param['u'];
$html = file_get_html('https://www.youtube.com/user/'.urlencode($this->request).'/videos') or $this->returnError('Could not request Youtube.', 404);
foreach($html->find('li.channels-content-item') as $element) {
if($count < $limit) {
$item = new \Item();
$videoquery = parse_url($element->find('a',0)->href, PHP_URL_QUERY); parse_str($videoquery, $videoquery);
$item->id = $videoquery['v'];
$item->uri = 'https://www.youtube.com/watch?v='.$item->id;
$item->thumbnailUri = 'https:'.$element->find('img',0)->src;
$item->title = trim($element->find('h3',0)->plaintext);
$item->timestamp = getPublishDate($item->id);
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br><a href="' . $item->uri . '">' . $item->title . '</a>';
$this->items[] = $item;
$count++;
}
}
}
else if (isset($param['c'])) { /* channel timeline mode */
$this->request = $param['c'];
$html = file_get_html('https://www.youtube.com/channel/'.urlencode($this->request).'/videos') or $this->returnError('Could not request Youtube.', 404);
foreach($html->find('li.channels-content-item') as $element) {
if($count < $limit) {
$item = new \Item();
$videoquery = parse_url($element->find('a',0)->href, PHP_URL_QUERY); parse_str($videoquery, $videoquery);
$item->id = $videoquery['v'];
$item->uri = 'https://www.youtube.com/watch?v='.$item->id;
$item->thumbnailUri = 'https:'.$element->find('img',0)->src;
$item->title = trim($element->find('h3',0)->plaintext);
$item->timestamp = getPublishDate($item->id);
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br><a href="' . $item->uri . '">' . $item->title . '</a>';
$this->items[] = $item;
$count++;
}
}
}
else if (isset($param['p'])) { /* playlist mode */
$this->request = $param['p'];
$html = file_get_html('https://www.youtube.com/playlist?list='.urlencode($this->request).'') or $this->returnError('Could not request Youtube.', 404);
foreach($html->find('tr.pl-video') as $element) {
if($count < $limit) {
$item = new \Item();
$item->uri = 'https://www.youtube.com'.$element->find('.pl-video-title a',0)->href;
$item->thumbnailUri = 'https:'.str_replace('/default.','/mqdefault.',$element->find('.pl-video-thumbnail img',0)->src);
$item->title = trim($element->find('.pl-video-title a',0)->plaintext);
$item->id = str_replace('/watch?v=', '', $element->find('a',0)->href);
$item->timestamp = getPublishDate($item->id);
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br><a href="' . $item->uri . '">' . $item->title . '</a>';
$this->items[] = $item;
$count++;
}
$this->request = 'Playlist '.trim(str_replace(' - YouTube', '', $html->find('title', 0)->plaintext)).', by '.$html->find('h1', 0)->plaintext;
}
}
else if (isset($param['s'])) { /* search mode */
$this->request = $param['s']; $page = 1; if (isset($param['pa'])) $page = (int)preg_replace("/[^0-9]/",'', $param['pa']);
$html = file_get_html('https://www.youtube.com/results?search_query='.urlencode($this->request).'&&page='.$page.'&filters=video&search_sort=video_date_uploaded') or $this->returnError('Could not request Youtube.', 404);
foreach($html->find('li.yt-lockup') as $element) {
$item = new \Item();
$item->uri = 'https://www.youtube.com'.$element->find('a',0)->href;
$checkthumb = $element->find('img', 0)->getAttribute('data-thumb');
if($checkthumb !== FALSE)
$item->thumbnailUri = $checkthumb;
else
$item->thumbnailUri = ''.$element->find('img',0)->src;
$item->title = trim($element->find('h3',0)->plaintext);
$item->id = str_replace('/watch?v=', '', $element->find('a',0)->href);
//$item->timestamp = getPublishDate($item->id); /* better not use it here */
$item->content = '<a href="' . $item->uri . '"><img src="' . $item->thumbnailUri . '" /></a><br><a href="' . $item->uri . '">' . $item->title . '</a>';
$this->items[] = $item;
}
$this->request = 'Search: '.str_replace(' - YouTube', '', $html->find('title', 0)->plaintext);
}
else
$this->returnError('You must either specify a Youtube username (?u=...) or a channel id (?c=...) or a playlist id (?p=...) or search (?s=...)', 400);
}
public function getName(){
return (!empty($this->request) ? $this->request .' - ' : '') .'Youtube Bridge';
}
public function getURI(){
return 'https://www.youtube.com/';
}
public function getCacheDuration(){
return 10800; // 3 hours
}
}

55
bridges/ZatazBridge.php Normal file
View file

@ -0,0 +1,55 @@
<?php
/**
* @name Zataz
* @homepage http://www.zataz.com/
* @description ZATAZ Magazine - S'informer, c'est déjà se sécuriser
* @maintainer aledeg
* @update 07/02/2015
*/
class ZatazBridge extends BridgeAbstract {
public function collectData(array $param) {
$html = file_get_html($this->getURI()) or $this->returnError('Could not request ' . $this->getURI(), 404);
$recent_posts = $html->find('#recent-posts-3', 0)->find('ul', 0)->find('li');
foreach ($recent_posts as $article) {
if (count($this->items) < 5) {
$uri = $article->find('a', 0)->href;
$this->items[] = $this->getDetails($uri);
}
}
}
private function getDetails($uri) {
$html = file_get_html($uri) or exit;
$item = new \Item();
$article = $html->find('.gdl-blog-full', 0);
$item->uri = $uri;
$item->title = $article->find('.blog-title', 0)->find('a', 0)->innertext;
$item->content = $article->find('.blog-content', 0)->innertext;
$item->timestamp = $this->getTimestampFromDate($article->find('.blog-date', 0)->find('a', 0)->href);
return $item;
}
private function getTimestampFromDate($uri) {
preg_match('/\d{4}\/\d{2}\/\d{2}/', $uri, $matches);
$date = new \DateTime($matches[0]);
return $date->format('U');
}
public function getName() {
return 'Zataz Magazine';
}
public function getCacheDuration() {
return 7200; // 2h
}
public function getURI() {
return 'http://www.zataz.com';
}
}

View file

@ -87,6 +87,10 @@ h2 {
margin-bottom: 10px;
}
h2 a {
color:black;
}
form {
margin-bottom: 10px;
}
@ -97,9 +101,13 @@ header,footer {
padding: 20px;
}
header h2 {
margin-left:1em;
}
footer {
text-align: center;
font-size: 60%;
font-size: 80%;
}
section {
@ -120,10 +128,16 @@ section {
color: #555;
}
.maintainer {
font-size:60%;
float:right;
color: #777;
}
.placeholder {
color: #aaa;
}
input, label {
font-size: 80%;
}
}

View file

@ -18,13 +18,14 @@ class AtomFormat extends FormatAbstract{
$extraInfos = $this->getExtraInfos();
$title = htmlspecialchars($extraInfos['name']);
$uri = htmlspecialchars($extraInfos['uri']);
$icon = 'http://g.etfv.co/'. $uri .'?icon.jpg';
$entries = '';
foreach($this->getDatas() as $data){
$entryName = is_null($data->name) ? $title : $data->name;
$entryAuthor = is_null($data->author) ? $uri : $data->author;
$entryTitle = is_null($data->title) ? '' : $data->title;
$entryUri = is_null($data->uri) ? '' : $data->uri;
$entryName = strip_tags(is_null($data->name) ? $title : $data->name);
$entryAuthor = strip_tags(is_null($data->author) ? $uri : $data->author);
$entryTitle = strip_tags(is_null($data->title) ? '' : $data->title);
$entryUri = htmlspecialchars(is_null($data->uri) ? '' : $data->uri);
$entryTimestamp = is_null($data->timestamp) ? '' : date(DATE_ATOM, $data->timestamp);
// We prevent content from closing the CDATA too early.
$entryContent = is_null($data->content) ? '' : '<![CDATA[' . $this->sanitizeHtml(str_replace(']]>','',$data->content)) . ']]>';
@ -53,6 +54,10 @@ EOD;
- <content type="html"> : RFC look with xhtml, keep this in spite of ?
*/
// #### TEMPORARY FIX ###
$feedTimestamp = date(DATE_ATOM, time());
// ################
/* Data are prepared, now let's begin the "MAGIE !!!" */
$toReturn = '<?xml version="1.0" encoding="UTF-8"?>';
$toReturn .= <<<EOD
@ -60,7 +65,9 @@ EOD;
<title type="text">{$title}</title>
<id>http{$https}://{$httpHost}{$httpInfo}/</id>
<updated></updated>
<icon>{$icon}</icon>
<logo>{$icon}</logo>
<updated>{$feedTimestamp}</updated>
<link rel="alternate" type="text/html" href="{$uri}" />
<link rel="self" href="http{$https}://{$httpHost}{$serverRequestUri}" />
{$entries}
@ -85,4 +92,4 @@ EOD;
return parent::display();
}
}
}

View file

@ -12,39 +12,61 @@ class HtmlFormat extends FormatAbstract{
$extraInfos = $this->getExtraInfos();
$title = htmlspecialchars($extraInfos['name']);
$uri = htmlspecialchars($extraInfos['uri']);
$atomquery = str_replace('format=HtmlFormat', 'format=AtomFormat', htmlentities($_SERVER['QUERY_STRING']));
$entries = '';
foreach($this->getDatas() as $data){
$entryUri = is_null($data->uri) ? $uri : $data->uri;
$entryTitle = is_null($data->title) ? '' : $this->sanitizeHtml(strip_tags($data->title));
$entryTimestamp = is_null($data->timestamp) ? '' : '<small>' . date(DATE_ATOM, $data->timestamp) . '</small>';
$entryTimestamp = is_null($data->timestamp) ? '' : '<small><time datetime="' . date(DATE_ATOM, $data->timestamp) . '">' . date(DATE_ATOM, $data->timestamp) . '</time></small>';
$entryContent = is_null($data->content) ? '' : '<p>' . $this->sanitizeHtml($data->content). '</p>';
$entries .= <<<EOD
<div class="rssitem">
<h2><a href="{$entryUri}">{$entryTitle}</a></h2>
{$entryTimestamp}
{$entryContent}
</div>
<div class="feeditem">
<h2><a href="{$entryUri}">{$entryTitle}</a></h2>
{$entryTimestamp}
{$entryContent}
</div>
EOD;
}
$styleCss = <<<'EOD'
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;}
body{
font-family:"Trebuchet MS",Verdana,Arial,Helvetica,sans-serif;
font-size:10pt;
background-color:#aaa;
background-image:linear-gradient(#eee, #aaa);
background-attachment:fixed;
}
div.feeditem{border:1px solid black;padding:1em;margin:1em;background-color:#fff;}
div.feeditem:hover { background-color:#ebf7ff; }
h1 {border-bottom:dotted #bbb;margin:0 1em 1em 1em;}
h2 {margin:0;}
h2 a {color:black;text-decoration:none;}
h2 a:hover {text-decoration:underline;}
span.menu {margin-left:1em;}
span.menu img {vertical-align:middle;}
span.menu a { color:black; text-decoration:none; padding:0.4em; }
span.menu a:hover { background-color:white; }
EOD;
/* Data are prepared, now let's begin the "MAGIE !!!" */
$toReturn = <<<EOD
<!DOCTYPE html>
<html>
<head>
<title>{$title}</title>
<style type="text/css">{$styleCss}</style>
</head>
<body>
<h1>{$title}</h1>
<head>
<meta charset="UTF-8">
<title>{$title}</title>
<style type="text/css">{$styleCss}</style>
<meta name="robots" content="noindex, follow">
</head>
<body>
<h1>{$title}</h1>
<span class="menu"><a href="./" onclick="window.history.back()"> back to rss-bridge</a> <a title="Get the ATOM feed" href="./?{$atomquery}"><img alt="feed" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZAgMAAAC5h23wAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAJUExURf+cCv/8+P/OhD2VurcAAAABdFJOU/4a4wd9AAAAbklEQVQI13XOMQ6AIAwFUGzCgLtHYPEUHMHBTwgTRyFOXoDdUT2ltCKbXV6b/iZV6qcMYmY1EJtw3MwFQRJU/Bfl6VaEzENQxbHIUxKTrY4Xgk4ct0EvcrYa9iTPGrxqbE3XHWSfRfIk1trp6O8+R38aBYbaAE4AAAAASUVORK5CYII="></a></span>
{$entries}
</body>
</body>
</html>
EOD;
@ -58,4 +80,4 @@ EOD;
return parent::display();
}
}
}

195
index.php
View file

@ -15,6 +15,52 @@ date_default_timezone_set('UTC');
error_reporting(0);
//ini_set('display_errors','1'); error_reporting(E_ALL); // For debugging only.
// extensions check
if (!extension_loaded('openssl'))
die('"openssl" extension not loaded. Please check "php.ini"');
// FIXME : beta test UA spoofing, please report any blacklisting by PHP-fopen-unfriendly websites
ini_set('user_agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20121202 Firefox/30.0 (rss-bridge/0.1; +https://github.com/sebsauvage/rss-bridge)');
// -------
// default whitelist
$whitelist_file = './whitelist.txt';
$whitelist_default = array(
"BandcampBridge",
"CryptomeBridge",
"DansTonChatBridge",
"DuckDuckGoBridge",
"FlickrExploreBridge",
"GooglePlusPostBridge",
"GoogleSearchBridge",
"IdenticaBridge",
"InstagramBridge",
"OpenClassroomsBridge",
"PinterestBridge",
"ScmbBridge",
"TwitterBridge",
"WikipediaENBridge",
"WikipediaEOBridge",
"WikipediaFRBridge",
"YoutubeBridge");
if (!file_exists($whitelist_file)) {
$whitelist_selection = $whitelist_default;
$whitelist_write = implode("\n", $whitelist_default);
file_put_contents($whitelist_file, $whitelist_write);
}
else {
$whitelist_selection = explode("\n", file_get_contents($whitelist_file));
}
// whitelist control function
function BridgeWhitelist( $whitelist, $name ) {
if(in_array("$name", $whitelist) or in_array("$name.php", $whitelist))
return TRUE;
else
return FALSE;
}
try{
require_once __DIR__ . '/lib/RssBridge.php';
@ -32,8 +78,11 @@ try{
$format = $_REQUEST['format'];
unset($_REQUEST['format']);
// FIXME : necessary ?
// ini_set('user_agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0');
// whitelist control
if(!BridgeWhitelist($whitelist_selection, $bridge)) {
throw new \HttpException('This bridge is not whitelisted', 401);
die;
}
$cache = Cache::create('FileCache');
@ -71,6 +120,84 @@ function getHelperButtonFormat($value, $name){
return '<button type="submit" name="format" value="' . $value . '">' . $name . '</button>';
}
function getHelperButtonsFormat($formats){
$buttons = '';
foreach( $formats as $name => $infos )
{
if ( isset($infos['name']) )
{
$buttons .= getHelperButtonFormat($name, $infos['name']) . PHP_EOL;
}
}
return $buttons;
}
function displayBridgeCard($bridgeReference, $bridgeInformations, $formats, $isActive = true)
{
$name = isset($bridgeInformations['homepage']) ? '<a href="'.$bridgeInformations['homepage'].'">'.$bridgeInformations['name'].'</a>' : $bridgeInformations['name'];
$description = isset($bridgeInformations['description']) ? $bridgeInformations['description'] : 'No description provided';
$card = <<<CARD
<section id="bridge-{$bridgeReference}" data-ref="{$bridgeReference}">
<h2>{$name}</h2>
<p class="description">
{$description}
</p>
CARD;
if( isset($bridgeInformations['use']) && count($bridgeInformations['use']) > 0 )
{
$card .= '<ol class="list-use">' . PHP_EOL;
foreach($bridgeInformations['use'] as $anUseNum => $anUse)
{
$card .= '<li data-use="' . $anUseNum . '">' . PHP_EOL;
$card .= '<form method="GET" action="?">
<input type="hidden" name="action" value="display" />
<input type="hidden" name="bridge" value="' . $bridgeReference . '" />' . PHP_EOL;
foreach($anUse as $argName => $argDescription)
{
$idArg = 'arg-' . $bridgeReference . '-' . $anUseNum . '-' . $argName;
$card .= '<input id="' . $idArg . '" type="text" value="" placeholder="' . $argDescription . '" name="' . $argName . '" />' . PHP_EOL;
}
$card .= '<br />';
if ($isActive)
{
$card .= getHelperButtonsFormat($formats);
}
else
{
$card .= '<span style="font-weight: bold;">Inactive</span>';
}
$card .= '</form></li>' . PHP_EOL;
}
$card .= '</ol>' . PHP_EOL;
}
else
{
$card .= '<form method="GET" action="?">
<input type="hidden" name="action" value="display" />
<input type="hidden" name="bridge" value="' . $bridgeReference . '" />' . PHP_EOL;
if ($isActive)
{
$card .= getHelperButtonsFormat($formats);
}
else
{
$card .= '<span style="font-weight: bold;">Inactive</span>';
}
$card .= '</form>' . PHP_EOL;
}
$card .= isset($bridgeInformations['maintainer']) ? '<span class="maintainer">'.$bridgeInformations['maintainer'].'</span>' : '';
$card .= '</section>';
return $card;
}
$bridges = Bridge::searchInformation();
$formats = Format::searchInformation();
?>
@ -91,48 +218,30 @@ $formats = Format::searchInformation();
<header>
<h1>RSS-Bridge</h1>
<h2>·Reconnecting the Web·</h2>
</header>
<?php foreach($bridges as $bridgeReference => $bridgeInformations): ?>
<section id="bridge-<?php echo $bridgeReference ?>" data-ref="<?php echo $bridgeReference ?>">
<h2><?php echo $bridgeInformations['name'] ?></h2>
<p class="description">
<?php echo isset($bridgeInformations['description']) ? $bridgeInformations['description'] : 'No description provided' ?>
</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="GET" action="?">
<input type="hidden" name="action" value="display" />
<input type="hidden" name="bridge" value="<?php echo $bridgeReference ?>" />
<?php foreach($anUse as $argName => $argDescription): ?>
<?php
$idArg = 'arg-' . $bridgeReference . '-' . $anUseNum . '-' . $argName;
?>
<input id="<?php echo $idArg ?>" type="text" value="" placeholder="<?php echo $argDescription; ?>" name="<?php echo $argName ?>" placeholder="<?php echo $argDescription ?>" />
<?php endforeach; ?>
<?php foreach( $formats as $name => $infos ): ?>
<?php if( isset($infos['name']) ){ echo getHelperButtonFormat($name, $infos['name']); } ?>
<?php endforeach; ?>
</form>
</li>
<?php endforeach; ?>
</ol>
<?php else: ?>
<form method="GET" action="?">
<input type="hidden" name="action" value="display" />
<input type="hidden" name="bridge" value="<?php echo $bridgeReference ?>" />
<?php foreach( $formats as $name => $infos ): ?>
<?php if( isset($infos['name']) ){ echo getHelperButtonFormat($name, $infos['name']); } ?>
<?php endforeach; ?>
</form>
<?php endif; ?>
</section>
<?php endforeach; ?>
<?php
$activeFoundBridgeCount = 0;
$showInactive = isset($_REQUEST['show_inactive']) && $_REQUEST['show_inactive'] == 1;
$inactiveBridges = '';
foreach($bridges as $bridgeReference => $bridgeInformations)
{
if(BridgeWhitelist($whitelist_selection, $bridgeReference))
{
echo displayBridgeCard($bridgeReference, $bridgeInformations, $formats);
$activeFoundBridgeCount++;
}
elseif ($showInactive)
{
// inactive bridges
$inactiveBridges .= displayBridgeCard($bridgeReference, $bridgeInformations, $formats, false) . PHP_EOL;
}
}
echo '<hr />' . $inactiveBridges;
?>
<footer>
<a href="https://github.com/sebsauvage/rss-bridge">RSS-Bridge</a> alpha 0.1
<?= $activeFoundBridgeCount; ?>/<?= count($bridges) ?> active bridges (<a href="?show_inactive=1">Show inactive</a>)<br />
<a href="https://github.com/sebsauvage/rss-bridge">RSS-Bridge alpha 0.1 ~ Public Domain</a>
</footer>
</body>
</html>
</html>

View file

@ -137,7 +137,7 @@ class Bridge{
$listBridge = array();
$searchCommonPattern = array('description', 'name');
$searchCommonPattern = array('maintainer', 'description', 'homepage', 'name');
$dirFiles = scandir($pathDirBridge);
if( $dirFiles !== false ){
@ -184,4 +184,4 @@ class Bridge{
return $listBridge;
}
}
}

1742
vendor/simplehtmldom/simple_html_dom.php vendored Normal file

File diff suppressed because it is too large Load diff