# # # delete "releases.xml" # # add_file "releases.xml.php" # content [f2aa77c225c0a9b33b37004015fa9e1c0a06b008] # ============================================================ --- releases.xml.php f2aa77c225c0a9b33b37004015fa9e1c0a06b008 +++ releases.xml.php f2aa77c225c0a9b33b37004015fa9e1c0a06b008 @@ -0,0 +1,221 @@ +get_releases(10); + +// ---------------------------------------------------------------------------- + +class news_parser +{ + private $fp, $sections; + + public function __construct($file) + { + $this->fp = fopen($file, 'r'); + if (!$this->fp) + throw Exception("couldn't open '$file' for reading"); + + $this->sections = array( + "Changes", "New features", "Bugs fixed", "Other", "Internal" + ); + } + + public function __destruct() + { + fclose($this->fp); + } + + public function get_releases($count) + { + $releases = array(); + for ($i=0; $i<$count; ++$i) + { + $release = $this->get_release(); + if ($release === false) + break; + $releases[] = $release; + } + return $releases; + } + + public function get_release() + { + $timestamp = $this->get_timestamp(); + if ($timestamp === false) + return false; + + return array( + "timestamp" => $timestamp, + "header" => $this->get_header(), + "sections" => $this->get_sections() + ); + } + + public function get_timestamp() + { + $this->eat_whitespace(); + $date = $this->get_line(); + if ($date === false) + return false; + return strtotime($date); + } + + public function get_header() + { + $this->eat_whitespace(); + return trim($this->get_line()); + } + + public function get_sections() + { + $sections = array(); + while (($section = $this->get_section()) !== false) + { + $sections[] = $section; + } + return $sections; + } + + public function get_section() + { + $this->eat_whitespace(); + $oldpos = ftell($this->fp); + $sec = trim($this->get_line()); + if ($sec === false || !in_array($sec, $this->sections)) + { + fseek($this->fp, $oldpos); + return false; + } + + return array( + "name" => $sec, + "entries" => $this->get_entries() + ); + } + + public function get_entries() + { + $entries = array(); + $current = -1; + + while (!feof($this->fp)) + { + $oldpos = ftell($this->fp); + $line = $this->get_line(); + + if (!empty($line) && ( + ltrim($line) == $line || // end of release + in_array(trim($line), $this->sections) // end of section + )) + { + fseek($this->fp, $oldpos); + break; + } + + $line = trim($line); + if (empty($line) && $current == -1) + continue; + + if (substr($line, 0, 1) == "-") + { + ++$current; + $entries[$current] = ""; + $line = substr($line, 2); + } + + if (empty($line)) + $line = "\n"; + + $filler = " "; + if (empty($entries[$current]) || + substr($entries[$current], -1, 1) == "\n") + { + $filler = ""; + } + + $entries[$current] .= "$filler$line"; + } + + return $entries; + } + + public function eat_whitespace() + { + $off = ftell($this->fp); + while (!feof($this->fp)) + { + $ch = fgetc($this->fp); + if (trim($ch) != '') + { + break; + } + $off++; + } + fseek($this->fp, $off); + } + + public function get_line() + { + if (feof($this->fp)) + return false; + return fgets($this->fp); + } +} + +header('Content-type: application/rss+xml'); +echo ''; +$self = "http://{$_SERVER['SERVER_NAME']}{$_SERVER['SCRIPT_NAME']}"; +?> + + + monotone - distributed version control + + + Recent monotone releases + en-us + + + + + <?php echo $release['header']; ?> + + +

+
    + +
  • \b]+)#', + '$1', + $entry); + + // link monotone bugs + $entry = preg_replace_callback( + '/monotone bugs?(?:(?:, |,and | and | )#\d+)+/', + create_function('$matches', ' + return preg_replace( + "/#(\d+)/", + "#$1", + $matches[0] + ); + '), + $entry); + echo nl2br($entry); + ?>
  • + +
+ + ]]>
+ + +
+ +
+
+