Note: This post does not talk about how to give your Ubuntu taskbar a Windows 7 look, you can download dockbarx themes and try them out yourself.

I normally do not have much love for windows because life for a web dev is generally easier on *nix platforms, but there is one feature that I really dig in Windows 7. The ability to pin items to your taskbar, and then switch between them using Win+[1..9] keys. This is very productive because I always know that my IDE will be running on Win+3, browser on Win+1, mail on Win + 2 etc. The Gnome/XFCE taskbar is really clunky, it hasn’t evolved in ages.

Anyhow, getting back to the original post, so you like those Win+n hotkeys, but don’t want to make a pact with the devil? Read on…

To get the same behaviour on gnome/xfce, we’ll need:

  1. A taskbar that lets you pin items (DockbarX)
  2. A way to execute applications if they’re not already running, otherwise focus them (A modified version of this script)
  3. A way to map your pinned items to your Win + n shortcut keys (my scripts)

Step 1: Getting DockbarX

If you have ubuntu-tweak on your system, you can find DockbarX in its Application Center. Just put the checkmark, click apply and you’re done.

If you do not have ubuntu-tweak and you’re using Ubuntu 9.10 (Karmic), just execute the following in your terminal:

sudo add-apt-repository ppa:dockbar-main/ppa
sudo apt-get update && sudo apt-get install dockbarx

For older versions of Ubuntu, the DockbarX repository is here. If you’re not sure how to add this repository and install DockbarX, just ask.

If you’re running Gnome, just logout and back in, then right click your panel and add DockbarX to your panel.

If you’re running Xfce, you’ll need to install xfapplet (sudo apt-get install xfce4-xfapplet-plugin). Then right click your panel, add xfapplet, and then select DockbarX.

Now that you have DockbarX running, you can choose to get rid of your taskbar. You can also pin some apps to the taskbar (right click -> pin application) to test if the hotkeys work later. You can also play around with DockbarX prefs and themes to get the right look. Here’s what I ended up with in Xfce:

mytaskbar

Step 2: Get the scripts:

Grab the attached scripts. Create a subdirectory in your home directory called ’scripts’ and extract all the scripts in there.

Next, we’ll make these scripts executable and place a link to them in the /usr/bin directory so they are easier to execute.

