0) { if (!($fp = @fopen($url, 'r'))) return NULL; $meta = stream_get_meta_data($fp); for ($j = 0; isset($meta['wrapper_data'][$j]); $j++) { if (strstr(strtolower($meta['wrapper_data'][$j]), 'last-modified')) { $modtime = substr($meta['wrapper_data'][$j], 15); break; } } fclose($fp); } else { $parts = parse_url($url); $host = $parts['host']; $path = $parts['path']; if (!($fp = @fsockopen($host, 80))) return NULL; $req = "HEAD $path HTTP/1.0\r\nUser-Agent: PHP/".phpversion()."\r\nHost: $host:80\r\nAccept: */*\r\n\r\n"; fputs($fp, $req); while (!feof($fp)) { $str = fgets($fp, 4096); if (strstr(strtolower($str), 'last-modified')) { $modtime = substr($str, 15); break; } } fclose($fp); } return isset($modtime) ? strtotime($modtime) : time(); } function parseRSS($url, $cache_file=NULL, $cache_time=NULL) { global $rss_contents, $rss_default_cache_time, $rss_isTextInput, $rss_cache_path, $rss_cache_age, $rss_tag, $rss_isImage, $rss_isItem, $rss_isChannel, $rss_index, $rss_debug_mode; $rss_error = '
Error on line %s of '.__FILE__.': %s
'; if (!function_exists('xml_parser_create')) { if ($rss_debug_mode) printf($rss_error, (__LINE__-3), 'PHP\'s XML Extension is not loaded or available.'); return false; } $rss_contents = array(); if (!is_null($cache_file)) { if (!isset($rss_cache_path) || !strlen($rss_cache_path)) $rss_cache_path = dirname(__FILE__); $cache_file = str_replace('//', '/', $rss_cache_path.'/'.$cache_file); if (is_null($cache_time)) $cache_time = $rss_default_cache_time; $rss_cache_age = file_exists($cache_file) ? ceil((time() - filemtime($cache_file)) / 60) : 0; $remotemodtime = stream_last_modified($url); if (is_null($remotemodtime)) { if ($rss_debug_mode) printf($rss_error, (__LINE__-4), 'Could not connect to remote RSS file ('.$url.').'); return false; } } if (is_null($cache_file) || (!is_null($cache_file) && !file_exists($cache_file)) || (!is_null($cache_file) && file_exists($cache_file) && $rss_cache_age > $cache_time && $remotemodtime > ((time()) - ($rss_cache_age * 60)))) { $rss_tag = ''; $rss_isItem = false; $rss_isChannel = false; $rss_index = 0; $saxparser = @xml_parser_create(); if (!is_resource($saxparser)) { if ($rss_debug_mode) printf($rss_error, (__LINE__-4), 'Could not create an instance of PHP\'s XML parser.'); return false; } xml_parser_set_option($saxparser, XML_OPTION_CASE_FOLDING, false); xml_set_element_handler($saxparser, 'sax_start', 'sax_end'); xml_set_character_data_handler($saxparser, 'sax_data'); if (!($fp = @fopen($url, 'r'))) { if ($rss_debug_mode) printf($rss_error, (__LINE__-3), 'Could not connect to remote RSS file ('.$url.').'); return false; } while ($data = fread($fp, 4096)) { $parsedOkay = xml_parse($saxparser, $data, feof($fp)); if (!$parsedOkay && xml_get_error_code($saxparser) != XML_ERROR_NONE) { if ($rss_debug_mode) printf($rss_error, (__LINE__-3), 'File has an XML error ('.xml_error_string(xml_get_error_code($saxparser)).' at line '.xml_get_current_line_number($saxparser).').'); return false; } } xml_parser_free($saxparser); fclose($fp); if (!is_null($cache_file)) { if (!($cache = @fopen($cache_file, 'w'))) { if ($rss_debug_mode) printf($rss_error, (__LINE__-3), 'Could not right to cache file ('.$cache_file.'). The path may be invalid or you may not have write permissions.'); return false; } fwrite($cache, serialize($rss_contents)); fclose($cache); } } else { if (!($fp = @fopen($cache_file, 'r'))) { if ($rss_debug_mode) printf($rss_error, (__LINE__-3), 'Could not read contents of cache file ('.$cache_file.').'); return false; } $rss_contents = unserialize(fread($fp, filesize($cache_file))); fclose($fp); } return $rss_contents; } function sax_start($parser, $name, $attribs) { global $rss_tag, $rss_isItem, $rss_isChannel, $rss_isImage, $rss_index, $rss_isTextInput; $rss_tag = $name = strtolower($name); if ($name == 'channel') { $rss_isChannel = true; $rss_isImage = false; $rss_isItem = false; } elseif ($name == 'image') { $rss_isChannel = false; $rss_isImage = true; $rss_isItem = false; } elseif ($name == 'item') { $rss_index++; $rss_isChannel = false; $rss_isImage = false; $rss_isItem = true; } elseif ($name == 'textinput') { $rss_isChannel = false; $rss_isImage = false; $rss_isItem = false; $rss_isTextInput = true; } } function sax_end($parser, $name){} function sax_data($parser, $data) { global $rss_tag, $rss_isItem, $rss_isChannel, $rss_contents, $rss_isTextInput, $rss_isImage, $rss_index; if ($data != "\n") { if ($rss_isChannel && !$rss_isItem && strlen($data)) (!isset($rss_contents['channel'][$rss_tag]) || !strlen($rss_contents['channel'][$rss_tag])) ? $rss_contents['channel'][$rss_tag] = $data : $rss_contents['channel'][$rss_tag].= $data ; elseif ($rss_isItem && strlen($data)) (!isset($rss_contents[$rss_index-1][$rss_tag]) || !strlen($rss_contents[$rss_index-1][$rss_tag])) ? $rss_contents[$rss_index-1][$rss_tag] = $data : $rss_contents[$rss_index-1][$rss_tag].= $data ; elseif ($rss_isImage && strlen($data)) (!isset($rss_contents['image'][$rss_tag]) || !strlen($rss_contents['image'][$rss_tag])) ? $rss_contents['image'][$rss_tag] = $data : $rss_contents['image'][$rss_tag].= $data ; elseif ($rss_isTextInput && strlen($data)) (!isset($rss_contents['textinput'][$rss_tag]) || !strlen($rss_contents['textinput'][$rss_tag])) ? $rss_contents['textinput'][$rss_tag] = $data : $rss_contents['textinput'][$rss_tag].= $data ; } } /////////////////////////////// function getVar($varName, $varDefaultVal) { global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_POST_FILES, $HTTP_COOKIE_VARS; if (isset($HTTP_GET_VARS[$varName])) { $varVal = $HTTP_GET_VARS[$varName]; } elseif (isset($HTTP_POST_VARS[$varName])) { $varVal = $HTTP_POST_VARS[$varName]; } elseif (isset($HTTP_POST_FILES[$varName])) { $varVal = $HTTP_POST_FILES[$varName]; } elseif (isset($HTTP_COOKIE_VARS[$varName])) { $varVal = $HTTP_COOKIE_VARS[$varName]; } else { $varVal = $varDefaultVal; } return $varVal; } function write_log ($logentry) { global $logfile; if (!$logfile) { $logfile = fopen ("./log.txt", "a"); } fwrite($logfile, date("m/d/y h:i:s A - ") . $logentry . "\n"); } function pre_fix($strText) { $strResult = $strText; //$strResult = strip_tags($strResult); $trans_array = array(); for ($i=127; $i<255; $i++) { $trans_array[chr($i)] = "&#" . $i . ";"; } $strResult = strtr($strResult, $trans_array); $strResult = ltrim($strResult); $strResult = rtrim($strResult); return $strResult; } function fix($data) { $data = pre_fix($data); $patterns = array( '/
/', '/<\/p>/', '//', '/(.*?)(.*?)<\/a>(.*?)/', '/(.*?)<\/code>/', '//', '/(.*?)<\/blockquote>/', '/(.*?)<\/cite>/', '/<[ou]l*?>(.+?)<\/[ou]l>/', '/(.+?)<\/li>/', '/(.*?)<\/span>/', '/(.*?)<\/strong>/', '/(.*?)<\/b>/', '/(.*?)<\/em>/', '/(.*?)<\/i>/', '/,/', '/;/', '/</', '/>/', '/&/', '/̵[67];/', '/̶[01];/' ); $replace = array( //br and p "\\n", "\\n\\n", "", //a element //"\\1\\3 [link: \\2]\\4", "\\1\\3 [link]\\4", //code "\\1", //img "[img]\\n", //cite=,cite "\\n\\2[cite: \\1]\\n\\n", "[cite]\\1", //ul/ol, li "\\n\\1", "* \\1\\n", "\\1", "\\1", "\\1", "\\1", "\\1", "\\,", "\\;", "<", ">", "&", "'", "\"" ); $data = preg_replace($patterns, $replace, $data); $data = strip_tags($data); return $data; } $url = getVar("url", ""); if (strlen($url) == 0) { echo "\n"; echo "\n"; echo "RSS2iCal\n"; echo "\n"; echo "\n"; echo "View and/or Subscribe to RSS/RDF News Feeds in iCalendar (vCal 2.0) format.

