Download txt2rss.php
<?php
class RssLib
{
var $date_format = "Y-m-d\\Th:i:sO";
function setDateFormat($fmt)
{
$this->date_format;
}
function formatDate($date)
{
return $this->w3cDateTimeFormat(date($this->date_format, $date));
}
function w3cDateTimeFormat($date)
{
return preg_replace('/\d\d$/', ':\0', $date);
}
}
class TextFileToRssItem extends RssLib
{
var $rss_lines = array('url' => "http://",
'title' => "No Title",
'description' => "No description",
'author' => "No Authors");
function getArray($file)
{
if (!file_exists($file)) {
return new Error("File does not exist", $file);
}
if (!is_readable($file)) {
return new Error("File is not readable", $file);
}
$date = filemtime($file);
$txt_file = new TextLineFile($this->rss_lines);
$data = $txt_file->parseFile($file);
if (Main::instance_of($data, 'Error')) {
return $data;
}
$data['file'] = $file;
$data['date'] = $this->formatDate($date);
return $data;
}
function getItem($file)
{
$id = $this->getArray($file);
if (Main::instance_of($id, 'Error')) {
return $id;
}
$xml = '<item rdf:about="' . htmlspecialchars($id['url']) . '">'
. "\n" . ' <!-- file: ' . htmlspecialchars($id['file']) . ' -->'
. "\n" . ' <title>' . htmlspecialchars($id['title']) . '</title>'
. "\n" . ' <link>' . htmlspecialchars($id['url']) . '</link>'
. "\n" . ' <description>' . htmlspecialchars($id['description'])
. '</description>'
. "\n" . ' <dc:creator>' . htmlspecialchars($id['author'])
. '</dc:creator>'
. "\n" . ' <dc:date>' . htmlspecialchars($id['date'])
. '</dc:date>'
. "\n" . '</item>';
return array($id['url'] => $xml);
}
}
class TextFilesToRss extends TextFileToRssItem
{
var $rss_meta_lines = array('update_period' => "daily",
'update_frequency' => "1");
var $update_base = "1901-01-01T00:00+00:00";
var $output_file = "rss.xml";
var $meta_file = "rss.txt";
var $template_file = "template.xml";
var $files = array();
var $template = array();
function TextFilesToRss($file)
{
$author_at = array_search('author', array_keys($this->rss_lines));
$this->rss_lines = array_splice($this->rss_lines, 0, $author_at);
$this->rss_meta_lines = array_merge($this->rss_lines,
$this->rss_meta_lines);
$this->setOutputFile($file);
}
function setOutputFile($file)
{
$this->output_file = $file;
}
function setTemplate($file)
{
$this->template_file = $file;
}
function setMetaFile($file)
{
$this->meta_file = $file;
}
function addFile($file)
{
$this->files[] = $file;
}
function getFiles()
{
return $this->files;
}
function getXml()
{
$meta = $this->getMetaData();
if (Main::instance_of($meta, 'Error')) {
return $meta;
}
$rss = $meta;
$items = array();
foreach ($this->getFiles() as $f) {
$item = $this->processRssItemFile($f);
if (Main::instance_of($item, 'Error')) {
return $item;
}
list($url, $xml) = each($item);
if (isset($items[$url])) {
return new Error("Duplicate RSS item",
"$url in $f");
}
$items[$url] = $xml;
}
$rss['item'] = $items;
$list_items = array_keys($items);
$rss['li'] = array();
foreach ($list_items as $li) {
$rss['li'][] = '<rdf:li rdf:resource="'
. htmlspecialchars($li) . '"/>';
}
$rss['file'] = $this->output_file;
$rss['update_base'] = $this->update_base;
return $this->mergeWithTemplateFile($rss);
}
function processRssItemFile($file)
{
$txt2item = new TextFileToRssItem;
$item = $txt2item->getItem($file);
return $item;
}
function getMetaData()
{
$this->rss_lines = $this->rss_meta_lines;
$meta = $this->getArray($this->meta_file);
if (Main::instance_of($meta, 'Error')) {
return $meta;
}
return $meta;
}
function mergeWithTemplateFile($rss)
{
if (!file_exists($this->template_file)) {
return new Error("Template file not found",
$this->template_file);
}
if (!is_readable($this->template_file)) {
return new Error("Template file not readable",
$this->template_file);
}
$this->template = file($this->template_file);
$prefixes = array();
$prefixes = $this->templateFileTagPrefixes();
if (isset($rss['li'])) {
$prefix = isset($prefixes['li']) ? $prefixes['li'] : "";
$rss['li'] = join("\n$prefix", $rss['li']) . "\n";
}
if (isset($rss['item'])) {
$prefix = isset($prefixes['item']) ? $prefixes['item'] : "";
$rss['item'] = join("\n", $rss['item']);
$rss['item'] = str_replace("\n", "\n$prefix", $rss['item'])
. "\n";
}
$tags_2_re = create_function('$t', 'return "/%%".$t."%%\n?/";');
$tag_res = array_map($tags_2_re, array_keys($rss));
$xml = "";
foreach ($this->template as $line) {
$xml .= preg_replace($tag_res, array_values($rss), $line);
}
return $xml . "\n";
}
function templateFileTagPrefixes()
{
foreach ($this->template as $line) {
preg_match_all("/^(.*)%%[^%]*?%%/", $line, &$p);
while (isset($p[1]) && list($k, $prefix) = each($p[1])) {
preg_match_all("/%%([^%]*?)%%/", $line, &$m);
while (isset($m[1]) && list($k, $tag) = each($m[1])) {
$prefixes[$tag] = $prefix;
}
}
}
return $prefixes;
}
}
class TextLineFile
{
var $lines;
var $lines_key;
var $n_fields;
function TextLineFile($key = null)
{
$this->setLineKey($key);
}
function setLineKey($key = null)
{
if (isset($key)) {
$this->lines_key = $key;
$n_fields = count($this->lines_key);
}
}
function nFields()
{
return $this->n_fields;
}
function parseFile($file)
{
$this->TextLineFile();
$lines = file($file);
if (count($lines) <= $this->nFields()) {
return new Error("Incomplete text file", $file);
}
$lines = array_map('chop', $lines);
return Main::array_combine(array_keys($this->lines_key),
$lines);
}
}
class Error {
var $message;
var $problem;
function Error($msg, $prob)
{
$this->message = $msg;
$this->problem = $prob;
}
function text()
{
return $this->message . ": " . $this->problem . "\n";
}
}
class Main
{
function main($glob, $out)
{
$rss = new TextFilesToRss($out);
$rss->setMetaFile("rss.txt");
$rss->setTemplate("rss.xml");
$files = array_reverse(glob($glob));
foreach ($files as $file) {
$rss->addFile($file);
}
$str = $rss->getXml();
if (Main::instance_of($str, 'Error')) {
if (strpos(($http = $_SERVER['SERVER_PROTOCOL']), 'HTTP') !== false) {
header("$http 500 Internal Server Error");
}
header("Content-type: text/plain");
print $str->text();
} else {
header("Content-type: text/xml; charset=utf-8");
print $str;
}
}
function instance_of($a, $b)
{
if (phpversion() >= 5) {
return $a instanceof $b;
} return (is_object($a) && is_string($b)
&& get_class($a) === strtolower($b))
|| (is_object($b) && is_string($a)
&& get_class($b) === strtolower($a));
}
function array_combine($keys, $values)
{
$n = array(); foreach ($keys as $k) {
list($vkey, $v) = each($values);
$n[$k] = $v;
}
return $n;
}
}
$main = new Main("event*.txt", "events.xml");
?>