<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Aeracode</title>
	<atom:link href="http://www.aeracode.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.aeracode.org</link>
	<description>Python, PHP, Programming and Projects.</description>
	<pubDate>Sun, 29 Jun 2008 12:22:21 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>LastGraph at Oxford Geek Night Seven</title>
		<link>http://www.aeracode.org/2008/06/26/lastgraph-ogn7/</link>
		<comments>http://www.aeracode.org/2008/06/26/lastgraph-ogn7/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 22:20:00 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<category><![CDATA[Graphication]]></category>

		<category><![CDATA[LastGraph]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/?p=90</guid>
		<description><![CDATA[Well, last night I gave a talk at one of the ever-brilliant Oxford Geek Nights, and in case you&#8217;re baying for the slides I used (all seven of them), you can find them at this wonderful OGN7 LastGraph Slides link. If you live within punting distance of Oxford, you should really try to come to the [...]]]></description>
			<content:encoded><![CDATA[<p>Well, last night I gave a talk at one of the ever-brilliant <a title="OGN7" href="http://oxford.geeknights.net/2008/jun-25th/">Oxford Geek Nights</a>, and in case you&#8217;re baying for the slides I used (all seven of them), you can find them at this wonderful <a href="http://www.aeracode.org/blog/wp-content/uploads/2008/06/ogn7-slides.pdf">OGN7 LastGraph Slides</a> link. If you live within punting distance of Oxford, you should really try to come to the next one on August 27th. If not; well, they put videos up on the site&#8230;</p>
<p>In a related note, I am enjoying the improvement on my slide-making capabilities via Inkscape. Previously, PDFs exported to massive file sizes and tying the individual pages together wasn&#8217;t easy. Now, the new Cairo export in Inkscape (the same PDF export library LastGraph uses, yay) makes reasonably-sized PDFs, and pdftk munges them together easily and in record time. One day I&#8217;ll give in and use an actual presentation program.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2008/06/26/lastgraph-ogn7/feed/</wfw:commentRss>
		</item>
		<item>
		<title>In The Pursuit Of Shiny Web Stats</title>
		<link>http://www.aeracode.org/2008/05/28/in-the-pursuit-of-shiny-web-stats/</link>
		<comments>http://www.aeracode.org/2008/05/28/in-the-pursuit-of-shiny-web-stats/#comments</comments>
		<pubDate>Wed, 28 May 2008 12:35:09 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[LastGraph]]></category>

		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/?p=88</guid>
		<description><![CDATA[Being a very visual person, I naturally wanted a nice way of visualising the traffic lastgraph gets (especially as I nurse it through the initial round of bugs, most of which have gone). The ever-wonderful gltail always helps, but the same author has gone one further and come up with gltrail:

It draws paths between pages [...]]]></description>
			<content:encoded><![CDATA[<p>Being a very visual person, I naturally wanted a nice way of visualising the traffic lastgraph gets (especially as I nurse it through the initial round of bugs, most of which have gone). The ever-wonderful <a href="http://www.fudgie.org/">gltail</a> always helps, but the same author has gone one further and come up with <a href="http://www.fudgie.org/gltrail.html">gltrail</a>:</p>
<p><a href="http://www.aeracode.org/blog/wp-content/uploads/2008/05/lg_gltrail2.png"><img class="alignnone size-full wp-image-89" title="GlTrail Screenshot" src="http://www.aeracode.org/blog/wp-content/uploads/2008/05/lg_gltrail2.png" alt="" width="500" height="300" /></a></p>
<p>It draws paths between pages visited, and looks pretty nice when visualising the lastgraph logs. It&#8217;s also incredibly tempting to put it on a large screen in my room, the only problem being that I lack a large screen. And enough room.</p>
<p>In a related note, it would be nice if there were some sort of AJAXy, real-time, web-based statistics like gltail; anyone know of any? Someone must have put that &lt;canvas&gt; element to good use by now&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2008/05/28/in-the-pursuit-of-shiny-web-stats/feed/</wfw:commentRss>
		</item>
		<item>
		<title>LastGraph Server Bouncing</title>
		<link>http://www.aeracode.org/2008/05/26/lastgraph-server-bouncing/</link>
		<comments>http://www.aeracode.org/2008/05/26/lastgraph-server-bouncing/#comments</comments>
		<pubDate>Mon, 26 May 2008 21:41:03 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[LastGraph]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/?p=87</guid>
		<description><![CDATA[Yes, this is my new official term for the server going up and down. It seems that some part of the system causes 100% CPU usage on the box it&#8217;s running on, and in fact is so nasty to the system that it even makes the serial console lag. This, for those who are not [...]]]></description>
			<content:encoded><![CDATA[<p>Yes, this is my new official term for the server going up and down. It seems that some part of the system causes 100% CPU usage on the box it&#8217;s running on, and in fact is so nasty to the system that it even makes the serial console lag. This, for those who are not server geeks, is Bad.</p>
<p>I&#8217;m on the case, and have brought the full force of monitoring tools to bear to see if I can track down the cause. In the meantime, please accept my apologies for any downtime.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2008/05/26/lastgraph-server-bouncing/feed/</wfw:commentRss>
		</item>
		<item>
		<title>LastGraph3 Beta!</title>
		<link>http://www.aeracode.org/2008/05/24/lastgraph3-beta/</link>
		<comments>http://www.aeracode.org/2008/05/24/lastgraph3-beta/#comments</comments>
		<pubDate>Sat, 24 May 2008 17:16:27 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<category><![CDATA[LastGraph]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/?p=86</guid>
		<description><![CDATA[After much work, lastgraph3&#8217;s beta is now out. Please be warned that it may not work, may explode, and may abduct your cat, dog or goldfish in the process of failing.
Apart from that, please feel free to give it a try at lastgraph3.aeracode.org. Report any and all problems back to me, either here, or at [...]]]></description>
			<content:encoded><![CDATA[<p>After much work, lastgraph3&#8217;s beta is now out. Please be warned that it may not work, may explode, and may abduct your cat, dog or goldfish in the process of failing.</p>
<p>Apart from that, please feel free to give it a try at <a href="http://lastgraph3.aeracode.org">lastgraph3.aeracode.org</a>. Report any and all problems back to me, either here, or at my email or something similar.</p>
<p>Oh, and it&#8217;s also very slow at fetching until I re-negotiate fast fetching with last.fm, since I&#8217;ve moved IP.</p>
<p>Update: I&#8217;ve decided to make this one of those public, neverending betas, so LastGraph is now basically open for anyone and everyone to use. The last feature I added was LastGraph Premium, my new way of soliciting donations (this time, you can donate, and in return get a few extra features). I&#8217;m still not sure about it, but I&#8217;ve had some emails before from people who would have liked it, so we&#8217;ll see how it turns out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2008/05/24/lastgraph3-beta/feed/</wfw:commentRss>
		</item>
		<item>
		<title>LastGraph3: Not Dead</title>
		<link>http://www.aeracode.org/2008/05/19/lastgraph3-not-dead/</link>
		<comments>http://www.aeracode.org/2008/05/19/lastgraph3-not-dead/#comments</comments>
		<pubDate>Mon, 19 May 2008 08:46:06 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[LastGraph]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/?p=84</guid>
		<description><![CDATA[It really isn&#8217;t, honest. I&#8217;m working on the final part - the graph scheduler, which replicates the previous queued graph functionality - and I&#8217;ll hopefully be pushing it all live soon.
I was tempted to just push the live artist browsing part live, which all works currently, but it&#8217;s only interesting for, oh, the first few [...]]]></description>
			<content:encoded><![CDATA[<p>It really isn&#8217;t, honest. I&#8217;m working on the final part - the graph scheduler, which replicates the previous queued graph functionality - and I&#8217;ll hopefully be pushing it all live soon.</p>
<p>I was tempted to just push the live artist browsing part live, which all works currently, but it&#8217;s only interesting for, oh, the first few hours&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2008/05/19/lastgraph3-not-dead/feed/</wfw:commentRss>
		</item>
		<item>
		<title>I&#8217;m Blue, Da-Ba-De&#8230;</title>
		<link>http://www.aeracode.org/2008/04/13/im-blue-da-ba-de/</link>
		<comments>http://www.aeracode.org/2008/04/13/im-blue-da-ba-de/#comments</comments>
		<pubDate>Sun, 13 Apr 2008 21:06:29 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/?p=82</guid>
		<description><![CDATA[People who know me, at all, will know I love two things: cheese, and the colour blue. Oddly enough, I don&#8217;t like blue cheese, but that must be some kind of cancellation effect.
Until the availability of web-based cheese, I have instead opted for sticking more blue in the site. Unless you&#8217;re using one of those [...]]]></description>
			<content:encoded><![CDATA[<p>People who know me, at all, will know I love two things: cheese, and the colour blue. Oddly enough, I don&#8217;t like blue cheese, but that must be some kind of cancellation effect.</p>
<p>Until the availability of web-based cheese, I have instead opted for sticking more blue in the site. Unless you&#8217;re using one of those newfangled &#8216;arr-ess-ess readers&#8217;, you&#8217;ll have noticed by now.</p>
<p>In other news, I&#8217;m working on an upgrade to lastgraph3. I&#8217;ve finally had a sudden onset of common sense and have modified the downloader to not be &#8217;scalable&#8217; and so not fail, am storing data in pickles rather than a database (it&#8217;s way faster and more efficient, since the data is denormalised). There&#8217;s also a more interactive interface, including browsing of artist-specific listening histories and weekly artist breakdowns.</p>
<p>Hopefully it&#8217;ll be out by the end of the week, but who knows, what with some exams apparently in the way.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2008/04/13/im-blue-da-ba-de/feed/</wfw:commentRss>
		</item>
		<item>
		<title>OpenTTD, for Maemo</title>
		<link>http://www.aeracode.org/2008/02/10/openttd-for-maemo/</link>
		<comments>http://www.aeracode.org/2008/02/10/openttd-for-maemo/#comments</comments>
		<pubDate>Sun, 10 Feb 2008 19:26:46 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/2008/02/10/openttd-for-maemo/</guid>
		<description><![CDATA[Anybody lucky enough to own an OS2008 internet tablet can be smug and happy knowing that OpenTTD is now available for OS2008.
You need the data files, of course, but that&#8217;s the same as usual, non-maemo OpenTTD. On the plus side, I actually discovered I really can still edit C++ without breaking it (I tend to [...]]]></description>
			<content:encoded><![CDATA[<p>Anybody lucky enough to own an OS2008 <a href="http://nokia.com/n800">internet</a> <a href="http://nokia.com/n810">tablet</a> can be smug and happy knowing that OpenTTD is <a href="/projects/maemo/openttd/">now available</a> for OS2008.</p>
<p>You need the data files, of course, but that&#8217;s the same as usual, non-maemo OpenTTD. On the plus side, I actually discovered I really can still edit C++ without breaking it (I tend to spend a reasonably large amount of time using high-level languages, as I value the amount of typing I do).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2008/02/10/openttd-for-maemo/feed/</wfw:commentRss>
		</item>
		<item>
		<title>LastGraph has been given a kick&#8230;.</title>
		<link>http://www.aeracode.org/2008/02/02/lastgraph-has-been-given-a-kick/</link>
		<comments>http://www.aeracode.org/2008/02/02/lastgraph-has-been-given-a-kick/#comments</comments>
		<pubDate>Sat, 02 Feb 2008 11:07:35 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<category><![CDATA[LastGraph]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/2008/02/02/lastgraph-has-been-given-a-kick/</guid>
		<description><![CDATA[LastGraph has been given a much needed refresh, including a tweak to the render nodes to stop them running out of file handles/memory/disk space, and the main site so it in fact remembers when it deletes XML caches to free up space rather than wandering around going &#8220;I&#8217;m sure I put that file somewhere&#8230;&#8221;.
I may [...]]]></description>
			<content:encoded><![CDATA[<p>LastGraph has been given a much needed refresh, including a tweak to the render nodes to stop them running out of file handles/memory/disk space, and the main site so it in fact remembers when it deletes XML caches to free up space rather than wandering around going &#8220;I&#8217;m sure I put that file somewhere&#8230;&#8221;.</p>
<p>I may also actually implement expiry soon, as my S3 bill is finally above $5. Yay&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2008/02/02/lastgraph-has-been-given-a-kick/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Django and Cairo: Rendering Pretty Titles</title>
		<link>http://www.aeracode.org/2007/12/15/django-and-cairo-rendering-pretty-titles/</link>
		<comments>http://www.aeracode.org/2007/12/15/django-and-cairo-rendering-pretty-titles/#comments</comments>
		<pubDate>Sat, 15 Dec 2007 23:29:23 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/2007/12/15/django-and-cairo-rendering-pretty-titles/</guid>
		<description><![CDATA[One of the overwhelming horrors of designing for the web (or so it would appear from a lot of the mockups I&#8217;ve seen) is that designers (and people who are just bored of Arial and Times New roman) want to make their titles on web pages using non-standard fonts. &#8220;But that&#8217;s shockingly non-accessible and uses [...]]]></description>
			<content:encoded><![CDATA[<p>One of the overwhelming horrors of designing for the web (or so it would appear from a lot of the mockups I&#8217;ve seen) is that designers (and people who are just bored of Arial and Times New roman) want to make their titles on web pages using <em>non-standard fonts</em>. &#8220;But that&#8217;s shockingly non-accessible and uses more bandwidth&#8221;, I hear you cry; well, there&#8217;s a reason the alt tag is around, and why broadband is much more common.</p>
<p>Well, perhaps this isn&#8217;t the sole reason, but nonetheless it&#8217;s a more than feasible idea these days to have headings, titles and short lines of text using fonts a user doesn&#8217;t have installed on their system. And, until the spec for embedding fonts is finialised in around 2065, there are two main options:</p>
<ul>
<li>Render the text <b>using *cough* Flash</b>. While Flash is perhaps not as bad as some would make out, it&#8217;s still horribly proprietary as well as having a noticeable loading time and a few other invented disadvantages that strengthen my case for using&#8230;</li>
<li><b>Images</b>. They&#8217;re lighterweight, and have been used for showing custom graphics since the dawn of [UNIX] time.</li>
</ul>
<p>So, we need header images. One horribly labour-intensive way of doing this is making them manually in Generic Graphics Editor 8.6. However, since we&#8217;re sensible people, we&#8217;ll generate them on the fly. And, since we&#8217;re sensible people, we&#8217;ll be using Django*, so we need to write some nice Python code.</p>
<p>I&#8217;ll be using Cairo to generate graphics, in part because it&#8217;s a nice library, and is pretty common these days. You&#8217;ll need the Python Cairo bindings; on debian-like systems, this is the package <em>python-cairo</em>; in other places, your mileage may vary.</p>
<p>The key to making Cairo work with Django is wrapping a Cairo canvas in a django view. For this reason, I have this function lying around:</p>
<p><code>def render_image(drawer, width, height):<br />
	import os, tempfile, cairo<br />
	# We render to a temporary file, since Cairo can&#8217;t stream nicely<br />
	filename = tempfile.mkstemp()[1]<br />
	# We render to a generic Image, being careful not to use colour hinting<br />
	surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))<br />
	font_options = surface.get_font_options()<br />
	font_options.set_antialias(cairo.ANTIALIAS_GRAY)<br />
	context = cairo.Context(surface)<br />
	# Call our drawing function on that context, now.<br />
	drawer(context)<br />
	# Write the PNG data to our tempfile<br />
	surface.write_to_png(filename)<br />
	surface.finish()<br />
	# Now stream that file&#8217;s content back to the client<br />
	fo = open(filename)<br />
	data = fo.read()<br />
	fo.close()<br />
	os.unlink(filename)<br />
	return HttpResponse(data, mimetype=&#8221;image/png&#8221;)<br />
</code></p>
<p>The idea is, you pass it a function which will draw the image onto a context, and the image&#8217;s width and height, and it takes care of all the boring tedium of wrapping cairo and django together.</p>
<p>Now, that&#8217;s not very useful by itself, is it? Time to draw some text!</p>
<p>Firstly, as an aside, we need a way of seeing how big a certain text string will be for a given font and size, so we can render an image just big enough for it. This function achieves that:</p>
<p><code>def text_bounds(text, size, font="Sans", weight=cairo.FONT_WEIGHT_NORMAL, style=cairo.FONT_SLANT_NORMAL):<br />
	import cairo<br />
	surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)<br />
	context = cairo.Context(surface)<br />
	context.select_font_face(font, style, weight)<br />
	context.set_font_size(size)<br />
	width, height = context.text_extents(text)[2:4]<br />
	return width, height<br />
</code></p>
<p>Yes, yes, it&#8217;s somewhat cryptic, but it does the job. Now, we can write a text-rendering view!</p>
<p><code><br />
def render_title(request, text, size=60):<br />
	# Get some variables pinned down<br />
	size = int(size) * 3<br />
	font = &#8220;Meta&#8221;<br />
	width, height = text_bounds(text, size, font)<br />
	def draw(cr):<br />
		import cairo<br />
		# Paint the background white. Replace with 1,1,1,0 for transparent PNGs.<br />
		cr.set_source_rgba(1,1,1,1)<br />
		cr.paint()<br />
		# Some black text<br />
		cr.set_source_rgba(0,0,0,1)<br />
		cr.select_font_face(font, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)<br />
		cr.set_font_size(size)<br />
		# We need to adjust by the text&#8217;s offsets to center it.<br />
		x_bearing, y_bearing, width, height = cr.text_extents(text)[:4]<br />
		cr.move_to(-x_bearing,-y_bearing)<br />
		# We stroke and fill to make sure thinner parts are visible.<br />
		cr.text_path(text)<br />
		cr.set_line_width(0.5)<br />
		cr.stroke_preserve()<br />
		cr.fill()<br />
	return render_image(draw, width, height)<br />
</code></p>
<p>Here, we construct the draw function with a simple text drawing command, and run the wrapper.</p>
<p>There&#8217;s some interesting text positioning going on up there; for more on this, and cairo in general, read through the excellent <a href="http://www.tortall.net/mu/wiki/CairoTutorial">Cairo Tutorial for Python Programmers</a>.</p>
<p>The last thing is to add an appropriate URL into your URLconf, such as</p>
<p><code>(r'^title/([^\/]+)/(\d+)/$&#8217;, &#8220;render_title&#8221;)</code></p>
<p>And then, when you browse to /title/HelloWorld/20/, you&#8217;ll hopefully get a nice PNG of your new title! Then, you can just use img tags instead of titles, in this sort of style:</p>
<p><code>&lt;img src="/title/{{ item.title }}/20" alt="{{ item.title }}" /&gt;</code></p>
<p>This process is quite quick, but not without a small cost of processing power; if you&#8217;re using it a lot, think about some sort of caching. Apart from that, be happy with your newfound title freedom&#8230;</p>
<p><small>* Or possily Pylons. As long as you don&#8217;t go and cavort with those Gems On Guiderails people, or heaven forbid the [PH/AS]P guys&#8230;</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2007/12/15/django-and-cairo-rendering-pretty-titles/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Lightning Talk Slides</title>
		<link>http://www.aeracode.org/2007/11/24/lightning-talk-slides/</link>
		<comments>http://www.aeracode.org/2007/11/24/lightning-talk-slides/#comments</comments>
		<pubDate>Sat, 24 Nov 2007 21:36:56 +0000</pubDate>
		<dc:creator>Andrew Godwin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.aeracode.org/2007/11/24/lightning-talk-slides/</guid>
		<description><![CDATA[I&#8217;ve put the slides up from my Lightning Talk about LastGraph I did last week for Oxford CompSoc. They&#8217;re almost the same as the ones from Barcamp Brighton, but with a few small changes, since I, er, kinda rewrote it since then.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve put <a href="/files/lastgraph-lightning-slides.zip">the slides</a> up from my Lightning Talk about LastGraph I did last week for <a href="http://ox.compsoc.net">Oxford CompSoc</a>. They&#8217;re almost the same as the ones from Barcamp Brighton, but with a few small changes, since I, er, kinda rewrote it since then.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aeracode.org/2007/11/24/lightning-talk-slides/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
