summaryrefslogtreecommitdiff
path: root/alot/__main__.py
diff options
context:
space:
mode:
authorLucas Hoffmann <l-m-h@web.de>2016-12-29 16:03:35 +0100
committerLucas Hoffmann <l-m-h@web.de>2017-01-10 08:56:26 +0100
commit2d7d048f3e2eb33b20944d307a998abe09f2329b (patch)
treedd4863ee0797cd582d03ea336f5cbf5172e4a921 /alot/__main__.py
parent658f83d7e5c78894bb427e088af51b092c1fb256 (diff)
Replace twisted command line parsing with argparse
The command line interface is copied as directly as possible. But at least the help output is formatted differently.
Diffstat (limited to 'alot/__main__.py')
-rw-r--r--alot/__main__.py190
1 files changed, 69 insertions, 121 deletions
diff --git a/alot/__main__.py b/alot/__main__.py
index 00b34c4e..de46a727 100644
--- a/alot/__main__.py
+++ b/alot/__main__.py
@@ -1,9 +1,10 @@
# Copyright (C) 2011-2012 Patrick Totzke <patricktotzke@gmail.com>
# This file is released under the GNU GPL, version 3 or a later revision.
# For further details see the COPYING file
-import sys
+import argparse
import logging
import os
+import sys
import alot
from alot.settings import settings
@@ -13,115 +14,65 @@ from alot.ui import UI
from alot.commands import *
from alot.commands import CommandParseError
-from twisted.python import usage
-
-
-class SubcommandOptions(usage.Options):
- optFlags = []
-
- def parseArgs(self, *args):
- self.args = args
-
- def as_argparse_opts(self):
- optstr = ''
- for k, v in self.iteritems():
- # flags translate int value 0 or 1..
- if k in [a[0] for a in self.optFlags]: # if flag
- optstr += ('--%s ' % k) * v
- else:
- if v is not None:
- optstr += '--%s \'%s\' ' % (k, v)
- return optstr
-
- def opt_version(self):
- print alot.__version__
- sys.exit(0)
-
-
-class ComposeOptions(SubcommandOptions):
- optParameters = [
- ['sender', '', None, 'From line'],
- ['subject', '', None, 'subject line'],
- ['to', [], None, 'recipients'],
- ['cc', '', None, 'copy to'],
- ['bcc', '', None, 'blind copy to'],
- ['template', '', None, 'path to template file'],
- ['attach', '', None, 'files to attach'],
- ]
- optFlags = [
- ['omit_signature', '', 'do not add signature'],
- ]
-
- def parseArgs(self, *args):
- SubcommandOptions.parseArgs(self, *args)
- self.rest = ' '.join(args) or None
-
-
-class SearchOptions(SubcommandOptions):
- accepted = ['oldest_first', 'newest_first', 'message_id', 'unsorted']
-
- def colourint(val):
- if val not in accepted:
- raise ValueError("Unknown sort order")
- return val
- colourint.coerceDoc = "Must be one of " + str(accepted)
- optParameters = [
- ['sort', 'newest_first', None, 'Sort order'],
- ]
-
-
-class Options(usage.Options):
- optFlags = [["read-only", "r", 'open db in read only mode'], ]
-
- def colourint(val):
- val = int(val)
- if val not in [1, 16, 256]:
- raise ValueError("Not in range")
- return val
- colourint.coerceDoc = "Must be 1, 16 or 256"
-
- def debuglogstring(val):
- if val not in ['error', 'debug', 'info', 'warning']:
- raise ValueError("Not in range")
- return val
- debuglogstring.coerceDoc = "Must be one of debug,info,warning or error"
-
- optParameters = [
- ['config', 'c', None, 'config file'],
- ['notmuch-config', 'n', None, 'notmuch config'],
- ['colour-mode', 'C', None, 'terminal colour mode', colourint],
- ['mailindex-path', 'p', None, 'path to notmuch index'],
- ['debug-level', 'd', 'info', 'debug log', debuglogstring],
- ['logfile', 'l', '/dev/null', 'logfile'],
- ]
- search_help = "start in a search buffer using the querystring provided "\
- "as parameter. See the SEARCH SYNTAX section of notmuch(1)."
-
- subCommands = [['search', None, SearchOptions, search_help],
- ['compose', None, ComposeOptions, "compose a new message"]]
-
- def opt_version(self):
- print alot.__version__
- sys.exit(0)
-
def main():
- # interpret cml arguments
- args = Options()
- try:
- args.parseOptions() # When given no argument, parses sys.argv[1:]
- except usage.UsageError as errortext:
- print '%s' % errortext
- print 'Try --help for usage details.'
- sys.exit(1)
+ # set up the parser to parse the command line options.
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-v', '--version', action='version',
+ version=alot.__version__)
+ parser.add_argument('-r', '--read-only', action='store_true',
+ help='open db in read only mode')
+ parser.add_argument('-c', '--config', type=argparse.FileType('r'),
+ help='config file')
+ parser.add_argument('-n', '--notmuch-config', type=argparse.FileType('r'),
+ help='notmuch config')
+ parser.add_argument('-C', '--colour-mode',
+ choices=(1, 16, 256), type=int, default=256,
+ help='terminal colour mode [default: %(default)s].')
+ parser.add_argument('-p', '--mailindex-path', #type=directory,
+ help='path to notmuch index')
+ parser.add_argument('-d', '--debug-level', default='info',
+ choices=('debug', 'info', 'warning', 'error'),
+ help='debug log [default: %(default)s]')
+ parser.add_argument('-l', '--logfile', default='/dev/null',
+ type=lambda x: argparse.FileType('w')(x).name,
+ help='logfile [default: %(default)s]')
+ parser.add_argument('command', nargs=argparse.REMAINDER)
+ options = parser.parse_args()
+ if options.command:
+ # We have a command after the initial options so we also parse that.
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(dest='subcommand')
+ search = subparsers.add_parser('search')
+ search.add_argument('--sort', default='newest_first',
+ help='sort order',
+ choices=('oldest_first', 'newest_first',
+ 'message_id', 'unsorted'))
+ search.add_argument('terms', nargs='+')
+ compose = subparsers.add_parser('compose')
+ compose.add_argument('--omit_signature', action='store_true',
+ help='do not add signature')
+ compose.add_argument('--sender', help='From line')
+ compose.add_argument('--subject', help='subject line')
+ compose.add_argument('--to', help='recipients')
+ compose.add_argument('--cc', help='copy to')
+ compose.add_argument('--bcc', help='blind copy to')
+ compose.add_argument('--template', type=argparse.FileType('r'),
+ help='path to template file')
+ compose.add_argument('--attach', type=argparse.FileType('r'),
+ help='files to attach')
+
+ command = parser.parse_args(options.command)
+ else:
+ command = None
# logging
root_logger = logging.getLogger()
for log_handler in root_logger.handlers:
root_logger.removeHandler(log_handler)
root_logger = None
- numeric_loglevel = getattr(logging, args['debug-level'].upper(), None)
- logfilename = os.path.expanduser(args['logfile'])
+ numeric_loglevel = getattr(logging, options.debug_level.upper(), None)
+ logfilename = os.path.expanduser(options.logfile)
logformat = '%(levelname)s:%(module)s:%(message)s'
logging.basicConfig(level=numeric_loglevel, filename=logfilename,
filemode='w', format=logformat)
@@ -132,8 +83,8 @@ def main():
os.path.expanduser('~/.config')),
'alot', 'config'),
]
- if args['config']:
- expanded_path = os.path.expanduser(args['config'])
+ if options.config:
+ expanded_path = os.path.expanduser(options.config)
if not os.path.exists(expanded_path):
msg = 'Config file "%s" does not exist. Goodbye for now.'
sys.exit(msg % expanded_path)
@@ -141,8 +92,8 @@ def main():
# locate notmuch config
notmuchpath = os.environ.get('NOTMUCH_CONFIG', '~/.notmuch-config')
- if args['notmuch-config']:
- notmuchpath = args['notmuch-config']
+ if options.notmuch_config:
+ notmuchpath = options.notmuch_config
notmuchconfig = os.path.expanduser(notmuchpath)
alotconfig = None
@@ -159,28 +110,25 @@ def main():
sys.exit(e)
# store options given by config swiches to the settingsManager:
- if args['colour-mode']:
- settings.set('colourmode', args['colour-mode'])
+ if options.colour_mode:
+ settings.set('colourmode', options.colour_mode)
# get ourselves a database manager
indexpath = settings.get_notmuch_setting('database', 'path')
- indexpath = args['mailindex-path'] or indexpath
- dbman = DBManager(path=indexpath, ro=args['read-only'])
+ indexpath = options.mailindex_path or indexpath
+ dbman = DBManager(path=indexpath, ro=options.read_only)
# determine what to do
try:
- if args.subCommand == 'search':
- query = ' '.join(args.subOptions.args)
- cmdstring = 'search %s %s' % (args.subOptions.as_argparse_opts(),
- query)
- elif args.subCommand == 'compose':
- cmdstring = 'compose %s' % args.subOptions.as_argparse_opts()
- if args.subOptions.rest is not None:
- cmdstring += ' ' + args.subOptions.rest
- else:
+ if command is None:
cmdstring = settings.get('initial_command')
- except CommandParseError as e:
- sys.exit(e)
+ elif command.subcommand == 'search':
+ query = ' '.join(command.terms)
+ cmdstring = 'search --sort {} {}'.format(command.sort, query)
+ elif command.subcommand == 'compose':
+ cmdstring = ' '.join(options.command)
+ except CommandParseError as err:
+ sys.exit(err)
# set up and start interface
UI(dbman, cmdstring)