<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>A collection of posts, links, images, and other tidbits from around the web, brought together and (in some cases) created by Zachary Voase.</description><title>Zack, virtual.</title><generator>Tumblr (3.0; @zvoase)</generator><link>http://zvoase.tumblr.com/</link><item><title>My Django Project Conventions, pt. I</title><description>&lt;p&gt;
      These few posts (there are more to come) are about some of my favourite Django project conventions. Python has this style of “there’s only one (obvious) way to do it”, and whilst this is nice, it is at best a bit idealistic and at worst a bit constraining. Of course, there will sometimes be ‘best practices’. That’s not the point of this blog post (although it will probably be the focus of the comments).
    &lt;/p&gt;
    &lt;p&gt;
      I have my own style which I like to adopt when working on Django projects. You might not want to use them, but maybe there will be some nuggets of gold in here for you to take.
    &lt;/p&gt;
    &lt;h2&gt;
      The Layout
    &lt;/h2&gt;
    &lt;p&gt;
      This is what the layout of a project of mine might look like. I’ll go into more depth later. I’ve laid out the files and folders in what, I hope, is an intuitive manner.
    &lt;/p&gt;
    &lt;div class="highlight"&gt;
      &lt;pre&gt;
DIRECTORY   myproject/
FILE            __init__.py
FILE            manage.py
FILE            urls.py
DIRECTORY       myproject/settings/
FILE                __init__.py
FILE                common.py
FILE                debug.py
FILE                staging.py
FILE                production.py
FILE                modes.txt
DIRECTORY       myproject/apps/
FILE                __init__.py
FILE                external.py
DIRECTORY           myproject/apps/local/
FILE                    __init__.py
FILES                   ...
DIRECTORY       myproject/templates/
FILES               ...
DIRECTORY       myproject/media/
DIRECTORY       myproject/media/css/
DIRECTORY       myproject/media/js/
DIRECTORY       myproject/media/img/
&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt;
      You might have a few questions about this already. I’m going to try and answer a few here:
    &lt;/p&gt;
    &lt;ol&gt;
&lt;li&gt;
        &lt;strong&gt;Why no uploads directory?&lt;/strong&gt; I like to use the &lt;code&gt;/var/&lt;/code&gt; directory for user-generated content. I believe that allowing users to upload their own data into the Python source tree is a little bit dangerous.
      &lt;/li&gt;
      &lt;li&gt;
        &lt;strong&gt;Why has settings.py been replaced by a directory?&lt;/strong&gt; There are a couple of reasons for this, which I shall explain shortly. Hang on tight!
      &lt;/li&gt;
      &lt;li&gt;
        &lt;strong&gt;Aren’t templates supposed to be at the app level?&lt;/strong&gt; Well, I like to stick some of the templates at the project level. This is especially important if you’re going to be making re-usable apps. A project is specific to a site, an app may be used on multiple sites. If you want to keep your apps re-usable, you probably need project-level templates.
      &lt;/li&gt;
      &lt;li&gt;
        &lt;strong&gt;You keep the media stuff here?&lt;/strong&gt; Yeah. I like to put the media in my project so that, when using a (D)VCS, the media gets included in the version control history. Images, JavaScript and &lt;span class="caps"&gt;CSS&lt;/span&gt; play an important part in the development process, too.
      &lt;/li&gt;
    &lt;/ol&gt;
&lt;p&gt;
      Now, on to the first major part of the project layout: the settings.
    &lt;/p&gt;
    &lt;h2&gt;
      The Settings
    &lt;/h2&gt;
    &lt;p&gt;
      As you can probably see, I have a settings directory instead of a simple Python module. When Django imports your settings, it does something like this:
    &lt;/p&gt;
    &lt;div class="highlight"&gt;
      &lt;pre&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myproject&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt;
      Normally, the &lt;code&gt;settings&lt;/code&gt; object which is created by this statement contains everything defined in the &lt;code&gt;myproject/settings.py&lt;/code&gt; file. In the case of a directory, it takes all the values defined in &lt;code&gt;myproject/settings/__init__.py&lt;/code&gt;. This file, therefore, is where the magic must happen. Look at the following piece of code:
    &lt;/p&gt;
    &lt;p&gt;
      &lt;ins&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;: Fixed some of this code so that it actually works.&lt;/ins&gt;
    &lt;/p&gt;
    &lt;div class="highlight"&gt;
      &lt;pre&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myproject.settings.common&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="n"&gt;SETTING_MODES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;SETTING_MODE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="n"&gt;modes_fp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;'modes.txt'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modes_fp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;SETTING_MODE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;SETTING_MODES&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;modes_fp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;SETTING_MODULE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;__import__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;'.'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;SETTING_MODE&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;fromlist&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SETTING_MODULE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'__'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'__'&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="nb"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SETTING_MODULE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt;
      I don’t know about you, but It makes &lt;strong&gt;me&lt;/strong&gt; want to hurl. Thing is, you see, it’s actually quite a useful piece of sludge. In fact, it’s possibly the most useful piece of sludge you’ll ever come across in your life, unless you are a member of a local &lt;span class="caps"&gt;SUG&lt;/span&gt; (Sludge User Group). What this does is the following: let’s say you have a project with some specified &lt;strong&gt;common&lt;/strong&gt; settings, such as timezone, default language, installed apps, middleware and other nick nacks. However, you’re working on a super-critical application which involves debugging, staging and production servers, so you can develop your code, test it out and then release it to the public. If you’re running off a central (D)VCS branch, you would normally (with a simple &lt;code&gt;settings.py&lt;/code&gt; file) have to change certain settings for each server, like database connections and cacheing. Every time you made a change and wanted to update the checked-out code on each server, you’d have to patch these settings in.
    &lt;/p&gt;
    &lt;p&gt;
      Well, no more!
    &lt;/p&gt;
    &lt;p&gt;
      Now, you get to have your &lt;strong&gt;common&lt;/strong&gt; settings in one file, the settings for the &lt;strong&gt;debug&lt;/strong&gt; server in another, the settings for the &lt;strong&gt;staging&lt;/strong&gt; server in yet another, and the &lt;strong&gt;production&lt;/strong&gt; settings in another file. This is all managed by the &lt;code&gt;modes.txt&lt;/code&gt; file you see in the settings directory. This file looks something like this:
    &lt;/p&gt;
    &lt;div class="highlight"&gt;
      &lt;pre&gt;
