#521 - Skill auto reload
parent
e47e38c92c
commit
1b0afe92de
|
@ -17,13 +17,17 @@
|
|||
|
||||
|
||||
import json
|
||||
|
||||
import sys
|
||||
import time
|
||||
from threading import Timer
|
||||
|
||||
import os
|
||||
from os.path import expanduser, exists
|
||||
|
||||
from mycroft.configuration import ConfigurationManager
|
||||
from mycroft.messagebus.client.ws import WebsocketClient
|
||||
from mycroft.skills.core import load_skills, THIRD_PARTY_SKILLS_DIR
|
||||
from mycroft.skills.core import load_skills, THIRD_PARTY_SKILLS_DIR, \
|
||||
load_skill, create_skill_descriptor, MainModule
|
||||
from mycroft.util.log import getLogger
|
||||
|
||||
logger = getLogger("Skills")
|
||||
|
@ -31,26 +35,9 @@ logger = getLogger("Skills")
|
|||
__author__ = 'seanfitz'
|
||||
|
||||
ws = None
|
||||
skills = []
|
||||
|
||||
|
||||
def load_skills_callback():
|
||||
global ws
|
||||
global skills
|
||||
skills += load_skills(ws)
|
||||
config = ConfigurationManager.get().get("skills")
|
||||
|
||||
try:
|
||||
ini_third_party_skills_dir = expanduser(config.get("directory"))
|
||||
except AttributeError as e:
|
||||
logger.warning(e.message)
|
||||
|
||||
for loc in THIRD_PARTY_SKILLS_DIR:
|
||||
if exists(loc):
|
||||
skills += load_skills(ws, loc)
|
||||
|
||||
if ini_third_party_skills_dir and exists(ini_third_party_skills_dir):
|
||||
skills += load_skills(ws, ini_third_party_skills_dir)
|
||||
loaded_skills = {}
|
||||
last_modified_skill = 0
|
||||
skills_directories = []
|
||||
|
||||
|
||||
def connect():
|
||||
|
@ -58,6 +45,73 @@ def connect():
|
|||
ws.run_forever()
|
||||
|
||||
|
||||
def load_watch_skills():
|
||||
global ws, loaded_skills, last_modified_skill, skills_directories
|
||||
|
||||
skills_directories = [os.path.dirname(os.path.abspath(__file__))]
|
||||
skills_directories = skills_directories + THIRD_PARTY_SKILLS_DIR
|
||||
|
||||
try:
|
||||
config = ConfigurationManager.get().get("skills")
|
||||
ini_third_party_skills_dir = expanduser(config.get("directory"))
|
||||
if ini_third_party_skills_dir and exists(ini_third_party_skills_dir):
|
||||
skills_directories.append(ini_third_party_skills_dir)
|
||||
except AttributeError as e:
|
||||
logger.warning(e.message)
|
||||
|
||||
timer = Timer(0, load_skills)
|
||||
timer.daemon = True
|
||||
timer.start()
|
||||
|
||||
# last_modified_skill = max(skills.values())
|
||||
|
||||
|
||||
def clear_skill_events(instance):
|
||||
global ws
|
||||
events = ws.emitter._events
|
||||
instance_events = []
|
||||
for event in events:
|
||||
e = ws.emitter._events[event]
|
||||
if len(e) > 0 and e[0].func_closure and isinstance(
|
||||
e[0].func_closure[1].cell_contents, instance.__class__):
|
||||
instance_events.append(event)
|
||||
|
||||
for event in instance_events:
|
||||
del events[event]
|
||||
|
||||
|
||||
def load_skills():
|
||||
global ws, loaded_skills, last_modified_skill, skills_directories
|
||||
for dir in skills_directories:
|
||||
if exists(dir):
|
||||
list = filter(lambda x: os.path.isdir(os.path.join(dir, x)),
|
||||
os.listdir(dir))
|
||||
for skill_folder in list:
|
||||
if not loaded_skills.has_key(skill_folder):
|
||||
loaded_skills[skill_folder] = {}
|
||||
skill = loaded_skills[skill_folder]
|
||||
skill["path"] = os.path.join(dir, skill_folder)
|
||||
if not MainModule + ".py" in os.listdir(skill["path"]):
|
||||
continue
|
||||
skill["last_modified"] = max(
|
||||
os.path.getmtime(root) for root, _, _ in
|
||||
os.walk(skill["path"]))
|
||||
if skill.get("instance") and skill.get("last_modified",
|
||||
0) <= last_modified_skill:
|
||||
continue
|
||||
elif skill.get("instance") and skill.get("last_modified",
|
||||
0) > last_modified_skill:
|
||||
skill["instance"].shutdown()
|
||||
clear_skill_events(skill["instance"])
|
||||
del skill["instance"]
|
||||
skill["instance"] = load_skill(
|
||||
create_skill_descriptor(skill["path"]), ws)
|
||||
last_modified_skill = max(
|
||||
map(lambda x: x.get("last_modified"), loaded_skills.values()))
|
||||
time.sleep(2)
|
||||
load_skills()
|
||||
|
||||
|
||||
def main():
|
||||
global ws
|
||||
ws = WebsocketClient()
|
||||
|
@ -76,7 +130,7 @@ def main():
|
|||
logger.debug(message)
|
||||
|
||||
ws.on('message', echo)
|
||||
ws.once('open', load_skills_callback)
|
||||
ws.once('open', load_watch_skills)
|
||||
ws.run_forever()
|
||||
|
||||
|
||||
|
@ -84,7 +138,7 @@ if __name__ == "__main__":
|
|||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
for skill in skills:
|
||||
for skill in loaded_skills:
|
||||
skill.shutdown()
|
||||
finally:
|
||||
sys.exit()
|
||||
|
|
Loading…
Reference in New Issue