Merge pull request #3068 from forslund/bugfix/vk-dialogfile-from-sentence
Voight kampff: Bugfix dialogfile from sentencepull/3079/head
commit
99ac12cbf8
|
@ -17,14 +17,17 @@ Predefined step definitions for handling dialog interaction with Mycroft for
|
||||||
use with behave.
|
use with behave.
|
||||||
"""
|
"""
|
||||||
from os.path import join, exists, basename
|
from os.path import join, exists, basename
|
||||||
from glob import glob
|
from pathlib import Path
|
||||||
import re
|
import re
|
||||||
|
from string import Formatter
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from behave import given, when, then
|
from behave import given, when, then
|
||||||
|
|
||||||
|
from mycroft.dialog import MustacheDialogRenderer
|
||||||
from mycroft.messagebus import Message
|
from mycroft.messagebus import Message
|
||||||
from mycroft.audio import wait_while_speaking
|
from mycroft.audio import wait_while_speaking
|
||||||
|
from mycroft.util.format import expand_options
|
||||||
|
|
||||||
from test.integrationtests.voight_kampff import (mycroft_responses, then_wait,
|
from test.integrationtests.voight_kampff import (mycroft_responses, then_wait,
|
||||||
then_wait_fail)
|
then_wait_fail)
|
||||||
|
@ -43,10 +46,15 @@ def find_dialog(skill_path, dialog, lang):
|
||||||
|
|
||||||
def load_dialog_file(dialog_path):
|
def load_dialog_file(dialog_path):
|
||||||
"""Load dialog files and get the contents."""
|
"""Load dialog files and get the contents."""
|
||||||
with open(dialog_path) as f:
|
renderer = MustacheDialogRenderer()
|
||||||
lines = f.readlines()
|
renderer.load_template_file('template', dialog_path)
|
||||||
return [l.strip().lower() for l in lines
|
expanded_lines = []
|
||||||
if l.strip() != '' and l.strip()[0] != '#']
|
for template in renderer.templates:
|
||||||
|
# Expand parentheses in lines
|
||||||
|
for line in renderer.templates[template]:
|
||||||
|
expanded_lines += expand_options(line)
|
||||||
|
return [line.strip().lower() for line in expanded_lines
|
||||||
|
if line.strip() != '' and line.strip()[0] != '#']
|
||||||
|
|
||||||
|
|
||||||
def load_dialog_list(skill_path, dialog):
|
def load_dialog_list(skill_path, dialog):
|
||||||
|
@ -65,6 +73,26 @@ def load_dialog_list(skill_path, dialog):
|
||||||
return load_dialog_file(dialog_path), debug
|
return load_dialog_file(dialog_path), debug
|
||||||
|
|
||||||
|
|
||||||
|
def _get_dialog_files(skill_path, lang):
|
||||||
|
"""Generator expression returning all dialog files.
|
||||||
|
|
||||||
|
This includes both the 'locale' and the older style 'dialog' folder.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
skill_path (str): skill root folder
|
||||||
|
lang (str): language code to check
|
||||||
|
|
||||||
|
yields:
|
||||||
|
(Path) path of each found dialog file
|
||||||
|
"""
|
||||||
|
in_dialog_dir = Path(skill_path, 'dialog', lang).rglob('*.dialog')
|
||||||
|
for dialog_path in in_dialog_dir:
|
||||||
|
yield dialog_path
|
||||||
|
in_locale_dir = Path(skill_path, 'locale', lang).rglob('*.dialog')
|
||||||
|
for dialog_path in in_locale_dir:
|
||||||
|
yield dialog_path
|
||||||
|
|
||||||
|
|
||||||
def dialog_from_sentence(sentence, skill_path, lang):
|
def dialog_from_sentence(sentence, skill_path, lang):
|
||||||
"""Find dialog file from example sentence.
|
"""Find dialog file from example sentence.
|
||||||
|
|
||||||
|
@ -75,9 +103,8 @@ def dialog_from_sentence(sentence, skill_path, lang):
|
||||||
|
|
||||||
Returns (str): Dialog file best matching the sentence.
|
Returns (str): Dialog file best matching the sentence.
|
||||||
"""
|
"""
|
||||||
dialog_paths = join(skill_path, 'dialog', lang, '*.dialog')
|
|
||||||
best = (None, 0)
|
best = (None, 0)
|
||||||
for path in glob(dialog_paths):
|
for path in _get_dialog_files(skill_path, lang):
|
||||||
patterns = load_dialog_file(path)
|
patterns = load_dialog_file(path)
|
||||||
match, _ = _match_dialog_patterns(patterns, sentence.lower())
|
match, _ = _match_dialog_patterns(patterns, sentence.lower())
|
||||||
if match is not False:
|
if match is not False:
|
||||||
|
@ -92,19 +119,25 @@ def dialog_from_sentence(sentence, skill_path, lang):
|
||||||
def _match_dialog_patterns(dialogs, sentence):
|
def _match_dialog_patterns(dialogs, sentence):
|
||||||
"""Match sentence against a list of dialog patterns.
|
"""Match sentence against a list of dialog patterns.
|
||||||
|
|
||||||
Returns index of found match.
|
dialogs (list of str): dialog file entries to match against
|
||||||
|
sentence (str): string to match.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(tup) index of found match, debug text
|
||||||
"""
|
"""
|
||||||
# Allow custom fields to be anything
|
# Allow custom fields to be anything
|
||||||
dialogs = [re.sub(r'{.*?\}', r'.*', dia) for dia in dialogs]
|
# i.e {field} gets turned into ".*"
|
||||||
# Remove left over '}'
|
regexes = []
|
||||||
dialogs = [re.sub(r'\}', r'', dia) for dia in dialogs]
|
for dialog in dialogs:
|
||||||
dialogs = [re.sub(r' .* ', r' .*', dia) for dia in dialogs]
|
data = {element[1]: '.*'
|
||||||
# Merge consequtive .*'s into a single .*
|
for element in Formatter().parse(dialog)}
|
||||||
dialogs = [re.sub(r'\.\*( \.\*)+', r'.*', dia) for dia in dialogs]
|
regexes.append(dialog.format(**data))
|
||||||
# Remove double whitespaces
|
|
||||||
dialogs = ['^' + ' '.join(dia.split()) for dia in dialogs]
|
# Remove double whitespaces and ensure that it matches from
|
||||||
|
# the beginning of the line.
|
||||||
|
regexes = ['^' + ' '.join(reg.split()) for reg in regexes]
|
||||||
debug = 'MATCHING: {}\n'.format(sentence)
|
debug = 'MATCHING: {}\n'.format(sentence)
|
||||||
for index, regex in enumerate(dialogs):
|
for index, regex in enumerate(regexes):
|
||||||
match = re.match(regex, sentence)
|
match = re.match(regex, sentence)
|
||||||
debug += '---------------\n'
|
debug += '---------------\n'
|
||||||
debug += '{} {}\n'.format(regex, match is not None)
|
debug += '{} {}\n'.format(regex, match is not None)
|
||||||
|
|
Loading…
Reference in New Issue