DEBUG *
STAGING
PRODUCTION
&lt;/pre&gt;
    &lt;/div&gt;
    &lt;p&gt;
      This is a list of all the modes you’re currently running. The one with the asterisk character (*) at the end of it is the currently selected mode. The code I showed you before does all the heavy lifting for you; change the line with the asterisk and it will switch from debugging mode to staging mode. In practice, what I normally do is have a .gitignore file in this directory with the single line ‘modes.txt’; this means each server’s settings mode persists through multiple commits and checkouts from and on different machines.
    &lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/77349312</link><guid>http://zvoase.tumblr.com/post/77349312</guid><pubDate>Wed, 11 Feb 2009 04:21:00 +0100</pubDate><category>django</category><category>conventions</category><category>python</category><category>programming</category></item><item><title>Call the Super NOW! This apartment is flooding quickly!</title><description>&lt;p&gt;The title of this post is far too dramatic. There is no &lt;i&gt;flooding&lt;/i&gt; situation right now. I’m so sorry to all of you who clicked on this hoping to read some intense story about one woman’s (or man’s or centaur’s) struggle with &lt;b&gt;too much water.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In true Zackeriffic style, I’m writing this for a couple of reasons. Firstly, I’m trying out &lt;a target="_blank" title="Snipt" href="http://snipt.net"&gt;Snipt&lt;/a&gt;’s new embedding feature (that’s the &lt;a target="_blank" title="The One True Snipt" href="http://snipt.net"&gt;one true snipt&lt;/a&gt;, not the &lt;a target="_blank" title="An Other Snipt." href="http://snipt.com"&gt;other&lt;/a&gt; &lt;a target="_blank" title="Yet Another Snipt" href="http://snipt.org"&gt;snipts&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;I’ve written a decorator which does a lil’ bit of awesome. Wrap a method with it. Then, from that method, raise the ‘CallSuper’ exception, optionally with some args. The supermethod (if defined) will be called with those args (if provided), and the result of calling the supermethod will then be returned as the result of the submethod you’ve defined. You can see an example in the code snippet below.&lt;/p&gt;
