summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/brain.py15
-rw-r--r--client/music.py6
-rw-r--r--client/speaker.py2
-rw-r--r--client/stt.py34
-rw-r--r--client/test.py23
-rwxr-xr-xjasper.py16
6 files changed, 69 insertions, 27 deletions
diff --git a/client/brain.py b/client/brain.py
index f57331c..007b7fe 100644
--- a/client/brain.py
+++ b/client/brain.py
@@ -32,13 +32,22 @@ class Brain(object):
module, a priority of 0 is assumed.
"""
+ logger = logging.getLogger(__name__)
module_locations = [jasperpath.PLUGIN_PATH]
+ logger.debug("Looking for modules in: %s", ', '.join(["'%s'" % location for location in module_locations]))
module_names = [name for loader, name, ispkg in pkgutil.walk_packages(module_locations, prefix='modules.')]
modules = []
for name in module_names:
- mod = importlib.import_module(name)
- if hasattr(mod, 'WORDS'):
- modules.append(mod)
+ try:
+ mod = importlib.import_module(name)
+ except:
+ logger.warning("Skipped module '%s' due to an error.", name, exc_info=True)
+ else:
+ if hasattr(mod, 'WORDS'):
+ logger.debug("Found module '%s' with words: %r", name, mod.WORDS)
+ modules.append(mod)
+ else:
+ logger.warning("Skipped module '%s' because it misses the WORDS constant.", name)
modules.sort(key=lambda mod: mod.PRIORITY if hasattr(mod, 'PRIORITY') else 0, reverse=True)
return modules
diff --git a/client/music.py b/client/music.py
index 2b6c055..ca9b776 100644
--- a/client/music.py
+++ b/client/music.py
@@ -17,14 +17,14 @@ def reconnect(func, *default_args, **default_kwargs):
# sometimes not enough to just connect
try:
- func(self, *default_args, **default_kwargs)
+ return func(self, *default_args, **default_kwargs)
except:
self.client = MPDClient()
self.client.timeout = None
self.client.idletimeout = None
self.client.connect("localhost", 6600)
- func(self, *default_args, **default_kwargs)
+ return func(self, *default_args, **default_kwargs)
return wrap
@@ -103,7 +103,7 @@ class Music:
self.client.play()
- #@reconnect -- this makes the function return None for some reason!
+ @reconnect
def current_song(self):
item = self.client.playlistinfo(int(self.client.status()["song"]))[0]
result = "%s by %s" % (item["title"], item["artist"])
diff --git a/client/speaker.py b/client/speaker.py
index 8344132..c20c01b 100644
--- a/client/speaker.py
+++ b/client/speaker.py
@@ -21,7 +21,7 @@ class eSpeakSpeaker:
return os.system("which espeak") == 0
def say(self, phrase, OPTIONS=" -vdefault+m3 -p 40 -s 160 --stdout > say.wav"):
- os.system("espeak " + json.dumps(phrase) + OPTIONS)
+ os.system("espeak " + json.dumps(phrase, False, False) + OPTIONS)
self.play("say.wav")
def play(self, filename):
diff --git a/client/stt.py b/client/stt.py
index 9191bf5..fc1bd1f 100644
--- a/client/stt.py
+++ b/client/stt.py
@@ -3,6 +3,8 @@
import os
import traceback
import json
+import tempfile
+import logging
import requests
import yaml
@@ -27,6 +29,8 @@ class PocketSphinxSTT(object):
dictd_persona -- filename of the 'Persona' dictionary (.dic)
"""
+ self._logger = logging.getLogger(__name__)
+
# quirky bug where first import doesn't work
try:
import pocketsphinx as ps
@@ -46,11 +50,23 @@ class PocketSphinxSTT(object):
if not hmm_dir:
hmm_dir = "/usr/local/share/pocketsphinx/model/hmm/en_US/hub4wsj_sc_8k"
+ with tempfile.NamedTemporaryFile(prefix='psdecoder_music_', suffix='.log', delete=False) as f:
+ self.logfile_music = f.name
+ with tempfile.NamedTemporaryFile(prefix='psdecoder_persona_', suffix='.log', delete=False) as f:
+ self.logfile_persona = f.name
+ with tempfile.NamedTemporaryFile(prefix='psdecoder_default_', suffix='.log', delete=False) as f:
+ self.logfile_default = f.name
+
if lmd_music and dictd_music:
- self.speechRec_music = ps.Decoder(hmm=hmm_dir, lm=lmd_music, dict=dictd_music)
+ self.speechRec_music = ps.Decoder(hmm=hmm_dir, lm=lmd_music, dict=dictd_music, logfn=self.logfile_music)
self.speechRec_persona = ps.Decoder(
- hmm=hmm_dir, lm=lmd_persona, dict=dictd_persona)
- self.speechRec = ps.Decoder(hmm=hmm_dir, lm=lmd, dict=dictd)
+ hmm=hmm_dir, lm=lmd_persona, dict=dictd_persona, logfn=self.logfile_persona)
+ self.speechRec = ps.Decoder(hmm=hmm_dir, lm=lmd, dict=dictd, logfn=self.logfile_default)
+
+ def __del__(self):
+ os.remove(self.logfile_music)
+ os.remove(self.logfile_persona)
+ os.remove(self.logfile_default)
def transcribe(self, audio_file_path, PERSONA_ONLY=False, MUSIC=False):
"""
@@ -68,12 +84,24 @@ class PocketSphinxSTT(object):
if MUSIC:
self.speechRec_music.decode_raw(wavFile)
result = self.speechRec_music.get_hyp()
+ with open(self.logfile_music, 'r+') as f:
+ for line in f:
+ self._logger.debug("speechRec_music %s", line.strip())
+ f.truncate()
elif PERSONA_ONLY:
self.speechRec_persona.decode_raw(wavFile)
result = self.speechRec_persona.get_hyp()
+ with open(self.logfile_persona, 'r+') as f:
+ for line in f:
+ self._logger.debug("speechRec_persona %s", line.strip())
+ f.truncate()
else:
self.speechRec.decode_raw(wavFile)
result = self.speechRec.get_hyp()
+ with open(self.logfile_default, 'r+') as f:
+ for line in f:
+ self._logger.debug("speechRec_default %s", line.strip())
+ f.truncate()
print "==================="
print "JASPER: " + result[0]
diff --git a/client/test.py b/client/test.py
index bac4d7b..9bd765d 100644
--- a/client/test.py
+++ b/client/test.py
@@ -4,7 +4,7 @@ import os
import sys
import unittest
import argparse
-from mock import patch
+from mock import patch, Mock
from urllib2 import URLError, urlopen
import test_mic
@@ -37,20 +37,23 @@ class TestVocabCompiler(unittest.TestCase):
languagemodel = "temp_languagemodel.lm"
words = [
- 'HACKER', 'LIFE', 'FACEBOOK', 'THIRD', 'NO', 'JOKE',
- 'NOTIFICATION', 'MEANING', 'TIME', 'TODAY', 'SECOND',
- 'BIRTHDAY', 'KNOCK KNOCK', 'INBOX', 'OF', 'NEWS', 'YES',
- 'TOMORROW', 'EMAIL', 'WEATHER', 'FIRST', 'MUSIC', 'SPOTIFY'
+ 'MUSIC', 'SPOTIFY'
]
+ mock_module = Mock()
+ mock_module.WORDS = [
+ 'MOCK'
+ ]
+
+ words.extend(mock_module.WORDS)
+
with patch.object(g2p, 'translateWords') as translateWords:
with patch.object(vocabcompiler, 'text2lm') as text2lm:
- vocabcompiler.compile(sentences, dictionary, languagemodel)
+ with patch.object(brain.Brain, 'get_modules', classmethod(lambda cls: [mock_module])) as modules:
+ vocabcompiler.compile(sentences, dictionary, languagemodel)
- # 'words' is appended with ['MUSIC', 'SPOTIFY']
- # so must be > 2 to have received WORDS from modules
- translateWords.assert_called_once_with(UnorderedList(words))
- self.assertTrue(text2lm.called)
+ translateWords.assert_called_once_with(UnorderedList(words))
+ self.assertTrue(text2lm.called)
os.remove(sentences)
os.remove(dictionary)
diff --git a/jasper.py b/jasper.py
index 62713ee..03f2071 100755
--- a/jasper.py
+++ b/jasper.py
@@ -4,8 +4,6 @@ import sys
import traceback
import shutil
import logging
-logging.basicConfig()
-logger = logging.getLogger(__name__)
import yaml
import argparse
@@ -21,9 +19,6 @@ parser.add_argument('--no-network-check', action='store_true', help='Disable the
parser.add_argument('--debug', action='store_true', help='Show debug messages')
args = parser.parse_args()
-if args.debug:
- logger.setLevel(logging.DEBUG)
-
if args.local:
from client.local_mic import Mic
else:
@@ -36,9 +31,10 @@ sys.path.append(jasperpath.LIB_PATH)
class Jasper(object):
def __init__(self):
+ self._logger = logging.getLogger(__name__)
# Read config
config_file = os.path.abspath(os.path.join(jasperpath.LIB_PATH, 'profile.yml'))
- logger.debug("Trying to read config file: '%s'", config_file)
+ self._logger.debug("Trying to read config file: '%s'", config_file)
with open(config_file, "r") as f:
self.config = yaml.safe_load(f)
@@ -51,7 +47,7 @@ class Jasper(object):
stt_engine_type = self.config['stt_engine']
except KeyError:
stt_engine_type = "sphinx"
- logger.warning("stt_engine not specified in profile, defaulting to '%s'", stt_engine_type)
+ self._logger.warning("stt_engine not specified in profile, defaulting to '%s'", stt_engine_type)
# Compile dictionary
sentences, dictionary, languagemodel = [os.path.abspath(os.path.join(jasperpath.LIB_PATH, filename)) for filename in ("sentences.txt", "dictionary.dic", "languagemodel.lm")]
@@ -77,6 +73,12 @@ if __name__ == "__main__":
print " Copyright 2013 Shubhro Saha & Charlie Marsh "
print "==========================================================="
+ logging.basicConfig()
+ logger = logging.getLogger()
+
+ if args.debug:
+ logger.setLevel(logging.DEBUG)
+
if not args.no_network_check and not Diagnostics.check_network_connection():
logger.warning("Network not connected. This may prevent Jasper from running properly.")