degal/command.py
author Tero Marttila <terom@fixme.fi>
Wed, 10 Jun 2009 23:33:28 +0300
changeset 84 891545a38a2b
parent 76 e22d9f699081
child 88 b1b0939517e7
child 92 eb50b4f7812d
permissions -rw-r--r--
change utils.LazyProperty to store the cached value using obj.__dict__
"""
    Command implementations
"""

import inspect, logging, traceback

class CommandList (object) :
    """
        A list of available Commands

        XXX: not yet used
    """

    def __init__ (self, commands) :
        """
            Store with given initial commands
        """

        self.list = commands
        self.dict = dict((cmd.name, cmd) for cmd in commands)

    def lookup (self, name) :
        """
            Lookup a command by name
        """

        return self.dict[name]

class Command (object) :
    """
        A Command is simply a function that can be executed from the command line with some options/arguments
    """

    def __init__ (self, name, func, doc=None) :
        """
            Create a new Command

             name       - the name of the command
             func       - the callable python function
             doc        - descriptive help text
        """

        self.name = name
        self.func = func
        self.doc = doc

    def setup (self, config, gallery) :
        """
            Run the command with the given context
        """
        
        return CommandContext(self, config, gallery)

class CommandContext (object) :
    """
        A CommandContext is the context that a Command executes in

        It is bound to a Configuration and a Gallery.
    """

    def __init__ (self, command, config, gallery) :
        """
            Create the execution environment
        """

        self.command = command
        self.config = config
        self.gallery = gallery

    def __call__ (self, *args, **kwargs) :
        """
            Run the command in this context
        """

        return self.command.func(self, *args, **kwargs)

    def log_msg (self, level, msg, *args, **kwargs) :
        """
            Output a log message with the given level

            XXX: unicode
        """
        
        # control level of output
        if level < self.config.log_level :
            return
        
        # format?
        if args or kwargs :
            if args and not kwargs :
                msg = msg % args

            elif kwargs and not args :
                msg = msg % kwargs

            else :
                raise Exception("log_msg called with both args and kwargs")
        
        # output
        # XXX: stdout/err?
        print msg

    def log_debug (self, msg, *args, **kwargs) :
        self.log_msg(logging.DEBUG, msg, *args, **kwargs)

    def log_info (self, msg, *args, **kwargs) :
        self.log_msg(logging.INFO, msg, *args, **kwargs)
    
    def log_warning (self, msg, *args, **kwargs) :
        self.log_msg(logging.WARNING, msg, *args, **kwargs)

    def log_error (self, msg, *args, **kwargs) :
        self.log_msg(logging.ERROR, msg, *args, **kwargs)
    
    def handle_error (self, exc_info=None) :
        """
            Do something to handle an error that occured
        """
        
        if exc_info :
            traceback.print_execption(*exc_info)

        else :
            traceback.print_exc()

def command (func) :
    """
        A function decorator used to define Commands automatically
    """

    return Command(func.__name__, func, inspect.getdoc(func))