12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- # This is part of Kaylee
- # -- this code is licensed GPLv3
- # Copyright 2015-2017 Clayton G. Hobbs
- # Portions Copyright 2013 Jezra
-
- """Run shell commands that match voice commands
-
- This Kaylee plugin can be used to perform the job of `Blather
- <https://gitlab.com/jezra/blather>`__. Its configuration is of the
- following format::
-
- ".shell": {
- "VOICE_COMMAND": "SHELL_COMMAND",
- ...
- }
-
- A VOICE_COMMAND may contain any number of the special word ``%d``,
- which is a stand-in for a spoken number. The spoken number is
- transformed into a decimal integer which may be substituted into the
- SHELL_COMMAND any number of times. These substitutions are made by
- writing ``{INDEX}`` in the SHELL_COMMAND, where INDEX is an integer
- counting the ``%d`` strings from 0. An example of this type of command
- is::
-
- "%d is a number": "echo 'the number you said was {0}'"
-
- """
-
- import subprocess
-
- from . import PluginBase, Handler
- from ..numbers import NumberParser
-
-
- class Plugin(PluginBase):
- """Run shell commands that match voice commands"""
-
- def __init__(self, config, name):
- """Initialize the shell plugin"""
- super().__init__(config, name)
- self.number_parser = NumberParser()
- self.commands = self.options
-
- for voice_cmd in self.commands.keys():
- self.corpus_strings.add(voice_cmd.strip().replace('%d', ''))
-
- def get_handler(self, text):
- """Return whether or not the command can be handled"""
- if text in self.commands:
- # If there's an exact match, return a handler for it
- return ShellHandler(1, self.commands[text])
- else:
- # Otherwise, try substituting numbers
- numt, nums = self.number_parser.parse_all_numbers(text)
- if numt in self.commands:
- # Return a handler if we have a match
- return ShellHandler(1, self.commands[numt], nums)
- # Return None if that fails too
- return None
-
-
- class ShellHandler(Handler):
- """Handle a voice command that corresponds to a shell command"""
-
- def __init__(self, confidence, command, nums=None):
- """Determine the exact command that will be run"""
- super().__init__(confidence)
- if nums is None:
- self.command = command
- else:
- self.command = command.format(*nums)
-
- def __call__(self, tts):
- """Print the command, then run it"""
- print(self.command)
- subprocess.call(self.command, shell=True)
|