Merge pull request #3068 from forslund/bugfix/vk-dialogfile-from-sentence

Voight kampff: Bugfix dialogfile from sentence
pull/3079/head
Kris Gesling 2022-02-23 16:44:33 +09:30 committed by GitHub
commit 99ac12cbf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 50 additions and 17 deletions

View File

@ -17,14 +17,17 @@ Predefined step definitions for handling dialog interaction with Mycroft for
use with behave.
"""
from os.path import join, exists, basename
from glob import glob
from pathlib import Path
import re
from string import Formatter
import time
from behave import given, when, then
from mycroft.dialog import MustacheDialogRenderer
from mycroft.messagebus import Message
from mycroft.audio import wait_while_speaking
from mycroft.util.format import expand_options
from test.integrationtests.voight_kampff import (mycroft_responses, then_wait,
then_wait_fail)
@ -43,10 +46,15 @@ def find_dialog(skill_path, dialog, lang):
def load_dialog_file(dialog_path):
"""Load dialog files and get the contents."""
with open(dialog_path) as f:
lines = f.readlines()
return [l.strip().lower() for l in lines
if l.strip() != '' and l.strip()[0] != '#']
renderer = MustacheDialogRenderer()
renderer.load_template_file('template', dialog_path)
expanded_lines = []
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):
@ -65,6 +73,26 @@ def load_dialog_list(skill_path, dialog):
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):
"""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.
"""
dialog_paths = join(skill_path, 'dialog', lang, '*.dialog')
best = (None, 0)
for path in glob(dialog_paths):
for path in _get_dialog_files(skill_path, lang):
patterns = load_dialog_file(path)
match, _ = _match_dialog_patterns(patterns, sentence.lower())
if match is not False:
@ -92,19 +119,25 @@ def dialog_from_sentence(sentence, skill_path, lang):
def _match_dialog_patterns(dialogs, sentence):
"""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
dialogs = [re.sub(r'{.*?\}', r'.*', dia) for dia in dialogs]
# Remove left over '}'
dialogs = [re.sub(r'\}', r'', dia) for dia in dialogs]
dialogs = [re.sub(r' .* ', r' .*', dia) for dia in dialogs]
# Merge consequtive .*'s into a single .*
dialogs = [re.sub(r'\.\*( \.\*)+', r'.*', dia) for dia in dialogs]
# Remove double whitespaces
dialogs = ['^' + ' '.join(dia.split()) for dia in dialogs]
# i.e {field} gets turned into ".*"
regexes = []
for dialog in dialogs:
data = {element[1]: '.*'
for element in Formatter().parse(dialog)}
regexes.append(dialog.format(**data))
# 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)
for index, regex in enumerate(dialogs):
for index, regex in enumerate(regexes):
match = re.match(regex, sentence)
debug += '---------------\n'
debug += '{} {}\n'.format(regex, match is not None)