[geeklog-cvs] geeklog-1.3/plugins/spamx/magpierss rss_cache.inc,NONE,1.1 rss_fetch.inc,NONE,1.1 rss_parse.inc,NONE,1.1 rss_utils.inc,NONE,1.1

tony at iowaoutdoors.org tony at iowaoutdoors.org
Fri Sep 3 15:59:57 EDT 2004


Update of /var/cvs/geeklog-1.3/plugins/spamx/magpierss
In directory www:/tmp/cvs-serv3542/plugins/spamx/magpierss

Added Files:
	rss_cache.inc rss_fetch.inc rss_parse.inc rss_utils.inc 
Log Message:
Spamx is officially part of Geeklog.  All should work fine minus the upgrade file...I'm still missing some key data that I will add yet this weekend


--- NEW FILE: rss_cache.inc ---
<?php
/*
 * Project:     MagpieRSS: a simple RSS integration tool
 * File:        rss_cache.inc, a simple, rolling(no GC), cache 
 *				for RSS objects, keyed on URL.
 * Author:      Kellan Elliott-McCrea <kellan at protest.net>
 * Version:		0.51
 * License:		GPL
 *
 * The lastest version of MagpieRSS can be obtained from:
 * http://magpierss.sourceforge.net
 *
 * For questions, help, comments, discussion, etc., please join the
 * Magpie mailing list:
 * http://lists.sourceforge.net/lists/listinfo/magpierss-general
 *
 */

class RSSCache {
	var $BASE_CACHE = './cache';	// where the cache files are stored
	var $MAX_AGE	= 3600;  		// when are files stale, default one hour
	var $ERROR 		= "";			// accumulate error messages
	
	function RSSCache ($base='', $age='') {
		if ( $base ) {
			$this->BASE_CACHE = $base;
		}
		if ( $age ) {
			$this->MAX_AGE = $age;
		}
		
		// attempt to make the cache directory
		if ( ! file_exists( $this->BASE_CACHE ) ) {
			$status = @mkdir( $this->BASE_CACHE, 0755 );
			
			// if make failed 
			if ( ! $status ) {
				$this->error(
					"Cache couldn't make dir '" . $this->BASE_CACHE . "'."
				);
			}
		}
	}
	
/*=======================================================================*\
	Function:	set
	Purpose:	add an item to the cache, keyed on url
	Input:		url from wich the rss file was fetched
	Output:		true on sucess	
\*=======================================================================*/
	function set ($url, $rss) {
		$this->ERROR = "";
		$cache_file = $this->file_name( $url );
		$fp = @fopen( $cache_file, 'w' );
		
		if ( ! $fp ) {
			$this->error(
				"Cache unable to open file for writing: $cache_file"
			);
			return 0;
		}
		
		
		$data = $this->serialize( $rss );
		fwrite( $fp, $data );
		fclose( $fp );
		
		return $cache_file;
	}
	
/*=======================================================================*\
	Function:	get
	Purpose:	fetch an item from the cache
	Input:		url from wich the rss file was fetched
	Output:		cached object on HIT, false on MISS	
\*=======================================================================*/	
	function get ($url) {
		$this->ERROR = "";
		$cache_file = $this->file_name( $url );
		
		if ( ! file_exists( $cache_file ) ) {
			$this->debug( 
				"Cache doesn't contain: $url (cache file: $cache_file)"
			);
			return 0;
		}
		
		$fp = @fopen($cache_file, 'r');
		if ( ! $fp ) {
			$this->error(
				"Failed to open cache file for reading: $cache_file"
			);
			return 0;
		}
		
		$data = fread( $fp, filesize($cache_file) );
		$rss = $this->unserialize( $data );
		
		return $rss;
	}

/*=======================================================================*\
	Function:	check_cache
	Purpose:	check a url for membership in the cache
				and whether the object is older then MAX_AGE (ie. STALE)
	Input:		url from wich the rss file was fetched
	Output:		cached object on HIT, false on MISS	
\*=======================================================================*/		
	function check_cache ( $url ) {
		$this->ERROR = "";
		$filename = $this->file_name( $url );
		
		if ( file_exists( $filename ) ) {
			// find how long ago the file was added to the cache
			// and whether that is longer then MAX_AGE
			$mtime = filemtime( $filename );
			$age = time() - $mtime;
			if ( $this->MAX_AGE > $age ) {
				// object exists and is current
				return 'HIT';
			}
			else {
				// object exists but is old
				return 'STALE';
			}
		}
		else {
			// object does not exist
			return 'MISS';
		}
	}

/*=======================================================================*\
	Function:	serialize
\*=======================================================================*/		
	function serialize ( $rss ) {
		return serialize( $rss );
	}

/*=======================================================================*\
	Function:	unserialize
\*=======================================================================*/		
	function unserialize ( $data ) {
		return unserialize( $data );
	}
	
/*=======================================================================*\
	Function:	file_name
	Purpose:	map url to location in cache
	Input:		url from wich the rss file was fetched
	Output:		a file name
\*=======================================================================*/		
	function file_name ($url) {
		$filename = md5( $url );
		return join( DIRECTORY_SEPARATOR, array( $this->BASE_CACHE, $filename ) );
	}

/*=======================================================================*\
	Function:	error
	Purpose:	register error
\*=======================================================================*/			
	function error ($errormsg, $lvl=E_USER_WARNING) {
		// append PHP's error message if track_errors enabled
		if ( isset($php_errormsg) ) { 
			$errormsg .= " ($php_errormsg)";
		}
		$this->ERROR = $errormsg;
		if ( MAGPIE_DEBUG ) {
			trigger_error( $errormsg, $lvl);
		}
		else {
			error_log( $errormsg, 0);
		}
	}
	
