Fear and Loathing on the Learning Curve: Observations on Life, Tech and Web Design from a Slightly Misanthropic Mind
Facebook is Shit
So over the last six months or so I’ve experienced a sour realisation. It took me a while to come to terms with it, but I think I can finally sensibly express what I’ve discovered: Facebook, the increasingly omnipresent social wünderkind that I so loved during my University years is now, in 2012, shit.
This revelation was long in coming, I think, thanks in no small part to my nostalgic hangover from those early days. Facebook has given me so many social goodtimes over the years that I hardly wanted to look the truth in the eye, but now I can finally accept that the incipient little community that first caught my attention in 2005 has now grown to a filthy, sprawling slum of irrelevance and bullshit, and I fear the time has come to leave town.
Facebook in the early years was a different beast – it had global reach, but its small feature set aimed squarely at the local level – college and university, with according barriers to entry. It connected the user with people in their immediate environment, right down to course and class level, and it all felt eminently manageable.
But that was then, as they say, and this is now. The Facebook of today has grown beyond a mere forum, positioning itself as a platform for everything, but ending up as an impenetrable amalgam of social network, calendar, phone book, photo album, event planner, games console, instant messenger, location service, app platform, recommendation engine, marketplace, and – by no means least – ad network. And unfortunately, it doesn’t do many of these very well.
As Facebook has permeated the mainstream, so too has the expectation that the parts of our social graph that we care about will follow suit; that since we now have access to the recorded lives of everyone we’ve ever known in the entire world, we’ll want to keep up with the activities of those people everywhere, all the time, forever. Coupled with the seemingly now commonplace assumption that our Facebook networks should be a complete analog of our real-life social graph, we’re left with a social system that rapidly escapes our ability to manage it.
When I was first at Uni my Facebook network consisted of fewer than a hundred people, all of whom I knew well enough to stop to talk to in the street; out in the real world of 2012, I now have nearly five hundred contacts, despite some pruning efforts, and for me at least this has just about destroyed Facebook’s usefulness as a platform for anything. To log in to Facebook now is to be assaulted by a never-ending stream of irrelevance and triviality from the countless contacts who I don’t really know, and many of those I do. Despite numerous reorganisations of the News Feed, Facebook seems to have taken the surfeit of available social data and disregarded it completely in favour of offering me progressively less relevant information. The “Top Stories” metric is poorly tuned, boosting items that have attracted comments and Likes from anyone, regardless of my relationship with them. It could at least prioritise stories from people I’m obviously more likely to be interested in, like those with whom I’ve interacted recently, but it doesn’t.
This sort of activity firehose was interesting and manageable back in the day due to the nature of the network – a smaller graph consisting mostly of people in my immediate environment whose posts and event invites were, more often than not, relevant to my interests – but now with hundreds of contacts scattered around the globe the Events system has become a gigantic spam machine-gun, helped in no small part by the ease with which someone can invite every single contact to join an event or become a fan of a page. The bullshit echo chamber of my News Feed fills up with near-strangers talking about their job, or the weather, or television, or standing next to their new car or a horse or their lunch; my inbox fills up with notifications of invites to events halfway round the world, and I’m increasingly minded to ignore everything. With all the computing power and historical social data in the world, Facebook remains unable to show me anything I actually give a shit about.
Clearly the solution is to aggressively prune my contact list until I’m left with only “real” friends, but where does one draw the line? And given all this data, surely it shouldn’t be necessary to do this? But it seems it is, because without it, Facebook becomes a terrifying global memory machine that subverts the traditional decay process of social connections and replaces them with a world where no-one is permitted to forget anyone, instead being constantly bombarded with minutiae about them. To derive any non-trivial value from it requires constant shitwork to maintain friend lists, adjust privacy settings and content preferences, time arguably better spent actually going outside and seeing people. And pruning those contact lists is tough, because everyone assumes your Facebook graph should mirror your meatspace one, and it’s tricky to get away with de-friending someone you might bump into again just to get their guff off your timeline.
Speaking of terrifying memory machines, the Timeline profile view is a particular exasperation that while optional now will soon no doubt be standard for all, with its grubby ability to instantly teleport back to any user’s first tentative shares and embarrassingly youthful photos. I know of more than one person who has deleted a large chunk of their early photos and data in response to this. With Facebook’s insistence on redesigning its UI every few months, the lack of control over this changing presentation of what is after all our data is pretty irritating. In the real-life friendship model we focus on the present with a few memories skimmed off the top of history, but no more. Now our drunk photos from forever are just a flick of the scrollbar away.
A lot has been written about Facebook’s data collection activities and while that isn’t such a major concern for me, it probably should be. Facebook’s huge valuation at their recent IPO underlines the importance of their leveraging the mountains of social data they retain, and we should be under no illusions as to their intentions. When the dimensions of data they have access to are combined, we reach the sort of level of intelligence governments get very excited about, and here we are giving all this information away for free.
So why not just leave altogether? That’s the million-dollar question, and the one I find most frustrating. Given Facebook’s pervasiveness, I feel like I have to retain at least a token presence for fear of missing out on key things. It’s mostly events, I think – since nobody seems to promote those by any other means anymore – but worse, more and more sites and apps now use Facebook Connect as their sole authentication system, making it even more painful to avoid having a Facebook account.
The trick, then, must be to trim those contacts back to the bare minimum, get rid of any surplus data that I don’t feel like keeping around, and try not to worry. Facebook will be around whether I’m on it or not, so I might as well try to salvage some value from it without being driven completely mad. Just don’t expect me to return your pokes or Like that photo of your feet.
Thanks to Tim Anderson for reading drafts of this post.
Your first Heroku Django app
I few weeks ago I decided to rewrite an old PHP site in Python + Django, and settled on hosting it on Heroku, as I didn’t have time to go through the rigmarole of setting up my own VPS just to demo the site. Heroku is a fantastic platform for app hosting but there are a few gotchas that I ran into on the way which I thought I’d share.
A quick overview of the platform, then, in case you’re not familiar with it – Heroku is a cloud hosting service for applications, rather than servers, and supports several software stacks, Python among the newest added. It plugs into your git workflow so you can deploy with a simple git push, and your app gets compiled down into a runtime known as a “slug” which Heroku serves from its network of app servers. Nearly all configuration/management of your app is done from your local command line via the heroku “toolbelt” app. The pricing structure is such that you can run a simple app with a small database for free.
Your application slug is read-only, and each of Heroku’s web server processes (known as “dynos”) runs in its own isolated environment so your app itself must be stateless – you can only persist stuff to database, anything else (e.g. uploaded media files) must be written to and served from another environment, such as S3. You can serve static files (e.g. JS, CSS, images) from your app, but you won’t be able to change them without doing a new deployment.
The first issue I encountered: Heroku detects your app’s software stack by looking for several common files, and in the case of Django apps it’s looking for settings.py. However in my Django project structure I like to maintain separate configs for common, local and production in separate directories, so I had to explicitly tell Heroku where to find my settings by setting the DJANGO_SETTINGS_MODULE environment variable thusly: heroku config:add DJANGO_SETTINGS_MODULE=myapp.config.heroku.settings (replacing myapp with your app name).
Heroku expects your Python app to use virtualenv, and also pip to install and manage packages.
I found that in order to run my app scripts on the remote side I also needed to update my Python path, which requires setting another environment variable: heroku config:add PYTHONPATH=/app:/app/myapp
Next I needed to set up what Heroku calls the “shared database” addon, which is basically a 5MB free PostgreSQL instance that your app can have access to. It took me a while to figure out that this isn’t provided by default, you have to enable it by running heroku addons:add shared-database . Heroku addons provide their access details via environment variables, so once you’ve enabled the shared database you’ll find (via heroku config, which lists them) that you’ve got a new variable called SHARED_DATABASE_URL containing the URL and login details for your app’s PostgreSQL db (you also need psycopg2 installed, via pip install psycopg2).
Because Heroku’s stack detection magic didn’t like my app structure, I found I also needed to manually add some bits to my settings file to introspect the environment and set up the database connection based on the SHARED_DATABASE_URL var. The code is here (at the bottom). A normally-structured Django app will have this code automatically added during deployment, but mine didn’t.
I also had to manually tell South (the migration library I was using) to use the PostgreSQL backend, by adding the following to my production settings file: SOUTH_DATABASE_ADAPTERS = { 'default': "south.db.postgresql_psycopg2" } .
The final big obstacle came when deploying – I run collectstatic on my Django apps to gather all my static files together into one location, and this wasn’t working on Heroku. It turns out that the collectstatic command runs in its own virtual environment, separate from the one in which the web server dyno runs, so the latter never has access to the collected files (the application slug is read-only, remember?). I found this helpful link on the subject, which explains how to combine the collectstatic and gunicorn start commands into one in your Procfile (which tells Heroku how to run your app) so they share an environment. Check the comments on that post for details on how to adjust your urls.py file to properly point to the static files too.
Worth noting that in that previous link, the Procfile command to start gunicorn refers to a $PORT var – this is present in the web server dyno environment: you have to bind to the port they specify, or nothing will work – but this is pretty much handled for you.
To get media files working properly and serving from S3, I used django-mediasync to copy my local media files to my S3 bucket (one time only), then used these settings in my production settings.py to hook it all up, via django-storages and boto. Note the last line, which instructs easy_thumbnails (if you’re using it) to use the same storage engine as the app default. Without this, easy_thumbnails won’t be able to save generated thumbnails to S3. Took me a while to diagnose that one.
A couple of other bits: if you want to send email from your app, you’ll need to use your own server or use the free Sendgrid addon which allows up to 200 messages a day, beyond which you’ll need to hand over some cash money. Heroku don’t provide outgoing email facilities themselves.
Lastly, it’s worth noting that Heroku’s architecture will automatically put a running app into a sleep state if it’s not accessed for a while. This can have the effect of making the first request in a while quite slow. I got around this by setting up a free Pingdom account to ping my app every few minutes, which keeps it alive.
Hope this sheds a little light on some of the less-documented aspects of running Python/Django apps on Heroku. It’s a great platform and I found getting to grips with it to be a really useful learning experience. Good luck!
On Certifications
I’m in the process of changing jobs at the moment, and have been struck by the difficulties inherent in trying to quantify experience and skill in people moving between companies in the web development sector.
Continued →

The Bloody Apprentice, S07E01
My viewing of the first episode of the new Apprentice series was conducted under an assumption, rapidly formulated during the first ninety seconds of the show, that these people cannot possibly be real; that such a concentration of frantically self-aggrandising, masturbatory gawpers cannot possibly exist — outside of fiction — in the space of one boardroom without the entire city of London disappearing up its own backside in an enormous implosion of bullshit. Once I established that premise, the show immediately became several times more watchable.
Be ye warned: this post contains spoilers. By which I mean I will talk about which useless shaft got fired last night.
Continued →
Book Review: “Designing with Web Standards” (1st Edition)
I’ve been making a conscious effort to read more “industry literature” lately, in as much as I’ve started seeking out books on web/software development and design that I feel, as a supposed pro, I ought to have read (possibly some time ago).
This endeavour eventually brought me to Jeffrey Zeldman’s Designing with Web Standards, which I’d never actually read despite it being revered as the book for anyone remotely serious about web design. Feeling nought but dust in my pockets, I hunted out a second-hand copy on the Amazon Marketplace, which I found for the princely sum of £0.01 plus postage. How do they do it?
Continued →

Introducing tweetvaultHQ
So I thought it was about time I wrote about my latest project: tweetvaultHQ. It launched a couple of weeks ago, and now things have settled down I’ve got time to write a bit about it and what the launch was like.
tweetvaultHQ is a hosted Twitter archiving service. Some time last year I got tired of not being able to effectively search my own tweet history (Twitter’s global search only goes back a few days, and there’s no per-profile search — you have to just keep paging through the timeline), and I thought it would be handy to have my own saved copy of my tweets. I’d also been doing quite a bit with the Twitter API at work, so I figured I’d build something.
Continued →

You can find a complete history of older posts in the Archive.