Welcome to Geoffrey Swift's βlog. Please subscribe to the Atom feed.


Demand Five Adverts skipped

In an old post I detailed how to avoid advert videos on the 4oD service. I have again I made use of the redirect_program feature of the Squid web proxy, but this time the adverts from Channel Five's Demand Five service are being removed.

I set about analysing how Demand Five works, by using the Fiddler web debugger from Microsoft. It became apparent that similar to the Channel Four service, there was a play list of (Flash) video files in an XML format.

So I attempted using the exact same technique as for 4oD. I created a "man in the middle" to filter out the adverts from the Demand Five play list, using my own PHP and XSLT code. Unfortunately the doctored play list I generated was rejected by the Flash player as invalid, presumably because required elements (adverts) were lacking. It's not clear whether this an intentional feature in Demand Five or not! Either way a different technique was needed.

I have avoided seeing banner adverts for some time, by having Squid serve upa 1 pixel by 1 pixel transparent GIF instead. Since modifying the XML play list on the fly didn't work out, I decided to get Squid to serve up a video of 0 seconds duration in place of an advertisement.

I searched the web and found a suitable dummy Flash video of 0 seconds length to use. So I just needed to let Squid know I wanted the dummy video instead of the advert videos. To do this I added the following line was added to my existing Perl script squid-redirector.pl:

s@http://[^ ]*\.akamai\.net/[^ ]*five\.tv[^ ]*\.flv@http://www.trollied.org/~blimey/fake/dummy.flv@;

Now I can enjoy Neighbours without having to wait for the adverts to finish. This is particularly useful when the playback gets interrupted and you have to start from the beginning.

Radio Tuner update

My Radio Tuner page lets you tune into a large number of internet radio stations, by providing playlists suitable for your favourite media player application. You can even tune in directly from my website using the Flash player.

I have been syndicating the Pirate Radio Toolbar's station list for some time, and am pleased to announce that I have implemented a similar interface for DJ Pete's Internet Radio Tuner. You no longer need to install any software to enjoy the station lists provided to users of these applications.

Unfortunately dnbstations.co.uk appears to be defunct, so I have removed the interface to it. I have however added several new stations to my own station list, diversifying the genres to include Techno and Goa Trance.

Sudoku Solver source code

I've made available the Delphi/Kylix source code, for the server part of my online Sudoku Solver.

The program can find solutions by brute force, and in many cases using logical deduction alone. The logical solver is considered adequate for its purpose, which is to give hints and validate against mistakes.

sodit.dpr
Main project file
SudokuSets.pas
Optimised library for set based operations, such as iterating permutations.
SudokuDeclarations.pas
Constants and type declarations.

The source code for "Sudoku Solver" is provided without warranty, and for non-commercial purposes only. "Sudoku solver" is copyright © 2007 - 2008 Geoffrey Swift. All rights are reserved.

Download: http://www.trollied.org/~blimey/sodit.zip (8 KB)
Website pet peeves part 4

It's been a while since the last rant, here are a few serious concerns for web developers to consider!

Resending POST data

The "back" button is very useful feature to have in web browsers. Unfortunately you can be prevented from going back to a page that is generated in response to filling in a form.

When you try to do this, the browser explains that the page can't be displayed without resubmitting the form data. This is since there are special rules which generally prevent an HTTP POST response from being cached.

So you can either resubmit the form, but you might not get the same results the next time around. There is no option of just seeing the original version of the page. The browser could ask you whether you wanted to see the old version, and could perhaps warn you that showing you the old version would be in defiance of web standards. This has to be an improvement over what is essentially a flat refusal to behave intuitively.

Web programmers can work around this problem, by making a web server respond to a web browser's posted form data appropriately. The solution is to instruct the web browser to be redirected to another web page, which can retrieved conventionally. This page you're redirected to appears in the browser's history instead, so your back button can work as normal.

For further technical details, I recommend reading the HTTP RFCs and the Wikipedia article on the "Post Redirect Get" pattern.

Click to close window

Many web pages, particularly those in popup windows have a hypertext link entitled "Click to close window". I feel this is redundant, since web browsers windows can be closed like any other. Given that web browsers open new "windows" as tabs, the wording itself isn't quite right either.

The only case for having such a link is for popup windows created in such a way to specifically hide the standard close window option. Even so this appears to be a case of trying invent a rounder wheel.

Print friendly version

When viewing websites like Google maps, it can be useful to make a hardcopy so you can review the information later. Unfortunately what you see on screen doesn't necessarily work so well on paper. This is what prompts web developers to create a "printer friendly" version.

While this seems like a great idea, I feel this is really just a sorry excuse that they couldn't figure out how to make a web page that appears correctly both on screen and on paper.

There exists a useful feature in CSS2, which lets you define formatting based on the "media" being used. You can use this to make your web page to look totally different when printed.

For an example of this in action, try using the "print preview" option in your browser when looking at my website. You should see immediately that the navigation menu disappears and background colours are turned off.

A useful article on this can be found on about.com

My name is URL

I've got through several email addresses, with all manner of quirky names, due to various reasons beyond my control. So I have finally gone ahead and acquired the geoffswift.com domain.

There's a new website on http://www.geoffswift.com/ with just a simple contact page for now. Some further content may be transferred from trollied.org in due course.

strace claims select() sets errno = ERESTARTNOHAND

The strace utility is well recommended for investigating all manner of Linux problems. But while using strace to debug a crash in the Linux version of my Talker application, I came across something which proved to be a red herring. It appeared that select() was failing and setting errno to ERESTARTNOHAND.

Without being side tracked by what that would have meant, the actual problem itself was actually a segmentation fault had happened in another thread. select() was actually setting errno = EINTR, due to the corresponding SIGSEGV signal.

The error outside of the main thread was only apparent when using strace -f. The "follow forks" option is necessary, since pthreads works by forking off new Light Weight Processes (LWPs).

I found plenty of posts on the web detailing similar issues, although no solutions offered. Hopefully this information will be helpful to someone else.

Drum and Bass mix

It's been quite a while since I last posted up a mix, although I have been getting a bit of practice in nonetheless. So here's a new drum and bass mix, to celebrate British Summer Time!

The tracks selected are all several years old, but don't expect to hear many 'classics'. This selection represents a selection of my favourite tracks which seemed to be off the radar of top DJs.