chmod a+x ~/scripts/run_or_focus.py
chmod a+x ~/scripts/*update_hotkeys*.py
sudo ln -s ~/scripts/run_or_focus.py /usr/bin/rof

You’ll need python, gconf and wmctrl to run these scripts. If you’re on xfce, you’ll also need xfquery. To get them:

Gnome: sudo apt-get install python wmctrl python-gconf
Xfce:
sudo apt-get install python wmctrl python-gconf xfconf

To test the scripts to see if they’re working, try entering “rof firefox” on the command line to either run firefox or focus it if its already running.

Setting hotkeys for DockbarX pinned items

First, pin some applications to your taskbar.

Here I’ve given you a couple of options. In your scripts directory, you’ll find autoupdate_hotkeys and update_hotkeys for gnome and xfce. The autoupdate_hotkeys version will keep running in the background and update your hotkeys as soon as you make a change. So if you drag a pinned item around, its hotkey will be updated automatically. If you unpin it, its hotkey will be removed. If you pin a new item, we’ll add a hotkey for it. This is useful because it requires nothing from you other than adding the scripts to your startup applications.So if you prefer this option, just add the autoupdate_hotkeys_(gnome|xfce).py to your startup applications (preferences -> startup applications in gnome and settings -> session and startup in xfce) and you’ll be good to go.

If you prefer not to have an extra app running in the background, you’ll need to run the update_hotkey scripts whenever you change items around in dockbar.

Comments? Problems? Enjoying Ubuntu a little teensy bit more? :)

Yay, I contributed a little bit to Django. Exciting to play a teeny tiny part in a really well designed web framework :) .

Most of the data in your webapp will be associated with a user (for e.g., I’m the author of this post). django.contrib.auth comes with the User model that handles a lot of basic functionality for dealing with users. Here’s some basic reading.

Some people like to subclass User to add their own pieces of data, others prefer to create a separate UserProfile model. This post assumes that you already know how you’re going to deal with user profiles. What I’ll be talking about is associating models with a specific users. Given that:

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField(null=True, blank=True)

I wanted a generic way to add a user to any model. I didn’t want to add a user as a foreign key to Post, and then come back later and have to add it to the comment model as well (if the requirement came up). I wanted a generic way to attach a user to whichever model I wanted. There’ll be other ways to do this (and feel free to point them out), but I went with this:

from django.db import models
from django.contrib.auth.models import User

class UserData(models.Model):
    user = models.ForeignKey(User, editable=False)
    class Meta:
        abstract = True

class Post(UserData):
    title =  models.CharField(max_length=100)
    body =  models.TextField(null=True, blank=True)

Anything that inherits from UserData will have the user field in it. I’ve kept editable=False so that the user doesn’t appear in any forms. However, by keeping editable=False, if you use a PostForm to create/edit, you’ll have to set the user field manually (because user is a required field) in your view like so:


post_form = PostForm(request.POST)

temp_post = post_form.save(commit=False)
temp_post.user = request.user
temp_post.save()

Another variation would be to create a UserDataForm and then inherit your PostForm from it:

class UserDataForm(models.ModelForm):

    # Overriding save allows us to add the user from the request
    def save(self, user, commit=True):
        # get the instance so we can add the user to it.
        instance = super(UserDataForm, self).save(commit=False)
        instance.user = user

        # Do we need to save all changes now?
        if commit:
            instance.save()
            self.save_m2m()

        return instance

class PostForm(UserDataForm):
    class Meta:
        model = Post

# in your view
def save_post(request):
     post_form = PostForm(request.POST)
     post_form.save(user=request.user)

Interested in hearing how others deal with the same issue.

I’ve been doing a lot Django reading recently (the docs, tutorials, the book, etc) for my current job (not launched yet). I’ve had to dive into the code a few times and it’s been a really fun ride. To help others “get up and running” as soon as possible, I thought I’d post some of the interesting tidbits I learnt from the django book. Ofcourse, you’ll learn more by reading the book yourself and diving into the source code head on.

Here are some cool tricks from the first few chapters, with more coming in the next few days:

  1. Instead of printing values of variables to help with debugging, just put “assert False” in your view and you’ll drop to the error page where you can view all your current variables.

    Ofcourse, if you have ipython installed (and there is no reason you shouldn’t, google it now if you don’t know about it), you can put the following in your view at the top:

    
    from IPython.Shell import IPShellEmbed
    ipython = IPShellEmbed()
    

    Now, whenever you put ipython() in your view, you’ll drop into an ipython shell as soon as django’s server hits that view.

  2. By default whenever you do the following in a template

    {{ some_model.some_method_or_attr }}
    

    django will do a dictionary, attribute, method or list index lookup (in that order). You really don’t want to end up in a situation where “some_method_or_var” is a method that can destructively affect your model. There’s a simple way to fix this:

    
    def some_destructive_method(self):
        pass
    
    some_destructive_method.alters_data = True
    

    Now, the template system will never execute the method call from the template (it’ll fail silently).

  3. Think its annoying to declare variables in your view and then pass them all one by one to your template like so:

    def my_view(request):
        var1= .. do something
        var2= .. do something
        varn= .. do something
        return render_to_response("template.html", {
            'var1':var1,'var2':var2..,'varn':varn
        }, context_instance=RequestContext(request))
    

    instead, you can use the locals() function (which returns a dict of all local variables for you to conveniently pass it all to the template. Not very pythonic (be explicit), and I personally would prefer never to use it, but a nice shortcut.

  4. You can do {{ block.super }} within a block in a template to get the rendered content of the parent template. A simplistic use-case of this would be using it for the title of the page:

    # base.html
    {% block title %} My cool site {% endblock title %}
    
    # child.html
    {% extends "base.html" %}
    {% block title %} {{ block.super }} : The child page {% endblock title %}
    
  5. Always find yourself getting data from your model and sorting it by a certain field? Put the default sort field in your model like so:

    class News:
        class Meta:
            ordering=['date_updated']
    
  6. You can use index slicing on QuerySet objects too (which translate to sql LIMIT statements). So, get your last 10 posts by:

    Posts.objects.all()[0:10]
    

These are some of the simpler/easier tricks. Some of the more complex stuff’ll be up next..

“hello, world”

Hey, this blogging thing is fun. Now I can be on the internetz.

And hey, people tell me that blogging looks good on the resume too… ;-)

blogging-comic-20