#!/usr/bin/env python
Asterisk/CLI.py: Command-line wrapper around the Asterisk Manager API.
__author__ = 'David M. Wilson <dw@autosols.com>'
__id__ = '$Id$'
import sys, os, inspect
from Asterisk import Manager, BaseException, Config
import Asterisk.Util
class ArgumentsError(BaseException):
    _prefix = 'bad arguments'
def usage(argv0, out_file):
    Print command-line program usage.
    argv0 = os.path.basename(argv0)
    usage = '''
        %(argv0)s actions
            Show available actions and their arguments.
        %(argv0)s action <API action> [<arg1> [<argn> ..]]
            Execute the specified action.
            For named arguments "--name=<val>" syntax may also be used.
        %(argv0)s command "<console command>"
            Execute the specified Asterisk console command.
        %(argv0)s usage
            Display this message.
        %(argv0)s help <action>
            Display usage message for the given <action>.
    ''' % locals()
    out_file.writelines([ line[6:] + '\n' for line in usage.splitlines() ])
def show_actions(action = None):
    if action is None:
        print 'Supported actions and their arguments.'
        print '======================================'
    class AllActions(Manager.CoreActions, Manager.ZapataActions):
    methods = [
        (name, obj) for (name, obj) in inspect.getmembers(AllActions) \
        if inspect.ismethod(obj) and name[0] != '_'
    if action is not None:
        methods = [ x for x in methods if x[0].lower() == action.lower() ]
    for name, method in methods:
        arg_spec = inspect.getargspec(method)
        print '   Action:', name
        fmt = inspect.formatargspec(*arg_spec)[1:-1]
        if fmt:
            print 'Arguments:', fmt
        foo = [ x.strip() for x in method.__doc__.strip().splitlines() ]
        print '           ' + '\n           '.join(foo)
def execute_action(manager, argv):
    method_name = argv.pop(0).lower()
    method_dict = dict(\
        [ (k.lower(), v) for (k, v) in inspect.getmembers(manager) \
        if inspect.ismethod(v) ])
        method = method_dict[method_name]
    except KeyError, e:
        raise ArgumentsError('%r is not a valid action.' % (method_name,))
    pos_args = []
    kw_args = {}
    process_kw = True
    for arg in argv:
        if process_kw and arg == '--':
            process_kw = False # stop -- processing.
        elif process_kw and arg[:2] == '--' and '=' in arg:
            key, val = arg[2:].split('=', 2)
            kw_args[key] = val
    Asterisk.Util.dump_human(method(*pos_args, **kw_args))
def command_line(argv):
    Act as a command-line tool.
    commands = [ 'actions', 'action', 'command', 'usage', 'help' ]
    if len(argv) < 2:
        raise ArgumentsError('please specify at least one argument.')
    command = argv[1]
    if command not in commands:
        raise ArgumentsError('invalid arguments.')
    if command == 'usage':
        return usage(argv[0], sys.stdout)
    manager = Manager.Manager(*Config.Config().get_connection())
    if command == 'actions':
    if command == 'help':
        if len(argv) < 3:
            raise ArgumentsError('please specify an action.')
    elif command == 'action':
        if len(argv) < 3:
            raise ArgumentsError('please specify an action.')
            execute_action(manager, argv[2:])
        except TypeError, e:
            print "Bad arguments specified. Help for %s:" % (argv[2],)
    elif command == 'command':
        execute_action('command', argv[2])