Somewhat fancy voice command recognition software
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

shell.py 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. # This is part of Kaylee
  2. # -- this code is licensed GPLv3
  3. # Copyright 2015-2017 Clayton G. Hobbs
  4. # Portions Copyright 2013 Jezra
  5. """Run shell commands that match voice commands
  6. This Kaylee plugin can be used to perform the job of `Blather
  7. <https://gitlab.com/jezra/blather>`__. Its configuration is of the
  8. following format::
  9. ".shell": {
  10. "VOICE_COMMAND": "SHELL_COMMAND",
  11. ...
  12. }
  13. A VOICE_COMMAND may contain any number of the special word ``%d``,
  14. which is a stand-in for a spoken number. The spoken number is
  15. transformed into a decimal integer which may be substituted into the
  16. SHELL_COMMAND any number of times. These substitutions are made by
  17. writing ``{INDEX}`` in the SHELL_COMMAND, where INDEX is an integer
  18. counting the ``%d`` strings from 0. An example of this type of command
  19. is::
  20. "%d is a number": "echo 'the number you said was {0}'"
  21. """
  22. import subprocess
  23. from .pluginbase import PluginBase
  24. from ..numbers import NumberParser
  25. class Plugin(PluginBase):
  26. """Run shell commands that match voice commands"""
  27. def __init__(self, config, name):
  28. """Initialize the shell plugin"""
  29. super().__init__(config, name)
  30. self.number_parser = NumberParser()
  31. self.commands = self.options
  32. for voice_cmd in self.commands.keys():
  33. self.corpus_strings.add(voice_cmd.strip().replace('%d', ''))
  34. def _run_command(self, cmd):
  35. """Print the command, then run it"""
  36. print(cmd)
  37. subprocess.call(cmd, shell=True)
  38. def confidence(self, text):
  39. """Return whether or not the command can be handled"""
  40. numt, nums = self.number_parser.parse_all_numbers(text)
  41. if text in self.commands:
  42. return 1
  43. elif numt in self.commands:
  44. return 1
  45. else:
  46. return 0
  47. def handle(self, text):
  48. """Run the shell command corresponding to a recognized voice command
  49. Spoken number(s) may be substituted in the shell command. The shell
  50. commands are printed immediately before they are executed.
  51. """
  52. numt, nums = self.number_parser.parse_all_numbers(text)
  53. # Is there a matching command?
  54. if text in self.commands:
  55. cmd = self.commands[text]
  56. self._run_command(cmd)
  57. return True
  58. # Is there a matching command with numbers substituted?
  59. elif numt in self.commands:
  60. cmd = self.commands[numt]
  61. cmd = cmd.format(*nums)
  62. self._run_command(cmd)
  63. return True
  64. else:
  65. return False