# HG changeset patch # User Tero Marttila # Date 1244232021 -10800 # Node ID 97e1bc208574ea92aab8f1a73cf2b4fd8db3dedc # Parent 4ebd563214d220b522e887cffdf309c3f9987d54 initial commands infrastructure diff -r 4ebd563214d2 -r 97e1bc208574 degal/command.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/degal/command.py Fri Jun 05 23:00:21 2009 +0300 @@ -0,0 +1,121 @@ +""" + Command implementations +""" + +import inspect, logging + +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 invoke (self, config, gallery, args, options) : + """ + Run the command with the given context + """ + + return CommandContext(self, config, gallery)(*args, **options) + +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) : + log_msg(logging.DEBUG, msg, *args, **kwargs) + + def log_info (self, msg, *args, **kwargs) : + log_msg(logging.INFO, msg, *args, **kwargs) + + def log_warning (self, msg, *args, **kwargs) : + log_msg(logging.WARNING, msg, *args, **kwargs) + + def log_error (self, msg, *args, **kwargs) : + log_msg(logging.ERROR, msg, *args, **kwargs) + +def command (func) : + """ + A function decorator used to define Commands automatically + """ + + return Command(func.__name__, func, inspect.getdoc(func)) + diff -r 4ebd563214d2 -r 97e1bc208574 degal/commands/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/degal/commands/__init__.py Fri Jun 05 23:00:21 2009 +0300 @@ -0,0 +1,6 @@ +""" + Core commands +""" + +from main import main +