Merge pull request #2009 from MycroftAI/bugfix/voc-match
Fix behavior of MycroftSkills.voc_match()pull/2017/head
commit
faf29d1fef
|
@ -26,6 +26,7 @@ from datetime import datetime, timedelta
|
|||
|
||||
import abc
|
||||
import re
|
||||
from itertools import chain
|
||||
from adapt.intent import Intent, IntentBuilder
|
||||
from os.path import join, abspath, dirname, basename, exists
|
||||
from threading import Event, Timer
|
||||
|
@ -41,7 +42,8 @@ from mycroft.messagebus.message import Message
|
|||
from mycroft.metrics import report_metric, report_timing, Stopwatch
|
||||
from mycroft.skills.settings import SkillSettings
|
||||
from mycroft.skills.skill_data import (load_vocabulary, load_regex, to_alnum,
|
||||
munge_regex, munge_intent_parser)
|
||||
munge_regex, munge_intent_parser,
|
||||
read_vocab_file)
|
||||
from mycroft.util import camel_case_split, resolve_resource_file
|
||||
from mycroft.util.log import LOG
|
||||
|
||||
|
@ -716,15 +718,15 @@ class MycroftSkill:
|
|||
if not voc or not exists(voc):
|
||||
raise FileNotFoundError(
|
||||
'Could not find {}.voc file'.format(voc_filename))
|
||||
|
||||
with open(voc) as f:
|
||||
self.voc_match_cache[cache_key] = f.read().splitlines()
|
||||
|
||||
# Check for match
|
||||
if utt and any(i.strip() in utt
|
||||
for i in self.voc_match_cache[cache_key]):
|
||||
return True
|
||||
return False
|
||||
# load vocab and flatten into a simple list
|
||||
vocab = list(chain(*read_vocab_file(voc)))
|
||||
self.voc_match_cache[cache_key] = vocab
|
||||
if utt:
|
||||
# Check for matches against complete words
|
||||
return any([re.match(r'.*\b' + i + r'\b.*', utt)
|
||||
for i in self.voc_match_cache[cache_key]])
|
||||
else:
|
||||
return False
|
||||
|
||||
def report_metric(self, name, data):
|
||||
""" Report a skill metric to the Mycroft servers
|
||||
|
|
|
@ -25,6 +25,28 @@ from mycroft.messagebus.message import Message
|
|||
from mycroft.util.format import expand_options
|
||||
|
||||
|
||||
def read_vocab_file(path):
|
||||
""" Read voc file.
|
||||
|
||||
This reads a .voc file, stripping out empty lines comments and expand
|
||||
parentheses. It retruns each line as a list of all expanded
|
||||
alternatives.
|
||||
|
||||
Arguments:
|
||||
path (str): path to vocab file.
|
||||
|
||||
Returns:
|
||||
List of Lists of strings.
|
||||
"""
|
||||
vocab = []
|
||||
with open(path, 'r', encoding='utf8') as voc_file:
|
||||
for line in voc_file.readlines():
|
||||
if line.startswith('#') or line.strip() == '':
|
||||
continue
|
||||
vocab.append(expand_options(line))
|
||||
return vocab
|
||||
|
||||
|
||||
def load_vocab_from_file(path, vocab_type, bus):
|
||||
"""Load Mycroft vocabulary from file
|
||||
The vocab is sent to the intent handler using the message bus
|
||||
|
@ -36,19 +58,15 @@ def load_vocab_from_file(path, vocab_type, bus):
|
|||
skill_id(str): skill id
|
||||
"""
|
||||
if path.endswith('.voc'):
|
||||
with open(path, 'r', encoding='utf8') as voc_file:
|
||||
for line in voc_file.readlines():
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
parts = expand_options(line)
|
||||
entity = parts[0]
|
||||
for parts in read_vocab_file(path):
|
||||
entity = parts[0]
|
||||
bus.emit(Message("register_vocab", {
|
||||
'start': entity, 'end': vocab_type
|
||||
}))
|
||||
for alias in parts[1:]:
|
||||
bus.emit(Message("register_vocab", {
|
||||
'start': entity, 'end': vocab_type
|
||||
'start': alias, 'end': vocab_type, 'alias_of': entity
|
||||
}))
|
||||
for alias in parts[1:]:
|
||||
bus.emit(Message("register_vocab", {
|
||||
'start': alias, 'end': vocab_type, 'alias_of': entity
|
||||
}))
|
||||
|
||||
|
||||
def load_regex_from_file(path, bus, skill_id):
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
(turn off|switch off)
|
|
@ -0,0 +1,3 @@
|
|||
turn off
|
||||
switch off
|
||||
|
|
@ -484,6 +484,28 @@ class MycroftSkillTest(unittest.TestCase):
|
|||
# handler
|
||||
self.assertTrue('A:sched_handler1' not in [e[0] for e in s.events])
|
||||
|
||||
def test_voc_match(self):
|
||||
s = SimpleSkill1()
|
||||
s.root_dir = abspath(dirname(__file__))
|
||||
|
||||
self.assertTrue(s.voc_match("turn off the lights", "turn_off_test"))
|
||||
self.assertTrue(s.voc_match("would you please turn off the lights",
|
||||
"turn_off_test"))
|
||||
self.assertFalse(s.voc_match("return office", "turn_off_test"))
|
||||
self.assertTrue(s.voc_match("switch off the lights", "turn_off_test"))
|
||||
self.assertFalse(s.voc_match("", "turn_off_test"))
|
||||
self.assertFalse(s.voc_match("switch", "turn_off_test"))
|
||||
self.assertFalse(s.voc_match("My hovercraft is full of eels",
|
||||
"turn_off_test"))
|
||||
|
||||
self.assertTrue(s.voc_match("turn off the lights", "turn_off2_test"))
|
||||
self.assertFalse(s.voc_match("return office", "turn_off2_test"))
|
||||
self.assertTrue(s.voc_match("switch off the lights", "turn_off2_test"))
|
||||
self.assertFalse(s.voc_match("", "turn_off_test"))
|
||||
self.assertFalse(s.voc_match("switch", "turn_off_test"))
|
||||
self.assertFalse(s.voc_match("My hovercraft is full of eels",
|
||||
"turn_off_test"))
|
||||
|
||||
|
||||
class _TestSkill(MycroftSkill):
|
||||
def __init__(self):
|
||||
|
|
Loading…
Reference in New Issue