VK simplify dialog matching

This uses the existing dialog renderer and the standard format library
to in two steps create a regex where the {elements} in a dialog is
replaced with ".*" to match the given sentence.
pull/3068/head
Åke Forslund 2022-01-26 21:01:46 +01:00
parent a3fd830cb0
commit f8aa77c8e7
1 changed files with 24 additions and 16 deletions

View File

@ -19,10 +19,12 @@ use with behave.
from os.path import join, exists, basename from os.path import join, exists, basename
from pathlib import Path 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 mycroft.util.format import expand_options
@ -44,14 +46,13 @@ 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)
# Expand parentheses in lines
expanded_lines = [] expanded_lines = []
for line in lines: for template in renderer.templates:
expanded_lines += expand_options(line) # Expand parentheses in lines
for line in renderer.templates[template]:
expanded_lines += expand_options(line)
return [line.strip().lower() for line in expanded_lines return [line.strip().lower() for line in expanded_lines
if line.strip() != '' and line.strip()[0] != '#'] if line.strip() != '' and line.strip()[0] != '#']
@ -118,18 +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:
# Merge consequtive .*'s into a single .* data = {element[1]: '.*'
dialogs = [re.sub(r'\.\*( \.\*)+', r'.*', dia) for dia in dialogs] for element in Formatter().parse(dialog)}
# Remove double whitespaces regexes.append(dialog.format(**data))
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)