Monthly Archives: May 2009

Installer sympathy for Linux

Nice to see the installation process on Linux can be as misguided as it is on Mac OS X.

The irritating thing about these system manglings is that by and large they’re unnecessary, especially things like the JDK ugliness. These companies are not running into novel problems in building RPM packages, and other software manages to do the right thing. The companies were just lazy. (And because of the license terms of their software, outsiders can’t fix the problem, build proper packages, and distribute the results.)

Chris Siebenmann’s blog, Wandering Thoughts.

Adobe AIR installer, a hateful tradition

Tweetdeck seems to be the path of least resistance for a desktop Twitter client on Mac OS X 10.4 (there are other free Mac desktop clients, Nambu and Tweetie but unfortunately they both require 10.5).

But Tweetdeck requires the Adobe AIR runtime. And the Adobe AIR 1.5 installer takes Adobe’s favourite approach of ignoring Mac OS X’s package installer format in favour of a custom installer application.

When you open the installer, it takes a few seconds and then gives you a license agreement. Here’s an excerpt:

2.3 Distribution. This license does not grant you the right to sublicense or distribute the Software. For information about obtaining the right to distribute the Software on tangible media or through an internal network or with your product or service please refer to…

I read that as explicitly banning any efforts to create a package to ease the pain of deploying AIR across a bunch of Macs. Damn it.

Clicking Accept moves you to the installation proper, and Adobe loses a few more points by immediately throwing up an authentication dialog box. Why does this dialog appear? What am I about to install? If only this was a package installer I could have looked at the installation manifest to get an idea of what was going to happen before granting the installer free rein to my computer.

Turns out that everything you care about is installed in /Library/Frameworks/Adobe AIR.framework and /Applications/Utilities/Adobe AIR Application Installer.app and /Applications/Utilities/Adobe AIR Uninstaller.app. For some reason the installer also touches a couple of files in /Users/Shared/Library/Application Support/Adobe/AIR/Updater and slips a couple utility apps in your Library somewhere. You can ignore those.

It feels particularly wrong when non-system applications put things in the Utilities folder – it is effectively a special system directory, and its contents are tools for tinkering with the system configuration or for diagnostics. Adobe Creative Suite 3 likes to create a folder Adobe Installers in there and Adobe Utilities, just in case you haven’t worked out how much you need their software on your computer.

Heaven is almost certainly running System 6.0.8. Nothing is installed without Font DA Mover.

Using plists for site-specific Django settings

I have a Django project that I am going to deploy at several sites, but I need to tweak the project settings slightly for each site. Specifically I need different a EMAIL_HOST address and related settings for sending mail at each site.

The simplest route is to customize the project settings.py as part of the site deployment, but that will drive you insane when you deploy the wrong custom-settings to a site.

Another approach is similar to that used by many for switching between settings when moving between testing / staging / live environments: your settings.py has a few lines something like

try:
    from sitesettings import *
except ImportError:
    pass

so you can over-ride any setting by putting them in a sitesettings.py file, and then make sure your deployment never overwrites that site-specific file.

In my case I want to make it easy for the site administrator to customize the settings, but I am worried that it is too easy for someone who does not know Python syntax to inadvertently break things by writing a sitesettings.py that throws a SyntaxError exception. Given the significance of white-space in Python I feel this would be easy to get wrong.

So I’ve gone for storing the custom settings in Mac OS X’s property list format. Bless Python for it has the plistlib module that reads and writes the simple XML format of property lists.

Here’s my module that imports all properties from a plist straight into the module’s namespace. This then makes it easy to over-ride Django’s settings by doing

from plistsettings import *

A couple bits made my lips move during the writing. The contents of __all__ are updated dynamically because I wanted to use this with from plistingsettings import * without worrying that my module’s imports would get clobbered by imports used in the plistsettings module. And working out how to bind keys and values to the module itself is not obvious to me - it feels like one ought to be able to use self within the scope of the module to refer to the module itself. Except you can’t. No biggie.

# plistsettings.py
import os.path
import plistlib
import sys
from xml.parsers.expat import ExpatError


__all__ = []


PLIST_PATH = '/Library/Preferences/com.example.plist'


def read_prefs(plist_path):
    """Import settings from preference file into this module's global namespace.

    Returns a dictionary as returned by plistlib.readPlist().
    """
    try:
        if os.path.exists(plist_path):
            prefs = plistlib.readPlist(plist_path)
        else:
            return
    except ExpatError:
        return

    mod = sys.modules[__name__]
    global __all__

    for key, value in prefs.items():
        setattr(mod, key, value)
        __all__.append(key)
    return prefs

read_prefs(PLIST_PATH)

Now if you are the kind of Mac guy who enjoys using defaults you can write out your site-specific settings from the command-line.

defaults write /Library/Preferences/com.example EMAIL_HOST smtp.example.com
plutil -convert xml1 /Library/Preferences/com.example.plist

N.B. Mac OS X 10.5 defaults uses the binary format by default, so you need plutil to convert it back to XML because plistlib does not handle the binary format.

10.5.7 fixes AppleShare speeds

The recently-released Mac OS X 10.5.7 update fixes the atrocious AppleShare transfer speed bug that was introduced by 10.5.6. The problem was that copying files larger than a few hundred kilobytes to certain AppleShare servers (including Mac OS X Server 10.4.11) would go extremely slow, and usually fail after a minute.

But copying files from the server to your Mac was hunky dory! Fun.

I like to think the programmers at Apple refuse to consider allowing software to be released until they have written comprehensive tests for regression testing. I like to think I do the same (I don’t, but I respond faster when you want my attention).