<?php
/*** BBC News AV Console Flattener V1.1 ***
Code produced by Ben Metcalfe, bbcnewstoys AT benmetcalfe.com

http://bbcnews.benmetcalfe.com - UINOFFICIAL BBC News Lab
http://bbcnews.benmetcalfe.com/av/ - Actual files produced by this tool if you simply wish to enjoy BBC News Audio Video material outside a console environment

DISCLAIMER
This script is in no way connected to the BBC's official output. Work produced on this and any script made available by me is strictly my own intellectual property produced in my own time mingled with open source code from the open source community. All assets and news material are taken from the publicly available html and xml pages produced by BBC News Interactive. I make no guarantees for the accuracy, availability and timeliness of any of these services - on this front you will always be better served using the BBC News website directly (http://www.bbc.co.uk/news).

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

*/



/* settings - you may touch, but only if you know what you are doing */
$goTracking "bbcnews.benmetcalfe.com/av"//see addTracking() below
$sections = array("front_page","uk","world","business","sci-tech","health","entertainment"); //The sections for the console to be generated.  Only modify if you know what you are doing as these gets string manipulated into urls!
$disclaimer "This feed is totally unofficial in no way connected to the BBC's official output. Work produced on the script producing this feed is strictly my own intellectual property produced in my own time mingled with open source code from the open source community. All assets and news material are taken from the publicly available html and xml pages produced by BBC News Interactive. I make no guarantees for the accuracy, availability and timeliness of this data - on this front you will always be better served using the BBC News website directly (http://www.bbc.co.uk/news).  Please include this disclaimer in any output you make publicly available from this XML file.  The BBC does not allow commercial use of it's feeds without prior agreement, so you should not use this feed commercially either";
$totalRequestSize 0//var set as global to ensure persistance during each feed/index generation
$mediaVersions = array("bb_rm","bb_wm","nb_rm","nb_wm");//these are the unique identifiers used by the BBC

/* loop around each section*/
foreach ($sections as $section)
{
    
$totalRequestSize 0;//reset to 0 for each unique set of requests
    
$data getIndexData($section);
    
$data getStoryData($data);

    
makeHTMLPage($data);    
    foreach (
$mediaVersions as $mediaVersion)
    {
        
makeXMLPage($data,$mediaVersion);
    }
}


/* functions */

function makeXMLPage($data,$mediaVersion)
/*
A very basic XML/RSS 2.0 output of the BBC's current Audio Video assets for a given index.  Needs lots more work - needs to validate but still be able to convey 4 unique link elements per item (which ultimatly may break the fundamental DTD of RSS 2.0... If so, need alternative way of presenting the 4 media link that will appear in News Readers, etc).
*/
{
    
$filecontents "<?xml version=\"1.0\" encoding=\"ISO-8859-15\"?>\n<rss version=\"2.0\">\n<channel>\n";
    
$filecontents .= "<title>BBC News | Audio Video | ".$data["index"]."</title>\n";
    
$filecontents .= "<link>http://www.bbc.co.uk/news</link>\n<description>Latest news in Audio and Video from the BBC.  Generated UNOFFICIALLY by Ben Metcalfe (http://bbcnews.benmetcalfe.com/av/)</description>\n<language>en-gb</language>\n";
    
$filecontents .= "<lastBuildDate>".$data["fetched"]."</lastBuildDate>\n";
    
$filecontents .= "<generator>The Unofficial BBC News Lab (http://bbcnews.benmetcalfe.com/)</generator>\n<webMaster>bbcnewslab@benmetcalfe.com</webMaster>\n";
    
$filecontents .= "<copyright>".$GLOBALS["disclaimer"]."</copyright>\n<docs>http://bbcnews.benmetcalfe.com</docs>\n";
    
$filecontents .= "<image><title>BBC News</title><url>http://news.bbc.co.uk/nol/shared/img/bbc_news_120x60.gif</url><link>http://news.bbc.co.uk</link></image>\n";
    
$filecontents .= "<help>All media assets are available in 4 formats: bb_rm = RealNetworks 9 codec @ 256kbps, bb_wm = Microsoft Windows Media 9 codec @ 256kbps, nb_rm = RealNetworks 9 codec @ 34kbps, nb_wm = Microsoft Windows Media 9 codec @ 34kbps.  This is the ".$mediaVersion." version - see http://bbcnews.benmetcalfe.com/av/ for other format options</help>\n";
    
    foreach (
$data["story"] as $story)
    {
        
$filecontents .= "<item>\n";
        
$filecontents .= "    <title>".$story["headline"]."</title>\n";
        
$filecontents .= "    <description>".$story["summary"];
        if (
$story["duration"])
        {
            
$filecontents .= "  Duration: ".$story["duration"];
        }    
        
$filecontents .= "</description>\n";
        
$filecontents .= "    <link>".addTracking($story["clipurl"][$mediaVersion],"rss")."</link>\n";
        
$filecontents .= "</item>\n";
    }
    
    
$t round($GLOBALS["totalRequestSize"]/1024);
    
    
$filecontents .= "<comment>Total amount of data requested from bbc servers to generate this page = ".$t."k</comment>\n";
    
$filecontents .= "</channel>\n</rss>";
    
    
//echo $filecontents;
    
$filename strtolower($data["index"])."_".$mediaVersion.".xml";
    
    
saveFile($filename,$filecontents);
    
}

function 
makeHTMLPage($data)
/*
A very basic HTML output of the BBC's current Audio Video assets for a given index.  Needs lots more work.
*/
{
    
$filecontents "<!-- DISCLAIMER: ".$disclaimer." -->";
    
$filecontents .= "<html><head><title>BBC News - Audio Video: ".$data["index"]."</title></head><body>";
    
$filecontents .= "<h1>BBC News - Audio Video</h1>";
    
$filecontents .= "<h2>".$data["index"]."</h2>";
    
$filecontents .= "<p><i>(last updated: ".$data["fetched"].")</i></p>";
    
    foreach (
$data["story"] as $story)
    {
        
$filecontents .= "<h3>".$story["headline"]."</h3>";
        
$image '<img src="'.$story["image"]["src"].'" width="'.$story["image"]["w"].'" height="'.$story["image"]["h"].'" alt="'.$story["image"]["alt"].'" />';
        
$filecontents .= "<p><b>".$image."&nbsp;".$story["summary"]."</b></p>";
        
$filecontents .= "<p>".nl2br($story["body"])."</p>";
        
$filecontents .= "<ul>";
        foreach (
$GLOBALS["mediaVersions"] as $mediaVersion)
        {
            
$filecontents .= '<li><a href="'.addTracking($story["clipurl"][$mediaVersion],"html").'"><b>'.$mediaVersion.': </b>'.addTracking($story["clipurl"][$mediaVersion],"html").'</a></li>';
        }
        
$filecontents .= "</ul>";
        if (
$story["duration"])
        {
            
$filecontents .= "<p>Duration: ".$story["duration"]."</p>";
        }    
        
$filecontents .= "<hr>";
    }

    
$filecontents .= "<p>Generated by the Unofficial BBC News Lab @ <a href=\"http://bbcnews.benmetcalfe.com/av/\">http://bbcnews.benmetcalfe.com/av/</a></p>";    

    
$t round($GLOBALS["totalRequestSize"]/1024);

    
$filecontents .= "<small>Total amount of data requested from bbc servers to generate this page = ".$t."k<small>";
    
$filecontents .= "</body></html>";
    
    
//echo $filecontents;
    
$filename strtolower($data["index"]).".html";
    
    
saveFile($filename,$filecontents);
    
}




function 
getIndexData($id)
/*
Basically a bunch of regEx's to extract the nessessary information from the console indexes.
*/
{
    
//get the date of this grab, so we can state our timleyness!
    
$data["fetched"] = date("r");
    
    
//get the HTML
    
$htmlCode getHTML("http://news.bbc.co.uk/nolavconsole/ukfs_news/hi/".$id."/bb_rm_default.stm");
    

    
    
//get name of index we're looking at
    
preg_match("/<div class=\"sectionHeader\">(.*?)<\/div>/"$htmlCode$matches);
    
$data["index"] = makeDataSafe($matches[1]);
    
    
//get an array of the raw story repetitions
    
preg_match_all ('/<div class="storybox">(.*)<br clear="all" \/><\/div>/U'$htmlCode$rawStories); 
    
    
    
//start to build up our stories array of with stories from the data available at index level
    
$i 1//foreach doesn't supply us with $i
    
foreach ($rawStories[1] as $rawStory)
    {
        
//get url of story
        
preg_match("/href=\"(.*?)\"/"$rawStory$matches);
        
$data["story"][$i]["url"] = "http://news.bbc.co.uk".trim($matches[1]);
        
        
//get image details for story
        
preg_match("/src=\"(.*?)\"/"$rawStory$matches);
        
$data["story"][$i]["image"]["src"] = "http://newsimg.bbc.co.uk".trim($matches[1]); //nol like to ref images via newsimg. not news.
        
        
preg_match("/width=\"(.*?)\"/"$rawStory$matches);
        
$data["story"][$i]["image"]["w"] = trim($matches[1]);
        
        
preg_match("/height=\"(.*?)\"/"$rawStory$matches);
        
$data["story"][$i]["image"]["h"] = trim($matches[1]);
        
        
preg_match("/alt=\"(.*?)\"/"$rawStory$matches);
        
$data["story"][$i]["image"]["alt"] = makeDataSafe($matches[1]);
        
        
//get clip duration
        
preg_match('/<div class=\"time\">(.*?)<\/div>/'$rawStory$matches); 
        
$data["story"][$i]["duration"] = makeDataSafe($matches[1]);
    
        
$i++;//iterate our, er, iterator
    
}
    
    return 
$data;
}


function 
getStoryData($data)
/*
Basically a bunch of regEx's to extract the nessessary information from the console stories.
*/
{
    
$mediaVersions = array("bb_wm","nb_rm","nb_wm"); //we will already have bb_rm when we get the default story version;
    
    
$i 1//foreach doesn't supply us with $i
    
foreach ($data["story"] as $story)
    {
        
$htmlCode getHTML($story["url"]);
        
        
//get headline of story
        
preg_match("/<meta name=\"Headline\" content=\"(.*?)\"/"$htmlCode$matches);
        
$data["story"][$i]["headline"] = makeDataSafe($matches[1]);
        
        
//get summary of story
        
preg_match("/<meta name=\"Description\" content=\"(.*?)\"/"$htmlCode$matches);
        
$data["story"][$i]["summary"] = makeDataSafe($matches[1]);
        
        
//get body of story (with <p>'s converted to nl's
        
preg_match("/<\/div><br\/><p>(.*?)<\/div>/"$htmlCode$matches);
        
$data["story"][$i]["body"] = str_replace("<p>","\n",makeDataSafe($matches[1]));
        
        
//get clipurl of media (we have BB already cached in $htmlCode, so let's take advantage of that now...
        
preg_match("/var clipurl = \"(.*?)\"/"$htmlCode$matches);
        
$data["story"][$i]["clipurl"]["bb_rm"] = trim($matches[1]);
        

        
        foreach (
$mediaVersions  as $mediaVersion)
        {
            
$url str_replace("/bb_rm_","/".$mediaVersion."_",$story["url"]); //swap out the default prefix for the others
            
$htmlCode getHTML($url);
            
            
preg_match("/var clipurl = \"(.*?)\"/"$htmlCode$matches);
            
$data["story"][$i]["clipurl"][$mediaVersion] = trim($matches[1]);
        }

        
$i++;
    }
    
//debug_var("$data",$data);
    
return $data;
}


function 
makeDataSafe($str)
//converts special characters into HTML safe code, trims whitespace, but preserves HTML
{
    
$str trim(htmlspecialchars($str));
    
/*
    $str = str_replace ('&lt;', '<', $str);// we want to preserve HTML tags
    $str = str_replace ('&gt;', '>', $string);// as above
    */
    
return $str;
}

function 
getHTML($url)
/*
Fairly standard fopen/getHTML function.  We clean up the HTML to remove excess white space and line breaks that WebObjects puts in.  We also monitor the total number of bytes were collecting from BBC.
*/
{
    
$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);
    
$file str_replace("> "">"$file);
    
$file str_replace(" <""<"$file);
    
$file str_replace(" <""<"$file);
    
    return 
$file;
}

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

{
    
$filename getcwd()."/av/".$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
}

function 
addTracking($url,$pageFormat)
/*
BBC uses a tracking system to track syndiacated link from internal partners and external sources.  I'm exploiting this to ensure that the popularity of this service can be measured statistically.  If you are editing this code, please ensure you keep the GO tracking code!
*/
{
    
$go $GLOBALS["goTracking"];
    if (
$go)
    {
        
$url str_replace(".bbc.co.uk",".bbc.co.uk/go/".$go."/".$pageFormat."/-",$url);
    }
    
    return 
$url;
}


?>