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.)
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.
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
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
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
that throws a
SyntaxError exception. Given the significance of
white-space in Python I feel this would be easy to get wrong.
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
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.
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).