Will hopefully appeal to fans of the darker side of drum and bass. Feel free to comment…

Download: http://www.trollied.org/~blimey/blimeydnbmix4.mp3 (55 MB)
Converting XSPF to M3U and PLS with XSLT

I'm now syndicating another internet radio station playlist, the new one is from http://www.dnbstations.co.uk/. This didn't take long to implement, as I was able to reuse existing code which converts from XSPF to both M3U and PLS. I did write some new code to convert a Wimpy play list to XSPF, this was pretty easy as the formats are very similar.

The XSLT code to convert a Wimpy play list to XSPF, and from XSPF to M3U and XSPF to PLS is hereby released into the public domain.

Not only does www.dnbstations.co.uk provide the Wimpy playlist, they act as a proxy for all the streams. This seems to be wasteful of their bandwidth, when they could easily let listeners access the stream directly. I was quite surprised when I noticed this, thinking that the stream URLs were just using HTTP redirects. Maybe they'll redo this in the future, depending on how successful they are!

Bypass JavaScript with Squid

I mentioned previously how I used the redirect_program feature in the Squid web proxy to filter out adverts from Channel 4's 4oD service. I did that by intercepting and modifying ASX files. In this article I explain how similarly one can deactivate unwanted JavaScript code.

One motivation for intercepting JavaScript is to avoid advertising, I'm also bypassing Google Analytics. For an entirely self contained JavaScript, your own blank script can be substituted. This works well for example with Google's advertising script show_ads.js.

To use Google Analytics, web site authors must write their own code to invoke the functions Google supply in their JavaScript files. So if Google's code is simply replaced by a blank file, JavaScript errors will result as required functions have not been defined. I've therefore written my own versions of their scripts which mimic the necessary code entry points, but don't actually do anything.

A replacement for the original Google file urchin.js was trivial:

function urchinTracker(){}

but the recently updated Google Analytics script ga.js was a bit more complicated:

var _gat = { _getTracker:function(s) { return { _initData:function(){}, _trackPageview:function(){} } } }

The scripts mentioned above are very popular on many websites. My replacement versions are obviously going to help speed up load times on several web pages, as the web browser has less work to do. Another bonus is that I avoid being included in my own Analytics data, and I get a better idea of who else is looking at my site!

XHTML DTD in XML catalog

I had read an article "W3C Gets Excessive DTD Traffic" on Slashdot last month. This struck a chord since I use XSLT to generate XHTML, and had noticed that the XHTML DTD is downloaded each time it is referenced. This is wasteful of both bandwidth and slows down the XSLT considerably.

To remedy this problem, I downloaded these files to my Linux box and added some XML catalogue entries. This ensures local copies of these files ares used instead of repeatedly downloading them from w3.org.

Here's the shell commands I used on my Slackware 12 box to set things up:

mkdir /usr/share/xml/xhtml1 cd /usr/share/xml/xhtml1 wget http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd \ http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd \ http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd \ http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent \ http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent \ http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent xmlcatalog --noout --add rewriteURI http://www.w3.org/TR/xhtml1/DTD/ \ file:///usr/share/xml/xhtml1/ \ /etc/xml/catalog

To confirm this was working as expected I ran xsltproc under strace. I did however discover what I'd done had no effect on libxslt in PHP. I looked through the source code for PHP, and found no code to initialise libxml to use XML catalogues. This would be a nice feature, hopefully it will be included in a future release of PHP.

Tinyfugue 4 patched for GCC 4

The CHANGES file in Tinyfugue 5 explains that the user interface has changed: New screen handling. See "/help windows". What this means is that when changing between worlds, the whole screen is replaced to show only output from the selected world. Previously messages from each world would all appear in succession on screen.

As I multi-spod and hold conversations across several talkers at the same time, this new interface is not my personal preference. I would rather be using the time honoured classic, which is Tinyfugue 4. However I discovered recently that this older version no longer compiles on modern Linux distributions.

I had a look into this problem, and fixed the source code by retro fitting the relevant fixes already done in Tinyfugue 5. The changes were minimal, so it didn't take long to get this compiling for GCC 4 on Linux. I made a unified diff of these changes. This has come in handy twice for me now, so I hope this proves useful to someone else.

--- history.c.orig 2008-03-04 00:49:30.000000000 +0000 +++ history.c 2008-03-04 00:47:01.000000000 +0000 @@ -66,7 +66,9 @@ static struct History input[1]; static int wnmatch = 4, wnlines = 5, wdmatch = 2, wdlines = 5; -struct History globalhist[1], localhist[1]; +struct History globalhist_buf, localhist_buf; +struct History * const globalhist = &globalhist_buf; +struct History * const localhist = &localhist_buf; int log_count = 0; int norecord = 0; /* supress history (but not log) recording */ int nolog = 0; /* supress log (but not history) recording */ --- history.h.orig 2008-03-04 00:49:37.000000000 +0000 +++ history.h 2008-03-04 00:46:51.000000000 +0000 @@ -13,7 +13,7 @@ # ifndef NO_HISTORY extern void NDECL(init_histories); -extern struct History *FDECL(init_history,(struct History *hist, int maxsize)); +extern struct History *init_history(struct History *hist, int maxsize); extern void FDECL(free_history,(struct History *hist)); extern void FDECL(recordline,(struct History *hist, Aline *aline)); extern void FDECL(record_input,(CONST char *line, struct timeval *tv)); @@ -31,7 +31,7 @@ #define record_global(aline) recordline(globalhist, (aline)) #define record_local(aline) recordline(localhist, (aline)) -extern struct History globalhist[], localhist[]; +extern struct History * const globalhist, * const localhist; extern int log_count, norecord, nolog; # else /* NO_HISTORY */
Download: http://www.trollied.org/~blimey/tf4.diff (1 KB)
Streaming Radio Formats

Implementing my radio player took more experimentation and research than actual coding. As with most software, things turn out more complicated than first anticipated!

To tune in into an Internet radio station, normally you would click on a link on the station's website. From this link your browser will download a play list file, which in turn contains the URL that your favourite media player can use to access the station's live stream. My goal was to make this accessible in a more convenient manner, by allowing access to several radio stations in one place.