&lt;p&gt;
&lt;script type="text/javascript" src="http://snipt.net/embed/09ae23b6a5f11bd37c0319fdde7fd0fe"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;I believe it looks rather nice, actually. Well done &lt;a href="http://snipt.net/" target="_blank"&gt;Snipt&lt;/a&gt;.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/77222994</link><guid>http://zvoase.tumblr.com/post/77222994</guid><pubDate>Tue, 10 Feb 2009 18:51:08 +0100</pubDate></item><item><title>A Programmer's Apology</title><description>&lt;p&gt;Today has been quite a pivotal day for me. I had an informal meeting with &lt;a target="_blank" href="http://matt.makalumedia.com/"&gt;Matt Henderson&lt;/a&gt;, who funnily enough I met on twitter (he’s the first person I actually know on twitter), and he very kindly introduced me to his colleagues (the &lt;a target="_blank" href="http://www.makalumedia.com/"&gt;Makalu Media&lt;/a&gt; gang) and lent me a stack of books (which I’m desperately looking forward to reading).&lt;/p&gt;
&lt;p&gt;I definitely took a lot away from the experience. I had a &lt;i&gt;very&lt;/i&gt; long conversation with &lt;a target="_blank" href="http://bendiken.net/"&gt;Arto Bendiken&lt;/a&gt; about all sorts of subjects, running the gamut from consciousness to web frameworks, and it was amazing to be in a development environment again—it’s something I haven’t seen since I did some summer work for &lt;a target="_blank" href="http://ravenpack.com"&gt;Ravenpack&lt;/a&gt; a couple of years ago.&lt;/p&gt;
&lt;p&gt;Makalu Media currently use &lt;a target="_blank" href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; and &lt;a target="_blank" href="http://drupal.org/"&gt;Drupal&lt;/a&gt; for most of their web projects, and in my discussions with them I did, of course, question this, thanks in no small to my &lt;a target="_blank" href="http://djangoproject.com"&gt;Djangonautical persuasion&lt;/a&gt;, and probably having &lt;i&gt;way&lt;/i&gt; too many preconceived notions about RoR. I had an epiphany of sorts when we were discussing Lisp and Python (my two favourite languages). I’ve realised something that’s affected me, and a lot of people I know—I am far too dogmatic when it comes to programming.&lt;/p&gt;
&lt;p&gt;I’ve realised that I’m doing everything in the wrong order. The way things &lt;i&gt;should&lt;/i&gt; work is this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I come across a problem. I try and understand the problem, which may involve some deep grokking of a subject I know little about. But I will get there in the end.&lt;/li&gt;
&lt;li&gt;With a fresh understanding of the problem, I set about trying to solve it conceptually, and in doing so plan out a system.&lt;/li&gt;
&lt;li&gt;With my system plan, I carefully select the tools I think &lt;i&gt;would best suit the task&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;I then set about implementing the plan, using those tools.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here’s the way I’ve been doing things lately (the bit I’d like to change):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I decide to use certain tools (most often &lt;a href="http://python.org" target="_blank"&gt;Python&lt;/a&gt; + &lt;a href="http://djangoproject.com" target="_blank"&gt;Django&lt;/a&gt;) before I even come across a problem.&lt;/li&gt;
&lt;li&gt;I encounter a problem, again with as much grokking as necessary.&lt;/li&gt;
&lt;li&gt;I try and fiddle with the problem until it becomes something that I can solve with those tools I chose in part 1. This usually involves writing a middle-layer between the nature of the problem and the selected tools.&lt;/li&gt;
&lt;li&gt;I then design a system that almost completely ignores the &lt;i&gt;actual&lt;/i&gt; problem, and just concentrates on how I will use those tools to solve the &lt;i&gt;perceived&lt;/i&gt; problem.&lt;/li&gt;
&lt;li&gt;I then implement the system using those tools, and it feels awkward (because 99 times out of 100 those tools aren’t the best for the job), but at least I’m comfortable with it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;OK, the second one sounds really pessimistic. But when I say ‘dogmatic’ about software, that’s what I mean. For far too long have I made pre-choices about what I’m going to use to solve a problem before I’ve even encountered the problem itself. Too many times have I vociferously defended my own choice of programming language or web framework without trying (or even considering) the alternatives. This sort of closed-mindedness (if that’s an actual word) is the kind of stuff you see when people engage in religious debates. Unfortunately, being human, I’m very susceptible to these kinds of emotional responses—I believe they’re known to psychologists as “defense mechanisms”. You see, the use of a particular toolset becomes a sort of paradigm to me, so my harsh attacks on other approaches are really just me defending my paradigm. It’s more of an inner insecurity than anything else.&lt;/p&gt;
&lt;p&gt;In the future, I promise myself that I will choose the best tool for the problem after actually figuring out what the problem is. And if the best tool is &lt;a href="http://xeny.net/files/Homespring-Proposed-Language-Standard.pdf" target="_blank"&gt;Homespring&lt;/a&gt; [PDF] (which, incidentally, looks incredibly awesome), then so be it. I’ll grok Homespring and create a system with it. At the end of the day, us programmers have the job of coming up with solutions.&lt;/p&gt;
&lt;p&gt;I’ve also listened way too much to what other people have said. Just because some ‘guru’ writes that Ruby on Rails is the devil’s web framework, doesn’t mean it is. I’ve been really quite mean about the project in the past, and I’ve now realized that, never having written a Rails web application, I don’t have the right to do that. Way too many people have poured hour upon hour and dollar upon dollar into Rails for me to decry and dismiss it without ever having used it before. I suppose what I’m also saying is that I’m going to stop listening to other people’s opinions on these things. When the local ‘guru’ claims that Rails is evil, I’m going to remember that everything is subjective. For example, I greatly enjoy programming in Common Lisp. But I acknowledge that it’s not for everyone; it just happens to suit my way of thinking quite well. I’d encourage people to try it, but if they don’t like it I’m not going to force it down their throats.&lt;/p&gt;
&lt;p&gt;I think that the people who do write inflammatory blog posts and articles on subjective opinions need to be more responsible and think about what they’re saying. A spirit of adventure needs to be adopted if we ever want to keep innovating. And I’m not saying I’ve been innocent in the past either, but I’m making a change.&lt;/p&gt;
&lt;p&gt;I’m going to begin by learning &lt;a href="http://ruby-lang.org" target="_blank"&gt;Ruby&lt;/a&gt;, and later Rails (although I might wait until Rails 3, I don’t know how different from this version it’s going to be). Why? Because I’ve been very harsh on the language in the past, and it’s sort of a token gesture. In the true spirit of irony, I’ll probably end up loving it. I mean, how can you resist “why’s (poignant) guide to ruby”? Have you actually read it? It’s crazy. In a good way.&lt;/p&gt;
&lt;p&gt;I’m going to end up branching into some languages that I never would have thought of before. This includes &lt;a target="_blank" href="http://erlang.org/"&gt;Erlang&lt;/a&gt;, &lt;a target="_blank" href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt;, &lt;a href="http://www.squeak.org" target="_blank"&gt;Squeak&lt;/a&gt;, &lt;a target="_blank" href="http://factorcode.org/"&gt;Factor&lt;/a&gt;, &lt;a target="_blank" href="http://clojure.org/"&gt;Clojure&lt;/a&gt;, and probably a few others. When I talk about ‘choosing tools’, I don’t mean just languages, but they’re a good starting point. And you know what? I might just come full circle, decide that these languages are just too far beyond the manic fringe for my liking, and end up sticking with the traditional (albeit brilliant) favourites Python and Django. But at least I can say I tried.&lt;/p&gt;
&lt;p&gt;Oh, and I’d probably like to learn C and/or C++ too, mainly because they tend to be the sort of ‘lowest common denominator’ languages, and a lot of jobs ask for C coding skills. I’m not much of a commercial programmer, but income is a nice thing to have.&lt;/p&gt;
&lt;p&gt;Thanks for reading. If you’ve made it this far, you’ve done well. Now, it’s 5:00 AM, so I think I’m going to sleep now.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/73398710</link><guid>http://zvoase.tumblr.com/post/73398710</guid><pubDate>Tue, 27 Jan 2009 05:03:21 +0100</pubDate><category>programming</category><category>python</category><category>django</category><category>rails</category><category>ruby</category><category>languages</category><category>dogma</category><category>practical</category></item><item><title>It’s funny ‘cos it’s true!</title><description>&lt;p&gt;It’s funny ‘cos it’s true!&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/72125864</link><guid>http://zvoase.tumblr.com/post/72125864</guid><pubDate>Wed, 21 Jan 2009 20:05:38 +0100</pubDate></item><item><title>"Don't Ask, Don't Tell" - Time for Change</title><description>&lt;p&gt;Note: Usually, this blog serves as a place for my more work-oriented stuff, but I thought it important to address an issue which means a lot to me.&lt;/p&gt;
&lt;p&gt;US Code TITLE 10, Subtitle A, PART II, CHAPTER 37, § 654. Most people know it by its short name: “Don’t Ask, Don’t Tell.”&lt;/p&gt;
&lt;p&gt;This is a policy of the United States military stating, amongst other things, that:&lt;/p&gt;
&lt;blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;The presence in the armed forces of persons who demonstrate a propensity or intent to engage in homosexual acts would create an unacceptable risk to the high standards of morale, good order and discipline, and unit cohesion that are the essence of military capability.&lt;/blockquote&gt;
&lt;p&gt;To give the short but not-so-sweet version, members of the US military who are part of the LGBTQ community must hide their sexual identity from other soldiers. Should it be discovered that they are not heterosexual, they will be ‘separated’ from the armed forces.&lt;/p&gt;
&lt;p&gt;The history of the bill is that, essentially, it was a compromise between those who wanted an outright ban on gays in the military, and those who wanted gays to be able to serve openly. That was in 1993. This is 2009. If you ask me, that’s one heck of a long compromise - if only an Israel-Palestine compromise could last that long!&lt;/p&gt;
&lt;p&gt;I’m not going to go into too much depth about the policy itself, because the &lt;a target="_blank" title="Don't Ask, Don't Tell Wikipedia Article" href="http://en.wikipedia.org/wiki/Don't_ask,_don't_tell"&gt;wikipedia article&lt;/a&gt; has a veritable treasure trove of information, but here’s an interesting perspective:&lt;/p&gt;
&lt;p&gt;“&lt;a target="_blank" title="The Axis of Evil" href="http://en.wikipedia.org/wiki/Axis_of_Evil"&gt;The Axis of Evil&lt;/a&gt;” (and &lt;a target="_blank" title="Beyond the Axis of Evil" href="http://en.wikipedia.org/wiki/Axis_of_Evil#Bolton:_.22Beyond_the_Axis_of_Evil.22"&gt;beyond&lt;/a&gt;) is a group of states that the US government believes are plotting to destroy the western world, by producing Weapons of Mass Destruction (WMDs) and supplying active terrorist organizations. This group is made up of the following countries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Iraq&lt;/li&gt;
&lt;li&gt;Iran&lt;/li&gt;
&lt;li&gt;North Korea&lt;/li&gt;
&lt;li&gt;Cuba&lt;/li&gt;
&lt;li&gt;Libya&lt;/li&gt;
&lt;li&gt;Syria.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You’ve probably heard of this axis before; it’s a phrase which has been used enough in the news for the past 7 years.&lt;/p&gt;
&lt;p&gt;How does this relate to the point of this article? Well, here’s just a few of the countries around the world where it’s either illegal to be homosexual, or illegal for homosexuals to serve openly in the military:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Iran (homosexuality illegal)&lt;/li&gt;
&lt;li&gt;Libya (homosexuality punishable by death)&lt;/li&gt;
&lt;li&gt;North Korea&lt;/li&gt;
&lt;li&gt;Syria (homosexuality illegal)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note how this lines up quite closely with the “Axis of Evil”, with the notable omission of Cuba (for which I could find no information) and Iraq (where, although homosexuality is legal, homosexuals are routinely killed by other citizens in hate crimes).&lt;/p&gt;
&lt;p&gt;Oh, and don’t forget the United States of America, where it’s illegal for a LGBT person to serve openly in the military (so I guess it gets on my list).&lt;/p&gt;
&lt;p&gt;I’m not saying that all countries with poor LGBT rights belong on the Axis of Evil, but still, it’s a common thread that all evil countries have poor LGBT rights. Just think about it. Maybe I’ve convinced you enough to vote on this &lt;a target="_blank" title="DADT Poll" href="http://www.military.com/hp/poll"&gt;poll&lt;/a&gt; (I think it’s going to change soon, so this link may go stale). Or something a bit more…influential (like writing to your representative, or something).&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/70059251</link><guid>http://zvoase.tumblr.com/post/70059251</guid><pubDate>Tue, 13 Jan 2009 00:00:18 +0100</pubDate><category>lgbtq</category><category>DADT</category><category>gay rights</category></item><item><title>The OAuth/Twitter kerfuffle.</title><description>&lt;p&gt;As a lot of people now know, Twitter’s been hit by the result of a few dodgy design decisions from the past (we’ve all made them at some point) and this has prompted a large call from web developers for Twitter to support &lt;a target="_blank" title="OAuth Spec" href="http://oauth.net/"&gt;OAuth&lt;/a&gt;, an authentication protocol that supposedly provides a bit more security than people going around and giving out their username and password to any old service.&lt;/p&gt;
&lt;p&gt;I’m going to summarize the pros and cons of using OAuth with Twitter, and then I’ll follow up with a couple of suggestions I have for fixing the issues.&lt;/p&gt;
&lt;p&gt;So, what’s this all about? Well, basically there is a service called Twply which asks for your Twitter username and password, and e-mails you every time you get a reply from someone. On signup, it gives the option to ‘support’ Twply, basically saying something along the lines of: “can we post a tweet from your account that advertises our service?” Needless to say, many people respond with “No.” Of course, Twply seems not to give two shits about what you want it to do, so it goes ahead and tweets the advertisement anyway. Lovely. So now, a bunch of Twitter users want to stop Twply from accessing their account; trouble is, they can’t without changing their password. Ug.&lt;/p&gt;
&lt;p&gt;Obviously, users of Twitter are enraged at the service for a breach of trust. But it turns out that this was just an incident waiting to happen. You see, the Twitter API is structured so that any application that needs access to it, has to use your username and password. Which means you are giving your username and password to other people, and blindly trusting them not to do something stupid or evil. Clearly someone, at some point, was going to abuse this trust. Twply has done so.&lt;/p&gt;
&lt;p&gt;Then, all eyes turned to OAuth. OAuth is a protocol, designed by a few &lt;a href="http://oauth.net/core/1.0/#anchor1" target="_blank"&gt;smart people&lt;/a&gt;, which allows you to give a third-party app (a ‘consumer’) permission to access a service (a ‘service provider’, i.e. Twitter) on your behalf. Now, basically, you are giving access to the consumer, which isn’t that different from giving them your username and password; where OAuth differs is that you can control access, only allowing the service to do certain things, and you can also revoke access without having to change your password. So you can see that, if OAuth were implemented on Twitter, people wouldn’t have to change their password, they could just go into some management console and revoke access. In this respect, OAuth is good. Also, people could have given Twply read-only access, meaning it could access their replies (in order to e-mail them) but not be able to send tweets from their account.&lt;/p&gt;
&lt;p&gt;OK, so OAuth seems to be pretty cool - though we can’t forget the cost of adoption, and the fact that it will have to be phased in over a relatively large time scale. But some people have expressed concerns over a vulnerability in the protocol. OAuth requires that the user log in with the service provider before it will grant access to an application. It is the responsibility of the consumer to redirect the user to Twitter to log in; this means that a fake consumer could potentially (maliciously) redirect a user to some phishing site and steal their password. So we need some kind of identity verification to make sure that you are, indeed, entering your details into Twitter, rather than a phishing website. This can be done in a couple of ways; firstly, Twitter should by default use HTTPS, and thus Twitter could be verified as the service provider. Secondly, users would have to be educated to check the authenticity of websites before entering sensitive data into them. Firefox (and maybe some other browsers - I don’t know) already checks against a blacklist (maintained by Google) and warns users when they are entering a potential phishing site. The phishing problem is one which will bug Twitter whether they’re using OAuth or not - it’s relatively easy to set up a clone of Twitter’s homepage and start spoofing users into handing over their credentials.&lt;/p&gt;
&lt;p&gt;So, to put it bluntly, OAuth isn’t the silver bullet that will kill phishing once and for all, but it’s certainly a step in the right direction. You shouldn’t make your users think it’s OK to just go around giving their usernames and passwords out to everyone who asks, but likewise, it’s stupid of users to do that as well. I’ll be the first one to admit that I’ve been stupid with my password; about a month ago, I changed my password to a very secure one, and removed myself from as many third-party services as possible. I won’t be signing up for any new services until OAuth is implemented and also until the first hole is found (because there probably will be quite a few holes to begin with).&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/68644321</link><guid>http://zvoase.tumblr.com/post/68644321</guid><pubDate>Tue, 06 Jan 2009 05:57:34 +0100</pubDate><category>twitter</category><category>oauth</category><category>twply</category></item><item><title>Twactor, and some Python descriptor amazingness.</title><description>&lt;p&gt;For the past few days, I’ve been working on a fledgling twitter client library for Python. The libraries which currently exist are, not to put too fine a point on it, cop-outs. One overrides __getattribute__ so that you are literally just making API calls directly from Python, and then it deserializes the JSON data it gets back and gives it straight to you. This might work for some, although I prefer a more refined approach.&lt;/p&gt;
&lt;p&gt;Anyways, I’m writing this library to take advantage of Python’s descriptors - you should be able to access data via attributes, not just dictionary calls, and it should be presented to you in a nice format, with names converted to more Pythonic equivalents and packaged into neat little namespaces so that it makes sense. I’ve also created a basic framework for incremental cacheing of the data — the library only ever contacts twitter when it needs to. An example of where this is important is the following: when you download info on one tweet, you get a small amount of info on the user who posted it. This info contains stuff like username, full name, profile image URL and the like - basic stuff. Now, a more naïve library might, if you wanted to fetch that user info, download all the info for that user. This library, however, creates a new instance of a ‘User’ class (compare to Django’s models), which contains a cached version of all the info from the tweet. So, if you want to access this User’s username, you can do status.user.username, and you’ll get the username without any additional requests being made. If, however, you want the user’s profile’s background color, more info needs to be fetched, and so status.user.profile.bg_color will go and fetch more info from the server, storing it in the cache. Then, any other information it fetched from the server will be accessible via that cache.&lt;/p&gt;
&lt;p&gt;All in all, I think this library will be pretty good when finished. Eventually, I’m hoping to make it a little more than just a twitter client, but more on that later…&lt;/p&gt;
&lt;p&gt;So, to the second purpose of this post, I’m going to explain the ‘Python descriptor amazingness…’ to you. Basically, when defining Python descriptors on classes (via property), you often have to write three functions — one for getting the value, one for setting it, and one for deleting it. An example might look something like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;class SomeClass(object):

    def __init__(self, somevalue=None):
        self._value = some_value

    def _get_value(self):
        return self._value

    def _set_value(self, value):
        self._value = value

    def _del_value(self):
        self._value = None

    value = property(
        fget=_get_value,
        fset=_set_value,
        fdel=_del_value)
