-# Copyright (C) 2008-2010 Alberto Gomez-Casado
+# Copyright (C) 2008-2012 Alberto Gomez-Casado <a.gomezcasado@tnw.utwente.nl>
# Massimo Sandal <devicerandom@gmail.com>
# W. Trevor King <wking@drexel.edu>
#
"""
import logging
+import os.path
from Queue import Queue
from ..command import Command, Argument, Success, Failure
-from ..command_stack import CommandStack
+from ..command_stack import FileCommandStack
+from ..config import Setting
from ..engine import CloseEngine, CommandMessage
from . import Builtin
class CommandStackCommand (Command):
"""Subclass to avoid pushing control commands to the stack.
"""
+ def __init__(self, *args, **kwargs):
+ super(CommandStackCommand, self).__init__(*args, **kwargs)
+ stack = [a for a in self.arguments if a.name == 'stack'][0]
+ stack.default = False
+
def _set_state(self, state):
try:
self.plugin.set_state(state)
return
assert isinstance(msg, CommandMessage), type(msg)
cmd = hooke.command_by_name[msg.command]
- if isinstance(cmd, CommandStackCommand):
+ if (msg.explicit_user_call == False
+ or isinstance(cmd, CommandStackCommand)):
if isinstance(cmd, StopCaptureCommand):
outqueue = Queue() # Grab StopCaptureCommand's completion.
cmd.run(hooke, inqueue, outqueue, **msg.arguments)
# The plugin itself
class CommandStackPlugin (Builtin):
+ """Commands for managing a command stack (similar to macros).
+ """
def __init__(self):
super(CommandStackPlugin, self).__init__(name='command_stack')
self._commands = [
StartCaptureCommand(self), StopCaptureCommand(self),
ReStartCaptureCommand(self),
PopCommand(self), GetCommand(self), GetStateCommand(self),
- SaveCommand(self), LoadCommand(self),
+ SaveCommand(self), LoadCommand(self), ExecuteCommand(self),
]
- self.command_stack = CommandStack()
- self.path = None
+ self._settings = [
+ Setting(section=self.setting_section, help=self.__doc__),
+ Setting(section=self.setting_section, option='path',
+ value=os.path.join('resources', 'command_stack'),
+ help='Directory containing command stack files.'), # TODO: allow colon separated list, like $PATH.
+ ]
+ self.command_stack = FileCommandStack()
self.state = 'inactive'
# inactive <-> active.
self._valid_transitions = {
'active': ['inactive'],
}
+ def default_settings(self):
+ return self._settings
+
def log(self, msg):
log = logging.getLogger('hooke')
log.debug('%s %s' % (self.name, msg))
def _run(self, hooke, inqueue, outqueue, params):
self._set_state('active')
- self.plugin.command_stack = CommandStack() # clear command stack
+ self.plugin.command_stack = FileCommandStack() # clear command stack
super(StartCaptureCommand, self)._run(hooke, inqueue, outqueue, params)
"""
def __init__(self, plugin):
super(SaveCommand, self).__init__(
- name='save command stack', help=self.__doc__, plugin=plugin)
+ name='save command stack',
+ arguments=[
+ Argument(name='output', type='file',
+ help="""
+File name for the output command stack. Defaults to overwriting the
+input command stack. If the command stack does not have an input file
+(e.g. it is the default) then the file name defaults to `default`.
+""".strip()),
+ ],
+ help=self.__doc__, plugin=plugin)
def _run(self, hooke, inqueue, outqueue, params):
- pass
-
+ params = self._setup_params(hooke, params)
+ self.plugin.command_stack.save(params['output'])
+
+ def _setup_params(self, hooke, params):
+ if params['output'] == None and self.plugin.command_stack.path == None:
+ params['output'] = 'default'
+ if params['output'] != None:
+ params['output'] = os.path.join(
+ os.path.expanduser(self.plugin.config['path']),
+ params['output'])
+ return params
class LoadCommand (CommandStackCommand):
"""Load the command stack.
+
+ .. warning:: This is *not safe* with untrusted input.
"""
def __init__(self, plugin):
super(LoadCommand, self).__init__(
- name='load command stack', help=self.__doc__, plugin=plugin)
+ name='load command stack',
+ arguments=[
+ Argument(name='input', type='file',
+ help="""
+File name for the input command stack.
+""".strip()),
+ ],
+ help=self.__doc__, plugin=plugin)
+
+ def _run(self, hooke, inqueue, outqueue, params):
+ params = self._setup_params(hooke, params)
+ self.plugin.command_stack.clear()
+ self.plugin.command_stack.load(params['input'])
+
+ def _setup_params(self, hooke, params):
+ if params['input'] == None and self.plugin.command_stack.path == None:
+ params['input'] = 'default'
+ if params['input'] != None:
+ params['input'] = os.path.join(
+ os.path.expanduser(self.plugin.config['path']),
+ params['input'])
+ return params
+
+
+class ExecuteCommand (Command):
+ """Execute a :class:`~hooke.command_stack.CommandStack`.
+ """
+ def __init__(self, plugin):
+ super(ExecuteCommand, self).__init__(
+ name='execute command stack',
+ arguments=[
+ Argument(name='commands', type='command stack',
+ help="""
+Command stack to apply to each curve. Defaults to the plugin's
+current stack.
+""".strip()),
+ ],
+ help=self.__doc__, plugin=plugin)
def _run(self, hooke, inqueue, outqueue, params):
- pass
+ params = self._setup_params(hooke=hooke, params=params)
+ if len(params['commands']) == 0:
+ return
+ params['commands'].execute(hooke=hooke, stack=params['stack'])
+
+ def _setup_params(self, hooke, params):
+ if params['commands'] == None:
+ params['commands'] = self.plugin.command_stack
+ return params