So I decided to create my own play list file that contained all the relevant URLs for my favourite stations. I wrote a PHP script that would generate this this play list by downloading each station's play list and extracting the relevant stream URL.

Play list file formats

There are three main formats used for these play list files, which are ASX (Windows Media Player), M3U and PLS (WinAmp).

Easiest to parse was M3U, this is just an ordinary text file that has the URL as a line of text. As PLS is an INI file, this seemed easy using PHP's built in functions to parse INI files. I quickly found that the PHP functions were unreliable so I wrote a kludge to get the URL myself, using a simple regular expression.

In a previous article I discussed problems with ASX files not being XML, so I avoided using this format unless the station did not also offer M3U or PLS. By sheer luck the few stations I am accessing via ASX are well formed XML. Unfortunately the structure of these ASX files vary, so it took a few iterations of the XSLT code to extract the stream URL realiably.

The file format I ultimately create my play list is is XSPF, as this is a well defined format based upon XML. From the master XSPF play list, I can readily generate ASX, M3U and PLS by using XSLT. Having the playlists available for means good support for tuning in with various different media players. I would personally recommend using the XSPF play list in VLC Media Player.

Streaming from a web page

I felt the stations should ideally be available directly a browser, without requiring an external application to be installed. After trying a few different options I opted to use the "XSPF Web Music Player" written in Flash. Getting Flash working is an exercise in itself made easy using the UFO JavaScript library. This setup offers good compatibility with typical browser setups.

Fixing the stream URL

The biggest problem with this was presented by a strange behaviour of Shoutcast servers. When you access the stream URL for a Shoutcast server using a web browser, you are served up a web page about the stream. This HTML content is provided instead of the MP3 stream, on the basis of the User-Agent header of the HTTP request.

Generally browser plugins have their HTTP requests made for them by the browser, so HTML content is delivered to a Flash movie or a Quicktime regardless. The exception to this is the Windows Media Player plugin, which bypasses the browser completely; disregarding proxy settings etc.

Shoutcast servers do provide a special URL that allows you to ensure the MP3 stream is returned regardless of the User-Agent. You just append ;stream.nsv for example http://example.com:1234/ becomes http://example.com:1234/;stream.nsv.

Appending this string confuses any servers that aren't using Shoutcast though. So it became necessary to probe each server, to adjust the URL where required. This works by impersonating Firefox and when HTML comes back, that's Shoutcast.

Memory usage

One significant problem appears to be that of memory consumption while listening to a stream. If you're listening for a few hours or so, expect your memory usage to be in the 100s of megabytes. This is enough to cause problems in a typical PC setup. A workaround for this is to stop and restart the stream occasionally.

The reason behind this is that the MP3 stream is treated as if a very long MP3 file is being downloaded. What you've heard so far remains in memory even though, with the exception of Real Player, you can't seek backwards. This is a well known problem that affects nearly all media players and browser/plugin combinations except VLC Media Player.

Recommended use

If you use the M3U or PLS play lists, you may well just see IP addresses and port numbers rather than meaningful station names. This is a limitation of the file formats used, and isn't fixable. Using the XSPF play list is recommended as it has the station name and website link. Also you can use the XSPF play list in VLC Media Player, without having to worry about your memory usage.

ASX and XML are incompatible

I have been working with various playlist file formats as part of my internet radio project. This has involved creating XSPF playlists from XML sources and using XSLT to convert from XSPF to the alternative PLS and M3U formats.

According to the Simple ASX article on MSDN: an ASX file is an eXtensible Markup Language (XML)-based text file which references a Uniform Resource Locator (URL) for a piece of media content. Having read this I felt that ASX files ought fit neatly into my XML and XSLT based architecture. Only when implementing this, did I discover that ASX actually has quite limited compatibility with XML.

The XML validation tool xmllint rejected a couple of ASX files, since they included the copyright symbol © encoded using ISO-8859-1. It seemed easy to solved this problem, by explicitly specifying the encoding in the XML declaration e.g. <?xml version="1.0" encoding="iso-8859-1"?>. Although the file could then be validated as XML using xmllint, Windows Media Player would simply not load this modified ASX file. It was then apparent that ASX is not compatible with XML.

Some URLs referenced in ASX files may well have query strings, which are of course delimited with ampersands. After seeing a few of these I noticed that none of the ampersand characters were escaped as they should be in XML. For a well formed XML document, a literal ampersand charater should be represented using an escape sequence, e.g. &amp;.

I edit an ASX file to make it valid XML, by ensuring the appropriate escape sequences were used. The play list came up in Windows Media Player, but it did not play as expected. When looking at the properties of the relevant track in Windows Media Player, the text &amp; could be clearly seen as part of the URL. Although I had made an ASX file into a valid XML document, once again this was futile since the ASX file was not interpreted as intended.

To summarise here are some quirks of ASX files that make it incompatible with XML:

  • The default encoding for ASX appears to be ISO-8859-1.
  • An XML declaration cannot be included in an ASX file.
  • Ampersand characters in ASX files are parsed as literal text and should not be escaped as &amp;.

To work around these problems, I wrote a PHP script that downloads an ASX file and converts it in an XML format. To achieve this it simply escapes all the ampersands, and serves this modified content with an appropriate HTTP header for ISO-8859-1 encoding: Content-Type: text/xml; charset=iso-8859-1. Aside from XML incompatibilities many ASX files are tag soup. My PHP script therefore includes kludges to address problems specific to the ASX files I'm working with.

This wasn't quite the clean solution I originally had in mind, but I am now able to import from multiple ASX files across the web. It was less trouble working around PHP's woeful ini file parsing routines to get the PLS file format supported, but that's another story!

Pirate Radio Toolbar "pirated"

Having made my own list of favourite internet radio stations available online, I was quite interested to hear about the "Pirate Radio Toolbar." I downloaded and installed the toolbar, and found it offered an impressive list of pirate radio stations. Most are pirate radio stations that also stream over the internet, a lot of the others were internet based stations that also play underground music.

The toolbar software itself is created (or rather configured) using the Conduit website. Conduit allows anyone to sign up to create similar toolbars for commercial use. These toolbars can be configured to have many different features, one of which is a radio playlist.

My sole interest was the list of stations, since I regularly enjoy listening to internet radio. The rest of the tool bar offered nothing I wanted; it merely obscured the top of my web browser. It seemed much more appropriate to listen using a more fully featured purpose built program like VLC Media Player to tune in. With music playing in another program you can obviously hide the player behind your browser!

So I mused with the idea of extracting the relevant data into an appropriate format. Using the Fiddler HTTP debugger, the URL for their play list data became apparent quite quickly.

The play list for the Pirate Radio Toolbar (and other Conduit toolbars) arrives over the web in an XML format, which is ideal for manipulation with the XSLT (the programming language used for my website). So I wrote some XSLT code to convert the playlist into an XSPF format, ideal for use in VLC Media Player.

I wrote a shell script to download the Pirate Radio Toolbar station list using wget, and convert it using xsltproc and my XSLT stylesheet code. This script runs nightly using cron, so my copy of the station list should keep up to date with any new stations they add.

I even wrote a couple of extra XSLT stylesheets to convert XSPF to the PLS and extended M3u file formats. I make use of these stylesheets to generate my own dynamic radio playlist now. I might post this XSLT code up for download in case anyone else wants to do similar conversions.

Please visit my radio page for more details. I host my own radio station play list, which exclusively comprises high bitrate drum and bass, jungle and dubstep.

Download: http://www.trollied.org/~blimey/pirateradio.xspf
Atom to RSS 2.0 feed conversion

I am pleased to say that there is now a valid RSS 2.0 feed available for my blog. Previously there was just the Atom 1.0 feed, since this is format I am using for storage.

I couldn't find any available Atom to RSS conversion utilities, except for atom2rss.xsl from http://atom.geekhood.net/. I had tried using this a while ago, but found it would not produce valid RSS and even corrupted parts of my text through inappropriate handling of escape sequences.

Feeling a bit more confident in my XSLT, I set about addressing these issues. The feed validation service from w3.org now tells me that "this is a valid RSS feed", and so consider this to be good enough for my purposes.

It is slightly disappointing that RSS limits you to a single enclosure (podcast) for each item in a channel, whereas Atom allows for multiple enclosures. Because of this it is not recommended to use the RSS feed since you will actually lose out on some of the mp3 content.

My Atom feed has brought to light some cases that cause a problem with the XSLT code, and there are probably other valid Atom feeds that would not be translated to a valid RSS feed. Nonetheless I feel this is an improvement and am releasing this updated version into the public domain.

I've emailed my fixes over to porneL who originally wrote atom2rss.xsl, and he's kindly updated his site to include my changes.

Web based Radio Tuner

I'm pleased to announce a brand new version of my radio tuner. This is now embedded into my website using a the XSPF Web Music Player, which is written in Flash. I hope other people will enjoy using it as much as I am, any feedback is welcome.

Oldskool jungle tracks

Here are a few oldskool jungle tracks I've written several years ago. Seemed about time to put them up in a podcast, as they weren't very prominently linked to before. Have been meaning to do this for a while, and if time allows more could I find time I might dig some more out.

These were all written using 8-bit breakbeat samples I created on the Atari ST using Mastersound. These were chopped up into tiny pieces, then sequenced using Fast Tracker 2 on the PC. Now turned into MP3z using XMPlay and Lame for your listening pleasure! Enjoy.

Download: http://www.trollied.org/~blimey/32e.mp3 (1 MB)
Download: http://www.trollied.org/~blimey/absurd.mp3 (2 MB)
Download: http://www.trollied.org/~blimey/backup.mp3 (3 MB)
Download: http://www.trollied.org/~blimey/press2.mp3 (3 MB)
Radio Tuner in IE7 - XSLT meets conditional comments

Getting Internet Explorer 7 to work with the HTML version of my internet radio tuner was no walk in the park. Read further to learn how to avoid the same pitfalls.

The first problem was that using <object type="application/x-mplayer2" data= … > yields the error "Internet Explorer has blocked this site from using an ActiveX control in an unsafe manner. As a result, this page may not display correctly." Puzzlingly I found that there is no such warning when using <embed type="application/x-mplayer2" src= … > instead.

Using <embed> rather than <object> just for the sake of Internet Explorer didn't make me feel entirely happy, as this proprietary tag is not valid HTML. To solve this problem and retain the validity of my HTML, I chose to use the even more proprietary trick specific to Internet Explorer - conditional comments. This means that the IE specific <embed> is effectively commented out, and the <object> tag is ignored by IE. See some example HTML below:

<!--[if IE]> <embed type="application/x-mplayer2" src="" width="290" height="64"></embed> <![endif]--> <!--[if !IE]><!--> <object type="application/x-mplayer2" data="" width="290" height="64"></object> <!--<![endif]-->

This was slightly tricky to get right in the XSLT. I could have tried using xsl:comment and CDATA sections, but xsl:text and disable-output-escaping seemed like less trouble:

<xsl:text disable-output-escaping="yes">&lt;!--[if IE]&gt;</xsl:text> <embed type="application/x-mplayer2" src="{@href}" width="290" height="64"/> <xsl:text disable-output-escaping="yes">&lt;![endif]--&gt;</xsl:text> <xsl:text disable-output-escaping="yes">&lt;!--[if !IE]&gt;&lt;!--&gt;</xsl:text> <object type="application/x-mplayer2" data="{@href}" width="290" height="64"/> <xsl:text disable-output-escaping="yes">&lt;!--&lt;![endif]--&gt;</xsl:text>

Problem number two relates to the "fix" Microsoft have made to avoid infringement of Eolas Technologies' patent "distributed hypermedia method for automatically invoking external application providing interaction and display of embedded objects within a hypermedia document." This means that Internet Explorer displays a message saying "Click to activate and use the control". Surprisingly the music starts playing automatically anyway, but this is still a minor annoyance. The problem was solved by calling this JavaScript function via document.onload():

function eolasWorkaround() { var i; if ('Microsoft Internet Explorer' != navigator.appName) { return; } if (typeof document.getElementsByTagName == 'undefined') { return; } var embeds = document.getElementsByTagName("embed"); for (i = 0; i < embeds.length; i++) { embeds[i].outerHTML = embeds[i].outerHTML; } }

This complete solution seems to work quite well on all the Windows based browsers I have available now, even Internet Explorer! I have no facility to develop and test this on other platforms, which may not know which plugin to use for the MIME type "application/x-mplayer2". I intend to address this in due course.

