Having taken some time to analyze the mailcap and mime.types files, which map media types to handler programs and file extensions respectively. I’ve decided to implement something, uhh…. more “fun” out of it, for my own usage. I’ll use mailcap and mime.types to setup a suitable mime/file associations to desire, and a mixture of m4 and environment varables to make it more useful hehe. I’ve also setup a small wrapper around Pythons mailcap and mimetypes modules, so I’m happy !
Since I need a handler that includes a web browser, rather then creating an if x is probably running … script, to just use $BROWSER. But since, there is a shitload of apps that don’t understand it, I’ve created quick python script to handle it. Thus, mailcap will execute this script, which will “figure it out”. Once I realized how much I could use such a quickie, I added a little more abstraction to it; making it usable with other variables. And used getopt for a simple interface to it.
#!/usr/bin/env python
import sys, os, getopt
# default values for -e and -s options
envvar = "BROWSER"
envsep = ":"
# skip executing program
noexec = False
# accepted options, usage statement, and manual page
shortopts = "hme:s:n"
longopts = [ 'help', 'man', 'environment=', 'separator=', 'no-exec' ]
def usage():
print """
usage: %s [options] file ...
Parse a field delimited list of programs, executing each in turn, until the
specified application has opened the indicated file(s).
Options:
-h,--help display this useless message
-e,--environment the environment variable to look up, default to BROWSER
-s,--separator the field separator for -e VAR, defaults to :
-m,--man view this manual page
-n,--no-exec do not execute any programs, useful if parsing $PATH
--long-options may be abbreviated.
Exit Status:
The return status of the last executed program handler. If no program was
executed, return with a non-zero exit status.
Caveats:
A non-zero exit status is considered a successful execution.
Programs found by parsing the environment variable, are passed onto the
system shell UNMODIFIED. This is not secure, but it is flexible.
""" % sys.argv[0]
sys.exit(1);
try:
opts, args = getopt.getopt(sys.argv[1:], shortopts, longopts)
except getopt.GetoptError, e:
print(str(e))
usage()
for opt, arg in opts:
if opt in ('-h', '--help'):
usage()
elif opt in ('-m', '--man'):
# XXX works on unix, dos, winnt, osx
os.system("%s -h | $PAGER || more" % sys.argv[0])
sys.exit(0)
elif opt in ('-e', '--environment'):
envvar = arg
elif opt in ('-s', '--separator'):
envsep = arg
elif opt in ('-n', '--no-exec'):
noexec=True
else:
assert False,"unhandled option: %s" % opt
# exec handlers until success, abort, or exit
try:
browser = os.environ[envvar]
apps = browser.split(envsep)
for handler in apps:
# just print it, don't execute it
if noexec:
print handler
continue
ret = os.system(handler)
if not ret == 0:
print("Bad handler -- %s" % (str(handler) % " ".join(args)))
except KeyError:
print("No %s set!!!" % envvar)
sys.exit(1)
except Exception, e:
print("Un-handled exception! -- %s" % e.message)
One of the common questions of a language, is how to parse command line options? I’ve tried several interfaces in differing languages, but I know one thing… The getopt(3) routine in C on unix is awesome for short options. Give something more portable and with (easy) support for long options, and I’ll have a big grin on my face >_>. But if I have to wade through 20 pages of documentation for a comparable OOP-Interface, I’ll be snoring before I get to writing usage().