Funnel - agréger plusieurs flux RSS en un seul

logo funnel (c) moi ;) Funnel est un script s'appuyant sur la lib syndexport qui permet de regrouper plusieurs flux RSS en un seul. Son nom est un jeu de mots avec Feed + tunnel = Funnel (entonnoir en anglais)

Deux possibilités pour lui fournir les url des flux: 

  • ajouter l'URL des flux dans le tableau $feeds de la partie configuration
  • passer les flux en $_GET, séparés par un espace (cette fonction peut être verrouillée via une variable de config)

Les items de tous les flux sont regroupés en un seul et classés par date du plus récent au plus ancien.

Un lien vers l'adresse de flux d'origine est conservée dans la description de chaque item.

 


<?php 
# Funnel (feed tunnel)
# @version: 1.0
# @author: bronco@warriordudimanche.net
# @url: http://www.warriordudimanche.net
# 
# 

Agréger plusieurs flux rss en un seul en conservant la hierarchie des dates.

(utilise l'excellente lib syndexport.php http://milletmaxime.net/syndexport/ )

CONFIG

$feeds=array( 'http://www.olissea.com/mb/1-links/?do=rss', 'http://lehollandaisvolant.net/rss.php?mode=links', 'http://sebsauvage.net/links/index.php?do=rss', );

date_default_timezone_set ('Europe/Paris'); define('FUNNEL_FEED_NAME','Warriordudimanche: le flux complet'); define('FUNNEL_FEED_DESCRIPTION','Tout ce qui est posté par Bronco sur WDD'); define('WEBSITE_REFERENCE_URL','http://warriordudimanche.net'); define('FUNNEL_FEED_URL','http://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF']); define('ALLOW_GET',false);

TEMPLATES

$r="\n"; define('TPL_RSS','<?xml version="1.0" encoding="utf-8" ?>'.$r.'<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"&gt;'.$r.'&lt;channel&gt;'.$r.'&lt;title&gt;&lt;![CDATA['.FUNNEL_FEED_NAME.']]&gt;&lt;/title&gt;'.$r.'&lt;link&gt;'.FUNNEL_FEED_URL.'&lt;/link&gt;'.$r.'&lt;description&gt;'.FUNNEL_FEED_DESCRIPTION.'&lt;/description&gt;'.$r); define('TPL_RSS_ITEM','<item>'.$r.'<title><![CDATA[#TITLE]]></title>'.$r.'<guid isPermaLink="false"><![CDATA[#GUID]]></guid>'.$r.'<link>#LIEN</link>'.$r.'<description><![CDATA[#DESCRIPTION]]></description>'.$r.'<pubDate>#DATE</pubDate>'.$r.'</item>'.$r); define('TPL_RSS_FOOTER','</channel></rss>'.$r);

FUNCTIONS

function file_curl_contents($url){$ch = curl_init();curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_URL, $url);if (!ini_get("safe_mode") && !ini_get('open_basedir') ) {curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);}curl_setopt($ch, CURLOPT_MAXREDIRS, 10); $data = curl_exec($ch);curl_close($ch);return $data;}
function load_feed($url){ try { $flux=file_curl_contents($url); $flux =new SyndExport($flux,false); $type = $flux->returnType(); } catch(Exception $e){ return false; } $contenu['infos']=$flux->exportInfos(); $contenu['items']=$flux->exportItems(-1); return $contenu; } function make_rss($array){ header("Content-Type: application/rss+xml"); echo TPL_RSS; foreach($array as $key=>$item){ if(!isset($item['date'])){$item['date']='';} if(!isset($item['description'])){$item['description']='';} if(!isset($item['guid'])){$item['guid']='';} if(!isset($item['link'])){$item['link']='';} if(!isset($item['title'])){$item['title']='';}

    $a=array(
        '#DATE'=&gt;$item['date'],
        '#DESCRIPTION'=&gt;$item['description'].'&lt;br/&gt;&lt;a href="https://www.warriordudimanche.net/'.$item['source_url'].'"&gt;[via '.$item['source'].']&lt;/a&gt;',
        '#GUID'=&gt;$item['guid'],
        '#LIEN'=&gt;$item['link'],
        '#TITLE'=&gt;$item['title'],
    );
    echo str_replace(array_keys($a),array_values($a),TPL_RSS_ITEM);
}
echo TPL_RSS_FOOTER;

}

include('syndexport.php');

ENGINE

$funnel_array=array(); if (isset($_GET['feeds'])&&ALLOW_GET){ $feeds=explode(' ',urldecode($_GET['feeds'])); }elseif(!isset($feeds)||count($feeds)==0){ exit('no feeds given'); }

foreach ($feeds as $feed){ # pour chaque flux if ($contenu=load_feed($feed)){ foreach($contenu['items'] as $item){

on ajoute les items à un tableau commun,

        # avec la date comme clé (classement global ultérieur)
        $item['source']=$contenu['infos']['title'];
        if(isset($contenu['infos']['link'])){$item['source_url']=$contenu['infos']['link'];}
        $funnel_array[strtotime($item['date']).'_'.$contenu['infos']['title']]=$item;
    }
}

} krsort($funnel_array); make_rss($funnel_array);

?>

Histoire de tester, vous pouvez  utiliser le nouveau lien dans mes flux RSS à droite -> le dernier cumule tout ce qui est posté sur wdd: articles+commentaires+shaarli+touïts... ça évite de jongler

Pour récupérer un zip prêt à l'emploi, passez par github...

 

Salut les copains, et ne lâchez rien !

P.S.: il est pas beau, mon logo ?!

❝ 6 commentaires ❞

1  bajazet le

Mec, tu développes tout ce que j'ai envie de dev. Merci !

 
2  Bronco le

ça c'est un compliment qui me va droit au coeur Merci !

 
3  jerrywham le

Nickel Miguel. Par contre, ta belle icône déconne pas sur la page d'accueil mais sur la page de l'article directement.

 
4  Nono le

J apprécie le coté phallique du logo :D (et plus de l'utilité de Funnel, évidemment).

 
5  tolima le

Juste une petite question : est-ce que tu sais comment récupérer les balises genre <content:encoded> avec SyndExport ?
Il y en a dans certains flux (http://korben.info/feed) et ça la qu'ils mettent le contenu de l'item !


ps: j'ai essayé de contacter l'auteur mais sans résultat et j'ai un peu de mal à comprendre certaines parties du code.

 
6  tolima le

c'est bon j'ai corrigé et partagé avec l'auteur, il devrait poster une correction. En attendant :
$this->p_list_ns = array_keys($this->p_ns);
à la fin du constructeur et après on accède aux namesapace via la clé "ns".

 

Fil RSS des commentaires de cet article

✍ Écrire un commentaire

les commentaires relevant du SPAM seront filtrés et dégagés direct...

Quelle est le cinquième caractère du mot x768fsw5 ?