Dan Watson
iPhone Web App Links

I was working on an iPhone web app recently (my first, actually) and came across an annoyance: any links in a web app with apple-mobile-web-app-capable set to “yes” will open in Safari, not the app itself. I wanted to keep things as simple as possible, and not have to change my code to support AJAX loading. Some research turned up this article which did almost exactly what I wanted, except I didn’t want to load a page into a container. I wanted all links to Just Work how you’d expect links to work. So I dropped this bit of jQuery code into my base template, and everything seems to work great:

$(document).ready( function() {
    $('a').each( function(idx,elem) {
        var url = $(elem).attr('href');
        var js = "javascript:window.location.href='"
                 + url + "';";
        $(elem).attr('href', js);
    } );
} );

This could probably be done just as easily without jQuery using getElementsByTagName, but I’ll leave that as an exercise for the reader.

A Django file storage backend that transparently compresses files using the gzip python module. Nothing fancy, but it gets the job done, with a few caveats:

  • Since the data returned by GzipFile.read is not necessarily of the length you requested, File.chunks would sometimes leave off the last bits. I wrote DjangoGzipFile to return just a single decompressed chunk to get around this, but a better approach would check to see if any data remains and yield it at the end.
  • For compressed files, the path has .gz appended to it, so the path you request via the storage system may not exist on the filesystem. Just something to note if you access the files without using the storage system.

Writing this also gave me a few ideas for some small refactorings to make FileSystemStorage more easily subclass-able:

  • Overriding the path method made it easy to append .gz transparently, but I had to write my own listdir since I didn’t want to add .gz when resolving a directory path. It might be nice to have a path transformation helper method that FileSystemStorage.path calls.
  • It would be nice to move the directory creation and permission “post-processing” out of FileSystemStorage._save and into helper methods to avoid having to copy/paste the code. Alternatively, there could be another method to actually write the file data that _save could call by default.

Not that any of this is difficult to deal with, but I’d imagine file system storage backends could almost be considered a class of their own when you start thinking about things like compression, sharding, etc. Making it just a bit cleaner to create them would be a nice touch.

    Subclassing SearchableModel and using SearchManager basically lets you do things like this:

    SomeModel.objects.search('query', rank_field='rank')

    Without having to worry about updating an index.

    My pydmtx library was included in libdmtx proper as of version 0.4.

    My sitemap app made it’s way into Django proper!

    Fun With Counting

    This entry is more of a note to myself, as any SQL guru will probably read it and think less of me for just now realizing it. My problem was as follows:

    I have a log table with login, type, and entry columns. What I wanted was a result set grouped by login with counts for when type was 2 and not 2. In other words: a list of logins, how many times they performed some action, and how many times they performed any other action.

    My first attempts at this involved sub-selects, extra joins, and sacrificing a chicken. Turns out, the solution was almost as elegant as you would think it should be:

    SELECT login, count(type=2 or NULL),
      count(type!=2 or NULL)
    FROM log GROUP BY login

    The count aggregate takes an expression that counts rows from the result set where the expression is not NULL. That’s an important point — false is not null. So doing count(type=2) and count(type!=2) will yield the same results. Adding an “or NULL” to the expression will cause it to short-circuit when true, and evaluate to NULL when false.

    Problem solved.

    On Indentation

    I don’t understand why so many otherwise intelligent programmers insist on using spaces to indent lines of code. The whole purpose of a tab is to advance the cursor to a specific position. These positions are customizable in every capable editor out there. Why force your formatting on everyone who has to read or edit your code? It’s not like you sit there and hit the spacebar 2, 3, 4, or 8 times; you hit tab and tell your editor to translate it to spaces. In fact, you go to great lengths to have your editor pretend a group of spaces at the beginning of a line is one unit — a tab, if you will. What’s the point? A tab is the semantically correct equivalent.

    This is especially aggravating in an environment where more than one person, each with his own indentation preference, is editing code. Even if you mandate that each developer must use spaces for indentation, and further, that they must use a specific number of them, the developer is still left with the problem of changing his editor preferences each time he wants to work on that project. This is further compounded when you have developers working on multiple projects, each with different “settings” due to managerial differences.