Changeset 52

Show
Ignore:
Timestamp:
11/08/05 10:25:54 (3 years ago)
Author:
alexx
Message:

Upgrade Magpierss to version 0.72 because : http://www.frsirt.com/bulletins/2591
Used by robots/fetch_rss.bot.php

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/includes/rss/rss_cache.inc.php

    r1 r52  
    33 * Project:     MagpieRSS: a simple RSS integration tool 
    44 * File:        rss_cache.inc, a simple, rolling(no GC), cache  
    5  *                             for RSS objects, keyed on URL. 
     5 *              for RSS objects, keyed on URL. 
    66 * Author:      Kellan Elliott-McCrea <kellan@protest.net> 
    7  * Version:            0.51 
    8  * License:            GPL 
     7 * Version:     0.51 
     8 * License:     GPL 
    99 * 
    1010 * The lastest version of MagpieRSS can be obtained from: 
     
    1818 
    1919class RSSCache { 
    20         var $BASE_CACHE = './cache';    // where the cache files are stored 
    21         var $MAX_AGE    = 3600;                 // when are files stale, default one hour 
    22         var $ERROR              = "";                   // accumulate error messages 
    23          
    24         function RSSCache ($base='', $age='') { 
    25                 if ( $base ) { 
    26                         $this->BASE_CACHE = $base; 
     20    var $BASE_CACHE = './cache';    // where the cache files are stored 
     21    var $MAX_AGE    = 3600;         // when are files stale, default one hour 
     22    var $ERROR      = "";           // accumulate error messages 
     23     
     24    function RSSCache ($base='', $age='') { 
     25        if ( $base ) { 
     26            $this->BASE_CACHE = $base; 
     27        } 
     28        if ( $age ) { 
     29            $this->MAX_AGE = $age; 
     30        } 
     31         
     32        // attempt to make the cache directory 
     33        if ( ! file_exists( $this->BASE_CACHE ) ) { 
     34            $status = @mkdir( $this->BASE_CACHE, 0755 ); 
     35             
     36            // if make failed  
     37            if ( ! $status ) { 
     38                $this->error( 
     39                    "Cache couldn't make dir '" . $this->BASE_CACHE . "'." 
     40                ); 
     41            } 
     42        } 
     43    } 
     44     
     45/*=======================================================================*\ 
     46    Function:   set 
     47    Purpose:    add an item to the cache, keyed on url 
     48    Input:      url from wich the rss file was fetched 
     49    Output:     true on sucess   
     50\*=======================================================================*/ 
     51    function set ($url, $rss) { 
     52        $this->ERROR = ""; 
     53        $cache_file = $this->file_name( $url ); 
     54        $fp = @fopen( $cache_file, 'w' ); 
     55         
     56        if ( ! $fp ) { 
     57            $this->error( 
     58                "Cache unable to open file for writing: $cache_file" 
     59            ); 
     60            return 0; 
     61        } 
     62         
     63         
     64        $data = $this->serialize( $rss ); 
     65        fwrite( $fp, $data ); 
     66        fclose( $fp ); 
     67         
     68        return $cache_file; 
     69    } 
     70     
     71/*=======================================================================*\ 
     72    Function:   get 
     73    Purpose:    fetch an item from the cache 
     74    Input:      url from wich the rss file was fetched 
     75    Output:     cached object on HIT, false on MISS  
     76\*=======================================================================*/  
     77    function get ($url) { 
     78        $this->ERROR = ""; 
     79        $cache_file = $this->file_name( $url ); 
     80         
     81        if ( ! file_exists( $cache_file ) ) { 
     82            $this->debug(  
     83                "Cache doesn't contain: $url (cache file: $cache_file)" 
     84            ); 
     85            return 0; 
     86        } 
     87         
     88        $fp = @fopen($cache_file, 'r'); 
     89        if ( ! $fp ) { 
     90            $this->error( 
     91                "Failed to open cache file for reading: $cache_file" 
     92            ); 
     93            return 0; 
     94        } 
     95         
     96        if ($filesize = filesize($cache_file) ) { 
     97                $data = fread( $fp, filesize($cache_file) ); 
     98                $rss = $this->unserialize( $data ); 
     99         
     100                return $rss; 
     101        } 
     102         
     103        return 0; 
     104    } 
     105 
     106/*=======================================================================*\ 
     107    Function:   check_cache 
     108    Purpose:    check a url for membership in the cache 
     109                and whether the object is older then MAX_AGE (ie. STALE) 
     110    Input:      url from wich the rss file was fetched 
     111    Output:     cached object on HIT, false on MISS  
     112\*=======================================================================*/      
     113    function check_cache ( $url ) { 
     114        $this->ERROR = ""; 
     115        $filename = $this->file_name( $url ); 
     116         
     117        if ( file_exists( $filename ) ) { 
     118            // find how long ago the file was added to the cache 
     119            // and whether that is longer then MAX_AGE 
     120            $mtime = filemtime( $filename ); 
     121            $age = time() - $mtime; 
     122            if ( $this->MAX_AGE > $age ) { 
     123                // object exists and is current 
     124                return 'HIT'; 
     125            } 
     126            else { 
     127                // object exists but is old 
     128                return 'STALE'; 
     129            } 
     130        } 
     131        else { 
     132            // object does not exist 
     133            return 'MISS'; 
     134        } 
     135    } 
     136 
     137        function cache_age( $cache_key ) { 
     138                $filename = $this->file_name( $url ); 
     139                if ( file_exists( $filename ) ) { 
     140                        $mtime = filemtime( $filename ); 
     141            $age = time() - $mtime; 
     142                        return $age; 
    27143                } 
    28                 if ( $age ) { 
    29                         $this->MAX_AGE = $age; 
    30                 } 
    31                  
    32                 // attempt to make the cache directory 
    33                 if ( ! file_exists( $this->BASE_CACHE ) ) { 
    34                         $status = @mkdir( $this->BASE_CACHE, 0755 ); 
    35                          
    36                         // if make failed  
    37                         if ( ! $status ) { 
    38                                 $this->error( 
    39                                         "Cache couldn't make dir '" . $this->BASE_CACHE . "'." 
    40                                 ); 
    41                         } 
     144                else { 
     145                        return -1;       
    42146                } 
    43147        } 
    44148         
    45149/*=======================================================================*\ 
    46         Function:       set 
    47         Purpose:        add an item to the cache, keyed on url 
    48         Input:          url from wich the rss file was fetched 
    49         Output:         true on sucess   
    50 \*=======================================================================*/ 
    51         function set ($url, $rss) { 
    52                 $this->ERROR = ""; 
    53                 $cache_file = $this->file_name( $url ); 
    54                 $fp = @fopen( $cache_file, 'w' ); 
    55                  
    56                 if ( ! $fp ) { 
    57                         $this->error( 
    58                                 "Cache unable to open file for writing: $cache_file" 
    59                         ); 
    60                         return 0; 
    61                 } 
    62                  
    63                  
    64                 $data = $this->serialize( $rss ); 
    65                 fwrite( $fp, $data ); 
    66                 fclose( $fp ); 
    67                  
    68                 return $cache_file; 
    69         } 
    70          
    71 /*=======================================================================*\ 
    72         Function:       get 
    73         Purpose:        fetch an item from the cache 
    74         Input:          url from wich the rss file was fetched 
    75         Output:         cached object on HIT, false on MISS      
    76 \*=======================================================================*/      
    77         function get ($url) { 
    78                 $this->ERROR = ""; 
    79                 $cache_file = $this->file_name( $url ); 
    80                  
    81                 if ( ! file_exists( $cache_file ) ) { 
    82                         $this->debug(  
    83                                 "Cache doesn't contain: $url (cache file: $cache_file)" 
    84                         ); 
    85                         return 0; 
    86                 } 
    87                  
    88                 $fp = @fopen($cache_file, 'r'); 
    89                 if ( ! $fp ) { 
    90                         $this->error( 
    91                                 "Failed to open cache file for reading: $cache_file" 
    92                         ); 
    93                         return 0; 
    94                 } 
    95                  
    96                 $data = fread( $fp, filesize($cache_file) ); 
    97                 $rss = $this->unserialize( $data ); 
    98                  
    99                 return $rss; 
    100         } 
    101  
    102 /*=======================================================================*\ 
    103         Function:       check_cache 
    104         Purpose:        check a url for membership in the cache 
    105                                 and whether the object is older then MAX_AGE (ie. STALE) 
    106         Input:          url from wich the rss file was fetched 
    107         Output:         cached object on HIT, false on MISS      
    108 \*=======================================================================*/              
    109         function check_cache ( $url ) { 
    110                 $this->ERROR = ""; 
    111                 $filename = $this->file_name( $url ); 
    112                  
    113                 if ( file_exists( $filename ) ) { 
    114                         // find how long ago the file was added to the cache 
    115                         // and whether that is longer then MAX_AGE 
    116                         $mtime = filemtime( $filename ); 
    117                         $age = time() - $mtime; 
    118                         if ( $this->MAX_AGE > $age ) { 
    119                                 // object exists and is current 
    120                                 return 'HIT'; 
    121                         } 
    122                         else { 
    123                                 // object exists but is old 
    124                                 return 'STALE'; 
    125                         } 
    126                 } 
    127                 else { 
    128                         // object does not exist 
    129                         return 'MISS'; 
    130                 } 
    131         } 
    132  
    133 /*=======================================================================*\ 
    134         Function:       serialize 
    135 \*=======================================================================*/              
    136         function serialize ( $rss ) { 
    137                 return serialize( $rss ); 
    138         } 
    139  
    140 /*=======================================================================*\ 
    141         Function:       unserialize 
    142 \*=======================================================================*/              
    143         function unserialize ( $data ) { 
    144                 return unserialize( $data ); 
    145         } 
    146          
    147 /*=======================================================================*\ 
    148         Function:       file_name 
    149         Purpose:        map url to location in cache 
    150         Input:          url from wich the rss file was fetched 
    151         Output:         a file name 
    152 \*=======================================================================*/              
    153         function file_name ($url) { 
    154                 $filename = md5( $url ); 
    155                 return join( DIRECTORY_SEPARATOR, array( $this->BASE_CACHE, $filename ) ); 
    156         } 
    157  
    158 /*=======================================================================*\ 
    159         Function:       error 
    160         Purpose:        register error 
    161 \*=======================================================================*/                      
    162         function error ($errormsg, $lvl=E_USER_WARNING) { 
    163                 // append PHP's error message if track_errors enabled 
    164                 if ( isset($php_errormsg) ) {  
    165                         $errormsg .= " ($php_errormsg)"; 
    166                 } 
    167                 $this->ERROR = $errormsg; 
    168                 if ( MAGPIE_DEBUG ) { 
    169                         trigger_error( $errormsg, $lvl); 
    170                 } 
    171                 else { 
    172                         error_log( $errormsg, 0); 
    173                 } 
    174         } 
    175          
    176         function debug ($debugmsg, $lvl=E_USER_NOTICE) { 
    177                 if ( MAGPIE_DEBUG ) { 
    178                         $this->error("MagpieRSS [debug] $debugmsg", $lvl); 
    179                 } 
    180         } 
     150    Function:   serialize 
     151\*=======================================================================*/      
     152    function serialize ( $rss ) { 
     153        return serialize( $rss ); 
     154    } 
     155 
     156/*=======================================================================*\ 
     157    Function:   unserialize 
     158\*=======================================================================*/      
     159    function unserialize ( $data ) { 
     160        return unserialize( $data ); 
     161    } 
     162     
     163/*=======================================================================*\ 
     164    Function:   file_name 
     165    Purpose:    map url to location in cache 
     166    Input:      url from wich the rss file was fetched 
     167    Output:     a file name 
     168\*=======================================================================*/      
     169    function file_name ($url) { 
     170        $filename = md5( $url ); 
     171        return join( DIRECTORY_SEPARATOR, array( $this->BASE_CACHE, $filename ) ); 
     172    } 
     173 
     174/*=======================================================================*\ 
     175    Function:   error 
     176    Purpose:    register error 
     177\*=======================================================================*/          
     178    function error ($errormsg, $lvl=E_USER_WARNING) { 
     179        // append PHP's error message if track_errors enabled 
     180        if ( isset($php_errormsg) ) {  
     181            $errormsg .= " ($php_errormsg)"; 
     182        } 
     183        $this->ERROR = $errormsg; 
     184        if ( MAGPIE_DEBUG ) { 
     185            trigger_error( $errormsg, $lvl); 
     186        } 
     187        else { 
     188            error_log( $errormsg, 0); 
     189        } 
     190    } 
     191     
     192    function debug ($debugmsg, $lvl=E_USER_NOTICE) { 
     193        if ( MAGPIE_DEBUG ) { 
     194            $this->error("MagpieRSS [debug] $debugmsg", $lvl); 
     195        } 
     196    } 
    181197 
    182198} 
  • trunk/includes/rss/rss_fetch.inc.php

    r1 r52  
    33 * Project:     MagpieRSS: a simple RSS integration tool 
    44 * File:        rss_fetch.inc, a simple functional interface 
    5                                to fetching and parsing RSS files, via the 
    6                                function fetch_rss() 
     5                to fetching and parsing RSS files, via the 
     6                function fetch_rss() 
    77 * Author:      Kellan Elliott-McCrea <kellan@protest.net> 
    8  * License:            GPL 
     8 * License:     GPL 
    99 * 
    1010 * The lastest version of MagpieRSS can be obtained from: 
     
    2121// with thanks to rajiv and smarty 
    2222if (!defined('DIR_SEP')) { 
    23        define('DIR_SEP', DIRECTORY_SEPARATOR); 
     23    define('DIR_SEP', DIRECTORY_SEPARATOR); 
    2424} 
    2525 
     
    3232 
    3333// for including 3rd party libraries 
    34 define('MAGPIE_EXTLIB', MAGPIE_DIR . 'net' . DIR_SEP); 
     34define('MAGPIE_EXTLIB', MAGPIE_DIR . 'extlib' . DIR_SEP); 
    3535require_once( MAGPIE_EXTLIB . 'Snoopy.class.inc.php'); 
    3636 
     
    6262 
    6363 
    64  
    65 /*=======================================================================*\ 
    66         Function: fetch_rss:  
    67         Purpose:  return RSS object for the give url 
    68                           maintain the cache 
    69         Input:    url of RSS file 
    70         Output:   parsed RSS object (see rss_parse.inc) 
    71  
    72         NOTES ON CACHEING:   
    73         If caching is on (MAGPIE_CACHE_ON) fetch_rss will first check the cache. 
    74          
    75         NOTES ON RETRIEVING REMOTE FILES: 
    76         If conditional gets are on (MAGPIE_CONDITIONAL_GET_ON) fetch_rss will 
    77         return a cached object, and touch the cache object upon recieving a 
    78         304. 
    79          
    80         NOTES ON FAILED REQUESTS: 
    81         If there is an HTTP error while fetching an RSS object, the cached 
    82         version will be return, if it exists (and if MAGPIE_CACHE_FRESH_ONLY is off) 
    83 \*=======================================================================*/ 
    84  
    85 define('MAGPIE_VERSION', '0.61'); 
    86 define('MAGPIE_CACHE_ON','0'); 
     64/*=======================================================================*\ 
     65    Function: fetch_rss:  
     66    Purpose:  return RSS object for the give url 
     67              maintain the cache 
     68    Input:    url of RSS file 
     69    Output:   parsed RSS object (see rss_parse.inc) 
     70 
     71    NOTES ON CACHEING:   
     72    If caching is on (MAGPIE_CACHE_ON) fetch_rss will first check the cache. 
     73     
     74    NOTES ON RETRIEVING REMOTE FILES: 
     75    If conditional gets are on (MAGPIE_CONDITIONAL_GET_ON) fetch_rss will 
     76    return a cached object, and touch the cache object upon recieving a 
     77    304. 
     78     
     79    NOTES ON FAILED REQUESTS: 
     80    If there is an HTTP error while fetching an RSS object, the cached 
     81    version will be return, if it exists (and if MAGPIE_CACHE_FRESH_ONLY is off) 
     82\*=======================================================================*/ 
     83 
     84define('MAGPIE_VERSION', '0.72'); 
     85 
    8786$MAGPIE_ERROR = ""; 
    8887 
    8988function fetch_rss ($url) { 
    90         // initialize constants 
    91         init(); 
    92          
    93         if ( !isset($url) ) { 
    94                 error("fetch_rss called without a url"); 
    95                 return false; 
    96         } 
    97         // if cache is disabled 
    98         if ( !MAGPIE_CACHE_ON ) { 
    99                 // fetch file, and parse it 
    100                 $resp = _fetch_remote_file( $url ); 
    101                 if ( is_success( $resp->status ) ) { 
    102                         return _response_to_rss( $resp ); 
    103                 } 
    104                 else { 
    105                         error("Failed to fetch $url and cache is off"); 
    106                         return false; 
    107                 } 
    108         }  
    109         // else cache is ON 
    110         else { 
    111                 // Flow 
    112                 // 1. check cache 
    113                 // 2. if there is a hit, make sure its fresh 
    114                 // 3. if cached obj fails freshness check, fetch remote 
    115                 // 4. if remote fails, return stale object, or error 
    116                  
    117                 $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE ); 
    118                  
    119                 if (MAGPIE_DEBUG and $cache->ERROR) { 
    120                         debug($cache->ERROR, E_USER_WARNING); 
    121                 } 
    122                  
    123                  
    124                 $cache_status    = 0;           // response of check_cache 
    125                 $request_headers = array(); // HTTP headers to send with fetch 
    126                 $rss                     = 0;           // parsed RSS object 
    127                 $errormsg                = 0;           // errors, if any 
    128                  
    129                 if (!$cache->ERROR) { 
    130                         // return cache HIT, MISS, or STALE 
    131                         $cache_status = $cache->check_cache( $url ); 
    132                 } 
    133                  
    134                 // if object cached, and cache is fresh, return cached obj 
    135                 if ( $cache_status == 'HIT' ) { 
    136                         $rss = $cache->get( $url ); 
    137                         if ( isset($rss) and $rss ) { 
    138                                 $rss->from_cache = 1; 
    139                                 if ( MAGPIE_DEBUG > 1) { 
    140                                 debug("MagpieRSS: Cache HIT", E_USER_NOTICE); 
    141                         } 
    142                                 return $rss; 
    143                         } 
    144                 } 
    145                  
    146                 // else attempt a conditional get 
    147                  
    148                 // setup headers 
    149                 if ( $cache_status == 'STALE' ) { 
    150                         $rss = $cache->get( $url ); 
    151                         if ( $rss->etag and $rss->last_modified ) { 
    152                                 $request_headers['If-None-Match'] = $rss->etag; 
    153                                 $request_headers['If-Last-Modified'] = $rss->last_modified; 
    154                         } 
    155                 } 
    156                  
    157                 $resp = _fetch_remote_file( $url, $request_headers ); 
    158                 if (isset($resp) and $resp) { 
    159                         if ($resp->status == '304' ) { 
    160                                 // we have the most current copy 
    161                                 if ( MAGPIE_DEBUG > 1) { 
    162                                         debug("Got 304 for $url"); 
    163                                 } 
    164                                 // reset cache on 304 (at minutillo insistent prodding) 
    165                                 $cache->set($url, $rss); 
    166                                 return $rss; 
    167                         } 
    168                         elseif ( is_success( $resp->status ) ) { 
    169                                 $rss = _response_to_rss( $resp ); 
    170                                 if ( $rss ) { 
    171                                         if (MAGPIE_DEBUG > 1) { 
    172                                                 debug("Fetch successful"); 
    173                                         } 
    174                                         // add object to cache 
    175                                         $cache->set( $url, $rss ); 
    176                                         return $rss; 
    177                                 } 
    178                         } 
    179                         else { 
    180                                 print $resp->status; 
    181                                 $errormsg = "Failed to fetch $url. "; 
    182                                 if ( $resp->error ) { 
    183                                         # compensate for Snoopy's annoying habbit to tacking 
    184                                         # on '\n' 
    185                                         $http_error = substr($resp->error, 0, -2);  
    186                                         $errormsg .= "(HTTP Error: $http_error)"; 
    187                                 } 
    188                                 else { 
    189                                         $errormsg .=  "(HTTP Response: " . $resp->response_code .')'; 
    190                                 } 
    191                         } 
    192                 } 
    193                 else { 
    194                         $errormsg = "Unable to retrieve RSS file for unknown reasons."; 
    195                 } 
    196                  
    197                 // else fetch failed 
    198                  
    199                 // attempt to return cached object 
    200                 if ($rss) { 
    201                         if ( MAGPIE_DEBUG ) { 
    202                                 debug("Returning STALE object for $url"); 
    203                         } 
    204                         return $rss; 
    205                 } 
    206                  
    207                 // else we totally failed 
    208                 error( $errormsg );      
    209                  
    210                 return false; 
    211                  
    212         } // end if ( !MAGPIE_CACHE_ON ) { 
     89    // initialize constants 
     90    init(); 
     91     
     92    if ( !isset($url) ) { 
     93        error("fetch_rss called without a url"); 
     94        return false; 
     95    } 
     96     
     97    // if cache is disabled 
     98    if ( !MAGPIE_CACHE_ON ) { 
     99        // fetch file, and parse it 
     100        $resp = _fetch_remote_file( $url ); 
     101        if ( is_success( $resp->status ) ) { 
     102            return _response_to_rss( $resp ); 
     103        } 
     104        else { 
     105            error("Failed to fetch $url and cache is off"); 
     106            return false; 
     107        } 
     108    }  
     109    // else cache is ON 
     110    else { 
     111        // Flow 
     112        // 1. check cache 
     113        // 2. if there is a hit, make sure its fresh 
     114        // 3. if cached obj fails freshness check, fetch remote 
     115        // 4. if remote fails, return stale object, or error 
     116         
     117        $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE ); 
     118         
     119        if (MAGPIE_DEBUG and $cache->ERROR) { 
     120            debug($cache->ERROR, E_USER_WARNING); 
     121        } 
     122         
     123         
     124        $cache_status    = 0;       // response of check_cache 
     125        $request_headers = array(); // HTTP headers to send with fetch 
     126        $rss             = 0;       // parsed RSS object 
     127        $errormsg        = 0;       // errors, if any 
     128         
     129        // store parsed XML by desired output encoding 
     130        // as character munging happens at parse time 
     131        $cache_key       = $url . MAGPIE_OUTPUT_ENCODING; 
     132         
     133        if (!$cache->ERROR) { 
     134            // return cache HIT, MISS, or STALE 
     135            $cache_status = $cache->check_cache( $cache_key); 
     136        } 
     137                 
     138        // if object cached, and cache is fresh, return cached obj 
     139        if ( $cache_status == 'HIT' ) { 
     140            $rss = $cache->get( $cache_key ); 
     141            if ( isset($rss) and $rss ) { 
     142                // should be cache age 
     143                $rss->from_cache = 1; 
     144                if ( MAGPIE_DEBUG > 1) { 
     145                    debug("MagpieRSS: Cache HIT", E_USER_NOTICE); 
     146                } 
     147                return $rss; 
     148            } 
     149        } 
     150         
     151        // else attempt a conditional get 
     152         
     153        // setup headers 
     154        if ( $cache_status == 'STALE' ) { 
     155            $rss = $cache->get( $cache_key ); 
     156            if ( $rss and $rss->etag and $rss->last_modified ) { 
     157                $request_headers['If-None-Match'] = $rss->etag; 
     158                $request_headers['If-Last-Modified'] = $rss->last_modified; 
     159            } 
     160        } 
     161         
     162        $resp = _fetch_remote_file( $url, $request_headers ); 
     163         
     164        if (isset($resp) and $resp) { 
     165          if ($resp->status == '304' ) { 
     166                // we have the most current copy 
     167                if ( MAGPIE_DEBUG > 1) { 
     168                    debug("Got 304 for $url"); 
     169                } 
     170                // reset cache on 304 (at minutillo insistent prodding) 
     171                $cache->set($cache_key, $rss); 
     172                return $rss; 
     173            } 
     174            elseif ( is_success( $resp->status ) ) { 
     175                $rss = _response_to_rss( $resp ); 
     176                if ( $rss ) { 
     177                    if (MAGPIE_DEBUG > 1) { 
     178                        debug("Fetch successful"); 
     179                    } 
     180                    // add object to cache 
     181                    $cache->set( $cache_key, $rss ); 
     182                    return $rss; 
     183                } 
     184            } 
     185            else { 
     186                $errormsg = "Failed to fetch $url "; 
     187                if ( $resp->status == '-100' ) { 
     188                    $errormsg .= "(Request timed out after " . MAGPIE_FETCH_TIME_OUT . " seconds)"; 
     189                } 
     190                elseif ( $resp->error ) { 
     191                    # compensate for Snoopy's annoying habbit to tacking 
     192                    # on '\n' 
     193                    $http_error = substr($resp->error, 0, -2);  
     194                    $errormsg .= "(HTTP Error: $http_error)"; 
     195                } 
     196                else { 
     197                    $errormsg .=  "(HTTP Response: " . $resp->response_code .')'; 
     198                } 
     199            } 
     200        } 
     201        else { 
     202            $errormsg = "Unable to retrieve RSS file for unknown reasons."; 
     203        } 
     204         
     205        // else fetch failed 
     206         
     207        // attempt to return cached object 
     208        if ($rss) { 
     209            if ( MAGPIE_DEBUG ) { 
     210                debug("Returning STALE object for $url"); 
     211            } 
     212            return $rss; 
     213        } 
     214         
     215        // else we totally failed 
     216        error( $errormsg );  
     217         
     218        return false; 
     219         
     220    } // end if ( !MAGPIE_CACHE_ON ) { 
    213221} // end fetch_rss() 
    214222 
    215223/*=======================================================================*\ 
    216        Function:       error 
    217        Purpose:        set MAGPIE_ERROR, and trigger error 
     224    Function:   error 
     225    Purpose:    set MAGPIE_ERROR, and trigger error 
    218226\*=======================================================================*/ 
    219227 
    220228function error ($errormsg, $lvl=E_USER_WARNING) { 
    221        global $MAGPIE_ERROR; 
    222  
    223        // append PHP's error message if track_errors enabled 
    224        if ( isset($php_errormsg) ) {  
    225                $errormsg .= " ($php_errormsg)"; 
    226        
    227        if ( $errormsg ) { 
    228                $errormsg = "MagpieRSS: $errormsg"; 
    229                $MAGPIE_ERROR = $errormsg; 
    230                 trigger_error( $errormsg, $lvl);                                 
    231        
     229        global $MAGPIE_ERROR; 
     230         
     231        // append PHP's error message if track_errors enabled 
     232        if ( isset($php_errormsg) ) {  
     233            $errormsg .= " ($php_errormsg)"; 
     234       
     235        if ( $errormsg ) { 
     236            $errormsg = "MagpieRSS: $errormsg"; 
     237            $MAGPIE_ERROR = $errormsg; 
     238            trigger_error( $errormsg, $lvl);                 
     239       
    232240} 
    233241 
    234242function debug ($debugmsg, $lvl=E_USER_NOTICE) { 
    235        trigger_error("MagpieRSS [debug] $debugmsg", $lvl); 
    236 } 
    237                          
    238 /*=======================================================================*\ 
    239        Function:       magpie_error 
    240        Purpose:        accessor for the magpie error variable 
     243    trigger_error("MagpieRSS [debug] $debugmsg", $lvl); 
     244} 
     245             
     246/*=======================================================================*\ 
     247    Function:   magpie_error 
     248    Purpose:    accessor for the magpie error variable 
    241249\*=======================================================================*/ 
    242250function magpie_error ($errormsg="") { 
    243        global $MAGPIE_ERROR; 
    244          
    245        if ( isset($errormsg) and $errormsg ) {  
    246                $MAGPIE_ERROR = $errormsg; 
    247        
    248          
    249         return $MAGPIE_ERROR;    
    250 } 
    251  
    252 /*=======================================================================*\ 
    253        Function:       _fetch_remote_file 
    254        Purpose:        retrieve an arbitrary remote file 
    255        Input:          url of the remote file 
    256                                headers to send along with the request (optional) 
    257         Output:         an HTTP response object (see Snoopy.class.inc)   
     251    global $MAGPIE_ERROR; 
     252     
     253    if ( isset($errormsg) and $errormsg ) {  
     254        $MAGPIE_ERROR = $errormsg; 
     255   
     256     
     257    return $MAGPIE_ERROR;    
     258} 
     259 
     260/*=======================================================================*\ 
     261    Function:   _fetch_remote_file 
     262    Purpose:    retrieve an arbitrary remote file 
     263    Input:      url of the remote file 
     264                headers to send along with the request (optional) 
     265    Output:     an HTTP response object (see Snoopy.class.inc)   
    258266\*=======================================================================*/ 
    259267function _fetch_remote_file ($url, $headers = "" ) { 
    260        // Snoopy is an HTTP client in PHP 
    261        $client = new Snoopy(); 
    262        $client->agent = MAGPIE_USER_AGENT; 
    263        $client->read_timeout = MAGPIE_FETCH_TIME_OUT; 
    264        $client->use_gzip = MAGPIE_USE_GZIP; 
    265        if (is_array($headers) ) { 
    266                $client->rawheaders = $headers; 
    267        
    268          
    269        @$client->fetch($url); 
    270        return $client; 
    271  
    272 } 
    273  
    274 /*=======================================================================*\ 
    275        Function:       _response_to_rss 
    276        Purpose:        parse an HTTP response object into an RSS object 
    277        Input:          an HTTP response object (see Snoopy) 
    278        Output:         parsed RSS object (see rss_parse) 
     268    // Snoopy is an HTTP client in PHP 
     269    $client = new Snoopy(); 
     270    $client->agent = MAGPIE_USER_AGENT; 
     271    $client->read_timeout = MAGPIE_FETCH_TIME_OUT; 
     272    $client->use_gzip = MAGPIE_USE_GZIP; 
     273    if (is_array($headers) ) { 
     274        $client->rawheaders = $headers; 
     275   
     276     
     277    @$client->fetch($url); 
     278    return $client; 
     279 
     280} 
     281 
     282/*=======================================================================*\ 
     283    Function:   _response_to_rss 
     284    Purpose:    parse an HTTP response object into an RSS object 
     285    Input:      an HTTP response object (see Snoopy) 
     286    Output:     parsed RSS object (see rss_parse) 
    279287\*=======================================================================*/ 
    280288function _response_to_rss ($resp) { 
    281         $rss = new MagpieRSS( $resp->results ); 
    282          
    283         // if RSS parsed successfully            
    284         if ( $rss and !$rss->ERROR) { 
    285                 // find Etag, and Last-Modified 
    286                 foreach($resp->headers as $h) { 
    287                         // 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1" 
    288                         if (strpos($h, ": ")) { 
    289                                 list($field, $val) = explode(": ", $h, 2); 
    290                         } 
    291                         else { 
    292                                 $field = $h; 
    293                                 $val = ""; 
    294                         } 
    295                          
    296                         if ( $field == 'ETag' ) { 
    297                                 $rss->etag = $val; 
    298                         } 
    299                          
    300                         if ( $field == 'Last-Modified' ) { 
    301                                 $rss->last_modified = $val; 
    302                         } 
    303                 } 
    304                  
    305                 return $rss;     
    306         } // else construct error message 
    307         else { 
    308                 $errormsg = "Failed to parse RSS file."; 
    309                  
    310                 if ($rss) { 
    311                         $errormsg .= " (" . $rss->ERROR . ")"; 
    312                 } 
    313                 error($errormsg); 
    314                  
    315                 return false; 
    316         } // end if ($rss and !$rss->error) 
    317 
    318  
    319 /*=======================================================================*\ 
    320         Function:       init 
    321         Purpose:        setup constants with default values 
    322                                 check for user overrides 
     289    $rss = new MagpieRSS( $resp->results, MAGPIE_OUTPUT_ENCODING, MAGPIE_INPUT_ENCODING, MAGPIE_DETECT_ENCODING ); 
     290     
     291    // if RSS parsed successfully        
     292    if ( $rss and !$rss->ERROR) { 
     293         
     294        // find Etag, and Last-Modified 
     295        foreach($resp->headers as $h) { 
     296            // 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1" 
     297            if (strpos($h, ": ")) { 
     298                list($field, $val) = explode(": ", $h, 2); 
     299            } 
     300            else { 
     301                $field = $h; 
     302                $val = ""; 
     303            } 
     304             
     305            if ( $field == 'ETag' ) { 
     306                $rss->etag = $val; 
     307            } 
     308             
     309            if ( $field == 'Last-Modified' ) { 
     310                $rss->last_modified = $val; 
     311            } 
     312        } 
     313         
     314        return $rss;     
     315    } // else construct error message 
     316    else { 
     317        $errormsg = "Failed to parse RSS file."; 
     318         
     319        if ($rss) { 
     320            $errormsg .= " (" . $rss->ERROR . ")"; 
     321        } 
     322        error($errormsg); 
     323         
     324        return false; 
     325    } // end if ($rss and !$rss->error) 
     326
     327 
     328/*=======================================================================*\ 
     329    Function:   init 
     330    Purpose:    setup constants with default values 
     331                check for user overrides 
    323332\*=======================================================================*/ 
    324333function init () { 
    325         if ( defined('MAGPIE_INITALIZED') ) { 
    326                 return; 
    327         } 
    328         else { 
    329                 define('MAGPIE_INITALIZED', 1); 
    330         } 
    331          
    332         if ( !defined('MAGPIE_CACHE_ON') ) { 
    333                 define('MAGPIE_CACHE_ON', 1); 
    334         } 
    335  
    336         if ( !defined('MAGPIE_CACHE_DIR') ) { 
    337                 define('MAGPIE_CACHE_DIR', './cache'); 
    338         } 
    339  
    340         if ( !defined('MAGPIE_CACHE_AGE') ) { 
    341                 define('MAGPIE_CACHE_AGE', 60*60); // one hour 
    342         } 
    343  
    344         if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) { 
    345                 define('MAGPIE_CACHE_FRESH_ONLY', 0); 
    346         } 
    347  
    348         if ( !defined('MAGPIE_DEBUG') ) { 
    349                 define('MAGPIE_DEBUG', 0); 
    350         } 
    351          
    352         if ( !defined('MAGPIE_USER_AGENT') ) { 
    353                 $ua = 'MagpieRSS/'. MAGPIE_VERSION . ' (+http://magpierss.sf.net'; 
    354                  
    355                 if ( MAGPIE_CACHE_ON ) { 
    356                         $ua = $ua . ')'; 
    357                 } 
    358                 else { 
    359   &nb