<?php
/*** London Tube Delays -> RSS V1.1 ***
Code produced by Ben Metcalfe, bbcnewstoys AT benmetcalfe.com

DISCLAIMER
(See disclaimer below)

Please include this disclaimer in any output you make publicly available with this script.

*/

$disclaimer "This feed is totally unofficial in no way connected to the TfL official output of live service disruption data (http://www.tfl.gov.uk/tube/travelinfo/realtime/).  I make no guarantees for the accuracy, availability and timeliness of this data - on this front you will always be better served using the official TfL website directly (http://www.tfl.gov.uk/tube/travelinfo/realtime/).  Please include this disclaimer in any output you make publicly available from this XML file.";

$data getRawAlerts();
$data prepareOutput($data);

makeXMLPage($data);


/* functions */

function makeXMLPage($data)
/*
A very basic XML/RSS 2.0 output of the TfL Tube Delay Webpage.  Needs lots more work - needs to validate for example!
*/
{
    
$filecontents "<?xml version=\"1.0\" encoding=\"ISO-8859-15\"?>\n<rss version=\"2.0\">\n<channel>\n";
    
$filecontents .= "<title>London Tube Delays</title>\n";
    
$filecontents .= "<link>http://www.tfl.gov.uk/tube/travelinfo/realtime/</link>\n<description>Latest service disruption on the London Underground.  Generated UNOFFICIALLY by Ben Metcalfe (http://bbcnews.benmetcalfe.com/londontubedelays/)</description>\n<language>en-gb</language>\n";
    
$filecontents .= "<lastBuildDate>".$data["updated"]."</lastBuildDate>\n";
    
$filecontents .= "<generator>Ben Metcalfe (http://www.benmetcalfe.com)</generator>\n<webMaster>tubealert@benmetcalfe.com</webMaster>\n";
    
$filecontents .= "<copyright>".$GLOBALS["disclaimer"]."</copyright>\n<docs>http://bbcnews.benmetcalfe.com/londontubedelays/</docs>\n";
    
$filecontents .= "<help>This RSS 2.0 feed only includes the London Underground lines currently experiencing service disruptions.  Each line is given it's own item element.  If you intend to use this feed in a newsreader, I recommended you flush your logs for this channel each time you refresh the data - that way you will only see the lines currently experiencing delay.</help>\n";
    
    foreach (
$data["alerts"] as $alert)
    {
        
$filecontents .= "<item>\n";
        
$filecontents .= "    <title>".$alert["name"]."</title>\n";
        
$filecontents .= "    <description>".htmlspecialchars(strip_tags($alert["alert"]));
        
$filecontents .= "</description>\n";
        
$filecontents .= "    <link>http://www.tfl.gov.uk/tube/travelinfo/realtime/</link>\n";
        
$filecontents .= "</item>\n";
    }
    
    
$t round($GLOBALS["totalRequestSize"]/1024);
    
    
$filecontents .= "<comment>Total amount of data requested from TfL servers to generate this page = ".$t."k</comment>\n";
    
$filecontents .= "</channel>\n</rss>";
    
    
//echo $filecontents;
    
    
saveFile("delays.xml",$filecontents);
    
}

function 
prepareOutput($data)
{
    
$lines = array("Bakerloo"=>"Bakerloo",
                    
"Central"=>"Central",
                    
"Circle"=>"Circle",
                    
"District"=>"District",
                    
"East_London"=>"East London",//check
                    
"Hammersmith_City"=>"Hammersmith + City",
                    
"Jubilee"=>"Jubilee",
                    
"Metropolitan"=>"Metropolitan",
                    
"Northern"=>"Northern",
                    
"Piccadilly"=>"Piccadilly",
                    
"Victoria"=>"Victoria",
                    
"Waterloo_City"=>"Waterloo + City");

    
    
$inputData $data;
    
$data = array();
    
    
$data["updated"] = $inputData["updated"];
    
    foreach (
$inputData["alerts"] as $alert)
    {
        foreach (
$lines as $lineCode => $lineName)
        {
            if (
strpos($alert,'class="'.$lineCode))
            {
                
preg_match("/<tr valign=top> <td>(.*?)<br> &nbsp; <\/td>/"$alert$matches);
                
$alert str_replace("<BR>"," ",$matches[1]);

                
$data["alerts"][$lineCode]["name"] = $lineName;
                
$data["alerts"][$lineCode]["alert"] = trim($alert);
            }
        }
    }
    return 
$data;
}


function 
getRawAlerts()
/*
Basically a bunch of explodes (seem to be faster than regexp's) to extract the nessessary information from the TfL website.
*/
{
    
//get the HTML
    
$htmlCode getHTML("http://www.tfl.gov.uk/tube/travelinfo/realtime/");
    
    
    
//get the travel alert section of index we're looking at
    //preg_match("<h1>Live travel news</h1>", $htmlCode, $matches);
    
$matches  explode('<h1>Live travel news</h1>'$htmlCode);

    
// use the handy <tr><td> tags as the delimiter
    
$data["alerts"] = explode('<tr valign=top> <td valign="middle"'$matches[1]);
    
    
// stuff before the frist tag and after the last tag is crap - loose those elements
    
$data["alerts"] = array_slice($data["alerts"], 1, -1);  
    
    
$data["fetched"] = $getDate;
    
    
//get the last updated date/time
    
preg_match("/<i>live information updated (.*?) <\/i>/"$htmlCode$matches);
    
$data["updated"] = $matches[1];
    
    return 
$data;
}



function 
getHTML($url)
/*
Fairly standard fopen/getHTML function.
*/
{
    
$fp fopen($url,"r");
    if(
$fp)
    {
        while(!
feof($fp)){
        
$buffer fgets($fp600);
        @
$file .= $buffer;
    }
        
fclose($fp);
    }
    else
    {
        die(
"Could not create a connection to website"); 
    }
    
    
$GLOBALS["totalRequestSize"] += strlen($file);
    
    
//clean up HTML
    
$file preg_replace('/\s+/'' '$file);
    
    return 
$file;
}

function 
saveFile($filename,$data)
/*
Bog-standard save function
*/

{
    
$filename getcwd()."/".$filename;
    
// Open file and wipe contents, create file if needed
    
if (!$h fopen($filename'w'))
    { 
        echo 
$filename." NOT saved - could not open file";
        return 
false;
    }
    
    
// Write $data to our opened file. 
    
if (!fwrite($h$data))
    { 
        echo 
$filename." NOT saved - could not write to file<br>";
        return 
false;
    } 
    
    
fclose($h); 
    echo 
$filename." saved<br>";
    return 
true
}

?>