In any case the MIME type should strictly speaking be "audio/mpegurl", but this is not supported by Windows. But in case of any difficulty, you can always just click the hypertext link to download the radio.m3u playlist and play it in an external application.

Eolas is a registered trademark of Eolas Technologies Inc. Microsoft, Windows, ActiveX and Internet Explorer are registered trademarks of Microsoft Corporation in the United States and other countries.

Goodbye 4oD adverts

I quite like using the 4oD service from Channel 4, I can watch their programs at a time that suits me without the regular ad breaks on live TV. The adverts appear just before the program starts instead, and although you can skip to the right part of a program once it's playing, you can't fast forward the adverts.

The program is delivered to the 4oD player as a play list for Windows Media Player in the ASX file format. The first few items in the play list are the URLs for adverts, and the last one is the actual TV program. To avoid having to sit through these adverts, I saw there was the potential to to intercept this play list and remove the entries pertaining to advertising.

To achieve this, I made use of the redirect_program feature of the Squid web proxy. In this case, it allows me to tell Squid to fetch the play list from my website rather than directly from Channel 4. I wrote the following Perl script based on the example in the Squid documentation:

#!/usr/bin/perl use URI::Escape; $|=1; while (<>) { s@(http://vodapp\.grid\.channel4\.com/c4site-web/playlist\.do\?[^ ]*)@"http://www.trollied.org/~blimey/4oD.php?url=" . uri_escape($1)@e; print; }

So when the 4oD client requests a play list from the vodapp.grid.channel4.com server, it instead requests the playlist from my website. My website then downloads the desired play list, and does the required filtering using PHP and XSLT.

This PHP, very simply downloads the play list into a DOM document and applies the the required XSLT to it.

<?php $basename = basename($_SERVER['SCRIPT_NAME'], '.php'); $xslfile = $basename . '.xsl'; $xmlfile = $_GET['url']; $xml = new DOMDocument; $xml->load($xmlfile); $xsl = new DOMDocument; $xsl->load($xslfile); $xslProc = new XSLTProcessor(); $xslProc->importStylesheet($xsl); header('Content-Type: video/x-ms-asf'); $doc = $xslProc->transformToDoc($xml); echo $doc->saveXML($doc->firstChild); ?>

Here's the XSL, that simply copies everything in the document except for any ENTRY that has a TITLE starting with the word advert.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" method="xml" media-type="video/x-ms-asf"/> <xsl:template match="/ASX/ENTRY"> <xsl:if test="not(starts-with(TITLE, 'Advert'))"> <xsl:copy-of select="."/> </xsl:if> </xsl:template> <xsl:template match="/ASX/*[name() != 'ENTRY']"> <xsl:copy-of select="."/> </xsl:template> <xsl:template match="/"> <ASX VERSION="3.0"> <xsl:apply-templates/> </ASX> </xsl:template> </xsl:stylesheet>
Website pet peeves part 3

Text size changing underneath mouse pointer

It might seem like a nice idea to have text become bold, or even larger when you position the mouse over it. But this can cause problems when the layout of the page is affected.

Suppose I position my mouse over such text, and it gets bigger. This can cause the text to be moved away from the mouse pointer, which means that the text reverts to its original size. Once the text has shrunk back to its original location under the mouse, it then grows and the cycle repeats until the mouse is repositioned.

My suggestion is to only do this if you can be sure you will not be affecting the layout of the web page. For example make sure the text is bounded within a box that is large enough for the text, regardless of whether it is enlarged by the position of the mouse.

Redirecting to an error page

Occasionally websites have problems, and so it is appropriate to display an error to the user. Rather than having the desired web page display an error, some websites redirect to a dedicated web page that explains an error has occurred.

Errors quite typically are due to a temporary glitch, and so you might expect to be able to use the refresh button in your browser to reload the web page. If you've been redirected to a separate page this isn't possible, even clicking back will redirect you to the error page again.

Instead it seems necessary to click back in rapid succession, before the redirection kicks in. That way you can once again attempt to repeat the steps required to load up the problematic page. This may involve filling in a form once again, but either way this is not user friendly! It would be preferable to display error messages on the web page the error occurred, so that it's possible to simply click refresh.

Website pet peeves part 2

What country am I in today?

Lots of websites have forms that let select your country. Unfortunately these websites generally have a large number of different countries to choose from. I find this means a regular chore of guessing which country to look for, the right one could be any of the following: Britain, England, Great Britain, United Kingdom or UK. The only option I haven't come across is the actual name of the country where I reside, the United Kingdom of Great Britain and Northern Ireland.

So to anyone writing a web pages with forms allowing a choice of countries. It would be nice to see a default country value determined using a country IP database. That would make things a bit easier.

"Back to" … the future

A lot of sites have links with text such as "Back to homepage", or "Return to to search results". But you may have accessed the page via a link on an external site or even a bookmark. So the wording of such links presumes that a visitor to the site came via the web page that's linked "back" to. My suggestion is to leave out the word "back", as it is fairly redundant and potentially inappropriate.

Comparing techniques

There are lots of interesting tips and ideas relating to programming techniques and related principals bandied about. The people who advocate them have all sorts of different backgrounds, and undeniably it can be very useful to draw on the experience of others.

Some techniques are devised to solve problems that are common to all programmers alike, but the significance of an underlying problem addressed will vary for each project. While something may be critically important for you, it could well be of insignificant concern to somebody working on a different project.

Each programmer faces difference challenges, and has difference experience - so the solutions they come up with are quite personal to the individual. For example a programmer may advocate a technique that merely addresses a problem specific to certain programming languages, or is specific to the size/complexity of their application or even their development team.

Techniques in computer programming have evolved significantly over time, and opinions are constantly changing. This is no surprise, considering the rapid pace of change in what software is used for and how it is used.

Because of this, I feel it is important to have an awareness of various different techniques. In each new scenario it's then possible to decide what is the most appropriate technique, treating each case on its merits.

Programming is a complex task and difficult to make generalisations about. There are many tips floating around that contradict one another, and have no explanation of what the basis for them is. It is more difficult to evaluate a technique, without some explanation of what its purpose is.