	function debug ($debugmsg, $lvl=E_USER_NOTICE) {
		if ( MAGPIE_DEBUG ) {
			$this->error("MagpieRSS [debug] $debugmsg", $lvl);
		}
	}

}

?>

--- NEW FILE: rss_parse.inc ---
<?php
/*
 * Project:     MagpieRSS: a simple RSS integration tool
 * File:        rss_parse.inc includes code for parsing
 *				RSS, and returning an RSS object
 * Author:      Kellan Elliott-McCrea <kellan at protest.net>
 * Version:		0.51
 * License:		GPL
 *
 * The lastest version of MagpieRSS can be obtained from:
 * http://magpierss.sourceforge.net
 *
 * For questions, help, comments, discussion, etc., please join the
 * Magpie mailing list:
 * magpierss-general at lists.sourceforge.net
 *
 */
 

/* 
 * NOTES ON RSS PARSING PHILOSOPHY (moderately important):
 * MagpieRSS parse all versions of RSS with a few limitation (mod_content, and
 * mod_taxonomy support is shaky) into a simple object, with 2 fields, 
 * the hash 'channel', and the array 'items'.
 *
 * MagpieRSS is a forgiving and inclusive parser.  It currently makes no
 * attempt to enforce the validity on an RSS feed.  It will include any
 * properly formatted tags it finds, allowing to you to mix RSS 0.93, with RSS
 * 1.0, with tags or your own imagining.  This sort of witches brew is a bad
 * bad idea!  But Magpie is less pendantic then I am.
 *
 * RSS validators are readily available on the web at:
 * http://feeds.archive.org/validator/
 * http://www.ldodds.com/rss_validator/1.0/validator.html
 *
 */

