Welcome to Aeracode. This is the personal site of Andrew Godwin (yes, I do like blue). Read my inane whitterings below, or have a look at some of my projects.
People who know me, at all, will know I love two things: cheese, and the colour blue. Oddly enough, I don’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’re using one of those newfangled ‘arr-ess-ess readers’, you’ll have noticed by now.
In other news, I’m working on an upgrade to lastgraph3. I’ve finally had a sudden onset of common sense and have modified the downloader to not be ’scalable’ and so not fail, am storing data in pickles rather than a database (it’s way faster and more efficient, since the data is denormalised). There’s also a more interactive interface, including browsing of artist-specific listening histories and weekly artist breakdowns.
Hopefully it’ll be out by the end of the week, but who knows, what with some exams apparently in the way.
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’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).
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 “I’m sure I put that file somewhere…”.
I may also actually implement expiry soon, as my S3 bill is finally above $5. Yay…
One of the overwhelming horrors of designing for the web (or so it would appear from a lot of the mockups I’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. “But that’s shockingly non-accessible and uses more bandwidth”, I hear you cry; well, there’s a reason the alt tag is around, and why broadband is much more common.
Well, perhaps this isn’t the sole reason, but nonetheless it’s a more than feasible idea these days to have headings, titles and short lines of text using fonts a user doesn’t have installed on their system. And, until the spec for embedding fonts is finialised in around 2065, there are two main options:
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’re sensible people, we’ll generate them on the fly. And, since we’re sensible people, we’ll be using Django*, so we need to write some nice Python code.
I’ll be using Cairo to generate graphics, in part because it’s a nice library, and is pretty common these days. You’ll need the Python Cairo bindings; on debian-like systems, this is the package python-cairo; in other places, your mileage may vary.
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:
def render_image(drawer, width, height):
import os, tempfile, cairo
# We render to a temporary file, since Cairo can’t stream nicely
filename = tempfile.mkstemp()[1]
# We render to a generic Image, being careful not to use colour hinting
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
font_options = surface.get_font_options()
font_options.set_antialias(cairo.ANTIALIAS_GRAY)
context = cairo.Context(surface)
# Call our drawing function on that context, now.
drawer(context)
# Write the PNG data to our tempfile
surface.write_to_png(filename)
surface.finish()
# Now stream that file’s content back to the client
fo = open(filename)
data = fo.read()
fo.close()
os.unlink(filename)
return HttpResponse(data, mimetype=”image/png”)
The idea is, you pass it a function which will draw the image onto a context, and the image’s width and height, and it takes care of all the boring tedium of wrapping cairo and django together.
Now, that’s not very useful by itself, is it? Time to draw some text!
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:
def text_bounds(text, size, font="Sans", weight=cairo.FONT_WEIGHT_NORMAL, style=cairo.FONT_SLANT_NORMAL):
import cairo
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
context = cairo.Context(surface)
context.select_font_face(font, style, weight)
context.set_font_size(size)
width, height = context.text_extents(text)[2:4]
return width, height
Yes, yes, it’s somewhat cryptic, but it does the job. Now, we can write a text-rendering view!
def render_title(request, text, size=60):
# Get some variables pinned down
size = int(size) * 3
font = “Meta”
width, height = text_bounds(text, size, font)
def draw(cr):
import cairo
# Paint the background white. Replace with 1,1,1,0 for transparent PNGs.
cr.set_source_rgba(1,1,1,1)
cr.paint()
# Some black text
cr.set_source_rgba(0,0,0,1)
cr.select_font_face(font, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
cr.set_font_size(size)
# We need to adjust by the text’s offsets to center it.
x_bearing, y_bearing, width, height = cr.text_extents(text)[:4]
cr.move_to(-x_bearing,-y_bearing)
# We stroke and fill to make sure thinner parts are visible.
cr.text_path(text)
cr.set_line_width(0.5)
cr.stroke_preserve()
cr.fill()
return render_image(draw, width, height)
Here, we construct the draw function with a simple text drawing command, and run the wrapper.
There’s some interesting text positioning going on up there; for more on this, and cairo in general, read through the excellent Cairo Tutorial for Python Programmers.
The last thing is to add an appropriate URL into your URLconf, such as
(r'^title/([^\/]+)/(\d+)/$', "render_title")
And then, when you browse to /title/HelloWorld/20/, you’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:
<img src="/title/{{ item.title }}/20" alt="{{ item.title }}" />
This process is quite quick, but not without a small cost of processing power; if you’re using it a lot, think about some sort of caching. Apart from that, be happy with your newfound title freedom…
* Or possily Pylons. As long as you don’t go and cavort with those Gems On Guiderails people, or heaven forbid the [PH/AS]P guys…
I’ve put the slides up from my Lightning Talk about LastGraph I did last week for Oxford CompSoc. They’re almost the same as the ones from Barcamp Brighton, but with a few small changes, since I, er, kinda rewrote it since then.
As some people know, and many don’t, I got accepted into Nokia’s N810 device program, which means I get this wonderful piece of technology* for a wonderful price.
* Sentence may be biased, due to cheap-tablet-buyingness.
This means I really, really feel like developing something for the device, and so I present my newest idea: HeThEv.
Short for “HereThereEverywhere” (yes, my naming is as useless as ever), it’s basically a program that exploits the ease with which the devices can now know where you are in space - with the N810’s built-in GPS, or an external receiver with the N800/770.
The idea is to have a geospatial memory environment (woo, buzzwords). Essentially, you can write down notes, and the program will remember where they were written, and at what time. So, if you remember jotting down something in the pub last tuesday, it’s trivial to locate the item.
What about alarms? Set the device to tell you what food you need to buy next time you go past a supermarket, and as you walk past it’ll remind you.
Perhaps the feature I want to implement (and try!) most is the “located music”, where you associate music tracks with locations and times. So, if you’re walking down streets at night, have edgy, scary music; if you’re in a park during the summer, have typical summer music; walk past a football ground and hear their anthem; there’s lots of possibilities, and it will also make real life more like movies, although I have yet to think of how to play ‘danger’ music when a fight breaks out…
So, hopefully that’ll turn up at some point soon, shortly after Nokia actually get around to shipping devices (*cough*).
After comments mysteriously stopped working on my old site, I’ve migrated www.aeracode.org to the Aeracode Network™ from my old host. Hopefully things should be nicer now.
Now, it’s not very often that I write long posts on random internet topics, but this is today’s exception, because there’s something that’s really been annoying me lately.
If you look at the Web, it seems to generally work quite well - it’s only partially centralised, and most of that is at the networking layer rather than the actual HTTP layer, where there is no requirement to rely on any central third party. We’ve had the freedom to host and create for several years now, and it’s done wonders for the Web, with what is quite possibly the most diverse thing in the history of humanity being easily accessible and easy to contribute to.
For years now, we’ve been hearing about how we’re going to take the step from simple 2D web pages to the ‘3D web’. First there was the fantastic flop that was VRML; a combination of obscurity, inflexibility and speed meant it was neglected and used by only a select few sites. Since then, we’ve had the massive explosion in home bandwidth and thus MMO games, and perhaps the most interesting thing to emerge from all of this is Second Life.
For those of you who have been living under a rock for a few years now, Second Life is a rough equivalent of what many people predicted the “future internet” would look like. It’s an interactive, open 3D world, with its own scripting language, fully customisable objects, and quite a few other things.
All in all, it sounds quite good. However, it does suffer from what I see as a few fundamental design flaws, the first and foremost being that it is a single, contiguous world. In other words, it emulates the real world (in perhaps a similar vein to Stephenson’s Metaverse, although obviously they differ in other ways). My issue with this is that the real world doesn’t translate so well to the internet environment (and also has several design flaws itself, but that’s a discussion for another time).
One of the many consequences of this (apart from making server-spanning more difficult) is that there has to be some central system (in this case, Linden Labs) which manages everything, thus reducing the one key advantage of the internet: that anyone with a server can simply hook up and host.
Even Linden’s open-sourcing of the client and server won’t help this problem, and so I believe a different solution has to be found, one which is more sustainable, and internet-friendly. I feel the key is to nick those parts of the web that worked so well - there’s no need to change them.
Firstly, get rid of the one solid virtual surface. Do what websites do, and split the ‘virtual universe’ into discrete spaces, each of which can be hosted on its own server. We can use URIs to identify these spaces - hostnames give the server, paths the particular world it hosts, and even anchors for specific points in the world. Obviously we wouldn’t use HTTP, but using identifiers like “3d.aeracode.org/gallery” would both mean we could use existing infrastructure to locate servers (no need for another central registry) as well as play on users’ familiarity with these types of addresses.
Then, steal hyperlinks. Since we already have a set of canonical identifiers, we can link people to other worlds; perhaps have objects you can click on, portals you can work on, or other similar analogous objects (perhaps even ‘load point’ like areas, where you’re transparently moved to a different world).
Of course, to make all this work, we need some way to define worlds and objects within them. This is a matter best left up to discussion; whether to go for an easily-readable XML-ish format, or an efficient binary format (or perhaps gzipped XML), would take a bit of debating. Throw in a scripting language for interactivity as well - we can learn from LSL and JavaScript, both of which are good for different reasons.
This is not as easy as it may first sound, if you’ve not tried these sorts of issues before; unlike (most) websites and VRML, I’m proposing a system that users all interact with at once, within the same instance. Synchronisation issues, security issues, and similar obstacles all present themselves; in my previous attempt at a quick-and-dirty MMO engine I came across more obstacles than I can describe here. However, the game industry has been tacking these for years, and so they’re not insurmountable.
We also have the issue of identity. The OpenID movement is a great example of what needs to be done here, although I don’t feel it could just be used directly, as it’s very much biased towards website services. Still, follow the same method of OpenID (and of my previous discussion) by using URIs as identifiers. Identity servers should also act as a kind of data and preferences store for the users, much like IMAP with email, so they can set their avatar/email/’bookmarks’/etc. only once and have it appear on whichever client they use.
Finally, there’s the issue of 2D versus 3D. Everyone thinks that these sorts of environments should be 3D, and while that’s certainly true for the vast majority of devices, there’s something to be said about having a 2D world protocol as well, with the growing popularity of low-power devices like mobile phones, UMPCs, Internet Tablets, and general cheap, small hardware.
There are many more issues that can be tackled, and it’s quite a massive thing. I have bits of code scattered over my code folders with ideas and half-hearted implementation attempts at all this (of course), and it’s somewhat unlikely all this will ever come into fruition - but, hey, it’s a nice idea. Perhaps one day I can do webworld designing alongside, or in lieu of, website designing…
Yes, people of the internet, LastGraph has returned. After over two weeks of beta testing and bugfixing, it’s finally in a useable state, and so I’m pushing it out to lastgraph.aeracode.org as I type this. If it doesn’t work for you yet, wait for the DNS change to propagate.
This version will, inevitably, contain bugs, so I would appreciate it if any bugs could be emailed to lastgraph at aeracode.org.
There have been some improvements, such as much better error handling, reduced PDF sizes, faster rendering (and more render nodes), and detailed progress. There are still some missing features, though, notably the ability to set the plays threshold and to remove a graph from the queue (this will only be possible if you’ve provided an email address).
Plans for the future include custom colourschemes, more notification methods (jabber, and perhaps some kind of twitter reply thing). If you have more ideas, send them in to that address above (or poke me via one of the many methods found on the contact page).
LastGraph is still undergoing rewriting after the beta showed up some lovely bugs (including inverted labels and labels everywhere they shouldn’t be). I’m working on it over the weekend, after my week was overtaken by the sheer mass of activity involved with university and Fresher’s Week (I find it strangely ironic that it’s actually more timeconsuming this year, when I’m not a fresher).
I’ll give a progress report soon; hopefully I can clear up the fetching errors (Last.fm have also kindly agreed to let me access the API more often, so fetching speed should increase), and make uploading to S3 faster (aegis’ upload speed is somewhat limited, so it will be done directly from the render nodes themselves - this does somewhat scupper my plans for distributing the rendernode client, though, as they need my S3 secret key to do this, unless they can upload elsewhere and pass back an appropriate URL).