Website pet peeves
From my referer logs I've noticed people looking up problems with XHTML, JavaScript and CSS. Hopefully some web designer will read my pet peeves below, and mend their ways!

Bad support for font resizing

I use a relatively high resolution 1600*1200, and so most websites look small to me. When I increase the font size in my browser (Firefox) to compensate, the layout of most sites become a complete mess. Typically words are crammed into columns that just look too narrow, or text becomes illegible because it no longer fits inside its containing box. This problem typically occurs because dimensions have been stipulated using pixels in the CSS code, but this will go wrong for other fixed unit of measurement. So when you're coding up your layout using the "box model", try using only em, ex or percentages instead of pixels and the layout should resize in proportion with the text.

Login forms setting focus away from password

Many websites have login pages, which set the focus to the user name field when the page finishes loading. This might sound like a great idea, but not while I'm in the middle of typing in my password! I don't really want half my password in the password box, and the other half plainly visible in the user name field. This is another quite common problem. A simple fix might be to only set focus on the user name field, when it is empty.

Click to enter site

There still seems to be no shortage of sites, with a main page that just says "click to enter site." The fact that such a page actually is the website, seems to be lost on the web designer. Unless there's a good reason for having such an entrance page (like a disclaimer) just let people surf straight in to meaningful content without any such inconvenience.

Radio tuner revamp

My homepage has a link to tune into my internet radio presets. This play list file is generated automatically by the web server, which checks whether each of my favourite stations is currently available.

I've updated some of the dead links for some Drum & Bass stations that have moved, and included some new Dubstep stations also. There's now also only one entry in the play list per station, to make channel hopping easier. This also makes the list load up quicker as it does fewer checks.

Give it a try, just click on the link to the file radio.m3u, it should open up in Media Player or iTunes etc. let me know what you think!

Windows Services in Delphi

The Win32 API methods for the Service Control Manager are powerful but rather unwieldy. Download the Delphi unit service.pas which contains wrapper functions for QueryServiceStatus(), StartService() and ControlService().

See the interface section for the unit below, hopefully it's all self explanatory.

unit service; // Some useful wrapper functions for NT Services. // Geoffrey Swift (c) 2006 interface uses Windows; function GetServiceStatus(const ServiceName: String): DWORD; function StartService(const ServiceName: String; const Wait: Boolean): DWORD; function StopService(const ServiceName: String; const Wait: Boolean): DWORD;
Sudoku enhancements

The Sudoku page has been improved today. When entering a number, some simple checks are made for an error. If the number entered is OK, it automatically moves to the next cell ready for another number to be typed. I updated the server application also, and the solution can be interactively solved. The server now solves easy parts of the puzzle as you key it in. This is implemented using AJAX programming techniques.

I would also like to set up a daily puzzle. The Pascal source code for the server side solution engine might get posted, if I find time to tidy it up. Please leave comments if you have any ideas!

CRUD features of blog

So far the Atom 1.0 XML feed for my blog has been written by hand using the Vim editor. Recent development on the website for the blog means that I may create, read, update and delete blog entries using a web browser. Browsing the blog through the web already possible, but this is now more or less complete CRUD.

Summer Drum & Bass mix

Some heavy drum and bass tracks in this mix. Turn your bass down!

Download: http://www.trollied.org/~blimey/blimeydnbmix3.mp3 (55 MB)
Blog is open for comments

The latest feature of my site is one that allows anyone to post a comment against items in my blog. Just like the blog itself, the storage mechanism is an Atom xml file, so there's even a feed.

While writing a template for the comment form in XSL, I found an interesting problem with whitespace normalisation. The XHTML produced originally included a tag like this <textarea/>, rather than <textarea></textarea>. Internet Explorer doesn't recognise XHTML, and so ignores the fact the tag has been closed as per XML rules. The result is that any subsequent HTML is assumed to be the contents of the textarea, and could be clearly seen as such on screen!

I solved a similar problem with script tags, by putting the opening and closing tags on separate lines. But this technique means the form does not initially appear blank, rather the blank line appears in the textarea instead. The solution I adopted was to use the "zero width no-break space" Unicode character, resulting in an apparently blank form:

<textarea> <xsl:text>&#65279;</xsl:text> </textarea>

This all looked fine, until I tried validating the form in DHTML. Although the form appears blank to the user, and does even in "view source", it is not blank! To check for the comment being blank, I stripped out the \uFEFF character in JavaScript first. Internet Explorer's JavaScript implementation at least understands Unicode regular expressions!

The form validation is written generically also, a new script looks for any forms and adds in a new onsubmit event handler. This event handler processes any elements with the attribute class="mandatory", and notifies the user they are blank. The message displayed on screen even makes use of the text in the <label> associated with the form element.

Attempt at hAtom microformat

I have managed to incorporate the hAtom microformat into the XHTML rendering of my atom feed on my webpage, albeit with limited success. Adding the extra class attributes to the XHTML elements in the XSL template seemed simple enough, but the microformat stipulates marking up the HTML element that corresponds to an atom:entry with class="hentry". Unfortunately I'm using a <dl> tag in place of an atom:feed, and using <dt> and <dd> tags for the atom:title and atom:summary respectively. Owing to the fact that these are the only valid child entities for a <dl> tag, I have to lose half the data per post! I can't for example just put in a <div class="hentry"> around each post, as that would not be valid XHTML. The existing DHTML code is geared up to use this hierarchical structure, so fully supporting hAtom might have to go on the back burner. A permalink for individual posts works OK in htatom2atom, but that's because the post title is taken from the <head> of the XHTML document.

Internet Explorer Kludges

In a previous post, I had complained about Internet Explorer being broken. It turns out that it actually is possible to set and check the class of a DOM element, but Internet Explorer erroneously uses the moniker className rather than class. So for example, the following works fine in all modern browsers, but has no effect in Internet Explorer:

node.setAttribute('class', 'example');

The following example solves the problem for Internet Explorer:

node.setAttribute('className', 'example');
node.setAttribute('class', 'example');

I have also found that Internet Explorer evaluates String.split() differently, when given a regular expression as a parameter. Notably the array of values returned does not include any empty string values. For example "a,,c".split(/,/) will confusingly be evaluated as ["a", "c"] rather than ["a", "", "c"].

