|
@@ -4,6 +4,7 @@
|
4
|
4
|
# Portions Copyright 2013 Jezra
|
5
|
5
|
|
6
|
6
|
import importlib
|
|
7
|
+import queue
|
7
|
8
|
import sys
|
8
|
9
|
import subprocess
|
9
|
10
|
import signal
|
|
@@ -36,7 +37,9 @@ class Kaylee:
|
36
|
37
|
self.plugins = []
|
37
|
38
|
for plugin in self.config.plugins.keys():
|
38
|
39
|
pmod = importlib.import_module(plugin, 'kayleevc.plugins')
|
39
|
|
- self.plugins.append(pmod.Plugin(self.config, plugin))
|
|
40
|
+ pobj = pmod.Plugin(self.config, plugin)
|
|
41
|
+ pobj.connect('tts', self.plugin_tts)
|
|
42
|
+ self.plugins.append(pobj)
|
40
|
43
|
|
41
|
44
|
# Create a hasher
|
42
|
45
|
self.hasher = Hasher(self.config)
|
|
@@ -74,11 +77,7 @@ class Kaylee:
|
74
|
77
|
# Create the recognizer
|
75
|
78
|
self.recognizer = Recognizer(self.config)
|
76
|
79
|
|
77
|
|
- # Connect the recognizer's finished signal to all the plugins
|
78
|
|
- for plugin in self.plugins:
|
79
|
|
- self.recognizer.connect('finished', plugin.recognizer_finished)
|
80
|
|
- plugin.connect('processed', self.plugin_processed)
|
81
|
|
- plugin.connect('tts', self.plugin_tts)
|
|
80
|
+ # Connect the recognizer's finished signal to the appropriate method
|
82
|
81
|
self.recognizer.connect('finished', self.recognizer_finished)
|
83
|
82
|
|
84
|
83
|
def update_voice_commands_if_changed(self):
|
|
@@ -113,17 +112,8 @@ class Kaylee:
|
113
|
112
|
strings.write(word + " ")
|
114
|
113
|
strings.write("\n")
|
115
|
114
|
|
116
|
|
- def plugin_processed(self, plugin, text):
|
117
|
|
- """Callback for ``processed`` signal from plugins
|
118
|
|
-
|
119
|
|
- Runs the valid_sentence_command and logs the recognized sentence to the
|
120
|
|
- history file.
|
121
|
|
- """
|
122
|
|
- # Run the valid_sentence_command if it's set
|
123
|
|
- if self.options['valid_sentence_command']:
|
124
|
|
- subprocess.call(self.options['valid_sentence_command'], shell=True)
|
125
|
|
-
|
126
|
|
- # Log the command to the history file
|
|
115
|
+ def _log_history(self, plugin, text):
|
|
116
|
+ """Log the recognized sentence to the history file"""
|
127
|
117
|
if self.options['history']:
|
128
|
118
|
self.history.append("{}: {}".format(plugin.name, text))
|
129
|
119
|
if len(self.history) > self.options['history']:
|
|
@@ -136,13 +126,49 @@ class Kaylee:
|
136
|
126
|
hfile.write(line + '\n')
|
137
|
127
|
self._stop_ui(text)
|
138
|
128
|
|
139
|
|
- def recognizer_finished(self, recognizer, text):
|
140
|
|
- # No loaded plugin wanted the text, so run the invalid_sentence_command
|
141
|
|
- # if it's set
|
|
129
|
+ def _valid_cmd(self):
|
|
130
|
+ """Run the valid_sentence_command if it's set"""
|
|
131
|
+ if self.options['valid_sentence_command']:
|
|
132
|
+ subprocess.call(self.options['valid_sentence_command'], shell=True)
|
|
133
|
+
|
|
134
|
+ def _invalid_cmd(self, text):
|
|
135
|
+ """Run the invalid_sentence_command if it's set"""
|
142
|
136
|
if self.options['invalid_sentence_command']:
|
143
|
137
|
subprocess.call(self.options['invalid_sentence_command'],
|
144
|
138
|
shell=True)
|
145
|
139
|
print("no matching command {0}".format(text))
|
|
140
|
+
|
|
141
|
+ def recognizer_finished(self, recognizer, text):
|
|
142
|
+ confidence_heap = queue.PriorityQueue()
|
|
143
|
+ # Add plugins to the heap
|
|
144
|
+ for index, plugin in enumerate(self.plugins):
|
|
145
|
+ # Get plugin confidence
|
|
146
|
+ confidence = plugin.confidence(text)
|
|
147
|
+ # Clamp confidence to [0, 1]
|
|
148
|
+ confidence = min(max(confidence, 0), 1)
|
|
149
|
+ # TODO: Only add items if they meet minimum confidence
|
|
150
|
+ if confidence > 0:
|
|
151
|
+ # Add a triple to the heap, so plugins are sorted first by
|
|
152
|
+ # confidence, then by index to break ties
|
|
153
|
+ confidence_heap.put_nowait((1 - confidence, index, plugin))
|
|
154
|
+
|
|
155
|
+ # Run valid or invalid sentence command
|
|
156
|
+ if confidence_heap.empty():
|
|
157
|
+ self._invalid_cmd(text)
|
|
158
|
+ else:
|
|
159
|
+ self._valid_cmd()
|
|
160
|
+
|
|
161
|
+ # Give the command to the plugins that want it
|
|
162
|
+ while True:
|
|
163
|
+ try:
|
|
164
|
+ plugin = confidence_heap.get_nowait()[2]
|
|
165
|
+ except queue.Empty:
|
|
166
|
+ break
|
|
167
|
+ # If the plugin successfully handled the command
|
|
168
|
+ if plugin.handle(text):
|
|
169
|
+ self._log_history(plugin, text)
|
|
170
|
+ break
|
|
171
|
+
|
146
|
172
|
self._stop_ui(text)
|
147
|
173
|
|
148
|
174
|
def plugin_tts(self, plugin, text):
|