&lt;/pre&gt;
&lt;p&gt;On instances of this class, you can access the value attribute to get the value. But the thing is, this quickly clutters up your class’s namespace with _get_*, _set_* and _del_* methods. Well, I’ve figured out a better way of doing this. All we need is a little helper lambda at the top called property_shortcut, which will handle the calling of property:&lt;/p&gt;
&lt;pre class="literal-block"&gt;property_shortcut = lambda x: property(**x())

class SomeClass(object):

    def __init__(self, somevalue=None):
        self._value = some_value

    @property_shortcut
    def value():
        def fget(self):
            return self._value
        def fset(self, value):
            self._value = value
        def fdel(self):
            self._value = None
        return locals()
&lt;/pre&gt;
&lt;p&gt;And this will work exactly the same as the one before, without cluttering your class’s namespace with junk. There are several things to note here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The value method takes no explicit self argument. This allows the method to be called unbound (i.e. without being on an instance). If it did accept self, then this wouldn’t work.&lt;/li&gt;
&lt;li&gt;The names of the functions fget, fset and fdel are the keyword arguments that the property function accepts. This means that calling locals() will return a dictionary with these three names, and that is why property_shortcut works, as it uses Python’s double asterisk method for unpacking a dictionary into keyword arguments.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So that’s how we roll. Hope you like it ;-)&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/67195160</link><guid>http://zvoase.tumblr.com/post/67195160</guid><pubDate>Sun, 28 Dec 2008 22:15:28 +0100</pubDate><category>python</category><category>oop</category><category>programming</category><category>twitter</category><category>twactor</category></item><item><title>Improve your jQuery - 25 excellent tips</title><description>&lt;a href="http://digg.com/programming/Improve_your_jQuery_25_excellent_tips"&gt;Improve your jQuery - 25 excellent tips&lt;/a&gt;: &lt;p&gt;25 tips and shortcuts, from beginner to advanced to make you a better jQuery coder.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/65377804</link><guid>http://zvoase.tumblr.com/post/65377804</guid><pubDate>Wed, 17 Dec 2008 17:19:08 +0100</pubDate></item><item><title>If programming languages were religions...</title><description>&lt;a href="http://digg.com/programming/If_programming_languages_were_religions"&gt;If programming languages were religions...&lt;/a&gt;: &lt;p&gt;Perl would be Voodoo - An incomprehensible series of arcane incantations that involve the blood of goats and permanently corrupt your soul. Often used when your boss requires you to do an urgent task…&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/65258876</link><guid>http://zvoase.tumblr.com/post/65258876</guid><pubDate>Wed, 17 Dec 2008 01:51:13 +0100</pubDate></item><item><title>Managers vs. Model Classmethods in Django</title><description>&lt;p&gt;Everyone who’s read the Django documentation on models and managers will know the following; methods on your models specify row-level functionality, whereas operations on the whole data set are better encapsulated in managers. I know this all too well; I used to be absolutely obsessed with writing managers - each model would have about five for all different possible uses.&lt;/p&gt;
&lt;p&gt;However.&lt;/p&gt;
&lt;p&gt;Recently, I’ve completely stopped writing my own managers, for a very simple reason. I’ll explain why after a quick briffet (a made-up word) of code:&lt;/p&gt;
&lt;pre&gt;from django.db import models