This caused a problem with highlighting search terms, when the search term was at the beginning of a string, and the unhighlighted prefix would be the empty string. I was able to work around this by using a sentinel value, to prefix the text.

Submenu items for blog categories

The existing menu had a flat structure, but now can accept hidden submenus. If present, a submenu will appear when moving the mouse over the appropriate top-level menu item.

I've populated the menu structure using AJAX techniques on my Atom feed. Menu items containing links to blog posts can now be found underneath the "blog", "updates" and "podcasts" menu items in the main menu. The posts are listed according to the category.

Highlighting of search terms from referer

Having had a look through my referer logs, it was clear people were obviously using Google to find the site. To make things easier to find, search terms used on Google are now highlighted in the page when a user finds their way here.

The work happens in the browser, rather than the web server producing a modified version specially for the user. This way caching all works as normal.

The first step is to parse the search query, into individual terms. Then my code recursively searches through the DOM and finds any text nodes which match the current search term. Any such text node is then replaced by a sequence of nodes containing either highlighted and unhighlited text.

The hard work in this is all done through regular expressions and the DOM/CSS. Try it out for yourself and use view source if you're really interested!

Darkside Drum & Bass mix

I did this mix a while ago now, but haven't had chance to upload it as I'm currently without an internet connection at home! The mix starts off with some techy stuff and winds down with some old classics.

Download: http://www.trollied.org/~blimey/blimeydnbmix2.mp3 (55 MB)
Yahoo! search engine integrated (and not Google)

I've used the Yahoo! search API within my personal site, and now have my own personal search engine. Having registered my "application", it was relatively straightforward to invoke the search engine using REST. The results come back in various formats including Serialized PHP and JSON - for me it made the most sense to use the default XML format. Having written a suitable template in XSL, it was a breeze to incorporate the search results into the site. There is some fiddly DHTML to put a search box in the top right corner of each page. I am pleased with the results, for my effort anyway.

Yahoo trumped Google on this occasion, as they aren't letting anyone sign up for their SOAP based search service. Both are taking data from my sitemap.xml file, but Yahoo allows you to submit an Atom feed as well. I noticed that Google Webmaster Tools reported a page not found in the "Web crawl errors" section. The URI was /~blimey/{sitemap:loc} - which GoogleBot attempted to spider, since my sitemap.xsl file contains the code <a href="{sitemap:loc}"> - d'oh! Google has mistaken my expression in XSL as a literal URL. I added noindex to the meta tag for robots in my sitemap.xsl, maybe in an equally daft way that'll help!

Code matures and delivers gzipped CSS

I've removed the big clunky "valid XHTML" and "valid CSS" icons, since the code is fairly mature and I'm confident it produces valid output. Besides which, I'm using a browser plugin to invoke the W3 validator now anyway.

I also ensured the CSS is sent gzipped where possible, with appropriate headers to allow them to be cached by browsers/proxies. The XHTML, JavaScript and RSS were already delivered in this fashion.

I made some of the code more generic, with a config file as well. This is because I'm using much of the code on another website now. As it is a commercial site, it's a good thing it seems to works OK!

Next job is probably allowing comments on blog posts, or some kind of archive / search facility for the blog.

HTTP Redirect for blog category tweak

I made the site a bit cleaner and removed some repetition in the content. The "updates" and "podcasts" categories each already had their own dedicated php page, to be directly accessed from the main menu. When the XPath query passed to the generic blog page would result in either of these categories, an HTTP redirect automagically sends you there instead. This then ties the blog filtering/navigation into the overall site navigation. Currently this is hardcoded, so I may look into a more generic mechanism to facilitate the addition of further categories into the main menu. Either way the XPath in the query string for blog.php generated by the XSL will work, as it did before.

delicious fixes / permalink titles

After an extensive break from working on the code for my website, I had a session involving PHP, XSL and C.

The egosurfing page didn't display all links, since del.icio.us limits the number of items returned in an RSS feed. It was trivial to adapt the XSL to use the XML produced by the del.icio.us API, although the HTTP-Authentication aspect was a bit trickier. Since it was necessary to hardcode my password somewhere, I wrote a setgid binary (chmod 2711) in C which is a wrapper for wget. Only my user can read the file which contains the password, but it can still be executed by the Apache process.

Individual blog posts now have a more appropriate <title>, when the permalink is used. The motivation being better exposure in the blogosphere, since the <title> tag being of importance for SEO. This wasn't so much trouble to implement, as I already had the Atom post and web page XHTML in DOM documents.

Saturday afternoon Junglism

I found some great old school CDs in Shipley's charity shops (they have a few), but nothing I didn't already have. This is either frustrating or reassuring, depending on how I look at it. I walked back and did a jungle mix, got a bit excited in the process and went a bit crazy on the high speed Amen breaks. Had to calm it down a bit towards the end!

Download: http://www.trollied.org/~blimey/blimeyjunglemix2.mp3 (55 MB)
New Year's Rave Mix

What better way to kick off the New Year than another mix of classic rave. Bringing things up to date there's even a couple of 1992 tracks this time! It was difficult to resist the temptation to play L.A. Style's "James Brown is Dead", to balance things up you also get "James Brown is Still Alive" from Holy Noise.

Download: http://www.trollied.org/~blimey/blimeyravemix2.mp3 (55 MB)
Blog attempt

Have refactored the XSL code for the podcasts/site updates pages, so that an XPath query can be passed into a generic implementation. This means I can have the blog.php page filter out individual posts for permalinks and by category currently. I'm doing this by manipulating DOM nodes in the XSL before applying it, seems to work alright anyway. This essentially paves the way for making a more fully featured search engine and navigation system. Maybe once it's working and I've run out of things to implement I might have more to say to justify its existence!

Radio Play list

While listening to internet radio stations, I found it a bit tedious to have to visit the radio station's site and find the link to tune in. This would then clear out the play list in media player.

My solution is a php page, which aggregates the play lists from various sites: http://www.trollied.org/~blimey/radio.m3u. Now I can channel-hop, just as I would when watching TV!

This wasn't so difficult to implement, the radio stations use either file format of m3u, pls or asx. The asx file format was tackled with some xsl, pls files are parsed with php's parse_ini() and m3u was absolutely effortless. I used the curl library in php to make a HTTP HEAD requests, to check each of the streams are up.

