def _rpc_method(method, *args, **kwargs): # Create a thread condition for waiting for the method's result. condition = threading.Condition() closure = [] def timer_func(): try: closure.append(method(*args, **kwargs)) except Exception as e: # Log any exceptions. _log.exception("Exception occurred during RPC method '%s': %s" % (method.__name__, e)) closure.append(e) # Notify the waiting thread that the result is ready. with condition: condition.notify() # Start a non-repeating timer to execute timer_func(). get_engine().create_timer(timer_func, 0, repeating=False) # Wait for the result. with condition: condition.wait() # Raise an error if it's an exception (json-rpc handles this), # otherwise return it. result = closure[0] if isinstance(result, Exception): raise result else: return result
def _execute_events(self, events): """ Send keyboard events. If instance was initialized with *autofmt* True, then this method will mimic a word recognition and analyze its formatting so as to autoformat the text's spacing and capitalization before sending it as keyboard events. """ if self._autofmt: # Mimic a word, select and copy it to retrieve capitalization. get_engine().mimic("test") Key("cs-left, c-c/5").execute() word = Clipboard.get_system_text() # Inspect formatting of the mimicked word. index = word.find("test") if index == -1: index = word.find("Test") capitalize = True if index == -1: self._log.error("Failed to autoformat.") return False else: capitalize = False # Capitalize given text if necessary. text = self._spec if capitalize: text = text[0].capitalize() + text[1:] # Reconstruct autoformatted output and convert it # to keyboard events. prefix = word[:index] suffix = word[index + 4:] events = self._parse_spec(prefix + text + suffix) # Calculate keyboard events. use_hardware = self.require_hardware_events() keyboard_events = [] for key_symbol in events: # Get a Typeable object for each key symbol, if possible. typeable = self._get_typeable(key_symbol, use_hardware) # Raise an error message if a Typeable could not be retrieved. if typeable is None: error_message = ("Keyboard interface cannot type this" " character: %r" % key_symbol) raise ActionError(error_message) # Get keyboard events using the Typeable. keyboard_events.extend(typeable.events(self._pause)) # Send keyboard events. self._keyboard.send_keyboard_events(keyboard_events) return True
def mimic(words): """ Mimic the given *words*. :param words: string or list of words to mimic :returns: whether the mimic was a success :rtype: bool """ if isinstance(words, string_types): words = words.split() try: get_engine().mimic(words) return True except MimicFailure: return False
def list_grammars(): """ Get a list of grammars loaded into the current engine. This includes grammar rules and attributes. """ # Send rule and grammar data back to the client. grammars = [] engine = get_engine() for grammar in engine.grammars: rules = [] for rule in grammar.rules: if isinstance(rule, CompoundRule): specs = [rule.spec] elif isinstance(rule, MappingRule): specs = sorted(rule.specs) else: specs = [rule.element.gstring()] rules.append({ "name": rule.name, "specs": specs, "exported": rule.exported, "active": rule.active }) # Add grammar attributes to the grammars list. is_active = any([r.active for r in grammar.rules]) grammars.append({ "name": grammar.name, "rules": rules, "enabled": grammar.enabled, "active": is_active }) return grammars
def _process_recognition(self, node, extras): dragonfly_dist = pkg_resources.get_distribution("dragonfly") print "Current Dragonfly version:", dragonfly_dist.version from dragonfly import engines #import dragonfly.engines.engine engine = engines.get_engine() print "Current language: %r" % engine.language
def test_dictation_non_ascii(self): """ Test handling of non-ASCII characters in dictation. """ def value_func(node, extras): return extras["text"] element = Compound("test <text>", extras=[Dictation(name="text")], value_func=value_func) tester = ElementTester(element) words = [u"test", u"touché"] engine = get_engine() uppercase_dictation_required = engine.name in ['sphinx', 'text'] if uppercase_dictation_required: words[1] = words[1].upper() dictation = tester.recognize(words) # Verify recognition returned dictation result. if not isinstance(dictation, DictationContainerBase): encoding = locale.getpreferredencoding() message = (u"Expected recognition result to be a dictation" u" container, but received %r" % (repr(dictation), )) self.fail(message.encode(encoding)) # Verifying dictation converts/encode successfully. string = "touché" if isinstance(string, binary_type): encoding = locale.getpreferredencoding() string = string.decode("windows-1252").encode(encoding) self.assertEqual(str(dictation), string) self.assertEqual(text_type(dictation), u"touché") self.assertTrue(isinstance(repr(dictation), string_types))
def _execute(self, data=None): engine = get_engine() words = self._words # If an extra was given, retrieve the associated value from # the *data* dict and append it to the static words. if self._extra: try: extra = data[self._extra] except KeyError: raise ActionError("No extra data available for extra %r" % self._extra) # Append the extra data to the static words depending on # the type of the extra data object. if isinstance(extra, engine.DictationContainer): words += tuple(extra.words) elif isinstance(extra, (tuple, list)): words += tuple(extra) elif isinstance(extra, string_types): words += (extra,) else: raise ActionError("Invalid extra data type: %r" % extra) # Mimic the series of words. self._log.debug("Mimicking recognition: %r", words) try: engine.disable_recognition_observers() engine.mimic(words) engine.enable_recognition_observers() except Exception as e: raise ActionError("Mimicking failed: %s" % e)
def main(): logging.basicConfig(level=logging.INFO) try: path = os.path.dirname(__file__) except NameError: # The "__file__" name is not always available, for example # when this module is run from PythonWin. In this case we # simply use the current working directory. path = os.getcwd() __file__ = os.path.join(path, "sphinx_module_loader.py") engine = get_engine("sphinx") engine.connect() # Register a recognition observer observer = Observer(engine) observer.register() directory = CommandModuleDirectory(path, excludes=[__file__]) directory.load() # TODO Have a simple GUI for pausing, resuming, cancelling and stopping recognition, etc # TODO Change script to import all modules before loading the grammars into Pocket Sphinx # Start the engine's main recognition loop engine.connect() engine.recognise_forever()
def setUp(self): self.log_capture = CapturingHandler() logging.getLogger("engine.timer").addHandler(self.log_capture) self.engine = get_engine() # Ensure the engine is connected to avoid errors. self.engine.connect()
def test_element(self): # Translate all inputs and outputs to the preferred encoding for # recognition so that the tests can run on Windows or Linux. engine = get_engine() encoding = locale.getpreferredencoding() uppercase_dictation_required = engine.name in ['sphinx', 'text'] def translate(string): # Any binary strings in this file will be encoded with # windows-1252 as per the specified source file encoding. if isinstance(string, binary_type): string = string.decode("windows-1252").encode(encoding) return string for i, (input, output) in enumerate(self.input_output): new_input = translate(input) new_output = translate(output) # Also map input dictation words to uppercase if necessary. if uppercase_dictation_required: words = new_input.split() new_input = ' '.join([words[0]] + [word.upper() for word in words[1:]]) # Manually uppercase the accented characters we use because # upper() doesn't do it for us. There's probably a better # way, but this will do. if isinstance(new_input, binary_type): new_input = (new_input.replace("\xa9", "\x89").replace( "\xb1", "\x91")) self.input_output[i] = (new_input, new_output) ElementTestCase.test_element(self)
def get_engine_language(): """ Get the current engine's language. :returns: language code :rtype: str """ return get_engine().language
def test_get_engine_nonexistent(self): """ Verify that getting a nonexistent engine raises an error. """ try: engine = get_engine("nonexistent") except EngineError: pass # Expected exception, so ignore. else: assert False, "Getting a nonexistent engine should have" " raised an exception, but it didn't!"
def _get_engine_language(self): try: from dragonfly.engines import get_engine language = get_engine().language except Exception as e: self._log.exception("Failed to retrieve speaker language: %s" % e) raise return language
def test_get_engine_nonexistent(self): """ Verify that getting a nonexistent engine raises an error. """ try: engine = get_engine("nonexistent") except EngineError: pass # Expected exception, so ignore. else: assert False, ("Getting a nonexistent engine should have" " raised an exception, but it didn't!")
def setUpClass(cls): # If the engine's timer manager is a ThreadedTimerManager, disable # the main callback to prevent race conditions. timer_manager = get_engine()._timer_manager if isinstance(timer_manager, ThreadedTimerManager): cls.threaded_timer_manager = timer_manager timer_manager.disable() else: cls.threaded_timer_manager = None
def test_get_engine_natlink_is_usable(self): """ Verify that the natlink engine is usable. """ engine = get_engine("natlink") assert isinstance(engine, EngineBase) assert engine.name == "natlink" engine.speak("testing natlink") from dragonfly import Literal from dragonfly.test import ElementTester tester = ElementTester(Literal("hello world")) results = tester.recognize("hello world") assert results == "hello world"
def speak(text): """ Speak the given *text* using text-to-speech using :meth:`engine.speak`. :param text: text to speak using text-to-speech :type text: str """ if not isinstance(text, string_types): raise TypeError("text must be a string") return get_engine().speak(text)
def _execute(self, data=None): engine = get_engine() # Mimic the series of recognitions. for words, interval in self._series: self._log.debug("Mimicking recognition: %r", words) try: engine.mimic(words) if interval and self._speed: sleep(interval / self._speed) except Exception as e: raise ActionError("Playback failed: %s" % e)
def setUp(self): self.engine = get_engine("kaldi") # Map for test functions self.test_map = {} # Connect the engine. self.engine.connect() # Register a recognition observer. self.test_recobs = RecognitionObserverTester() self.test_recobs.register()
def test_get_engine_sapi5_is_usable(self): """ Verify that the sapi5 engine is usable. """ engine = get_engine() self.assert_(isinstance(engine, EngineBase)) self.assertEqual("sapi5", engine.name) engine.speak("testing WSR") from dragonfly import Literal, Sequence from dragonfly.test import ElementTester seq = Sequence([Literal("hello"), Literal("world")]) tester = ElementTester(seq, engine=engine) results = tester.recognize("hello world") self.assertEqual([u"hello", u"world"], results)
def test_get_engine_sapi5_is_usable(self): """ Verify that the sapi5 engine is usable. """ engine = get_engine() self.assertTrue(isinstance(engine, EngineBase)) self.assertEqual("sapi5", engine.name) engine.speak("testing WSR") from dragonfly import Literal, Sequence from dragonfly.test import ElementTester seq = Sequence([Literal("hello"), Literal("world")]) tester = ElementTester(seq, engine=engine) results = tester.recognize("hello world") self.assertEqual([u"hello", u"world"], results)
def test_get_engine_automatic_is_usable(self): """ Verify that the automatically selected engine is usable. """ engine = get_engine() engine.connect() try: engine.speak("testing automatic") from dragonfly import Literal from dragonfly.test import ElementTester tester = ElementTester(Literal("hello world")) results = tester.recognize("hello world") assert results == "hello world" finally: engine.disconnect()
def test_get_engine_sphinx_is_usable(self): """ Verify that the sphinx engine is usable by testing that a simple rule is loaded correctly and works correctly. """ engine = get_engine() assert engine.name == "sphinx" assert isinstance(self.engine, EngineBase) engine.speak("testing sphinx") # Test that a basic rule can be loaded and recognized. seq = Sequence([Literal("hello"), Literal("world")]) tester = ElementTester(seq, engine=engine) results = tester.recognize("hello world") self.assertEqual(results, [u"hello", u"world"])
def test_get_engine_natlink_is_usable(self): """ Verify that the natlink engine is usable. """ engine = get_engine("natlink") assert isinstance(engine, EngineBase) assert engine.name == "natlink" engine.connect() try: engine.speak("testing natlink") from dragonfly import Literal from dragonfly.test import ElementTester tester = ElementTester(Literal("hello world")) results = tester.recognize("hello world") assert results == "hello world" finally: engine.disconnect()
def test_get_engine_kaldi_is_usable(self): """ Verify that the kaldi engine is usable by testing that a simple rule is loaded correctly and works correctly. """ engine = get_engine() assert engine.name == "kaldi" assert isinstance(self.engine, EngineBase) engine.speak("testing kaldi") # Test that a basic rule can be loaded and recognized. seq = Sequence([Literal("hello"), Literal("world")]) tester = ElementTester(seq, engine=engine) results = tester.recognize("hello world") self.assertEqual(results, [u"hello", u"world"])
def test_get_engine_sapi5_is_usable(self): """ Verify that the sapi5 engine is usable. """ engine = get_engine("sapi5") assert isinstance(engine, EngineBase) assert engine.name == "sapi5" engine.connect() try: engine.speak("testing WSR") from dragonfly import Literal from dragonfly.test import ElementTester tester = ElementTester(Literal("hello world"), engine=engine) results = tester.recognize("hello world") assert results == "hello world", "%r != %r" % (results, "hello world") finally: engine.disconnect()
def main(): logging.basicConfig(level=logging.INFO) try: path = os.path.dirname(__file__) except NameError: # The "__file__" name is not always available, for example # when this module is run from PythonWin. In this case we # simply use the current working directory. path = os.getcwd() __file__ = os.path.join(path, "sphinx_module_loader.py") engine = get_engine("sphinx") assert isinstance(engine, SphinxEngine) # Try to import the local engine configuration object first. If there isn't one, # use the default engine configuration. log = logging.getLogger("config") try: import config engine.config = config log.info("Using local engine configuration module 'config.py'") except ImportError: pass except EngineError as e: # Log EngineErrors caught when setting the configuration. log.warning(e) log.warning("Falling back to using the default engine configuration " "instead of 'config.py'") # Call connect() now that the engine configuration is set. engine.connect() # Register a recognition observer observer = Observer(engine) observer.register() directory = CommandModuleDirectory(path, excludes=[__file__]) directory.load() # TODO Have a simple GUI for pausing, resuming, cancelling and stopping recognition, etc # TODO Change script to import all modules before loading the grammars into Pocket Sphinx # Start the engine's main recognition loop try: engine.recognise_forever() except KeyboardInterrupt: pass
def __init__(self, name, description=None, context=None, engine=None): self._name = name self._description = description if not (isinstance(context, Context) or context is None): raise TypeError("context must be either a Context object or " "None") self._context = context if engine: self._engine = engine else: self._engine = get_engine() self._rules = [] self._lists = [] self._rule_names = None self._loaded = False self._enabled = True self._in_context = False
def setUp(self): self.engine = get_engine("sphinx") # Ensure the relevant configuration values are used. self.engine.config.TRAINING_DATA_DIR = "" self.engine.config.START_ASLEEP = False self.engine.config.WAKE_PHRASE = "wake up" self.engine.config.SLEEP_PHRASE = "go to sleep" self.engine.config.START_TRAINING_PHRASE = "start training session" self.engine.config.END_TRAINING_PHRASE = "end training session" self.engine.config.LANGUAGE = "en" # Map for test functions self.test_map = {} # Connect the engine. self.engine.connect() # Register a recognition observer. self.test_recobs = RecognitionObserverTester() self.test_recobs.register()
import os import sys import unittest from dragonfly.engines import _engines_by_name, get_engine if not _engines_by_name: engine = get_engine("text") engine.connect() def get_master_suite(): return unittest.defaultTestLoader.discover(os.path.dirname(__file__)) def run_tests(): return unittest.TextTestRunner(verbosity=2).run(get_master_suite()) if __name__ == '__main__': result = run_tests() sys.exit(len(result.failures) + len(result.errors) + len(result.unexpectedSuccesses))
def test_get_engine_nonexistent(self): engine = get_engine("nonexistent")
def test_get_engine_automatic(self): """ Verify that an engine can be selected automatically. """ engine = get_engine() assert isinstance(engine, EngineBase)
def add_callback(self, function, interval): t = get_engine().create_timer(function, interval) c = self.Callback(function, interval) c.timer = t self.callbacks.append(c)
callback_called = [0] def callback(): callback_called[0] += 1 interval = 0.01 timer = self.engine.create_timer(callback, interval, False) time.sleep(0.02) timer.manager.main_callback() time.sleep(0.02) timer.manager.main_callback() # Callback was only called once. try: self.assertEqual(callback_called[0], 1) finally: # Stop the timer at the end regardless of the result. timer.stop() #=========================================================================== if __name__ == "__main__": # Use the "text" engine by default and disable timer manager callbacks # to avoid race conditions. get_engine("text")._timer_manager.disable() from dragonfly.log import setup_log setup_log() # tests require sane logging levels unittest.main()
def run(self, result=None): self.engine = get_engine() self.grammar = RuleTestGrammar() return unittest.TestCase.run(self, result)
def setUp(self): self.log_capture = CapturingHandler() logging.getLogger("engine.timer").addHandler(self.log_capture) self.engine = get_engine()