Cool features of GitHub

I put together a simple presentation about some of the amazing features of GitHub. I focus on stuff that can be very useful even for folks who might not know Git and GitHub very well, or not at all. The idea is that by starting to use GitHub, they just might actually get on the fast track to becoming full-time Git users, who knows…

It’s a presentation, so the slides are not really designed for reading, but here they are anyway:

Once again, I used many tips from Zach Holman’s blog to “design” the slides. I also shamelessly borrowed colors and fonts from his other fantastic slides, especially this one. (I hope he wouldn’t mind…)

I created the slides using Google Docs, and since it looks like the links didn’t come out right in the PDF export, here they are:

My book Bazaar Version Control is now published

I am happy to announce that my book “Bazaar Version Control” has been released, and it is now available in online stores:
https://www.packtpub.com/bazaar-version-control/book

The sample chapter (Chapter 2: Diving into Bazaar) is a FREE download. It includes the preface, which is a nice, short and sweet introduction of the book. The chapter reveals quite a lot: it explains all the basic operations of Bazaar using both the command line client and Bazaar Explorer. It is a good sample of the overall writing style in the book, and you should definitely read this first before buying.

If you find the cover familiar, it is based on Gource, a truly awesome VCS visualization tool that works transparently with Bazaar. I wanted to include a proper section featuring Gource somewhere in the book, unfortunately due to time and space constraints I was not able to do so in the end. So here goes my very special thanks to the author, Andrew Caudwell, of this fantastic open-source project.

ImproperlyConfigured: The SECRET_KEY setting must not be empty

I hit by a strange issue with Django. If I try to use a local configuration with

./manage.py shell --settings=myproject.local_settings

I got the error:

ImproperlyConfigured: The SECRET_KEY setting must not be empty

Strange because SECRET_KEY is certainly set. No stack trace, just a single line of error.

The cause turned out to be that in the main settings.py file I imported a method from one of my apps like this:

from accounts.views import render_failure
OPENID_RENDER_FAILURE = render_failure

I don’t understand why exactly this is a problem, but removing the import solved the issue. On the other hand, I needed that import as the OPENID_RENDER_FAILURE setting of the django-openid-auth package takes a callable, giving it the absolute function name accounts.views.render_failure as a string doesn’t cut it. I worked around that like this:

def render_failure(*args, **kwargs):
    from accounts.views import render_failure
    return render_failure(*args, **kwargs)
OPENID_RENDER_FAILURE = render_failure

Now everything works fine.

Deploying new releases using Git and the post-receive hook

I used to deploy new versions of my websites like this:

  1. ssh to the server
  2. cd to the website project directory (under version control)
  3. Update from VCS to the latest version

Doing this a few times is ok, but if you want to release frequently it’s better to automate these steps. One way to do that is using the post-receive hook of Git like this:

  1. Setup a mirror repository on the server called “releases”, with a branch called “beta”
  2. Make the deployment directory track the “beta” branch of the “releases” repository
  3. Setup a post-receive hook in the “releases” repository to trigger a script that updates the deployment directory (perform a git pull or git checkout -f)

The goal of this setup is to simplify the deployment steps to a single git push command from my local development/test environment to the releases repository. Then thanks to the post-receive hook, the pushed changes will be automatically propagated to the deployment directory, without manually logging in to the server.

First I created the releases repository from my deployment directory:

Next I created the post-commit hook:

(Hook scripts are in the hooks/ directory of a Git repository, and must be executable.)

I typically use two branches: “beta” and “prod”, and reuse the same “releases” repository for these. The above hook script checks the branch that is being pushed to, and checks if an upgrade script exists with the filename in the format “upgrade-BRANCHNAME.sh”. The real upgrade scripts exist in my deployment directories, because I don’t want to have too much logic inside the Git repository directory, I prefer that to be together with the project itself. In the Git repository root I put only symlinks to the real upgrade scripts.

Writing an upgrade script depends on your project. Here’s an example from one of my Django sites:

The script is written in a way to be reusable in multiple of my Django sites, but you may need to adjust to match your typical deployment. The unset GIT_DIR is necessary, because it seems the variable is automatically set when the hook is executed, otherwise the git pull operation would result in the error:

remote: fatal: Not a git repository: '.'

Finally, I setup the releases remote in my local Git project:

# go to the directory of my local project
cd ~/project/dir

# add the "releases" remote
git remote add releases ssh://user@example.com/home/user/path/to/project.git

