, and PukiWiki Developer Team * Licence: GPL, same as PukiWiki * This plugin needs 'PHP xml extension' */ // Show this plugin is enable or not for this PukiWiki function plugin_showrss_action() { $xml_extension = extension_loaded('xml'); $mbstring_extension = extension_loaded('mbstring'); $xml_msg = $xml_extension ? 'xml extension is loaded' : 'COLOR(RED){xml extension is not loaded}'; $mbstring_msg = $mbstring_extension ? 'mbstring extension is loaded' : 'COLOR(RED){mbstring extension is not loaded}'; $showrss_info = '| xml parser | ' . $xml_msg . ' |' . "\n" . '| multibyte | ' . $mbstring_msg . ' |' . "\n"; return array('msg' => 'showrss_info', 'body' => convert_html($showrss_info)); } function plugin_showrss_convert() { if (func_num_args() == 0) { return '

showrss: no parameter(s).

' . "\n"; } else if (! extension_loaded('xml')) { return '

showrss: xml extension is not loaded

' . "\n"; } $array = func_get_args(); $rssurl = $tmplname = $usecache = $usetimestamp = ''; switch (func_num_args()) { case 4: $usetimestamp = trim($array[3]); case 3: $usecache = $array[2]; case 2: $tmplname = strtolower(trim($array[1])); case 1: $rssurl = trim($array[0]); } if (! is_url($rssurl)) return '

showrss: syntax error. ' . htmlspecialchars($rssurl) . '

' . "\n"; $class = 'ShowRSS_html_' . $tmplname; if (! class_exists($class)) $class = 'ShowRSS_html'; list($rss, $time) = plugin_showrss_get_rss($rssurl, $usecache); if ($rss === FALSE) return '

showrss: cannot get rss from server.

' . "\n"; $obj = new $class($rss); $timestamp = ''; if ($usetimestamp > 0) { $time = get_date('Y/m/d H:i:s',$time); $timestamp = '

Last-Modified:' . $time . '

'; } return $obj->toString($timestamp); } // Create HTML from RSS array() class ShowRSS_html { var $items = array(); var $class = ''; function ShowRSS_html($rss) { foreach ($rss as $date=>$items) { foreach ($items as $item) { $link = $item['LINK']; $title = $item['TITLE']; $passage = get_passage($item['_TIMESTAMP']); $link = '' . $title . ''; $this->items[$date][] = $this->format_link($link); } } } function format_link($link) { return $link . '
' . "\n"; } function format_list($date, $str) { return $str; } function format_body($str) { return $str; } function toString($timestamp) { $retval = ''; foreach ($this->items as $date=>$items) $retval .= $this->format_list($date, join('', $items)); $retval = $this->format_body($retval); return <<class}> $retval$timestamp EOD; } } class ShowRSS_html_menubar extends ShowRSS_html { var $class = ' class="small"'; function format_link($link) { return '
  • ' . $link . '
  • ' . "\n"; } function format_body($str) { return '' . "\n"; } } class ShowRSS_html_recent extends ShowRSS_html { var $class = ' class="small"'; function format_link($link) { return '
  • ' . $link . '
  • ' . "\n"; } function format_list($date, $str) { return '' . $date . '' . "\n" . '' . "\n"; } } // Get RSS function plugin_showrss_get_rss($target, $usecache) { $buf = ''; $time = NULL; if ($usecache) { // Remove expired cache plugin_showrss_cache_expire($usecache); // Get the cache not expired $filename = CACHE_DIR . encode($target) . '.tmp'; if (is_readable($filename)) { $buf = join('', file($filename)); $time = filemtime($filename) - LOCALZONE; } } if ($time === NULL) { // Newly get RSS $data = http_request($target); if ($data['rc'] !== 200) return array(FALSE, 0); $buf = $data['data']; $time = UTIME; // Save RSS into cache if ($usecache) { $fp = fopen($filename, 'w'); fwrite($fp, $buf); fclose($fp); } } // Parse $obj = new ShowRSS_XML(); return array($obj->parse($buf),$time); } // Remove cache if expired limit exeed function plugin_showrss_cache_expire($usecache) { $expire = $usecache * 60 * 60; // Hour $dh = dir(CACHE_DIR); while (($file = $dh->read()) !== FALSE) { if (substr($file, -4) != '.tmp') continue; $file = CACHE_DIR . $file; $last = time() - filemtime($file); if ($last > $expire) unlink($file); } $dh->close(); } // Get RSS and array() them class ShowRSS_XML { var $items; var $item; var $is_item; var $tag; var $encoding; function parse($buf) { $this->items = array(); $this->item = array(); $this->is_item = FALSE; $this->tag = ''; // Detect encoding $this->encoding = mb_detect_encoding($buf); if (! in_array(strtolower($this->encoding), array('us-ascii', 'iso-8859-1', 'utf-8'))) { $buf = mb_convert_encoding($buf, 'utf-8', $this->encoding); $this->encoding = 'utf-8'; } $xml_parser = xml_parser_create($this->encoding); xml_set_element_handler($xml_parser, array(& $this, 'start_element'), array(& $this, 'end_element')); xml_set_character_data_handler($xml_parser, array(& $this, 'character_data')); if (! xml_parse($xml_parser, $buf, 1)) { return(sprintf('XML error: %s at line %d in %s', xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser), $buf)); } xml_parser_free($xml_parser); return $this->items; } function escape($str) { // Unescape already-escaped chars (<, >, &, ...) in RSS body before htmlspecialchars() $str = strtr($str, array_flip(get_html_translation_table(ENT_COMPAT))); // Escape $str = htmlspecialchars($str); // Encoding conversion $str = mb_convert_encoding($str, SOURCE_ENCODING, $this->encoding); return trim($str); } // Tag start function start_element($parser, $name, $attrs) { if ($this->is_item) { $this->tag = $name; } else if ($name == 'ITEM') { $this->is_item = TRUE; } } // Tag end function end_element($parser, $name) { if (! $this->is_item || $name != 'ITEM') return; $item = array_map(array(& $this, 'escape'), $this->item); $this->item = array(); if (isset($item['DC:DATE'])) { $time = plugin_showrss_get_timestamp($item['DC:DATE']); } else if (isset($item['PUBDATE'])) { $time = plugin_showrss_get_timestamp($item['PUBDATE']); } else if (isset($item['DESCRIPTION']) && ($description = trim($item['DESCRIPTION'])) != '' && ($time = strtotime($description)) != -1) { $time -= LOCALZONE; } else { $time = time() - LOCALZONE; } $item['_TIMESTAMP'] = $time; $date = get_date('Y-m-d', $item['_TIMESTAMP']); $this->items[$date][] = $item; $this->is_item = FALSE; } function character_data($parser, $data) { if (! $this->is_item) return; if (! isset($this->item[$this->tag])) $this->item[$this->tag] = ''; $this->item[$this->tag] .= $data; } } function plugin_showrss_get_timestamp($str) { if (($str = trim($str)) == '') return UTIME; $matches = array(); if (! preg_match('/(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})(([+-])(\d{2}):(\d{2}))?/', $str, $matches)) { $time = strtotime($str); return ($time == -1) ? UTIME : $time - LOCALZONE; } $str = $matches[1]; $time = strtotime($matches[1] . ' ' . $matches[2]); if (! empty($matches[3])) { $diff = ($matches[5] * 60 + $matches[6]) * 60; $time += ($matches[4] == '-' ? $diff : -$diff); } return $time; } ?>