MacPython Logo from __future__ import *

Kailash and Friends Kailash Kher Kaipa

online mp3 Anoice albums buy Amund Maarud albums online Asia online CD Andy M. Stewart buy tracks Axis online Astral Rising A Beautiful Machine download CD Aereda buy tracks Aksent online tracks Absidia Atrium Carceri A Beautiful Machine Absolum buy CD Aryan Wind and Brumalis and Valhalla Saints online music Atomsmasher download albums AK1200 download music Angelzoom online CD Arturo Mantovani and his Orchestra buy music 16 buy tracks Ashtorath online CD Aimee Mann buy music Anael And Bradfield buy mp3 Autumnblaze download mp3 Aggrolites download CD Arj Snoek buy albums Ada buy CD Aalto Andy With Rama West A Beautiful Machine Absolum online tracks Asura albums online Albert Lee 4 Non Blondes A Beautiful Machine Absolum download albums Andrew Lloyd Webber and Ar Rahman online music African Head Charge download mp3 Amber Asylum online music Analena online music ANTIX feat ROB SALMON A.R. Rahman A Beautiful Machine Absolum online tracks African Blackwood buy mp3 Axis buy mp3 Alan Menken buy music Amoebic Dysentery buy Alph Secakuku A Beautiful Machine albums download Albita online Amparo Ochoa A Beautiful Machine download tracks Andy Partridge and Harold Budd download tracks Anubian Lights Alient Project A Beautiful Machine Absolum buy albums Antonio Forcione download CD Ali G Indahouse online mp3 Art and Jazz Messengers Blakey download Arab Strap A Beautiful Machine online albums Adema buy Agua de Annique A Beautiful Machine buy CD Avalanches download tracks Acroma Andi Deris A Beautiful Machine Absolum download tracks American Steel download albums Amanda Perez online 999 A Beautiful Machine download mp3 Arild Andersen download CD American Steel buy tracks Absolute Beginner download tracks Anubi online albums Ancient Wisdom online A Verse Unsung A Beautiful Machine buy music Aghast Andromeda Island A Beautiful Machine Absolum download Arlo Guthrie A Beautiful Machine online mp3 Aavepyora online albums Achillea buy Andrew Bird A Beautiful Machine buy music Alexey Aigui and Ensemble 4'33'' albums buy Abbey Lincoln and Archie Shepp download albums Archive download CD A Guy Called Gerald feat. D.S. download music Al Di Meola online music Abigail download music Angel Witch online music Adelaide

2004-02-23

graphviz on the Mac, LaunchServices

Filed under: python — bob @ 5:22 pm

For an excellent example of what it takes to do a great port of UNIX software to OS X, look no further than Glen Low's port of graphviz for OS X. For good reasons to take a look at graphviz, check out John Schull's Weblog, especially entries such as Outline to graphviz.

This port and GUI front-end adds features such as rendering via the native OS X APIs (finally, good fast PDFs!), and it can actually use kqueue on OS X 10.3 to automatically re-render when a file changes!

Not only does at add a slew of cool new features (most of which I didn't mention), but all of the CLI tools are wrapped up in a nice little application bundle; making installation and removal painless, and relocation no longer becomes a problem.

If all OS X with significant UNIX heritage were distributed this way, one might think it would become difficult to add them all to your PATH. Fortunately, that's just not true [1]. Here's a nice little snippet of LaunchServices [2] code that will return the full path of an application by name regardless of where it happens to be or if it has moved [3]:

#!/usr/bin/python
from LaunchServices.Launch import LSFindApplicationForInfo
from Carbon.CoreFoundation import kCFURLPOSIXPathStyle
# this would normally come from LaunchServices.LaunchServices
# but bgen isn't perfect, and doesn't make this constant a
# four char code.
kLSUnknownCreator = '\x00\x00\x00\x00'

def pathForName(appName):
    """
    Returns the file system path for an application by name.
    NOTE: You should include the suffix, as in "Python.app".
    """
    fsRef, cfURL = LSFindApplicationForInfo(kLSUnknownCreator, None, appName)
    return cfURL.CFURLCopyFileSystemPath(kCFURLPOSIXPathStyle).toPython()

if __name__ == '__main__':
    import sys
    if len(sys.argv) == 1:
        import os
        raise SystemExit, "Usage: %s SomeApplication.app" % (
            os.path.basename(sys.argv[0])
        )
    for appName in sys.argv[1:]:
        print pathForName(appName.decode('utf8')).encode('utf8')

Usage looks like this (note: I use tcsh not bash):

[crack:~/bin] bob% setenv PATH ${PATH}:`./findapp.py GraphViz.app`/Contents/MacOS
[crack:~/bin] bob% rehash
[crack:~/bin] bob% which dot
/Applications/GraphViz/Graphviz.app/Contents/MacOS/dot
[crack:~/bin] bob% dot --help
dot: option -- unrecognized

Usage: dot [-Vv?] [-(GNE)name=val] [-(Tlso)<val>] <dot files>
 -V          - Print version and exit
 -v          - Enable verbose mode 
 -Gname=val  - Set graph attribute 'name' to 'val'
 -Nname=val  - Set node attribute 'name' to 'val'
 -Ename=val  - Set edge attribute 'name' to 'val'
 -Tv         - Set output format to 'v'
 -lv         - Use external library 'v'
 -ofile      - Write output to 'file'
 -q[l]       - Set level of message suppression (=1)
 -s[v]       - Scale input by 'v' (=72)
 -y          - Invert y coordinate in output
[1]Well, so long as application developers can agree on where those binaries should go in a bundle. The dust hasn't quite settled on this issue yet, it's a toss-up between MacOS, Resources, and arbitrary subfolders of Resources (probably mirroring a "usr prefix", like Resources/bin, Resources/lib, etc.)
[2]This code for LaunchServices from Python 2.4, not my LaunchServices wrapper. It is backwards compatible to Python 2.3, but is not yet available from a PackageManager repository.
[3]There are some limitations to the power of Launch Services. For example, The application must have been launched via the Launch Services API (i.e. through Finder) at least once since it has been on that volume, or it must reside in a standard Applications folder such as /Applications or /Network/Applications.

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Protected by WP-Hashcash.

Powered by WordPress