/*
 * EXAMPLE PARSE RESULTS:
 *
 * Magpie tries to parse RSS into ease to use PHP datastructures.
 *
 * For example, Magpie on encountering RSS 1.0 item entry:
 *
 * <item rdf:about="http://protest.net/NorthEast/calendrome.cgi?span=event&ID=210257">
 * <title>Weekly Peace Vigil</title>
 * <link>http://protest.net/NorthEast/calendrome.cgi?span=event&ID=210257</link>
 * <description>Wear a white ribbon</description>
 * <dc:subject>Peace</dc:subject>
 * <ev:startdate>2002-06-01T11:00:00</ev:startdate>
 * <ev:location>Northampton, MA</ev:location>
 * <ev:enddate>2002-06-01T12:00:00</ev:enddate>
 * <ev:type>Protest</ev:type>
 * </item>
 * 
 * Would transform it into the following associative array, and push it
 * onto the array $rss-items
 *
 * array(
 *	title => 'Weekly Peace Vigil',
 *	link =>
 *	'http://protest.net/NorthEast/calendrome.cgi?span=event&ID=210257',
 *	description => 'Wear a white ribbon',
 *	dc => array (
 *			subject => 'Peace'
 *		),
 *	ev => array (
 *		startdate => '2002-06-01T11:00:00',
 *		enddate => '2002-06-01T12:00:00',
 *		type => 'Protest',
 *		location => 'Northampton, MA'
 *	)
 * )
 *
 */

class MagpieRSS {
	/*
	 * Hybrid parser, and object.  (probably a bad idea! :)
	 *
	 * Useage Example:
	 *
	 * $some_rss = "<?xml version="1.0"......
	 *
	 * $rss = new MagpieRSS( $some_rss );
	 *
	 * // print rss chanel title
	 * echo $rss->channel['title'];
	 *
	 * // print the title of each item
	 * foreach ($rss->items as $item ) {
	 *	  echo $item[title];
	 * }
	 *
	 * see rss_fetch.inc for a simpler interface
	 */
	 
	var $parser;
	
	var $current_item	= array();	// item currently being parsed
    var $items			= array();	// collection of parsed items
	var $channel		= array();	// hash of channel fields
	var $textinput		= array();
	var $image			= array();
	
	var $parent_field	= array('RDF');
	var $current_field	= '';
	var $current_namespace	= false;
	
	var $ERROR = "";
	
/*======================================================================*\
    Function: MagpieRSS
    Purpose:  Constructor, sets up XML parser,parses source,
			  and populates object.. 
	Input:	  String containing the RSS to be parsed
\*======================================================================*/
	function MagpieRSS ($source) {
		
		# if PHP xml isn't compiled in, die
		#
		if (!function_exists('xml_parser_create')) {
			$this->error( "Failed to load PHP's XML Extension. " . 
						  "http://www.php.net/manual/en/ref.xml.php",
						   E_USER_ERROR );
		}
		
		$parser = @xml_parser_create();
		
		if (!is_resource($parser))
		{
			$this->error( "Failed to create an instance of PHP's XML parser. " .
						  "http://www.php.net/manual/en/ref.xml.php",
						  E_USER_ERROR );
		}

		
		$this->parser = $parser;
		
		# pass in parser, and a reference to this object
		# setup handlers
		#
		xml_set_object( $this->parser, $this );
		xml_set_element_handler($this->parser, 'start_element', 'end_element');
		xml_set_character_data_handler( $this->parser, 'cdata' ); 
	
		
		$status = xml_parse( $this->parser, $source );
		
		if (! $status ) {
			$errorcode = xml_get_error_code( $this->parser );
			if ( $errorcode != XML_ERROR_NONE ) {
				$xml_error = xml_error_string( $errorcode );
				$error_line = xml_get_current_line_number($this->parser);
				$error_col = xml_get_current_column_number($this->parser);
				$errormsg = "$xml_error at line $error_line, column $error_col";

				$this->error( $errormsg );
			}
		}
		
		xml_parser_free( $this->parser );
	}
	
