Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IBM Watson support #661

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions client/conversation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,90 @@
from notifier import Notifier
from brain import Brain

from subprocess import Popen, PIPE

def bounce():
scpt = '''
tell application "Logic Pro X" to activate
delay 1
tell application "System Events"
keystroke "b" using command down
delay 1
keystroke return
end tell
'''
args = []

p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
print (p.returncode, stdout, stderr)

def record():
scpt = '''
tell application "Logic Pro X" to activate
delay 1
tell application "System Events"
keystroke "r"
end tell
'''
args = []

p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
print (p.returncode, stdout, stderr)

def stop_req():
scpt = '''
tell application "Logic Pro X" to activate
delay 1
tell application "System Events"
key code 49
end tell
'''
args = []

p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
print (p.returncode, stdout, stderr)

def copy_track():
scpt = '''
tell application "Logic Pro X" to activate
delay 1
tell application "System Events"
keystroke "d" using command down
end tell
'''
args = []

p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
print (p.returncode, stdout, stderr)

def bring_begin():
scpt = '''
tell application "System Events"
keystroke return
end tell
'''
args = []

p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
print (p.returncode, stdout, stderr)

def confirm():
scpt = '''
tell application "System Events"
keystroke return
end tell
'''
args = []

p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
print (p.returncode, stdout, stderr)


class Conversation(object):

Expand All @@ -29,6 +113,28 @@ def handleForever(self):
self._logger.debug("Started listening for keyword '%s'",
self.persona)
threshold, transcribed = self.mic.passiveListen(self.persona)
found = (transcribed + [''])[0]
if 'AMOS' not in found: continue

if 'BOUNCE' in found or 'BALANCE' in found:
print("BOUNCEING...")
bounce()
if 'REC' in found or 'RECORD' in found or 'START' in found:
print("RECORDING...")
record()
if 'STOP' in found or 'END' in found:
print("STOPPING...")
stop_req()
if 'DUPLICATE' in found or 'COPY' in found:
print("COPYING...")
copy_track()
if 'FRONT' in found or 'BEGINING' in found or 'FRONT' in found:
print("BRINGING BEGIN...")
bring_begin()
if 'CONFIRM' in found or 'YES' in found or 'ENTER' in found or 'CONTINUE' in found:
print("CONFIRMING...")
confirm()

self._logger.debug("Stopped listening for keyword '%s'",
self.persona)

Expand Down
9 changes: 7 additions & 2 deletions client/diagnose.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import subprocess
import pkgutil
import logging
import pip.req
import jasperpath
if sys.version_info < (3, 3):
from distutils.spawn import find_executable
Expand Down Expand Up @@ -89,6 +88,12 @@ def check_python_import(package_or_module):
return found


def parse_requirements(filename):
""" load requirements from a pip requirements file """
lineiter = (line.strip() for line in open(filename))
return [line for line in lineiter if line and not line.startswith("#")]


def get_pip_requirements(fname=os.path.join(jasperpath.LIB_PATH,
'requirements.txt')):
"""
Expand All @@ -104,7 +109,7 @@ def get_pip_requirements(fname=os.path.join(jasperpath.LIB_PATH,
"""
logger = logging.getLogger(__name__)
if os.access(fname, os.R_OK):
reqs = list(pip.req.parse_requirements(fname))
reqs = list(parse_requirements(fname))
logger.debug("Found %d PIP requirements in file '%s'", len(reqs),
fname)
return reqs
Expand Down
112 changes: 112 additions & 0 deletions client/stt.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,118 @@ def is_available(cls):
return diagnose.check_network_connection()


class WatsonSTT(AbstractSTTEngine):
"""
Speech-To-Text implementation which relies on the Watson Speech to Text API.

This implementation requires a IBM Cloud user name and password to be present in
profile.yml. Please follow this tutuorial: https://console.bluemix.net/docs/services/speech-to-text/getting-started.html#gettingStarted
or select Text to Speach from https://console.bluemix.net/developer/watson/services .
This will present you with the following:
{
"speech_to_text": [
{
"name": "speech-to-text-jasper-ne-speech-to--123456789",
"plan": "lite",
"credentials": {
"url": "https://stream.watsonplatform.net/speech-to-text/api",
"username": "••••••••••••••••••••••••••••••••••••",
"password": "••••••••••••"
}
}
]
}
which you can past into your profile.yml:
...
stt_engine: watson
watson-stt:
user_name: 'b9981d71-99a9-1234-some-bPASSCODEd'
password: 'supasswordT6'
"""

SLUG = "watson"

def __init__(self, user_name, password):
self._logger = logging.getLogger(__name__)
self.user_name = user_name
self.password = password
self._headers = {'accept': 'application/json',
'Content-Type': 'audio/wav'}

@classmethod
def get_config(cls):
# FIXME: Replace this as soon as we have a config module
config = {}
profile_path = jasperpath.config('profile.yml')
if os.path.exists(profile_path):
with open(profile_path, 'r') as f:
profile = yaml.safe_load(f)
if 'watson-stt' in profile:
if 'user_name' in profile['watson-stt']:
config['user_name'] = profile['watson-stt']['user_name']
if 'password' in profile['watson-stt']:
config['password'] = profile['watson-stt']['password']
return config

@property
def user_name(self):
return self._user_name

@user_name.setter
def user_name(self, value):
self._user_name = value

@property
def password(self):
return self._password

@password.setter
def password(self, value):
self._password = value

@property
def headers(self):
return self._headers

def transcribe(self, fp):
data = fp.read()
r = requests.post('https://stream.watsonplatform.net/speech-to-text/api/v1/recognize',
data=data,
auth=(self.user_name, self.password),
headers=self.headers)
text=''
try:
r.raise_for_status()
for result in r.json()['results']:
for alt in result['alternatives']:
text += alt['transcript']
except requests.exceptions.HTTPError:
self._logger.critical('Request failed with response: %r',
r.text,
exc_info=True)
return []
except requests.exceptions.RequestException:
self._logger.critical('Request failed.', exc_info=True)
return []
except ValueError as e:
self._logger.critical('Cannot parse response: %s',
e.args[0])
return []
except KeyError:
self._logger.critical('Cannot parse response.',
exc_info=True)
return []
else:
transcribed = []
if text:
transcribed.append(text.upper())
self._logger.info('Transcribed: %r', transcribed)
return transcribed

@classmethod
def is_available(cls):
return diagnose.check_network_connection()

class WitAiSTT(AbstractSTTEngine):
"""
Speech-To-Text implementation which relies on the Wit.ai Speech API.
Expand Down
5 changes: 5 additions & 0 deletions run.command
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

echo "Hello"

# /usr/bin/python /Users/zoe/Developer/jasper-client/jasper.py
7 changes: 7 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo "hello"

cd /Users/zoe/Developer/jasper-client

/usr/bin/python /Users/zoe/Developer/jasper-client/jasper.py