Thursday, June 3, 2010

Why hasn't Django moved to Git or Hg yet?

This is a question that has been bothering me a lot recently. But it bothers someone else even more and for longer time.

Oh yes, this "someone else" are the core developers of Django. I believe I've seen their response to this question for multiple times and I think it makes a lot of sense. Everytime I feel bothered again, I'd read this response and peace will come back. So here is one of those responses from RKM on the developer group:

Moving to git will change *exactly nothing* in Django's development process. There will *always* be an "official" repository. Commit access to that core repository will be limited. It doesn't matter whether that repository is git, svn, or hg - there will always be a single, canonical, exclusive repository for trunk.

If you want to use Git to help you manage your own source code or your contributions to Django, you're welcome to do so. There are well maintained git mirrors that you can use as a starting point. There are many people in the Django community using this mirror to manage their
own development work. Allow me to assure you that if you have a git branch that is worth pulling, someone in the Django core will be able to pull that branch and merge it into SVN trunk without *any* difficulty. Multi-db, for instance, was almost entirely developed by
Alex Gaynor on his github branch.

And this is completely independent of the bike shed argument of which DVCS we will adopt. This isn't even remotely a settled argument. By making an official move to git, we would alienate a large community that, for better or worse, can't move their production platforms to git. It also alienates the hg and bzr communities, which is a not insignificant consideration (for the record, there are also well maintained hg and bzr mirrors).

Wednesday, April 21, 2010

How to read PDF of Django Documentation on iPod

This is how I got a pdf of the latest Django Documentation onto my iPod. Of course this would work on your iPhone (iPad?) too. Everything shown here is don in Ubuntu. But the steps shouldn't be much different on other OS, be it Windows or Mac OS X, as long as you have root.

Step 1: get the source.
Good news, Django is Open Source! OK, that's kinda silly. But it's the fundamental reason all this is possible. Anyway, more useful info is that Django uses svn as its version control system and the Doc is part of the source in the repository. So let's check the source out:
svn co http://code.djangoproject.com/svn/django/trunk/
Caution: this is a fairly big repo so the check-out takes quite a bit of time!

Step 2: Compile the documentation
Here's the key to the next piece: Django uses a Python documentation generator called Sphinx to produce the Doc. Sphinx compiles reStructuredText into multiple formats, including HTML, CHM and LaTeX. And the source of the documentation is maintained in reStructuredText format. Our final goal here is to get a pdf, obviously we would generate that from LaTex. So, we need the sphinx-build script to compile the source into LaTeX. For Ubuntu users, the sphinx package in the official repo is called python-sphinx, install it:
sudo apt-get install python-sphinx
This will automatically install several related packages. When it's done, the compile should be smooth:
sphinx-build .../path/to/Doc/source/ .../path/to/the/latex/files

Step 3: Get the PDF
Now it's time to turn the LaTeX source code from last step into a PDF file. I'm a daily LaTeX user on Ubuntu, so for others there might be some additional latex-related packages to install from the official repo. But when I tried running pdflatex command, it complains that two style package were missing. I had to find them online: wrapfig.sty, titlesec.sty. According to Ubuntu Community Documentation, I did the following:

mkdir ~/texmf/tex/latex/titlesec
mv titlesec.sty ~/texmf/tex/latex/titlesec/
mkdir ~/texmf/tex/latex/wrapfig
mv wrapfig.sty ~/texmf/tex/latex/wrapfig/
texhash ~/texmf/

Basically, this creates folders for each package under the home path and informs tex of the added packages.

And now it should compile:
cd .../path/to/latex/files
pdflatex django.tex django.toc

When its done, you should find django.pdf lying in the folder, epic.

Step 4: Put the PDF into the iPod/iPhone(/iPad?)

There are tons of PDF reading apps in App Store. The one I've been using is a free app called Good Reader. It lets you read text, pics and PDF. The reason I'm using it is that it supports some really handy ways to transfer the files on to the mobile devices, including Dropbox.

If you haven't used Dropbox to sync files between your different devices I highly recommend that you follow this link to create a account and start using it immediately. For a starter, it's waaaay more convenient than emailing files as attachments. Anyway, once you get Dropbox folder syncing on your box, drop in djang.pdf there.

Open Good Read on your iPod/iPhone, go to Web Downloads -> Connect to Server -> Create New Connection to -> Dropbox. Fill in your username and password, hit "add". Go back to Connect to Server, click the the newly added account to navigate to the Dropbox folder, find django.pdf and download it.

And we are done, enjoy your mobile, beautiful copy of Django Documentation!

Saturday, March 27, 2010

A little hack on AJAX timing

Say you need to initialize a web/app page with data dynamically loaded from some server by a Javascript module written with jQuery. Often, the problem encountered would be the pacing. That is, the events in the script don't necessarily take place in the same order as your code indicated. Here's an example that illustrates the evilness:

data = someModule.AjaxFetch(); // loading...
alert(data.item1); // Oh no, executed before AjaxFetch() has returned, undefined!

The typical solution is passing a callback function to the AjaxFetch() method. I don't know about you, but leaving that callback-function argument always makes me feel itchy(I'm a big Python fan, so doubt not about my awareness of the benefit of having the flexibility. After all, what's the point of modularization if I have to call a method from module A in module B?). It could be worse, what if the Ajax module doesn't provide the callback slot you needed?

The other possible solution is using some kind of delay function, pausing the script for some time and hope that the communication would be finished by then. Obviously this is too lousy for a reasonable programmer.

Here's what I came up today.

data = someModule.AjaxFetch();
$(document).ajaxComplete(function(){
    $(document).unbind($.ajaxComplete);
    alert(data.item1);
    // some more useful and complex code here.
});

The trick is to take advantage of $.ajaxComplete() provided by jQuery and unbind this event immediately after it happens for the first time.

The reason to unbind doesn't seem obvious at the first look. Here it is: $.ajaxComplete() listens to all kinds of Ajax communication conducted by jQuery. If the code in its call back involves more Ajax events, the call back will be called again, which is usually not an expected behavior!

Happy AJAXing!