	function start_element ($p, $element, &$attrs) {
		$element 	= strtolower( $element );
				
		# check for a namespace, and split if found
		#
		$namespace	= false;
		if ( strpos( $element, ':' ) ) {
			list($namespace, $element) = split( ':', $element, 2); 
		}
		$this->current_field = $element;
		if ( $namespace and $namespace != 'rdf' ) {
			$this->current_namespace = $namespace;
		}
		
		if ( $element == 'channel' ) {
			array_unshift( $this->parent_field, 'channel' );
		}
		elseif ( $element == 'items' ) {
			array_unshift( $this->parent_field, 'items' );
		}
		elseif ( $element == 'item' ) {
			array_unshift( $this->parent_field, 'item' );
		}
		elseif ( $element == 'textinput' ) {
			array_unshift( $this->parent_field, 'textinput' );
		}
		elseif ( $element == 'image' ) {
			array_unshift( $this->parent_field, 'image' );
		}
		
	}
	
	function end_element ($p, $element) {
		$element = strtolower($element);
							
		if ( $element == 'item' ) {		
			$this->items[] = $this->current_item;
			$this->current_item = array();
			array_shift( $this->parent_field );
		}
		elseif ( $element == 'channel' or $element == 'items' or 
				 $element == 'textinput' or $element == 'image' ) {
			array_shift( $this->parent_field );
		}
		
		$this->current_field = '';
		$this->current_namespace = false;
	}
	
	function cdata ($p, $text) {
		# skip item, channel, items first time we see them
		#
		if ( $this->parent_field[0] == $this->current_field or
			 ! $this->current_field ) {
			return;
		}
		elseif ( $this->parent_field[0] == 'channel') {
			if ( $this->current_namespace ) {
				$this->append(
					$this->channel[ $this->current_namespace ][ $this->current_field ],
					$text);
			}
			else {
				$this->append($this->channel[ $this->current_field ], $text);
			}
		
		}
		elseif ( $this->parent_field[0] == 'item' ) {
			if ( $this->current_namespace ) {
				$this->append(
					$this->current_item[ $this->current_namespace ][$this->current_field ],
					$text);
			}
			else {
				$this->append(
					$this->current_item[ $this->current_field ],
					$text );
			}
		}
		elseif ( $this->parent_field[0] == 'textinput' ) {
			if ( $this->current_namespace ) {
				$this->append(
					$this->textinput[ $this->current_namespace ][ $this->current_field ],
					 $text );
			}
			else {
				$this->append(
					$this->textinput[ $this->current_field ],
					$text );
			}
		}
		elseif ( $this->parent_field[0] == 'image' ) {
			if ( $this->current_namespace ) {
				$this->append(
					$this->image[ $this->current_namespace ][ $this->current_field ],
					$text );
			}
			else {
				$this->append(
					$this->image[ $this->current_field ],
					$text );
			}
		}
	}
	
	function append (&$str1, $str2="") {
		if (!isset($str1) ) {
			$str1="";
		}
		$str1 .= $str2;
	}
	
	function error ($errormsg, $lvl=E_USER_WARNING) {
		// append PHP's error message if track_errors enabled
		if ( $php_errormsg ) { 
			$errormsg .= " ($php_errormsg)";
		}
		$this->ERROR = $errormsg;
		if ( MAGPIE_DEBUG ) {
			trigger_error( $errormsg, $lvl);		
		}
		else {
			error_log( $errormsg, 0);
		}
	}
		

/*======================================================================*\
	EVERYTHING BELOW HERE IS FOR DEBUGGING PURPOSES
\*======================================================================*/
	function show_list () {
		echo "<ol>\n";
		foreach ($this->items as $item) {
			echo "<li>", $this->show_item( $item );
		}
		echo "</ol>";
	}
	
	function show_channel () {
		echo "channel:<br>";
		echo "<ul>";
		while ( list($key, $value) = each( $this->channel ) ) {
			echo "<li> $key: $value";
		}
		echo "</ul>";
	}
	