With this setup in place, deploying a new version is as simple as:

git push releases master:beta

To make it even easier, I created aliases in my .gitconfig:

deploy-beta = push releases master:beta
deploy-prod = push releases master:prod

Debugging deprecation warnings in Django

Ever since switching to Django 1.5, I’ve been annoyed by this:

DeprecationWarning: django.conf.urls.defaults is deprecated; use django.conf.urls instead

I’ve been annoyed because I duly made the necessary changes in my project and verified that I’m not using the old module anymore:

grep -rl django.conf.urls.defaults .

Yet I was still getting this warning… Finally I understood (thanks to some googling) that the cause is that one of the apps included in the project are still using the old module. To find out which one, here’s a really elegant solution:

python -W error manage.py runserver

This way deprecation warnings will raise an error and from the stack trace it’s easy to find the perpetrator. In my case it was django-openid-auth, which at version 0.5 is still using the old format. I recently learned about django-social-auth, probably I’ll be switching to that one in the near future.

Using XBMC with an external player

First of all, XBMC looks really awesome:

I’m using XBMC mainly to watch my favorite internet streams, such as TED and vimcasts.

I’m not using it yet for my movie collection, because I have some issues with its built-in player:

  • Adjusting the volume is not easy enough: in VLC I can just use the mouse scroll
  • Adjusting the aspect ratio is not easy enough

Finally I figured out how to use an external player. I created a configuration file in ~/.xbmc/userdata/playercorefactory.xml like this:

This way it will use VLC for local video files only, and continue to use the built-in player for others.

For more information on hacking the configuration, see the docs.

Using custom fonts on Android

The default fonts you can choose from when developing for Android are not very interesting. Normally they are OK for my simple purposes, but for once I wanted something a little bit prettier for my new app, Happy Moments.

I found this tutorial very useful for using custom fonts on Android:

http://mobile.tutsplus.com/tutorials/android/customize-android-fonts/

And I found some pretty nice fonts on this site suitable for the concept of my app:

http://www.fontsquirrel.com/fonts/list/category/Handwritten

Here’s the gist:

Step 1: Find a nice font and put it in your assets/ folder

Step 2: Set the custom font in code (which is the only way to do it), like this:

TextView message = (TextView) findViewById(R.id.message); 
Typeface font = Typeface.createFromAsset(getAssets(), "Chantelli_Antiqua.ttf");
message.setTypeface(font);

And voila, the result in the app itself:

Fixing system date out of sync in Debian

I started using my old-ish Debian server again and realized the system date is off by 20 minutes…

The solution is to install ntpdate, which automatically synchronizes the clock at certain system events, for example when the network interface comes up.

To force synchronizing now, you can run ntpdate manually, but you must specify the NTP servers to use as reference on the command line, otherwise it will give you an error like this:

14 May 06:53:06 ntpdate[6505]: no servers can be used, exiting

An easier way is to run ntpdate-debian without arguments, which will use the NTP servers configured in /etc/default/ntpdate, which is a Debian-specific setup.

Viewing old revisions in the web browser interface of Subversion

If Apache is configured to browse a Subversion repository, its files and directories are shown as of the latest version by default, for example:

http://svn.apache.org/repos/asf/subversion/trunk/

If you want to browse the content of older revisions, there is a non-trivial way by inserting /!svn/bc/REVNO between the base URL of the repository and the path component of the target directory inside the repository, for example you can browse the contents as of revision 1234123 like this:

http://svn.apache.org/repos/asf/!svn/bc/1234123/subversion/trunk/

Practical tips & tricks in the Linux shell

I put together this simple presentation about a few simple but very effective practical tips that should make you lightning fast on the command line. I use these literally every minute I spend in the shell. All the tips should work in Linux, UNIX, BSD and similar.

  • I used many tips from Zach Holman’s blog to “design” the slides.
  • I created the presentation using Google Docs, but it was not really a great experience:
    • The dotted green line you see under headings is not intentional, it appears only after exporting to PDF. I don’t know why. I would prefer it without the line as shown correctly in Google’s viewer, but I want to use Speaker Deck as it is not blocked at my workplace and has a better WordPress plugin.
    • The JavaScript seems to go crazy in the presentation editor. The longer I use it, the heavier it gets, until I do a clean fresh reload.
  • I used the Speaker Deck Embed plugin to embed the presentation here. Oh and Speaker Deck is really awesome.