class MyModel(models.Model):
    field1 = models.CharField(max_length=100)
    ...
    fieldn = models.IntegerField()
    fieldn_1_manager = MyManager()

class MyManager(models.Manager):

    def get_query_set(self):
        return super(MyManager, self).get_query_set().filter(fieldn=1)

&lt;/pre&gt;
&lt;p&gt;This is a simple model definition in Django, which uses a manager to filter for a particular set of rows. MyModel.objects represents the primary manager, which will contain all objects in the database, and MyModel.fieldn_1_manager will contain all the rows where the value of fieldn is &lt;b&gt;1&lt;/b&gt;. This is, and has been, and may well be for a while, the conventional way to do things. I don’t like it though, so I’ve come up with my own way of doing things.&lt;/p&gt;
&lt;p&gt;Most people don’t really use the classmethod and staticmethod decorators which are in the top-level &lt;i&gt;built-in&lt;/i&gt; namespace; however, they are very useful as the first, for example, allows you to define a method which, instead of receiving the instance as the first argument, gets the class instead. This allows you to define class-level operations using the typical method syntax, like so:&lt;/p&gt;
&lt;pre&gt;class MyModel(models.Model):

    field1 = models.CharField(...)
    field2 = models.CharField(...)
    ...
    fieldn = models.IntegerField()

    @classmethod
    def fieldn_1(cls):
        return cls.objects.filter(fieldn=1)