	function show_item ($item) {
		echo "item: $item[title]";
		echo "<ul>";
		while ( list($key, $value) = each($item) ) {
			if ( is_array($value) ) {
				echo "<br><b>$key</b>";
				echo "<ul>";
				while ( list( $ns_key, $ns_value) = each( $value ) ) {
					echo "<li>$ns_key: $ns_value";
				}
				echo "</ul>";
			}
			else {
				echo "<li> $key: $value";
			}
		}
		echo "</ul>";
	}

/*======================================================================*\
	END DEBUGGING FUNCTIONS	
\*======================================================================*/
	


} # end class RSS
?>

--- NEW FILE: rss_utils.inc ---
<?php
/*
 * Project:     MagpieRSS: a simple RSS integration tool
 * File:        rss_utils.inc, utility methods for working with RSS
 * Author:      Kellan Elliott-McCrea <kellan at protest.net>
 * Version:		0.51
 * License:		GPL
 *
 * The lastest version of MagpieRSS can be obtained from:
 * http://magpierss.sourceforge.net
 *
 * For questions, help, comments, discussion, etc., please join the
 * Magpie mailing list:
 * magpierss-general at lists.sourceforge.net
 */


/*======================================================================*\
    Function: parse_w3cdtf
    Purpose:  parse a W3CDTF date into unix epoch

	NOTE: http://www.w3.org/TR/NOTE-datetime
\*======================================================================*/

function parse_w3cdtf ( $date_str ) {
	
	# regex to match wc3dtf
	$pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/";
	
	if ( preg_match( $pat, $date_str, $match ) ) {
		list( $year, $month, $day, $hours, $minutes, $seconds) = 
			array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[6]);
		
		# calc epoch for current date assuming GMT
		$epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year);
		
		$offset = 0;
		if ( $match[10] == 'Z' ) {
			# zulu time, aka GMT
		}
		else {
			list( $tz_mod, $tz_hour, $tz_min ) =
				array( $match[8], $match[9], $match[10]);
			
			# zero out the variables
			if ( ! $tz_hour ) { $tz_hour = 0; }
			if ( ! $tz_min ) { $tz_min = 0; }
		
			$offset_secs = (($tz_hour*60)+$tz_min)*60;
			
			# is timezone ahead of GMT?  then subtract offset
			#
			if ( $tz_mod == '+' ) {
				$offset_secs = $offset_secs * -1;
			}
			
			$offset = $offset_secs;	
		}
		$epoch = $epoch + $offset;
		return $epoch;
	}
	else {
		return -1;
	}
}

?>

--- NEW FILE: rss_fetch.inc ---
<?php
/*
 * Project:     MagpieRSS: a simple RSS integration tool
 * File:        rss_fetch.inc, a simple functional interface
 				to fetching and parsing RSS files, via the
				function fetch_rss()
 * Author:      Kellan Elliott-McCrea <kellan at protest.net>
 * Version:		0.51
 * License:		GPL
 *
 * The lastest version of MagpieRSS can be obtained from:
 * http://magpierss.sourceforge.net
 *
 * For questions, help, comments, discussion, etc., please join the
 * Magpie mailing list:
 * magpierss-general at lists.sourceforge.net
 *
 */
 
// Setup MAGPIE_DIR for use on hosts that don't include
// the current path in include_path.
// with thanks to rajiv and smarty
if (!defined('DIR_SEP')) {
	define('DIR_SEP', DIRECTORY_SEPARATOR);
}

if (!defined('MAGPIE_DIR')) {
    define('MAGPIE_DIR', dirname(__FILE__) . DIR_SEP);
}

require_once( MAGPIE_DIR . 'rss_parse.inc' );
require_once( MAGPIE_DIR . 'rss_cache.inc' );

// for including 3rd party libraries
define('MAGPIE_EXTLIB', MAGPIE_DIR . 'extlib' . DIR_SEP);
require_once( MAGPIE_EXTLIB . 'Snoopy.class.inc');


