#
# mailplate — reformat mail drafts according to templates
#
-# This script reformats mail drafts according to a given template. The
-# template may be specified on the command line, but mailplate can also use
-# control information from the template files to automatically select an
-# appropriate template (--auto). A selection menu feature is planned (--menu).
-#
-# Applying a template means obtainined select data from an existing mail
-# message (unless --new is specified) and to fill it into appropriate slots in
-# the template. Messages are processed in three parts: headers, body, and
-# signature.
-#
-# The template can define two types of headers: mandatory and preservatory.
-# Mandatory headers take precedence over headers in the existing message and
-# thus overwrite them. Preservatory headers instruct mailplate to port their
-# data from the existing mail message. Headers in the existing message but not
-# defined in the template are dropped, unless --keep-unknown is given.
-#
-# Body and signature are separated by '-- '. If this sentinel is not found,
-# no signature is extracted.
-#
-# Templates can be interpolated and data filled into slots. Helper slots are
-# filled with the output of helper commands (which must be defined in the
-# configuration), environment variable slots are just that, and mail variable
-# slots can be filled with data obtained by running regexps or commands over
-# the message.
-#
-# This script can be run in multiple ways:
-#
-# As a filter, it applies a template to data from stdin and writes the result
-# to stdout.
-#
-# Given a file, it modifies the file, unless it cannot write to the file, in
-# which case it writes to stdout.
-#
-# When --editor is passed, the script spawns sensible-editor on the result. It
-# may thus be used as the editor for your mail user agent.
+# Please see the mailplate(1) manpage or the homepage for more information:
+# http://madduck.net/code/mailplate/
#
# TODO: if headers like From are absent from the mail, they should not be kept
# but replaced with a default.
# parse the arguments
for arg in args:
if arg == '-':
- # filename is -, so do nothing, since stdin/stdout are default
- continue
+ infname = arg
+ outfname = arg
+ elif arg.find(os.path.sep) == -1 and os.access(os.path.join(TPATH, arg), os.R_OK):
+ if templname is not None:
+ err("template already specified (%s), unsure what to do with '%s'"
+ % (templname, arg))
+ sys.exit(posix.EX_USAGE)
+ # argument references an existing template
+ templname = arg
elif os.path.isfile(arg):
+ if infname is not None:
+ err("input file already specified (%s), unsure what to do with '%s'"
+ % (infname, arg))
+ sys.exit(posix.EX_USAGE)
# the file exists, so use it as in/out if read/writeable
if os.access(arg, os.R_OK):
infname = arg
if os.access(arg, os.W_OK):
outfname = arg
- elif os.access(os.path.join(TPATH, arg), os.R_OK):
- # argument referenced an existing template
- templname = arg
else:
- err('unknown argument, and cannot find a template by this name: %s' % arg)
+ err('unknown argument: %s' % arg)
sys.exit(posix.EX_USAGE)
# sanity checks
l = line[:-1]
if len(l) == 0:
payload = '' # end of headers
- elif l[0] == KEEP_SLOT_LEADER and KEEP_HEADERS.has_key(l[1:]):
- # found predefined header slot keyword
- for header in KEEP_HEADERS[l[1:]]:
- headers[header.lower()] = (header, _keep_header)
+ elif l[0] == KEEP_SLOT_LEADER:
+ if KEEP_HEADERS.has_key(l[1:]):
+ # found predefined header slot keyword
+ for header in KEEP_HEADERS[l[1:]]:
+ headers[header.lower()] = (header, _keep_header)
+ else:
+ err('unknown header slot ' + l + ' found')
+ sys.exit(posix.EX_CONFIG)
else:
header, content = l.split(':', 1)
content = content.strip()
sys.exit(posix.EX_USAGE)
os.execlp('sensible-editor', 'sensible-editor', outfname)
-