<?xml version="1.0" encoding="iso-8859-1"?>
		<rss version="2.0" 
		    xmlns:dc="http://purl.org/dc/elements/1.1/"
		    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
		    xmlns:content="http://purl.org/rss/1.0/modules/content/">
		<channel>
		    <title>Associative Trails</title>
		    <link>http://www.associativetrails.com/</link>
		    <description>An internet consultancy that specialises in data-driven websites, Content Management Systems (CMS) and effective web communications. Experts in Coldfusion, XHTML, CSS, database design and web standards. Based in London, UK.</description>
		    <dc:language>en-uk</dc:language>
		    <dc:creator>Matt Perdeaux</dc:creator>
		    <dc:rights>Copyright 2010</dc:rights>
		    <dc:date>2010-09-06T04:49:31-00:00</dc:date>
		    <sy:updatePeriod>daily</sy:updatePeriod>
		    <sy:updateFrequency>1</sy:updateFrequency>
		    <sy:updateBase>2010-02-25T03:23:00-00:00</sy:updateBase><item> <title>def spawnChildProcess(new_baby, *args)</title> <link>http://www.associativetrails.com/blog/entry/def-spawnChildProcessnewbaby-args</link> <guid isPermaLink="false">04409C53-5056-897F-ED9188C188B6484F@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p><p>I've been very busy this year, but not got much work done...</p></p><p><p><img src="http://farm3.static.flickr.com/2681/4368465873_ab272b5cb5.jpg" width="333" height="500" alt="Homepage" /><br /><strong>Atticus Robert David Perdeaux</strong>. Practising the Mexican Wave with his Dad.</p></p><p><p><a href="http://www.flickr.com/photos/perdeaux/">More pics...</a></p></p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>Culture</dc:subject> <dc:date>2010-02-25T03:23:00-00:00</dc:date> </item> <item> <title>An automated email that you don't mind receiving</title> <link>http://www.associativetrails.com/blog/entry/An-automated-email-that-you-dont-mind-receiving</link> <guid isPermaLink="false">A0CEE83C-5056-897F-ED94DCFE41DC89FB@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p>I've just ordered some new business cards from <a href="http://www.moo.com/">moo.com</a> and as always, its a joy to use such a well-designed and thoughtful interface.</p><p>There's too many things about this website that I love to list here, but the thing that really struck me this time was in the automated emails. The confirmation email you get when you place an order begins with:</p><p><blockquote>Hello<br /><br />I'm Little MOO - the bit of software that will be managing your order with us. It will shortly be sent to Big MOO, our print machine who will print it for you in the next few days. I'll let you know when it's done and on its way to you.<br /></blockquote></p><p>Which is quite nice because it makes it clear its an automated message in a relaxed and humorous way. The email I got the next day to confirm dispatch begins with:</p><p><blockquote>Hello<br /><br />it's Little MOO again. I thought you'd like to know, the following items from your order are now in the mail:<br /></blockquote></p><p>Which I had to read a few times to realise what was striking about it. It seems really simple, the system knows it has already sent an email to the user, so acknowledges the fact in the follow-up. Giving a conversational aspect to the machine-generated content makes a difference. That's one of the reasons I keep going back to them - these little things really matter. Excellent stuff.</p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>Front-end, Design</dc:subject> <dc:date>2009-12-18T02:52:00-00:00</dc:date> </item> <item> <title>Listing the affected files in a Subversion revision</title> <link>http://www.associativetrails.com/blog/entry/Listing-the-affected-files-in-a-Subversion-revision</link> <guid isPermaLink="false">273CB566-5056-897F-ED67AA6024A8E787@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p><p>A quick trick that I'm finding very useful for those little deployments that don't require a full export of the Subversion repository. A little regex on the standard verbose output of the Subversion log like so:</p><br /><p><code>svn log -r HEAD -v | egrep '^ +[A-Z]'</code></p><br /><p>will output a list of the files included in the specified revision, e.g.:</p><br /><p><code>M /trunk/apps/Feedback/views.py<br />A /trunk/fabfile.py</code></p><br /><p>The letters "A", "M" or "D" denote whether the file was added, modified or deleted.</p></p><p><p>A little bit of Python looping and manipulation later, and there's a very nice little code snippet:</p><br /><p><code>pipe = os.popen("svn log -r "HEAD -v | egrep '^ +[A-Z]'")</p><p>lstUpload = []<br />lstRemove = []<br />for i in pipe.readlines():<br />&nbsp;&nbsp;file = i.strip().replace('/trunk/','').split(' ')<br />&nbsp;&nbsp;if file[0] == 'A' or file[0] == 'M':              lstUpload.append(file[1])<br />&nbsp;&nbsp;if file[0] == 'D': lstRemove.append(file[1])<br /></code></p><br /><p>Which gives us a list of files to upload to the live server, and a list of files to delete from it. Very quick and easy - bung it in your Fabric script and rest easy pilgrim.</p></p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>Python, Sysadmin, Subversion</dc:subject> <dc:date>2009-11-24T12:08:00-00:00</dc:date> </item> <item> <title>Collaboration with Universitat Pompeu Fabra (Barcelona)</title> <link>http://www.associativetrails.com/blog/entry/Collaboration-with-Universitat-Pompeu-Fabra-Barcelona</link> <guid isPermaLink="false">C827B418-5056-897F-EDA62B10D0993EDE@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p>One of the nice things about running your own business is that you can occasionally decide to spend a bit of time doing a bit of research into stuff you find interesting. The <a href="http://www.normalisr.com">Normalisr</a> is an example of this - an application that I built to reflect some of my ideas on attention data and what could be measured in last.fm listening charts.</p><p>Well, it seems that it's not just me that found this particular idea interesting. I was recently contacted by a PhD student at the <a href="http://mtg.upf.edu/">Music Technology Group</a> of the <a href="http://www.upf.edu/en/">Universitat Pompeu Fabra</a> in Barcelona, who wanted to research people's views on the different approaches to ranking their music listening habits.</p><p>The upshot is a short survey that has just been added to the chart pages of the Normalisr, and we're hoping for around a thousand users to fill it in to give Dmitry a nice big chunk of data to analyse. So, if you are a user, please get over to the <a href="http://www.normalisr.com">Normalisr</a> and complete the survey.</p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>Mashups, Technology &amp; applications</dc:subject> <dc:date>2009-11-06T01:03:00-00:00</dc:date> </item> <item> <title>Setting up Apache monitoring with Munin</title> <link>http://www.associativetrails.com/blog/entry/Setting-up-Apache-monitoring-with-Munin</link> <guid isPermaLink="false">2EE8445A-5056-897F-ED17E791313B8508@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p><p>After a few solid days of Linux server wrangling, I found getting <a href="http://munin.projects.linpro.no/">Munin</a> to monitor our Apache server more hassle than I thought it would be.</p><p>Salient system details:</p><ul><li>Ubuntu Hardy</li><li><a href="http://nginx.net/">Nginx</a> web server (port 80) proxy</li><li>Apache web server (port 8080)</li></ul></p><p><p>So, if only for my own future reference, here's how I managed it:</p><ol><li>Make sure the <a href="http://ftp.ics.uci.edu/pub/websoft/libwww-perl/">WWW Protocol library for Perl</a> is installed:<br /><code>sudo apt-get install libwww-perl</code></li><li>Apache needs to be running mod_status (which serves of the stats that Munin draws charts for). Add the following somewhere in /etc/apache2/apache2.conf:<br /><code><br />ExtendedStatus On<br />&lt;Location /server-status&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;SetHandler server-status<br />&nbsp;&nbsp;&nbsp;&nbsp;Order deny,allow<br />&nbsp;&nbsp;&nbsp;&nbsp;Deny from all<br />&nbsp;&nbsp;&nbsp;&nbsp;Allow from 127.0.0.1<br />&lt;/Location&gt;<br /></code></li><li>Restart Apache:<br /><code>sudo /etc/init.d/apache2 restart</code><br /></li><li>The Munin plugins actually live in /usr/share/munin/plugins, and are symlinked to in /etc/munin/plugins:<br /><div style="overflow:scroll; white-space: nowrap;"><br /><code><br />sudo&nbsp;ln&nbsp;-s&nbsp;/usr/share/munin/plugins/apache_accesses&nbsp;/etc/munin/plugins/apache_accesses<br />sudo&nbsp;ln&nbsp;-s&nbsp;/usr/share/munin/plugins/apache_activity&nbsp;/etc/munin/plugins/apache_activity<br />sudo&nbsp;ln&nbsp;-s&nbsp;/usr/share/munin/plugins/apache_processes&nbsp;/etc/munin/plugins/apache_processes<br />sudo&nbsp;ln&nbsp;-s&nbsp;/usr/share/munin/plugins/apache_volume&nbsp;/etc/munin/plugins/apache_volume<br /></code><br /></div><br />NB - If you have uploaded any additional plugins, ensure root has execute permission:<br /><code>sudo chmod 755 apache_activity</code><br /></li><li>Make sure the Munin plugins are monitoring port 8080 - in this setup I've got Nginx on the default port. Add the following to /etc/munin/plugin-conf.d/munin-node:<br /><code><br />[apache_*]<br />env.ports 8080<br /></code><br /></li><li>Restart the Munin node:<br /><code>sudo /etc/init.d/munin-node restart</code><br /></li></ol></p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>Sysadmin, Backend</dc:subject> <dc:date>2009-10-07T07:09:00-00:00</dc:date> </item> <item> <title>New-look Normalisr launched</title> <link>http://www.associativetrails.com/blog/entry/Newlook-Normalisr-launched</link> <guid isPermaLink="false">1AB239CA-5056-897F-ED0756F610532578@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p><p>Hooray! It's live! Your all-new "<a href="http://www.normalisr.com/">Normalisr</a>" experience can now boast the following improvements:</p><br /><ul><li>A new URL - <a href="http://www.normalisr.com/">http://www.normalisr.com/</a></li><li>A slick new design, including gig photographs</li><li>Thumbnail views of artist and album charts</li><li>The ability to manually find artists and albums that come from last.fm without a proper Musicbrainz ID - we're hoping that this will improve the accuracy of your charts</li><li>Proper Unicode support (fingers crossed!)</li><li>A graphical widget of your artist chart to add to your blog or last.fm profile</li></ul><br /><p>We hope you enjoy it. If you have any questions, feedback or issues to report, please use the <a href="http://www.normalisr.com/feedback/">feedback form</a>.</p></p><p><p>PS - Here's a nice example of the widget:</p><br /><p><br /><a href="http://www.normalisr.com/?username=mattperdeaux"> <img src="http://media.normalisr.com/media/charts/mattperdeaux-overall-20.jpg" border="0" alt="mattperdeaux's Profile Page" /> </a><br /></p></p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>Technology &amp; applications, Mashups</dc:subject> <dc:date>2009-10-03T08:56:00-00:00</dc:date> </item> <item> <title>Normaliser v2 in production</title> <link>http://www.associativetrails.com/blog/entry/Normaliser-v2-in-production</link> <guid isPermaLink="false">55576723-5056-897F-EDFBDE8F4DDB268C@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p>After months of neglect, we've finally got round to working on an update to our <a href="http://www.associativetrails.com/stuff/normalisefm/">last.fm normaliser application</a>. We've decided to build the whole thing from the ground up using Python/Django, our new favourite toys. Version two will hopefully include the following improvements:</p><p><ul><li>Proper unicode support.</li><li>The ability to find artists & albums that have a blank Musicbrainz ID in last.fm. This will involve users doing an additional search for each artist, but it should vastly improve most people's charts. We will try to make the search process as easy as possible (see screenshots below).</li><li>A whizzy new design using gig photos from Flickr.</li><li>Updated XML format to mirror v2 of last.fm's data feeds (we will keep the older XML versions available on the same URL).</li><li>Hopefully, some form of export code that will allow charts to be shown on user blogs, etc.</li><li>We're still scratching our heads trying to think of ways we can make a few quid out of all the work we're putting into this...</li></ul></p><p>Anyway, some work in progress screenshots below.</p><p><p><strong>Homepage</strong><br /><img src="http://www.associativetrails.com/blogCFC/images/normaliser-home.jpg" width="500" height="278" alt="Homepage" /></p></p><p><p><strong>Artist chart listing</strong><br /><img src="http://www.associativetrails.com/blogCFC/images/normaliser-artist.jpg" width="500" height="838" alt="Artist chart" /></p><br /><p><strong>Album chart listing</strong><br /><img src="http://www.associativetrails.com/blogCFC/images/normaliser-album.jpg" width="500" height="838" alt="Album chart" /></p><br /><p><strong>Find an album in the Musicbrainz database</strong><br /><img src="http://www.associativetrails.com/blogCFC/images/normaliser-find.jpg" width="500" height="278" alt="Find an album" /></p></p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>Mashups, Technology &amp; applications</dc:subject> <dc:date>2009-08-26T01:04:00-00:00</dc:date> </item> <item> <title>Smile - you're on Google Maps</title> <link>http://www.associativetrails.com/blog/entry/Smile--youre-on-Google-Maps</link> <guid isPermaLink="false">1E75F6E4-5056-897F-ED2091D15596E931@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p>Google have <a href="http://londonist.com/2009/03/google_street_view_now_live_in_uk.php">just launched Street view in the UK</a>, which gives pretty informative street-level photographs as part of their mapping service. Funny little cars with weird rigs attached to them were scooting round London all last summer, capturing the photographs.</p><p>Of course, if you see one of those cars, chances are you may appear in the photographs they take. My wife remembered a particular location where we saw one last summer, and we've tracked ourselves down, strolling back home from a trip to Broadway Market in Hackney:</p><p><iframe width="425" height="240" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.com/maps/sv?cbp=12,34.79021625156689,,2,4.50684931506849&amp;cbll=51.532962,-0.065321&amp;panoid=&amp;v=1&amp;hl=en&amp;gl="></iframe><br /><small><a href="http://maps.google.com/?ie=UTF8&amp;layer=c&amp;cbll=51.532962,-0.065321&amp;panoid=ck471tsq_KJxWRKvRlSqzg&amp;cbp=12,34.79021625156689,,2,4.50684931506849&amp;ll=51.533029,-0.065274&amp;spn=0,359.984336&amp;z=16&amp;source=embed" style="color:#0000FF;text-align:left">View Larger Map</a></small></p><p>Which actually feels a bit strange. We've been Google-papped. Lucky it was my wife I was out with that day ;)</p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>London</dc:subject> <dc:date>2009-03-19T06:09:00-00:00</dc:date> </item> <item> <title>Django unit testing gotcha: test case methods run in alphabetical order</title> <link>http://www.associativetrails.com/blog/entry/Django-unit-testing-gotcha-test-case-methods-run-in-alphabetical-order</link> <guid isPermaLink="false">ED9D6DCE-5056-897F-ED8DA35784E0E2FF@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p>After a good few hours of increasing frustration, I managed to work out why the Django unit tests I was working on were doing funny things. As it turns out, the individual test case methods are, by default, sorted alphabetically by the TestLoader.</p><p>This is worth knowing if you're testing things that rely on the tests being run in order, such as creating, editing and deleting of records in the database.</p><p>For instance:<br /><code><br />import unittest<br />from myapp.models import MyModel<br /><br />class MyModelTestCase(unittest.TestCase):<br />    def test_create_item(self):<br />        obj = MyModel.objects.create(title="hello")<br />        .... run tests ....<br /><br />    def test_edit_item(self):<br />        obj = MyModel.objects.get(id=1)<br />        obj.title = "goodbye"<br />        obj.save()<br />        .... run tests ....<br /><br />    def test_delete_item(self):<br />        obj = MyModel.objects.get(id=1)<br />        obj.delete()<br />        .... run tests ....<br /></code></p><p>In the above example, when the tests are sorted alphabetically, "test_create_item" is run first, but "test_delete_item" will be run before "test_edit_item", leading to a few unexpected test failures for no apparent reason.</p><p>It looks like this is all to do with the "sortTestMethodsUsing" attribute of the <a href="http://docs.python.org/library/unittest.html#unittest.TestLoader">TestLoader class</a>, and I daresay there is a way of overriding it in Django, but for now, I'm just happy knowing how my tests are being sorted so I can name them sensibly.</p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>Quality &amp; standards, Backend</dc:subject> <dc:date>2009-03-09T18:39:00-00:00</dc:date> </item> <item> <title>Having fun with widows</title> <link>http://www.associativetrails.com/blog/entry/Fun-with-widows</link> <guid isPermaLink="false">6F68C5D0-5056-897F-ED46AF7240BB3065@http://www.associativetrails.com/</guid> <content:encoded><![CDATA[<p>It's amazing the little details your mind sometimes fixates upon when you're deeply into an intense coding phase. I'm currently building a news aggregator interface, and just can't make a seemingly trivial decision regarding headline typography.</p><p>The issue is all about <a href="http://en.wikipedia.org/wiki/Widows_and_orphans">widows</a> - single words that appear on their own when text wraps onto multiple lines. Design-wise, these are bad. So I've been using the rather nifty <a href="http://code.google.com/p/typogrify/">typogrify extension to Django</a> that makes it very simple to replace the final space in a block of dynamic text with a "&amp;nbsp;" so you don't need to worry about the final word wrapping onto its own line. </p><p>Fantastic, very straightforward, on to next thing. But, I simply cannot decide whether I should be doing this for headlines. The homepage of my app has 3 columns of imported feed content, with the most recent headline in quite large type. Depending on the headline content, the widow filter sometimes makes an obvious change to how the headline is rendered. The problem is, the relatively narrow column width means that it can often make the penultimate headline row seem a bit small.</p><p>For instance, the following before/after shows a pretty standard headline both with and without widow filtering:<br /><br /><br /><div style="float: left; margin: 0; padding: 0; width: 50%; text-align: center;"><br /><img src="http://www.associativetrails.com/blogCFC/images/ex2-withwidow.png" width="200" height="92" style="border: 1px solid #999; padding: 5px;" alt="widow" /><br />widow</div><div style="float: left; margin: 0; padding: 0; width: 50%; text-align: center;"><br /><img src="http://www.associativetrails.com/blogCFC/images/ex2-withoutwidow.png" width="200" height="92" style="border: 1px solid #999; padding: 5px;" alt="no widow" /><br />No widow</div><br style="clear:both;" /><br /></p><p>This one seems pretty cut and dried, the widowless headline looks better and is easier to read. But problems occur with this kind of example:<br /><br /><br /><div style="float: left; margin: 0; padding: 0; width: 50%; text-align: center;"><br /><img src="http://www.associativetrails.com/blogCFC/images/ex1-withwidow.png" width="200" height="92" style="border: 1px solid #999; padding: 5px;" alt="widow" /><br />widow</div><div style="float: left; margin: 0; padding: 0; width: 50%; text-align: center;"><br /><img src="http://www.associativetrails.com/blogCFC/images/ex1-withoutwidow.png" width="200" height="92" style="border: 1px solid #999; padding: 5px;" alt="no widow" /><br />No widow</div><br style="clear:both;" /><br /></p><p>To me, its not obvious which one of these headlines is easier to read. If I had a choice, I'd maybe go with the widow version. But this is all dynamic text, so I need to choose whether to run ALL headlines through the widow filter or not.</p><p>Currently, I am keeping the widow filter on. But I reserve the right to change my mind about five times a day before this thing is finished.</p>]]></content:encoded> <dc:creator>Matt Perdeaux</dc:creator> <dc:subject>Front-end, Design</dc:subject> <dc:date>2009-02-13T06:25:00-00:00</dc:date> </item></channel>
		</rss>