/* 
 * CONSTANTS - redefine these in your script to change the
 * behaviour of fetch_rss() currently, most options effect the cache
 *
 * MAGPIE_CACHE_ON - Should Magpie cache parsed RSS objects? 
 * For me a built in cache was essential to creating a "PHP-like" 
 * feel to Magpie, see rss_cache.inc for rationale
 *
 *
 * MAGPIE_CACHE_DIR - Where should Magpie cache parsed RSS objects?
 * This should be a location that the webserver can write to.   If this 
 * directory does not already exist Mapie will try to be smart and create 
 * it.  This will often fail for permissions reasons.
 *
 *
 * MAGPIE_CACHE_AGE - How long to store cached RSS objects? In seconds.
 *
 *
 * MAGPIE_CACHE_FRESH_ONLY - If remote fetch fails, throw error
 * instead of returning stale object?
 *
 * MAGPIE_DEBUG - Display debugging notices?
 *
*/


/*=======================================================================*\
	Function: fetch_rss: 
	Purpose:  return RSS object for the give url
			  maintain the cache
	Input:	  url of RSS file
	Output:	  parsed RSS object (see rss_parse.inc)

	NOTES ON CACHEING:  
	If caching is on (MAGPIE_CACHE_ON) fetch_rss will first check the cache.
	
	NOTES ON RETRIEVING REMOTE FILES:
	If conditional gets are on (MAGPIE_CONDITIONAL_GET_ON) fetch_rss will
	return a cached object, and touch the cache object upon recieving a
	304.
	
	NOTES ON FAILED REQUESTS:
	If there is an HTTP error while fetching an RSS object, the cached
	version will be return, if it exists (and if MAGPIE_CACHE_FRESH_ONLY is off)
\*=======================================================================*/

define('MAGPIE_VERSION', '0.51');

$MAGPIE_ERROR = "";

function fetch_rss ($url) {
	// initialize constants
	init();
	
	if ( !isset($url) ) {
		error("fetch_rss called without a url");
		return false;
	}
	
	// if cache is disabled
	if ( !MAGPIE_CACHE_ON ) {
		// fetch file, and parse it
		$resp = _fetch_remote_file( $url );
		if ( is_success( $resp->status ) ) {
			return _response_to_rss( $resp );
		}
		else {
			error("Failed to fetch $url and cache is off");
			return false;
		}
	} 
	// else cache is ON
	else {
		// Flow
		// 1. check cache
		// 2. if there is a hit, make sure its fresh
		// 3. if cached obj fails freshness check, fetch remote
		// 4. if remote fails, return stale object, or error
		
		$cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
		
		if (MAGPIE_DEBUG and $cache->ERROR) {
			debug($cache->ERROR, E_USER_WARNING);
		}
		
		
		$cache_status 	 = 0;		// response of check_cache
		$request_headers = array(); // HTTP headers to send with fetch
		$rss 			 = 0;		// parsed RSS object
		$errormsg		 = 0;		// errors, if any
		
		if (!$cache->ERROR) {
			// return cache HIT, MISS, or STALE
			$cache_status = $cache->check_cache( $url );
		}
		
		// if object cached, and cache is fresh, return cached obj
		if ( $cache_status == 'HIT' ) {
			$rss = $cache->get( $url );
			if ( isset($rss) and $rss ) {
				$rss->from_cache = 1;
				if ( MAGPIE_DEBUG > 1) {
				debug("MagpieRSS: Cache HIT", E_USER_NOTICE);
			}
				return $rss;
			}
		}
		
		// else attempt a conditional get
		
		// setup headers
		if ( $cache_status == 'STALE' ) {
			$rss = $cache->get( $url );
			if ( $rss->etag and $rss->last_modified ) {
				$request_headers['If-None-Match'] = $rss->etag;
				$request_headers['If-Last-Modified'] = $rss->last_modified;
			}
		}
		
		$resp = _fetch_remote_file( $url, $request_headers );
		
		if (isset($resp) and $resp) {
			if ($resp->status == '304' ) {
				// we have the most current copy
				if ( MAGPIE_DEBUG > 1) {
					debug("Got 304 for $url");
				}
				// reset cache on 304 (at minutillo insistent prodding)
				$cache->set($url, $rss);
				return $rss;
			}
			elseif ( is_success( $resp->status ) ) {
				$rss = _response_to_rss( $resp );
				if ( $rss ) {
					if (MAGPIE_DEBUG > 1) {
						debug("Fetch successful");
					}
					// add object to cache
					$cache->set( $url, $rss );
					return $rss;
				}
			}
			else {
				$errormsg = "Failed to fetch $url. ";
				if ( $resp->error ) {
					# compensate for Snoopy's annoying habbit to tacking
					# on '\n'
					$http_error = substr($resp->error, 0, -2); 
					$errormsg .= "(HTTP Error: $http_error)";
				}
				else {
					$errormsg .=  "(HTTP Response: " . $resp->response_code .')';
				}
			}
		}
		else {
			$errormsg = "Unable to retrieve RSS file for unknown reasons.";
		}
		
		// else fetch failed
		
		// attempt to return cached object
		if ($rss) {
			if ( MAGPIE_DEBUG ) {
				debug("Returning STALE object for $url");
			}
			return $rss;
		}
		
		// else we totally failed
		error( $errormsg );	
		
		return false;
		
	} // end if ( !MAGPIE_CACHE_ON ) {
} // end fetch_rss()

