commit
2d3846fd42
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
sudo pacman -S \
|
||||
sudo pacman -S --needed \
|
||||
git \
|
||||
python2 \
|
||||
python2-pip \
|
||||
|
|
|
@ -27,6 +27,7 @@ setup(
|
|||
'mycroft-audio-test=mycroft.util.audio_test:main',
|
||||
'mycroft-enclosure-client=mycroft.client.enclosure.main:main',
|
||||
'mycroft-wifi-setup-client=mycroft.client.wifisetup.main:main',
|
||||
'mycroft-skill-container=mycroft.skills.container:main',
|
||||
'mycroft-cli-client=mycroft.client.text.main:main'
|
||||
]
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class Api(object):
|
|||
query = self.build_query(params)
|
||||
url = self.build_url(params)
|
||||
response = requests.request(method, url, headers=headers, params=query,
|
||||
data=data, json=json)
|
||||
data=data, json=json, timeout=(3.05, 15))
|
||||
return self.get_response(response)
|
||||
|
||||
def request(self, params):
|
||||
|
|
|
@ -80,10 +80,22 @@ def handle_multi_utterance_intent_failure(event):
|
|||
|
||||
def handle_speak(event):
|
||||
utterance = event.data['utterance']
|
||||
chunks = re.split(r'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s', utterance)
|
||||
for chunk in chunks:
|
||||
mute_and_speak(chunk)
|
||||
|
||||
|
||||
# This is a bit of a hack for Picroft. The analog audio on a Pi blocks
|
||||
# for 30 seconds fairly often, so we don't want to break on periods
|
||||
# (decreasing the chance of encountering the block). But we will
|
||||
# keep the split for non-Picroft installs since it give user feedback
|
||||
# faster on longer phrases.
|
||||
#
|
||||
# TODO: Remove or make an option? This is really a hack, anyway,
|
||||
# so we likely will want to get rid of this when not running on Mimic
|
||||
if not config.get('enclosure', {}).get('platform') == "picroft":
|
||||
chunks = re.split(r'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s',
|
||||
utterance)
|
||||
for chunk in chunks:
|
||||
mute_and_speak(chunk)
|
||||
else:
|
||||
mute_and_speak(utterance)
|
||||
|
||||
def handle_sleep(event):
|
||||
loop.sleep()
|
||||
|
|
|
@ -374,7 +374,7 @@ class WiFi:
|
|||
if "(incomplete)" in o:
|
||||
# ping the IP to get the ARP table entry reloaded
|
||||
ip_disconnected = o.split(" ")[0]
|
||||
cli_no_output('/bin/ping', '-c', '1', '-W', 3,
|
||||
cli_no_output('/bin/ping', '-c', '1', '-W', '3',
|
||||
ip_disconnected)
|
||||
else:
|
||||
return True # something on subnet is connected!
|
||||
|
@ -520,7 +520,7 @@ def main():
|
|||
try:
|
||||
wifi.run()
|
||||
except Exception as e:
|
||||
print (e)
|
||||
print(e)
|
||||
finally:
|
||||
sys.exit()
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ class ConfigurationSkill(ScheduledSkill):
|
|||
self.update()
|
||||
except HTTPError as e:
|
||||
if e.response.status_code == 401:
|
||||
self.log.warn("Impossible to update configuration because device isn't paired")
|
||||
self.log.warn("Impossible to update configuration because "
|
||||
"device isn't paired")
|
||||
self.schedule()
|
||||
|
||||
def update(self):
|
||||
|
|
|
@ -37,7 +37,9 @@ __author__ = 'seanfitz'
|
|||
PRIMARY_SKILLS = ['intent', 'wake']
|
||||
BLACKLISTED_SKILLS = ["send_sms", "media"]
|
||||
SKILLS_BASEDIR = dirname(__file__)
|
||||
THIRD_PARTY_SKILLS_DIR = "/opt/mycroft/skills"
|
||||
THIRD_PARTY_SKILLS_DIR = ["/opt/mycroft/third_party", "/opt/mycroft/skills"]
|
||||
# Note: /opt/mycroft/skills is recommended, /opt/mycroft/third_party
|
||||
# is for backwards compatibility
|
||||
|
||||
MainModule = '__init__'
|
||||
|
||||
|
@ -117,6 +119,14 @@ def get_skills(skills_folder):
|
|||
possible_skills = os.listdir(skills_folder)
|
||||
for i in possible_skills:
|
||||
location = join(skills_folder, i)
|
||||
if (isdir(location) and
|
||||
not MainModule + ".py" in os.listdir(location)):
|
||||
for j in os.listdir(location):
|
||||
name = join(location, j)
|
||||
if (not isdir(name) or
|
||||
not MainModule + ".py" in os.listdir(name)):
|
||||
continue
|
||||
skills.append(create_skill_descriptor(name))
|
||||
if (not isdir(location) or
|
||||
not MainModule + ".py" in os.listdir(location)):
|
||||
continue
|
||||
|
@ -132,15 +142,22 @@ def create_skill_descriptor(skill_folder):
|
|||
|
||||
|
||||
def load_skills(emitter, skills_root=SKILLS_BASEDIR):
|
||||
skill_list = []
|
||||
skills = get_skills(skills_root)
|
||||
for skill in skills:
|
||||
if skill['name'] in PRIMARY_SKILLS:
|
||||
load_skill(skill, emitter)
|
||||
skill_list.append(load_skill(skill, emitter))
|
||||
|
||||
for skill in skills:
|
||||
if (skill['name'] not in PRIMARY_SKILLS and
|
||||
skill['name'] not in BLACKLISTED_SKILLS):
|
||||
load_skill(skill, emitter)
|
||||
skill['name'] not in BLACKLISTED_SKILLS):
|
||||
skill_list.append(load_skill(skill, emitter))
|
||||
return skill_list
|
||||
|
||||
|
||||
def unload_skills(skills):
|
||||
for s in skills:
|
||||
s.cleanup()
|
||||
|
||||
|
||||
class MycroftSkill(object):
|
||||
|
@ -252,3 +269,7 @@ class MycroftSkill(object):
|
|||
def is_stop(self):
|
||||
passed_time = time.time() - self.stop_time
|
||||
return passed_time < self.stop_threshold
|
||||
|
||||
def cleanup(self):
|
||||
""" Clean up running threads, etc. """
|
||||
pass
|
||||
|
|
|
@ -41,8 +41,9 @@ def load_skills_callback():
|
|||
except AttributeError as e:
|
||||
logger.warning(e.message)
|
||||
|
||||
if exists(THIRD_PARTY_SKILLS_DIR):
|
||||
load_skills(ws, THIRD_PARTY_SKILLS_DIR)
|
||||
for loc in THIRD_PARTY_SKILLS_DIR:
|
||||
if exists(loc):
|
||||
load_skills(client, loc)
|
||||
|
||||
if ini_third_party_skills_dir and exists(ini_third_party_skills_dir):
|
||||
load_skills(ws, ini_third_party_skills_dir)
|
||||
|
|
|
@ -85,7 +85,9 @@ class PairingSkill(MycroftSkill):
|
|||
return device is not None
|
||||
|
||||
def speak_code(self):
|
||||
data = {"code": '. '.join(self.data.get("code"))}
|
||||
code = self.data.get("code")
|
||||
self.log.info("Pairing code: " + code)
|
||||
data = {"code": '. '.join(code).replace("0", "zero")}
|
||||
self.speak_dialog("pairing.code", data)
|
||||
|
||||
def stop(self):
|
||||
|
|
|
@ -113,6 +113,11 @@ class ScheduledSkill(MycroftSkill):
|
|||
def notify(self, timestamp):
|
||||
pass
|
||||
|
||||
def cleanup(self):
|
||||
""" Cancel timer making the skill ready for shutdown """
|
||||
if self.timer:
|
||||
self.timer.cancel()
|
||||
|
||||
|
||||
class ScheduledCRUDSkill(ScheduledSkill):
|
||||
"""
|
||||
|
|
|
@ -179,7 +179,7 @@ class WolframAlphaSkill(MycroftSkill):
|
|||
if len(others) > 0:
|
||||
self.speak_dialog('others.found',
|
||||
data={'utterance': utterance, 'alternative':
|
||||
others[0]})
|
||||
others[0]})
|
||||
else:
|
||||
self.speak_dialog("not.understood", data={'phrase': phrase})
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class TTS(object):
|
|||
|
||||
def __init__(self, lang, voice, validator):
|
||||
super(TTS, self).__init__()
|
||||
self.lang = lang
|
||||
self.lang = lang or 'en-us'
|
||||
self.voice = voice
|
||||
self.filename = '/tmp/tts.wav'
|
||||
self.validator = validator
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
from gtts import gTTS
|
||||
|
||||
from mycroft.tts import TTS, TTSValidator
|
||||
from mycroft.util import play_wav
|
||||
from mycroft.util import play_mp3
|
||||
|
||||
__author__ = 'jdorleans'
|
||||
|
||||
|
@ -31,7 +31,8 @@ class GoogleTTS(TTS):
|
|||
def execute(self, sentence):
|
||||
tts = gTTS(sentence, self.lang)
|
||||
tts.save(self.filename)
|
||||
play_wav(self.filename).communicate()
|
||||
p = play_mp3(self.filename)
|
||||
p.communicate() # Wait for termination
|
||||
|
||||
|
||||
class GoogleTTSValidator(TTSValidator):
|
||||
|
|
|
@ -22,6 +22,16 @@ from mycroft.util.log import getLogger
|
|||
|
||||
__author__ = 'augustnmonteiro'
|
||||
|
||||
# The following lines are replaced during the release process.
|
||||
# START_VERSION_BLOCK
|
||||
CORE_VERSION_MAJOR = 0
|
||||
CORE_VERSION_MINOR = 8
|
||||
CORE_VERSION_BUILD = 1
|
||||
# END_VERSION_BLOCK
|
||||
|
||||
CORE_VERSION_STR = (str(CORE_VERSION_MAJOR) + "." +
|
||||
str(CORE_VERSION_MINOR) + "." +
|
||||
str(CORE_VERSION_BUILD))
|
||||
LOG = getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -30,10 +40,12 @@ class VersionManager(object):
|
|||
|
||||
@staticmethod
|
||||
def get():
|
||||
if exists(VersionManager.__location) and isfile(VersionManager.__location):
|
||||
if (exists(VersionManager.__location) and
|
||||
isfile(VersionManager.__location)):
|
||||
try:
|
||||
with open(VersionManager.__location) as f:
|
||||
return json.load(f)
|
||||
except:
|
||||
LOG.error("Failed to load version from '%s'" % VersionManager.__location)
|
||||
LOG.error("Failed to load version from '%s'"
|
||||
% VersionManager.__location)
|
||||
return {"coreVersion": None, "enclosureVersion": None}
|
||||
|
|
|
@ -2,11 +2,12 @@ shortuuid==0.4.3
|
|||
pystache==0.5.4
|
||||
configobj==5.0.6
|
||||
wikipedia==1.4.0
|
||||
requests==2.8.1
|
||||
requests==2.12.5
|
||||
pyOpenSSL==16.0.0
|
||||
ndg-httpsclient==0.4.0
|
||||
pyasn1==0.1.9
|
||||
gTTS==1.0.7
|
||||
gTTS==1.1.7
|
||||
gTTS-token==1.1.1
|
||||
backports.ssl-match-hostname==3.4.0.2
|
||||
certifi==2016.2.28
|
||||
PyAudio==0.2.8
|
||||
|
@ -38,4 +39,4 @@ wifi==0.3.8
|
|||
pyroute2==0.4.5
|
||||
urllib5==5.0.0
|
||||
pyric==0.1.6
|
||||
inflection==0.3.1
|
||||
inflection==0.3.1
|
||||
|
|
|
@ -50,8 +50,13 @@ class IntentTestSequence(unittest.TestCase):
|
|||
__metaclass__ = IntentTestSequenceMeta
|
||||
|
||||
def setUp(self):
|
||||
self.emitter = MockSkillsLoader(
|
||||
os.path.join(PROJECT_ROOT, 'mycroft', 'skills')).load_skills()
|
||||
self.loader = MockSkillsLoader(
|
||||
os.path.join(PROJECT_ROOT, 'mycroft', 'skills'))
|
||||
self.emitter = self.loader.load_skills()
|
||||
|
||||
def tearDown(self):
|
||||
self.loader.unload_skills()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -3,7 +3,7 @@ import json
|
|||
from pyee import EventEmitter
|
||||
|
||||
from mycroft.messagebus.message import Message
|
||||
from mycroft.skills.core import load_skills
|
||||
from mycroft.skills.core import load_skills, unload_skills
|
||||
|
||||
__author__ = 'seanfitz'
|
||||
|
||||
|
@ -31,9 +31,12 @@ class MockSkillsLoader(object):
|
|||
self.emitter = RegistrationOnlyEmitter()
|
||||
|
||||
def load_skills(self):
|
||||
load_skills(self.emitter, self.skills_root)
|
||||
self.skills = load_skills(self.emitter, self.skills_root)
|
||||
return self.emitter.emitter # kick out the underlying emitter
|
||||
|
||||
def unload_skills(self):
|
||||
unload_skills(self.skills)
|
||||
|
||||
|
||||
class SkillTest(object):
|
||||
def __init__(self, skill, example, emitter):
|
||||
|
|
Loading…
Reference in New Issue