\n"; echo "Subscriptions have only been tested with Apple's iCal application.

\n"; echo "Once you have subscribed to a news feed in Apple's iCal, iSync can be used to synchronize it with your iPod, Palm, or cell phone.

\n"; echo "


\n"; echo "
\n"; echo "RSS/RDF URL: \n"; echo "\n"; echo "\n"; echo "\n"; echo "
\n"; echo "
\n"; echo "\n"; echo "\n"; echo "
\n"; echo "Links to Common RSS Feeds Converted to iCal format and subscriptions to them:\n"; echo "\n"; echo "\n"; echo "\n"; } else { $url = preg_replace('/http:\/\//', '', $url); header("Content-type: text/plain"); //header("Content-Disposition: inline; filename=MyiCalFile.ics"); if ($rssData = parseRSS ( "http://$url")) { $channel_title = fix($rssData["channel"]["title"]); $channel_description = fix($rssData["channel"]["description"]); if (strlen($channel_description) == 0) { $channel_description = $channel_title; } $channel_date = pre_fix($rssData["channel"]["dc:date"]); $channel_pubdate = pre_fix($rssData["channel"]["pubdate"]); $channel_lastbuilddate = pre_fix($rssData["channel"]["lastbuilddate"]); if (strlen($channel_pubdate) > 0 && (strlen($channel_date) == 0)) { $channel_date = $channel_pubdate; } if (strlen($channel_lastbuilddate) > 0 && (strlen($channel_date) == 0)) { $channel_date = $channel_lastbuilddate; } echo "BEGIN:VCALENDAR\n"; echo "CALSCALE:GREGORIAN\n"; //echo "X-WR-TIMEZONE;VALUE=TEXT:US/Eastern\n"; echo "METHOD:PUBLISH\n"; echo "PRODID:RSS2iCal 0.0.1\n"; echo "X-WR-CALNAME;VALUE=TEXT:" . $channel_title . "\n"; echo "X-WR-CALDESC;VALUE=TEXT:" . $channel_description . "\n"; //echo "X-WR-RELCALID;VALUE=TEXT:123456789\n"; echo "VERSION:2.0\n"; for ( $i = 0; isset ( $rssData[$i] ); $i++ ) { $item_title = fix($rssData[$i]["title"]); $item_link = fix($rssData[$i]["link"]); if (strlen(fix($rssData[$i]["guid"])) > 0 && (strlen($item_link) == 0)) { $item_link = fix($rssData[$i]["guid"]); } $item_description = fix($rssData[$i]["description"]); if (strlen(fix($rssData[$i]["content:encoded"])) > 0) { $item_description = fix($rssData[$i]["content:encoded"]); } if ((strlen($item_description) > 0) && (strlen($item_title) == 0)) { $item_title = substr($item_description, 0, 30) . "..."; } $item_date = pre_fix($rssData[$i]["dc:date"]); $item_pubdate = pre_fix($rssData[$i]["pubdate"]); if (strlen($item_pubdate) > 0 && (strlen($item_date) == 0)) { $item_date = $item_pubdate; } //If we use the channel date, all entries have the same datetime //This datetime is erroneous because it only applies to the latest item //For now don't use it. This results in prettier iCal display //if (strlen($channel_date) > 0 && (strlen($item_date) == 0)) { //$item_date = $channel_date; //} //echo $item_date; if (strlen($item_date) == 25) { $strDT = substr($item_date, 5, 2) . "/"; $strDT = $strDT . substr($item_date, 8, 2) . "/"; $strDT = $strDT . substr($item_date, 0, 4) . " "; $strDT = $strDT . substr($item_date, 11, 8) . " GMT"; //echo "strDT: " . $strDT; $gmt_offset = substr($item_date, 19, 3); $gmt_offset = 60 * 60 * $gmt_offset; //echo "gmt_offset: " . $gmt_offset; $unix_time = strtotime($strDT) - $gmt_offset; //echo "unixtime: " . $unix_time; $item_date = gmdate("Ymd\THis\Z", $unix_time); } elseif (strlen($item_date) == 29) { $item_date = gmdate("Ymd\THis\Z", strtotime($item_date)); } else { $item_date = date("Ymd"); } echo "BEGIN:VEVENT\n"; echo "UID:" . md5($item_link . $item_title) . "\n"; echo "DTSTAMP;VALUE=DATE:$item_date\n"; echo "SUMMARY:" . $item_title . "\n"; if ((strlen($item_link) > 0) && (strlen($item_description) > 0)) { echo "DESCRIPTION:" . $item_link . "\\n\\n" . $item_description . "\n"; } elseif (strlen($item_description) > 0) { echo "DESCRIPTION:" . $item_description . "\n"; } elseif (strlen($item_link) > 0) { echo "DESCRIPTION:" . $item_link . "\\n\\n\n"; } echo "DTSTART;VALUE=DATE:$item_date\n"; echo "DTEND;VALUE=DATE:$item_date\n"; echo "END:VEVENT\n"; } echo "END:VCALENDAR\n"; } else { echo "Unable to parse RSS feed."; } } ?>