/*=======================================================================*\
	Function:	error
	Purpose:	set MAGPIE_ERROR, and trigger error
\*=======================================================================*/

function error ($errormsg, $lvl=E_USER_WARNING) {
		global $MAGPIE_ERROR;
		
		// append PHP's error message if track_errors enabled
		if ( isset($php_errormsg) ) { 
			$errormsg .= " ($php_errormsg)";
		}
		if ( $errormsg ) {
			$errormsg = "MagpieRSS: $errormsg";
			$MAGPIE_ERROR = $errormsg;
			trigger_error( $errormsg, $lvl);				
		}
}

function debug ($debugmsg, $lvl=E_USER_NOTICE) {
	trigger_error("MagpieRSS [debug] $debugmsg", $lvl);
}
			
/*=======================================================================*\
	Function:	magpie_error
	Purpose:	accessor for the magpie error variable
\*=======================================================================*/
function magpie_error ($errormsg="") {
	global $MAGPIE_ERROR;
	
	if ( isset($errormsg) and $errormsg ) { 
		$MAGPIE_ERROR = $errormsg;
	}
	
	return $MAGPIE_ERROR;	
}

/*=======================================================================*\
	Function:	_fetch_remote_file
	Purpose:	retrieve an arbitrary remote file
	Input:		url of the remote file
				headers to send along with the request (optional)
	Output:		an HTTP response object (see Snoopy.class.inc)	
\*=======================================================================*/
function _fetch_remote_file ($url, $headers = "" ) {
	// Snoopy is an HTTP client in PHP
	$client = new Snoopy();
	$client->agent = MAGPIE_USER_AGENT;
	$client->read_timeout = MAGPIE_FETCH_TIME_OUT;
	$client->use_gzip = MAGPIE_USE_GZIP;
	if (is_array($headers) ) {
		$client->rawheaders = $headers;
	}
	
	@$client->fetch($url);
	return $client;

}

/*=======================================================================*\
	Function:	_response_to_rss
	Purpose:	parse an HTTP response object into an RSS object
	Input:		an HTTP response object (see Snoopy)
	Output:		parsed RSS object (see rss_parse)
\*=======================================================================*/
function _response_to_rss ($resp) {
	$rss = new MagpieRSS( $resp->results );
	
	// if RSS parsed successfully		
	if ( $rss and !$rss->ERROR) {
		
		// find Etag, and Last-Modified
		foreach($resp->headers as $h) {
			// 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1"
			if (strpos($h, ": ")) {
				list($field, $val) = explode(": ", $h, 2);
			}
			else {
				$field = $h;
				$val = "";
			}
			
			if ( $field == 'ETag' ) {
				$rss->etag = $val;
			}
			
			if ( $field == 'Last-Modified' ) {
				$rss->last_modified = $val;
			}
		}
		
		return $rss;	
	} // else construct error message
	else {
		$errormsg = "Failed to parse RSS file.";
		
		if ($rss) {
			$errormsg .= " (" . $rss->ERROR . ")";
		}
		error($errormsg);
		
		return false;
	} // end if ($rss and !$rss->error)
}

