Merge pull request #1454 from MycroftAI/bugfix/intent-mixups
Use function attributes for intent decoratorspull/1461/head
commit
2719f96950
|
@ -18,7 +18,6 @@ import sys
|
||||||
import time
|
import time
|
||||||
import csv
|
import csv
|
||||||
import inspect
|
import inspect
|
||||||
from functools import wraps
|
|
||||||
from inspect import getargspec
|
from inspect import getargspec
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
@ -126,7 +125,7 @@ def load_skill(skill_descriptor, emitter, skill_id, BLACKLISTED_SKILLS=None):
|
||||||
# The very first time a skill is run, speak the intro
|
# The very first time a skill is run, speak the intro
|
||||||
first_run = skill.settings.get("__mycroft_skill_firstrun", True)
|
first_run = skill.settings.get("__mycroft_skill_firstrun", True)
|
||||||
if first_run:
|
if first_run:
|
||||||
LOG.info("First run of "+skill_descriptor["name"])
|
LOG.info("First run of " + skill_descriptor["name"])
|
||||||
skill.settings["__mycroft_skill_firstrun"] = False
|
skill.settings["__mycroft_skill_firstrun"] = False
|
||||||
skill.settings.store()
|
skill.settings.store()
|
||||||
intro = skill.get_intro_message()
|
intro = skill.get_intro_message()
|
||||||
|
@ -166,21 +165,16 @@ def get_handler_name(handler):
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
# Lists used when adding skill handlers using decorators
|
|
||||||
_intent_list = []
|
|
||||||
_intent_file_list = []
|
|
||||||
|
|
||||||
|
|
||||||
def intent_handler(intent_parser):
|
def intent_handler(intent_parser):
|
||||||
""" Decorator for adding a method as an intent handler. """
|
""" Decorator for adding a method as an intent handler. """
|
||||||
|
|
||||||
def real_decorator(func):
|
def real_decorator(func):
|
||||||
@wraps(func)
|
# Store the intent_parser inside the function
|
||||||
def handler_method(*args, **kwargs):
|
# This will be used later to call register_intent
|
||||||
return func(*args, **kwargs)
|
if not hasattr(func, 'intents'):
|
||||||
|
func.intents = []
|
||||||
_intent_list.append((intent_parser, func))
|
func.intents.append(intent_parser)
|
||||||
return handler_method
|
return func
|
||||||
|
|
||||||
return real_decorator
|
return real_decorator
|
||||||
|
|
||||||
|
@ -189,12 +183,12 @@ def intent_file_handler(intent_file):
|
||||||
""" Decorator for adding a method as an intent file handler. """
|
""" Decorator for adding a method as an intent file handler. """
|
||||||
|
|
||||||
def real_decorator(func):
|
def real_decorator(func):
|
||||||
@wraps(func)
|
# Store the intent_file inside the function
|
||||||
def handler_method(*args, **kwargs):
|
# This will be used later to call register_intent_file
|
||||||
return func(*args, **kwargs)
|
if not hasattr(func, 'intent_files'):
|
||||||
|
func.intent_files = []
|
||||||
_intent_file_list.append((intent_file, func))
|
func.intent_files.append(intent_file)
|
||||||
return handler_method
|
return func
|
||||||
|
|
||||||
return real_decorator
|
return real_decorator
|
||||||
|
|
||||||
|
@ -455,14 +449,20 @@ class MycroftSkill(object):
|
||||||
def _register_decorated(self):
|
def _register_decorated(self):
|
||||||
"""
|
"""
|
||||||
Register all intent handlers that have been decorated with an intent.
|
Register all intent handlers that have been decorated with an intent.
|
||||||
|
|
||||||
|
Looks for all functions that have been marked by a decorator
|
||||||
|
and read the intent data from them
|
||||||
"""
|
"""
|
||||||
global _intent_list, _intent_file_list
|
for attr_name in dir(self):
|
||||||
for intent_parser, handler in _intent_list:
|
method = getattr(self, attr_name)
|
||||||
self.register_intent(intent_parser, handler, need_self=True)
|
|
||||||
for intent_file, handler in _intent_file_list:
|
if hasattr(method, 'intents'):
|
||||||
self.register_intent_file(intent_file, handler, need_self=True)
|
for intent in getattr(method, 'intents'):
|
||||||
_intent_list = []
|
self.register_intent(intent, method)
|
||||||
_intent_file_list = []
|
|
||||||
|
if hasattr(method, 'intent_files'):
|
||||||
|
for intent_file in getattr(method, 'intent_files'):
|
||||||
|
self.register_intent_file(intent_file, method)
|
||||||
|
|
||||||
def translate(self, text, data=None):
|
def translate(self, text, data=None):
|
||||||
"""
|
"""
|
||||||
|
@ -572,9 +572,8 @@ class MycroftSkill(object):
|
||||||
Args:
|
Args:
|
||||||
name: IntentParser name
|
name: IntentParser name
|
||||||
handler: method to call
|
handler: method to call
|
||||||
need_self: optional parameter, when called from a
|
need_self: optional parameter, pass if giving a local
|
||||||
decorated intent handler the function will
|
function or lambda (not defined in the class)
|
||||||
need the self variable passed as well.
|
|
||||||
once: optional parameter, Event handler will be
|
once: optional parameter, Event handler will be
|
||||||
removed after it has been run once.
|
removed after it has been run once.
|
||||||
handler_info: base message when reporting skill event handler
|
handler_info: base message when reporting skill event handler
|
||||||
|
@ -679,7 +678,7 @@ class MycroftSkill(object):
|
||||||
removed = True
|
removed = True
|
||||||
return removed
|
return removed
|
||||||
|
|
||||||
def register_intent(self, intent_parser, handler, need_self=False):
|
def register_intent(self, intent_parser, handler):
|
||||||
"""
|
"""
|
||||||
Register an Intent with the intent service.
|
Register an Intent with the intent service.
|
||||||
|
|
||||||
|
@ -687,9 +686,6 @@ class MycroftSkill(object):
|
||||||
intent_parser: Intent or IntentBuilder object to parse
|
intent_parser: Intent or IntentBuilder object to parse
|
||||||
utterance for the handler.
|
utterance for the handler.
|
||||||
handler: function to register with intent
|
handler: function to register with intent
|
||||||
need_self: optional parameter, when called from a decorated
|
|
||||||
intent handler the function will need the self
|
|
||||||
variable passed as well.
|
|
||||||
"""
|
"""
|
||||||
if type(intent_parser) == IntentBuilder:
|
if type(intent_parser) == IntentBuilder:
|
||||||
intent_parser = intent_parser.build()
|
intent_parser = intent_parser.build()
|
||||||
|
@ -701,10 +697,10 @@ class MycroftSkill(object):
|
||||||
munge_intent_parser(intent_parser, name, self.skill_id)
|
munge_intent_parser(intent_parser, name, self.skill_id)
|
||||||
self.emitter.emit(Message("register_intent", intent_parser.__dict__))
|
self.emitter.emit(Message("register_intent", intent_parser.__dict__))
|
||||||
self.registered_intents.append((name, intent_parser))
|
self.registered_intents.append((name, intent_parser))
|
||||||
self.add_event(intent_parser.name, handler, need_self,
|
self.add_event(intent_parser.name, handler, False,
|
||||||
'mycroft.skill.handler')
|
'mycroft.skill.handler')
|
||||||
|
|
||||||
def register_intent_file(self, intent_file, handler, need_self=False):
|
def register_intent_file(self, intent_file, handler):
|
||||||
"""
|
"""
|
||||||
Register an Intent file with the intent service.
|
Register an Intent file with the intent service.
|
||||||
For example:
|
For example:
|
||||||
|
@ -729,14 +725,13 @@ class MycroftSkill(object):
|
||||||
intent_file: name of file that contains example queries
|
intent_file: name of file that contains example queries
|
||||||
that should activate the intent
|
that should activate the intent
|
||||||
handler: function to register with intent
|
handler: function to register with intent
|
||||||
need_self: use for decorator. See <register_intent>
|
|
||||||
"""
|
"""
|
||||||
name = str(self.skill_id) + ':' + intent_file
|
name = str(self.skill_id) + ':' + intent_file
|
||||||
self.emitter.emit(Message("padatious:register_intent", {
|
self.emitter.emit(Message("padatious:register_intent", {
|
||||||
"file_name": join(self.vocab_dir, intent_file),
|
"file_name": join(self.vocab_dir, intent_file),
|
||||||
"name": name
|
"name": name
|
||||||
}))
|
}))
|
||||||
self.add_event(name, handler, need_self, 'mycroft.skill.handler')
|
self.add_event(name, handler, False, 'mycroft.skill.handler')
|
||||||
|
|
||||||
def register_entity_file(self, entity_file):
|
def register_entity_file(self, entity_file):
|
||||||
"""
|
"""
|
||||||
|
@ -1115,6 +1110,7 @@ class FallbackSkill(MycroftSkill):
|
||||||
ident = message.context['ident']
|
ident = message.context['ident']
|
||||||
report_timing(ident, 'fallback_handler', stopwatch,
|
report_timing(ident, 'fallback_handler', stopwatch,
|
||||||
{'handler': handler_name})
|
{'handler': handler_name})
|
||||||
|
|
||||||
return handler
|
return handler
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -1137,11 +1133,13 @@ class FallbackSkill(MycroftSkill):
|
||||||
register a fallback with the list of fallback handlers
|
register a fallback with the list of fallback handlers
|
||||||
and with the list of handlers registered by this instance
|
and with the list of handlers registered by this instance
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
if handler(*args, **kwargs):
|
if handler(*args, **kwargs):
|
||||||
self.make_active()
|
self.make_active()
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.instance_fallback_handlers.append(wrapper)
|
self.instance_fallback_handlers.append(wrapper)
|
||||||
self._register_fallback(handler, priority)
|
self._register_fallback(handler, priority)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue