Playing with Coder (on Ubuntu)

Coder from Google Creative Lab looks really interesting:

Now I’ve got a Raspberry Pi, and I will set this up for my kids to try out, but I wanted to try it out now (and downloading ~1GB on my rural ADSL connection takes time).

Coder itself is Node.js, so you can try it directly on you computer. These instructions are for Ubuntu (naturally), but you should be able to adapt them.

First make sure you have node installed:

$ sudo add-apt-repository ppa:chris-lea/node.js
$ sudo apt-get update
$ sudo apt-get install nodejs

Next create a pi user (Coder looks for this):

$ sudo sudo adduser pi

Now check out the Coder repository:

$ git clone https://github.com/googlecreativelab/coder.git

Install the dependencies:

$ cd coder/coder-base
$ npm install

…and run it:

$ sudo npm start

(You need to run with sudo because it changes the password for the pi user.)

Now visit https://localhost:8081 (it only runs over SSL), accept the self-signed certification, and play away!

Writing better commit messages

I was browsing Twitter last night when Thoughbot linked to their post about commit messages.

This was quite timely as my team has been thinking about improving the process of creating our release notes, and it has been proposed that we generate them automatically from our commit messages. This in turn requires that we have commit messages of sufficient quality, which – to be honest – we don’t always. So the second proposal is to enforce “good” commit messages as part of reviewing and approving merge proposals into our projects. See this post from Kevin on my team for an overview of our branching strategies to get an idea of how our projects are structured.

We still need to define what constitutes a “good” message, but we will certainly use both the article from Thoughtbot and the oft-referenced advice from Tim Pope as our basis. We are also only planning to apply this to commits to trunk because, well, you don’t need a novel – or even a short story – for every commit in your spike branch!

Now, back to the Thoughtbot article, and this piece of advice stood out for me:

Never use the -m <msg> / --message=<msg> flag to git commit.

Since I first discovered -m I have used it almost exclusively, thinking I’m being so clever and efficient, but in reality I’ve been restricting what I could say to what felt “right” on an 80 character terminal. If nothing else, I will be trying to avoid the use of -m from now on.

Continuous Integration with Tarmac and Vagrant

As part of our self-improvement and knowledge sharing within Canonical, within our group (Professional and Engineering Services) we regularly – at least once a month – run what we call an “InfoSession”. Basically it is Google Hangout on Air with a single presenter on a topic that is of interest/relevance to others, and one of my responsibilities is organising them. Previously we have had sessions on:

  • Go (a couple of sessions in fact)
  • SystemTap
  • Localization (l10n) and internationalization (i18n)
  • Juju
  • Graphviz
  • …and many others…

Today the session was on continuous integration with Tarmac and Vagrant, presented by Daniel Manrique from our certification team. In his own words:

Merge requests and code reviews are a fact of life in Canonical. Most projects start by manually merging approved requests, including running a test suite prior to merging.

This infosession will talk about tools that automate this workflow (Tarmac), while leveraging your project’s test suite to ensure quality, and virtual machines (using Vagrant) to provide multi-release, repeatable testing.

Like most of our sessions it is publicly available, here it is is for your viewing pleasure:

django-getenv – use environment variables in your Django settings

So I made a thing for using environment variables within your Django settings: django-getenv.

Although the code itself is trivial (and, to be honest, not coupled with Django in any way), because I was re-using the same code in multiple projects I decided – if only to make my life easier – to made it into a standalone module and package.

Enough of the what, let us get onto the why.

I’m a big fan of The Twelve-Factor App, and although I can’t or don’t always follow its tenets in every app I write, I do my best.

One of the tenets is “Store config in the environment”:

The twelve-factor app stores config in environment variables (often shortened to env vars or env). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.

Although Django has a range of configuration options, it does not lend itself well to using environment variables out of the box.

Jacob Kaplan-Moss has addressed part of this with django-dotenv which lets you use a Foreman-style .env file to populate your environment with the settings contained within that file.

django-getenv is another piece of the puzzle, helping you use those environment variables in your Django project settings. As well as simplifying accessing these variables, it will also convert boolean, integer and float values to their native Python types.

The module is BSD (3-clause) licensed, available on Pypi, and the project is hosted on Github.

Using Django flatpages content in other (class-based) views

The flatpages application that ships with Django is both (intentionally) simple and useful. In previous projects I’ve found myself both extending the models (to add data like meta tags) and duplicating the whole application (when I wanted to add a whole bunch of extra details, multiple content sections, or a WYSIWYG editor).

In a recent project I had the need to editable (by administrators) content in other views, and I turned to flatpages again for my solution.

What I did was to create a class-based view mixin to find the flatpage for a given URL (defaulting to the one defined in request.path), and include the resulting object in the context (once the title and content had been marked safe of course):

from django.contrib.flatpages.models import FlatPage


class FlatPageMixin(object):
    """
    Retrieves the FlatPage object for the specified url, and includes it in the
    context.

    If no url is specified, request.path is used.
    """
    url = None

    def get_context_data(self, **kwargs):
        if not self.url:
            self.url = self.request.path

        context = super(FlatPageMixin, self).get_context_data(**kwargsG)
        try:
            flatpage = FlatPage.objects.get(url=self.url)
            flatpage.title = mark_safe(flatpage.title)
            flatpage.content = mark_safe(flatpage.content)
            context["flatpage"] = flatpage
        except FlatPage.DoesNotExist:
            context["flatpage"] = None

        return context

Then you just need to ensure a flatpage exists for the expected (or specified) URL, add the mixin to your class-based view(s) and use {{ flatpage.title }} and {{ flatpage.content }} in the template(s).