/*=======================================================================*\
	Function:	init
	Purpose:	setup constants with default values
				check for user overrides
\*=======================================================================*/
function init () {
	if ( defined('MAGPIE_INITALIZED') ) {
		return;
	}
	else {
		define('MAGPIE_INITALIZED', 1);
	}
	
	if ( !defined('MAGPIE_CACHE_ON') ) {
		define('MAGPIE_CACHE_ON', 0);
	}

	if ( !defined('MAGPIE_CACHE_DIR') ) {
		define('MAGPIE_CACHE_DIR', './cache');
	}

	if ( !defined('MAGPIE_CACHE_AGE') ) {
		define('MAGPIE_CACHE_AGE', 60*60); // one hour
	}

	if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) {
		define('MAGPIE_CACHE_FRESH_ONLY', 0);
	}

	if ( !defined('MAGPIE_DEBUG') ) {
		define('MAGPIE_DEBUG', 0);
	}
	
	if ( !defined('MAGPIE_USER_AGENT') ) {
		$ua = 'MagpieRSS/'. MAGPIE_VERSION . ' (+http://magpierss.sf.net';
		
		if ( MAGPIE_CACHE_ON ) {
			$ua = $ua . ')';
		}
		else {
			$ua = $ua . '; No cache)';
		}
		
		define('MAGPIE_USER_AGENT', $ua);
	}
	
	if ( !defined('MAGPIE_FETCH_TIME_OUT') ) {
		define('MAGPIE_FETCH_TIME_OUT', 5);	// 5 second timeout
	}
	
	// use gzip encoding to fetch rss files if supported?
	if ( !defined('MAGPIE_USE_GZIP') ) {
		define('MAGPIE_USE_GZIP', true);	
	}
}

// NOTE: the following code should really be in Snoopy, or at least
// somewhere other then rss_fetch!

/*=======================================================================*\
	HTTP STATUS CODE PREDICATES
	These functions attempt to classify an HTTP status code
	based on RFC 2616 and RFC 2518.
	
	All of them take an HTTP status code as input, and return true or false

	All this code is adapted from LWP's HTTP::Status.
\*=======================================================================*/


/*=======================================================================*\
	Function:	is_info
	Purpose:	return true if Informational status code
\*=======================================================================*/
function is_info ($sc) { 
	return $sc >= 100 && $sc < 200; 
}

/*=======================================================================*\
	Function:	is_success
	Purpose:	return true if Successful status code
\*=======================================================================*/
function is_success ($sc) { 
	return $sc >= 200 && $sc < 300; 
}

/*=======================================================================*\
	Function:	is_redirect
	Purpose:	return true if Redirection status code
\*=======================================================================*/
function is_redirect ($sc) { 
	return $sc >= 300 && $sc < 400; 
}

/*=======================================================================*\
	Function:	is_error
	Purpose:	return true if Error status code
\*=======================================================================*/
function is_error ($sc) { 
	return $sc >= 400 && $sc < 600; 
}

/*=======================================================================*\
	Function:	is_client_error
	Purpose:	return true if Error status code, and its a client error
\*=======================================================================*/
function is_client_error ($sc) { 
	return $sc >= 400 && $sc < 500; 
}

/*=======================================================================*\
	Function:	is_client_error
	Purpose:	return true if Error status code, and its a server error
\*=======================================================================*/
function is_server_error ($sc) { 
	return $sc >= 500 && $sc < 600; 
}

?>




More information about the geeklog-cvs mailing list