Page MenuHomeIn-Portal Phabricator

rssparser.php
No OneTemporary

File Metadata

Created
Sun, Feb 1, 6:17 AM

rssparser.php

<?php
/*
CaRP
Copyright (c) 2002-3 Antone Roundy
http://www.mouken.com/rss/
This program may be copied, modified and redistributed under the terms of the
GNU General Public License. This program is distributed with NO WARRANTY
WHATSOEVER, including the implied warranty of merchantability or fitness for
a particular purpose.
See http://www.gnu.org/copyleft/gpl.html for details.
*/
$carpversion='2.4.1';
$carpconf=array(
'cachepath'=>'/www/data/rsscache',
'cacheinterval'=>60,
'cachetime'=>'',
'timeout'=>15,
'sendhost'=>1,
'descriptiontags'=>'b|/b|i|/i|br|p|/p|hr|span|/span|font|/font',
'newwindow'=>0,
'showdesc'=>0,
'maxdesc'=>0,
'truncdesc'=>0,
'posttruncdesc'=>'<i>... continues</i>',
'maxitems'=>15,
'maxtitle'=>80,
'defaulttitle'=>'(no title)',
'linkclass'=>'',
'linkstyle'=>'',
'linkdiv'=>'',
'preitem'=>'',
'postitem'=>'<br>',
'preitems'=>'',
'postitems'=>'',
'showctitle'=>0,
'showclink'=>1,
'showcdesc'=>0,
'maxctitle'=>80,
'cclass'=>'',
'cstyle'=>'',
'cdiv'=>'',
'encodingin'=>'',
'encodingout'=>'',
'maxredir'=>10,
/* If you modify or override the next line, please post a similar link
somewhere on your website. If you incorporate CaRP into another product and
feel the need to change this line, please ensure that there is a similar link
which will be displayed by default somewhere in your product. Thanks! */
'poweredby'=>'<br><i><a href="http://www.mouken.com/rss/" target="_blank">Newsfeed display by CaRP</a></i>'
);
class RSSParser {
var $insideitem=0;
var $insidechannel=0;
var $tag='';
var $title='';
var $description='';
var $link='';
var $ctitle='';
var $cdescription='';
var $clink='';
var $itemcount=0;
var $top='';
var $body='';
var $truncdesc=0;
function startElement($parser,$tagName,$attrs) {
$this->tag=$tagName;
if ($tagName=="ITEM") $this->insideitem=1;
if ($tagName=="CHANNEL") $this->insidechannel=1;
else if ($this->insidechannel&&!(($tagName=="TITLE")||($tagName=="DESCRIPTION")||($tagName=="LINK"))) $this->insidechannel++;
}
function endElement($parser,$tagName) {
global $carpconf;
if ($tagName=="ITEM") {
if ($this->itemcount<$carpconf['maxitems']) {
if (strlen($this->title)>$carpconf['maxtitle']) $this->title=substr($this->title,0,$carpconf['maxtitle']-3).'...';
$this->title=htmlspecialchars(trim($this->title));
if (!strlen($this->title)) $this->title=$carpconf['defaulttitle'];
$this->body.=$carpconf['preitem'].$carpconf['linkdiv'];
$this->body.="<a href=\"".trim($this->link)."\"".($carpconf['newwindow']?' target="_blank"':'').
(strlen($carpconf['linkclass'])?(' class="'.$carpconf['linkclass'].'"'):'').
(strlen($carpconf['linkstyle'])?(' style="'.$carpconf['linkstyle'].'"'):'').
'>'.$this->title.'</a>'.(strlen($carpconf['linkdiv'])?"</div>\n":($carpconf['showdesc']?"<br>\n":''));
if ($carpconf['showdesc']) {
if (strlen($carpconf['desctags'])) $adddesc=trim(preg_replace("#<(?!".$carpconf['desctags'].")(.*?)>#is","&lt;\\1\\2&gt;",$this->description));
else $adddesc=trim(preg_replace("#<(.*?)>#is","&lt;\\1&gt;",$this->description));
if ($carpconf['maxdesc']&&(strlen($adddesc)>$carpconf['maxdesc'])) $this->body.=substr($adddesc,0,$this->truncdesc).$carpconf['posttruncdesc'];
else $this->body.=$adddesc;
}
$this->body.=$carpconf['postitem']."\n";
$this->itemcount++;
$this->title=$this->description=$this->link='';
}
$this->insideitem=false;
} else if ($tagName=="CHANNEL") {
if ($carpconf['showctitle']) {
if (strlen($this->ctitle)>$carpconf['maxctitle']) $this->ctitle=substr($this->ctitle,0,$carpconf['maxctitle']-3).'...';
$this->ctitle=htmlspecialchars(trim($this->ctitle));
if (!strlen($this->ctitle)) $this->ctitle=$carpconf['defaulttitle'];
$this->top.=$carpconf['cdiv'];
if ($carpconf['showclink']) $this->top.="<a href=\"".trim($this->clink)."\"".($carpconf['newwindow']?' target="_blank"':'').
(strlen($carpconf['cclass'])?(' class="'.$carpconf['cclass'].'"'):'').
(strlen($carpconf['cstyle'])?(' style="'.$carpconf['cstyle'].'"'):'').
">".$this->ctitle."</a>";
else if (strlen($carpconf['cclass'].$carpconf['cstyle'])) $this->top.='<span'.
(strlen($carpconf['cclass'])?(' class="'.$carpconf['cclass'].'"'):'').
(strlen($carpconf['cstyle'])?(' style="'.$carpconf['cstyle'].'"'):'').
'>'.$this->ctitle."</span>";
else $this->top.=$this->ctitle;
$this->top.=strlen($carpconf['cdiv'])?"</div>\n":"<br>\n";
if ($carpconf['showcdesc']) {
if (strlen($carpconf['desctags'])) $this->top.=trim(preg_replace("#<(?!".$carpconf['desctags'].")(.*?)>#is","&lt;\\1\\2&gt;",$this->cdescription))."<p>\n";
else $this->top.=trim(preg_replace("#<(.*?)>#is","&lt;\\1&gt;",$this->cdescription))."<p>\n";
}
}
$this->ctitle=$this->cdescription=$this->clink='';
$this->insidechannel=false;
} else if ($this->insidechannel>1) $this->insidechannel--;
}
function characterData($parser,$data) {
if ($this->insideitem) {
switch ($this->tag) {
case "TITLE": $this->title.=$data; break;
case "DESCRIPTION": $this->description.=$data; break;
case "LINK": $this->link.=$data; break;
}
} else if ($this->insidechannel==1) {
switch ($this->tag) {
case "TITLE": $this->ctitle.=$data; break;
case "DESCRIPTION": $this->cdescription.=$data; break;
case "LINK": $this->clink.=$data; break;
}
}
}
}
function CaRPError($s) { echo "<br>\n[CaRP] $s<br>\n"; }
function OpenRSSFeed($url) {
global $carpconf,$carpversion,$CaRPRedirs;
if (preg_match("#^http://#i",$url)) {
list($domain,$therest)=explode('/',substr($url,7),2);
if (preg_match("/\:[0-9]+$/",$domain)) list($domain,$port)=explode(':',$domain,2);
else $port=80;
$fp=fsockopen($domain,$port,$errno,$errstr,$carpconf['timeout']);
if ($fp) {
$slash=preg_match("#^http://#i",$therest)?'':'/';
$senddomain=$carpconf['sendhost']?"\r\nHost: $domain":'';
fputs($fp,"GET $slash$therest HTTP/1.0$senddomain\r\nUser-Agent: CaRP/$carpversion\r\n\r\n");
while ((!feof($fp))&&preg_match("/[^\r\n]/",$header=fgets($fp,1000))) {
if (preg_match("/^Location:/i",$header)) {
fclose($fp);
if (count($CaRPRedirs)<$carpconf['maxredir']) {
$loc=trim(preg_replace("/^Location:/i",'',$header));
$lochttp=preg_match("#^http://#i",$loc);
if (!(strlen($slash)||$lochttp)) {
list($rdomain,$rtherest)=explode('/',substr($therest,strpos($therest,':')+3),2);
$loc="http://$rdomain$loc";
}
if (!(strlen($slash)&&$lochttp)) $loc="http://$domain".(($port==80)?'':":$port").(strlen($slash)?'':'/').$loc;
for ($i=count($CaRPRedirs)-1;$i>=0;$i--) if (!strcmp($loc,$CaRPRedirs[$i])) {
CaRPError('Redirection loop detected. Giving up.');
return 0;
}
$CaRPRedirs[count($CaRPRedirs)]=$loc;
return OpenRSSFeed($loc);
} else {
CaRPError('Too many redirects. Giving up.');
return 0;
}
}
}
} else echo CaRPError("$errstr ($errno)");
} else $fp=fopen($url,'r');
return $fp;
}
function ShowRSSPage($url,$cachefile) { ShowRSSFeed($url,$cachefile); }
function ShowRSSFeed($url,$cachefile='') {
global $carpconf,$CaRPRedirs;
$carpconf['desctags']=preg_replace("/\|/",'\b|',$carpconf['descriptiontags']).'\b';
$cache=0;
if (strlen($cachefile)) {
$cachefile=preg_replace("/\.\./",'.',$cachefile);
if (file_exists($carpconf['cachepath']."/$cachefile")) {
$mtime=filemtime($carpconf['cachepath']."/$cachefile");
$nowtime=time();
if (strlen($carpconf['cachetime'])) {
list($hour,$min)=explode(':',$carpconf['cachetime']);
$limtime=mktime($hour,$min,0);
$cache=($mtime>$limtime-(($nowtime<$limtime)?86400:0))?1:2;
} else $cache=(($nowtime-$mtime)<($carpconf['cacheinterval']*60))?1:2;
} else $cache=2;
}
if ($cache%2==0) {
$xml_parser=xml_parser_create($carpconf['encodingin']);
if (strlen($carpconf['encodingout'])) xml_parser_set_option($xml_parser,XML_OPTION_TARGET_ENCODING,$carpconf['encodingout']);
$rss_parser=new RSSParser();
xml_set_object($xml_parser,$rss_parser);
xml_set_element_handler($xml_parser,"startElement","endElement");
xml_set_character_data_handler($xml_parser,"characterData");
if ($cache) {
if (!($cfp=fopen($carpconf['cachepath']."/$cachefile",'w'))) {
CaRPError("Unable to create/open RSS cache file.");
xml_parser_free($xml_parser);
return;
}
}
$CaRPRedirs=array();
if ($fp=OpenRSSFeed($url)) {
if ($carpconf['maxdesc']) $rss_parser->truncdesc=$carpconf['truncdesc']?$carpconf['truncdesc']:($carpconf['maxdesc']-strlen($carpconf['posttruncdesc']));
while ($data=preg_replace("/&(?!lt|gt|amp|apos|quot)(.*\b)/is","&amp;\\1\\2",fread($fp,4096))) {
if (!xml_parse($xml_parser,$data,feof($fp))) {
CaRPError("XML error: ".xml_error_string(xml_get_error_code($xml_parser))." at line ".xml_get_current_line_number($xml_parser));
fclose($fp);
xml_parser_free($xml_parser);
return;
}
}
fclose($fp);
echo $rss_parser->top.$carpconf['preitems'].$rss_parser->body.$carpconf['postitems'].$carpconf['poweredby'];
if ($cfp) {
fwrite($cfp,$rss_parser->top.$carpconf['preitems'].$rss_parser->body.$carpconf['postitems'].$carpconf['poweredby']);
fclose($cfp);
}
xml_parser_free($xml_parser);
} else readfile($carpconf['cachepath']."/$cachefile");
} else readfile($carpconf['cachepath']."/$cachefile");
}
?>

Event Timeline