&lt;/pre&gt;
&lt;p&gt;You can probably see here why this advantage is a lot prettier. No subclassing, models and operations are tied together to prevent confusion, and good prevails throughout the land.&lt;/p&gt;
&lt;p&gt;I’d love to know people’s reasons for choosing to use managers over classmethods. Please twitter me @zvoase with ideas and explanations.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/64576757</link><guid>http://zvoase.tumblr.com/post/64576757</guid><pubDate>Sat, 13 Dec 2008 02:32:09 +0100</pubDate><category>django</category><category>models</category><category>managers</category><category>classmethod</category></item><item><title>Jeffrey Zeldman Presents : 20 signs you don’t want that web design project</title><description>&lt;a href="http://www.zeldman.com/2008/12/04/20-signs-you-dont-want-that-web-design-project/"&gt;Jeffrey Zeldman Presents : 20 signs you don’t want that web design project&lt;/a&gt;</description><link>http://zvoase.tumblr.com/post/63054283</link><guid>http://zvoase.tumblr.com/post/63054283</guid><pubDate>Thu, 04 Dec 2008 20:38:00 +0100</pubDate></item><item><title>The Man in the Moon, from "Sylvie and Bruno Concluded" by Lewis Carroll</title><description>Me: What a useful thing a pocket-map is!&lt;br /&gt;&#13;
Mein Herr: That’s another thing we’ve learned from your Nation, map-making. But we’ve carried it much further than you. What do you consider the largest map that would be really useful?&lt;br /&gt;&#13;
Me: About six inches to the mile.&lt;br /&gt;&#13;
Mein Herr: Only six inches! We very soon got to six yards to the mile. Then we tried a hundred yards to the mile. And then came the grandest idea of all! We actually made a map of the country, on the scale of a mile to the mile!&lt;br /&gt;&#13;
Me: Have you used it much?&lt;br /&gt;&#13;
Mein Herr: It has never been spread out, yet. The farmers objected: they said it would cover the whole country, and shut out the sunlight! So we now use the country itself, as its own map, and I assure you it does nearly as well.</description><link>http://zvoase.tumblr.com/post/62145583</link><guid>http://zvoase.tumblr.com/post/62145583</guid><pubDate>Sat, 29 Nov 2008 19:00:00 +0100</pubDate></item><item><title>"I’ve noticed lately that the paranoid fear of computers becoming intelligent and taking over the..."</title><description>“I’ve noticed lately that the paranoid fear of computers becoming intelligent and taking over the world has almost entirely disappeared from the common culture.  Near as I can tell, this coincides with the release of MS-DOS.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Larry DeLuca&lt;/em&gt;</description><link>http://zvoase.tumblr.com/post/61798470</link><guid>http://zvoase.tumblr.com/post/61798470</guid><pubDate>Thu, 27 Nov 2008 09:10:39 +0100</pubDate><category>intelligence</category><category>MS-DOS</category><category>funnyhaha</category></item><item><title>I Want A Pony</title><description>&lt;p&gt;I want a pony.&lt;/p&gt;
&lt;p&gt;Update: I forgot there was already an &lt;i&gt;include&lt;/i&gt; template tag in Django. I’m now calling this &lt;i&gt;mediainclude&lt;/i&gt;.&lt;/p&gt;
&lt;pre&gt;{% mediainclude stylesheet /media/css/example.css screen print %}
{% mediainclude javascript /media/js/example.js %}
&lt;/pre&gt;
&lt;p&gt;Tonight, I’m going to start on this. I haven’t really gone into Django template tags that much before, but this should be an interesting experience. Really, it’s very simple, but it will save me so much HTML time it’s not even funny.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/61671700</link><guid>http://zvoase.tumblr.com/post/61671700</guid><pubDate>Wed, 26 Nov 2008 15:55:00 +0100</pubDate><category>django</category><category>pony</category><category>template tags</category></item><item><title>My SAT I Reasoning Results</title><description>&lt;p&gt;Guess who just got his SAT I Reasoning results?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Critical Reading: 760/800 (99% National Percentile)&lt;/li&gt;
&lt;li&gt;Mathematics: 780/800 (99% National Percentile)&lt;/li&gt;
&lt;li&gt;Writing: 720/800 (97% National Percentile)
&lt;ul&gt;
&lt;li&gt;Multiple Choice: 72 (score range 20-80)&lt;/li&gt;
&lt;li&gt;Essay: 9 (score range 2-12)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not &lt;i&gt;astounding&lt;/i&gt;, but I hope it’s enough for MIT.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/60683408</link><guid>http://zvoase.tumblr.com/post/60683408</guid><pubDate>Thu, 20 Nov 2008 13:36:12 +0100</pubDate></item><item><title>Using memcached for Django Sessions</title><description>&lt;p&gt;Django comes with a useful sessions framework which allows you to implement persistence during a single ‘session’ of interaction between a user and your site. Aside from storing things like preferences, this allows you to implement “wizards” (forms split across multiple pages), history and memory (i.e. for pagination) across a short period of time. A session is essentially a dictionary, available in the request object’s session attribute, which you can set and retrieve keys on. I don’t really need to explain it, because &lt;a target="_blank" title="Django's session documentation" href="http://docs.djangoproject.com/en/dev/topics/http/sessions/"&gt;Django’s documentation on sessions&lt;/a&gt; is perfect, thank you very much.&lt;/p&gt;
&lt;p&gt;One feature of sessions, however, is not very well publicized. The sessions framework supports an additional setting (in settings.py, of course) called SESSION_ENGINE. Usually, you see, the sessions are stored in your main database, in a special table for the purpose. However, if you heavily rely on sessions in your views, this will incur a large cost to the database; each page will have an additional read and an additional write. If your database is the kind that likes to explode in your face occasionally, that’s not really cool.&lt;/p&gt;
&lt;p&gt;In fact, I &lt;strike&gt;probably&lt;/strike&gt; definitely don’t need to explain how reducing database hits is a good thing.&lt;/p&gt;
&lt;p&gt;So what can be done about this problem? Well, two years ago, ticket #&lt;a target="_blank" title="Ticket #2066" href="http://code.djangoproject.com/ticket/2066"&gt;2066&lt;/a&gt; came along, asking for pluggable session backends. About a year later it was closed, and the option to change the session backend was added to Django. You can now choose to use different backends instead of the usual database method.&lt;/p&gt;
&lt;p&gt;To exploit this functionality, simply add SESSION_ENGINE to your settings.py, and set it to “django.contrib.sessions.backends.cache”. This will cause sessions to be stored in your configured cache backend, which (usually) will be memcached. If, however, you don’t have a memcached instance up and running, you can get it going relatively easily; search the Django docs for how to set up a cache (hint: it’s SUPER-easy).&lt;/p&gt;
&lt;p&gt;That’s the end of this unnecessarily long blog post on an über-simple feature of Django. If I’d written all the Django docs, they’d have to be shipped on DVDs.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/60282649</link><guid>http://zvoase.tumblr.com/post/60282649</guid><pubDate>Tue, 18 Nov 2008 13:35:19 +0100</pubDate><category>django</category><category>cache</category><category>sessions</category><category>python</category><category>memcached</category></item><item><title>Google needs to update its cache of http://zvoase.tumblr.com so that I can start messing about with...</title><description>&lt;p&gt;Google needs to update its cache of &lt;a href="http://zvoase.tumblr.com" target="_blank"&gt;http://zvoase.tumblr.com&lt;/a&gt; so that I can start messing about with the Social Graph API.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/60030413</link><guid>http://zvoase.tumblr.com/post/60030413</guid><pubDate>Mon, 17 Nov 2008 02:17:32 +0100</pubDate></item><item><title>Disruptive Realism: http://is.gd/7Ml4. It looks like fun. I might have a go at disrupting some...</title><description>&lt;p&gt;Disruptive Realism: &lt;a href="http://is.gd/7Ml4." target="_blank"&gt;http://is.gd/7Ml4.&lt;/a&gt; It looks like fun. I might have a go at disrupting some reality. I might have a sandwich first though&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/60030404</link><guid>http://zvoase.tumblr.com/post/60030404</guid><pubDate>Mon, 17 Nov 2008 02:17:31 +0100</pubDate></item><item><title>Just submitted my tumblelog’s sitemap to Google Webmaster tools, awaiting a flood of...</title><description>&lt;p&gt;Just submitted my tumblelog’s sitemap to Google Webmaster tools, awaiting a flood of popularity and general internet fame. Or something.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/60030406</link><guid>http://zvoase.tumblr.com/post/60030406</guid><pubDate>Mon, 17 Nov 2008 02:17:31 +0100</pubDate></item><item><title>Jeezus, Google’s Social Graph API is effing awesome. Orgasmically, Vigorously, Awesome.</title><description>&lt;p&gt;Jeezus, Google’s Social Graph API is effing awesome. Orgasmically, Vigorously, Awesome.&lt;/p&gt;</description><link>http://zvoase.tumblr.com/post/60030401</link><guid>http://zvoase.tumblr.com/post/60030401</guid><pubDate>Mon, 17 Nov 2008 02:17:30 +0100</pubDate></item></channel></rss>
