<?php
###############################################################################
# Gregarius - A PHP based RSS aggregator.
# Copyright (C) 2003 - 2006 Marco Bonetti
#
###############################################################################
# This program is free software and open source software; you can redistribute
# it and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the License,
# or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit
# http://www.gnu.org/licenses/gpl.html
#
###############################################################################
# E-mail: mbonetti at gmail dot com
# Web page: http://gregarius.net/
#
###############################################################################
require_once('init.php');
function getOpml($url) {
$arr = parse_weblogsDotCom($url);
if (!$arr) {
return false;
} else {
return $arr;
}
}
/**** mbi: from http://www.stargeek.com/php_scripts.php?script=20&cat=blog */
function parse_weblogsDotCom($url) {
/*
Grab weblogs.com list of recently updated RSS feeds
$blogs is array() of feeds
NAME name
URL address
WHEN seconds since ping
*/
global $blogs,$folder,$inOpmlfolder, $inOpmlItem;
$folder = __('Root');
$inOpmlfolder = $inOpmlItem = false;
$opml = getUrl($url);
$opml = str_replace("\r", '', $opml);
$opml = str_replace("\n", '', $opml);
$xp = xml_parser_create() or xml_error("couldn't create parser");
xml_set_element_handler($xp, '_xml_startElement', '_xml_endElement')
or xml_error("couldnt set XML handlers");
xml_parse($xp, $opml, true) or xml_error("failed parsing xml at line ".xml_get_current_line_number().": " . xml_error_string());
xml_parser_free($xp) or xml_error("failed freeing the parser");
return $blogs;
}
function xml_error($error_msg){
rss_error($error_msg, RSS_ERROR_ERROR,true);
echo("\n</div>\n</body></html>\n");
die();
}
function _xml_startElement($xp, $element, $attr) {
global $blogs,$folder,$inOpmlfolder, $inOpmlItem;
if (strcasecmp('outline', $element)) {
return;
}
//$attr['__opml_folder__'] = $folder;
if (!array_key_exists('XMLURL',$attr) && (array_key_exists('TEXT',$attr)||array_key_exists('TITLE',$attr)) ) {
//some opml use title instead of text to define a folder (ex: newzcrawler)
$folder = $attr['TEXT']?$attr['TEXT']:$attr['TITLE'];
$inOpmlfolder = true;
$inOpmlItem = false;
//echo "start of folder $folder\n";
} else {
$inOpmlItem = true;
//echo "start of item $folder/".$attr['TEXT']."\n";
if ($folder != '') {
$blogs[$folder][] = $attr;
} else {
$blogs[] = $attr;
}
}
}
function _xml_endElement($xp, $element) {
global $blogs,$folder,$inOpmlfolder, $inOpmlItem;
if (strcasecmp( $element, "outline") === 0) {
if (!$inOpmlItem && $inOpmlfolder) {
//echo "end of folder $folder\n";
// end of folder element!
$inOpmlfolder = false;
$folder = __('Root');
} else {
// end of item element
$inOpmlItem = false;
//echo "end of item\n";
}
}
return;
}
/** OPML Export */
/** OPML2.0 RFC: http://techno-weenie.com/archives/2003/04/01/003067.php */
/** OPML1.0 Specs: http://opml.scripting.com/spec */
// This is a pretty lame opml 1.1 generation routine, in that it is not
// recursive, but instead relies on the fact that we only have one level
// of folders.
// Output should be valid xml. (*fingers crossed*)
if (array_key_exists('act',$_REQUEST)) {
$rs = rss_query( "select fid,tag from " .getTable('tag') ." t "
."inner join " .getTable('metatag') ." mt on mt.tid = t.id "
." where ttype='channel'");
$cats=array();
while(list($cid,$tag) = rss_fetch_row($rs)) {
if (!isset($cats[$cid])) {
$cats[$cid]=array();
}
$cats[$cid][]=$tag;
}
$sql = "select "
." c.id, c.title, c.url, c.siteurl, d.name, c.parent, c.descr "
." from ". getTable("channels") . " c "
." inner join " . getTable("folders") ." d on d.id = c.parent "
." where not (c.mode & ". RSS_MODE_DELETED_STATE .") ";
if (hidePrivate()) {
$sql .=" and not(c.mode & " . RSS_MODE_PRIVATE_STATE .") ";
}
// note: should we export deprecated feeds?
if (getConfig('rss.config.absoluteordering')) {
$sql .= " order by d.position asc, c.position asc";
} else {
$sql .=" order by d.name asc, c.title asc";
}
$res = rss_query($sql);
$dateRes = rss_query("select max(dateadded) from " . getTable("channels"));
list($dateModif) = rss_fetch_row($dateRes);
$dateLabel = date("r", strtotime($dateModif));
header("Content-Type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"" . getConfig('rss.output.encoding') . "\"?>\n"
."<?xml-stylesheet type=\"text/xsl\" href=\"".getPath()."css/opml.xsl\"?>\n"
."<!-- Generated by "._TITLE_. " " . _VERSION_ ." -->\n"
."<opml version=\"2.0\">\n";
echo "\t<head>\n"
."\t\t<title>"._TITLE_." OPML Feed</title>\n"
."\t\t<dateModified>$dateLabel</dateModified>\n"
."\t</head>\n"
."\t<body>\n";
$prev_parent=0;
while (list($id, $title, $url, $siteurl, $name, $parent, $descr) = rss_fetch_row($res)) {
$descr_ = htmlspecialchars ($descr);
$descr_ = trim(preg_replace('/(\r\n|\r|\n)/', ' ', $descr_));
$title_ = htmlspecialchars($title);
$url_ = preg_replace('|(https?://)([^:]+:[^@]+@)(.+)$|','\1\3',$url);
$url_ = htmlspecialchars($url_);
$siteurl_ = preg_replace('|(https?://)([^:]+:[^@]+@)(.+)$|','\1\3',$siteurl);
$siteurl_ = htmlspecialchars($siteurl_);
$name_ = htmlspecialchars($name);
if ($parent != $prev_parent) {
if ($prev_parent != 0) {
echo "\t\t</outline>\n";
}
$prev_parent = $parent;
echo "\t\t<outline text=\"$name_\">\n";
}
if ($parent > 0) {
echo "\t";
}
echo "\t\t<outline text=\"$title_\" description=\"$descr_\" type=\"rss\"";
if ($siteurl != "") {
echo " htmlUrl=\"$siteurl_\"";
}
if (isset($cats[$id]) && count($cats[$id])) {
echo " category=\"" . implode(",",$cats[$id]) ."\"";
}
echo " xmlUrl=\"$url_\" />\n";
}
if ($prev_parent > 0) {
echo "\t</outline>\n";
}
echo "\t</body>\n</opml>\n";
}
?>