This is something I wrote for my own use, but I realised others might find it useful. I started a thread advertising this on the dogsonacid forum, so it will be interesting to see if there's any feedback.

Sanity checks for legacy browsers

I've been using a few sites which take screenshots of a website in different browsers for you. This sites are: http://browsershots.org , http://www.browsercam.com and http://www.browsrcamp.com/

This is a very useful service. It has enabled me to find and fix problems in legacy browsers. In many cases there is just a sanity check to detect whether the browser is capable of performing a required feature. Some problems I haven't yet solved because the browser simply crashed without giving me any kind of error message to go on.

XHTML document.writeln() imposter functions.

I thought it'd be a nice idea to include my del.icio.us tagrolls on my homepage. This is made possible by some JavaScript served up by their website. Unfortunately their implementation relies on document.writeln() which is not compatible with XHTML.

Undeterred, I created imposter versions of document.write and document.writeln. My implementations progressively concatenate the parameters into a buffer. When the web page loads, the buffered XHTML is positioned appropriately by using an empty placeholder tag.

I originally tried parsing the buffer as an XML document, with the intention of merging the XML nodes into the XHTML document. I tried using xmlDoc.documentElement.cloneNode(true) as a parameter for appendChild() on an XHTML node.

While this worked like a charm in both Firefox and Opera, Internet Explorer complains of "Interface not supported" and Safari has a fatal error! The failing browsers have an incompatibility of XML and XHTML DOM nodes, even though they both support a common DOM interface.

In the end I had to write my own version of cloneNode() to copy elements between the incompatible schemas and ensure valid nesting of elements. There's an exception handler that fails over to using innerHTML complete with IE kludges just in case.

If you're interested to see how this was achieved, please feel free to view the JavaScript source code.

Sudoku Solver page added

I dug out some Delphi code I wrote to solve Sudoku puzzles, and it compiled unmodified in Kylix. This and a bit of XMLHttpRequest are now the basis for the backend of the Sudoku solver. If time permits, I'll make it solve the puzzle as you key it in, something like Google suggest.

Flash MP3 player for podcast enclosures

Having seen thefixup.net, I felt the need for a flash MP3 player for my podcasts too. I'm using the same one, which is the Audio Player Wordpress plugin from 1 Pixel Out. While it's nicely packaged up, it seems the authors have perhaps missed a trick that perhaps playing MP3s might be useful for non Wordpress sites! It was fun reverse engineering it into my XSL anyway, although I wish I knew how to write Flash myself.

Updates page created

Having made my PHP and XSL more generic, there's an updates page. Much like the podcasts page, it's syndicated from the Atom XML. More blog categories may follow, as needed. Must get around to a page for displaying individual posts, for permalinks etc.

Much needed remixing and MP3 tagging
I've remixed a couple of tracks here, tweaked the graphical equalizer and added some reverb etc. I even managed to persuade XMPlay to repeat properly with a fade out too. This sounds so much better than the defaults, so I'll be sure to give similar treatment to the other XM files. I even put on ID3 tags too, but had trouble picking a genre; so Christian Gangster Rap it is!
Download: http://www.trollied.org/~blimey/amusic.mp3 (782 KB)
Download: http://www.trollied.org/~blimey/phoique2.mp3 (903 KB)
Parse Atom with XSL not PHP

I've written some XSL to process the RSS from del.icio.us, and my own Atom feed. See the results on these pages: http://www.trollied.org/~blimey/egosurfing.php and http://www.trollied.org/~blimey/podcasts.php.

Prior to using XSL, I was using the Simplepie PHP library. Google webmaster tools reported that this produced an error when the site was crawled, although it looks alright in a web browser. Also Simplepie had poor support for Atom, and as a workaround I was making use the RSS conversion of the Atom feed. The RSS conversion works using XSL anyway.

I had originally looked into using Magpie RSS, which had no support for Atom. Conclusion is both PHP libraries are redundant, in favour of XSL which obviously supports anything XML; RSS, Atom or otherwise.

Menu created, conditional HTTP GET etc

I found the time to write a DHTML menu for this site. The page gets restructured onload to put it in there.

I also ensured that the Last-Modified and ETag headers are set so pages can be cached appropriately, seems Apache2Handler takes care of the rest.

I also did a style sheet for the Atom feed, in case anyone is still using older browsers.

All the pages are now sent back compressed, for compatible clients.

The individual JavaScript files are rolled up into one big file to minimise on browser requests / round trips, and like the other pages it's all zipped and with suitable Last-Modified header based on the newest script's time stamp.

Jungle Mix
This mix session is basically old school jungle, with tracks by Remarc, DJ Trace, Ray Keith etc. There's no shortage of tearing "Amen" tracks, some ragga influenced others just plain dark.
Download: http://www.trollied.org/~blimey/blimeyjunglemix.mp3 (56 MB)
Font Resizing
I've added functionality which lets you choose the font size used for my site now. Click on the letter 'A' of the appropriate size at the bottom of the page. There's a "span" element which is a place holder, and the letters are added in using DOM.
All the code is in an external script. The intention is to ultimately add a navigation/menu part to the site using similar techniques.
Google Ranking
After a long wait the site now appears in Google search results. For the first time, I've attained the #1 spot for Geoffrey Swift. Seems a bit of extra SEO is required to achieve the same for "Geoffrey Swift", Geoff Swift and "Geoff Swift" though!
Egosurfing

I've added a page with links to external sites which pertain to me, more syndication of RSS this time powered by del.icio.us.

Podcast page
I've syndicated the atom feed back into the website itself, to provide download URLs for the DJ mix MP3z.
Drum and Bass Mix
This mix features lots of DarkStep from the likes of Technical Itch, Dylan, Noisia and Teebee to name a few.
Download: http://www.trollied.org/~blimey/blimeydnbmix.mp3 (50 MB)
Rave Mix
I did a DJ mix of 1991 Techno / Rave classics, plenty of Belgian and UK tracks on here.
Download: http://www.trollied.org/~blimey/blimeyravemix.mp3 (56 MB)
Website Created with feeds
My website is up and running, but could definitely use some more work! Today I've got around to adding Atom and RSS feeds. The RSS feed is generated from the Atom XML using PHP and XSLT.