|
@@ -1,12 +1,10 @@
|
|
# coding: utf8
|
|
# coding: utf8
|
|
-import re
|
|
|
|
import collections
|
|
import collections
|
|
from collections import Counter
|
|
from collections import Counter
|
|
|
|
|
|
from kalliope.core.Utils.Utils import Utils
|
|
from kalliope.core.Utils.Utils import Utils
|
|
from kalliope.core.ConfigurationManager import SettingLoader
|
|
from kalliope.core.ConfigurationManager import SettingLoader
|
|
from kalliope.core.Models import Order
|
|
from kalliope.core.Models import Order
|
|
-from kalliope.core.NeuronLauncher import NeuronLauncher
|
|
|
|
|
|
|
|
import logging
|
|
import logging
|
|
|
|
|
|
@@ -14,228 +12,48 @@ logging.basicConfig()
|
|
logger = logging.getLogger("kalliope")
|
|
logger = logging.getLogger("kalliope")
|
|
|
|
|
|
|
|
|
|
-class OrderAnalyser:
|
|
|
|
|
|
+class OrderAnalyser2:
|
|
"""
|
|
"""
|
|
- This Class is used to compare the incoming message to the Signal/Order sentences.
|
|
|
|
|
|
+ This Class is used to get a list of synapses that match a given Spoken order
|
|
"""
|
|
"""
|
|
|
|
|
|
- def __init__(self, order, brain=None):
|
|
|
|
- """
|
|
|
|
- Class used to load brain and run neuron attached to the received order
|
|
|
|
- :param order: spelt order
|
|
|
|
- :param brain: loaded brain
|
|
|
|
- """
|
|
|
|
- sl = SettingLoader()
|
|
|
|
- self.settings = sl.settings
|
|
|
|
- self.order = order
|
|
|
|
- if isinstance(self.order, str):
|
|
|
|
- self.order = order.decode('utf-8')
|
|
|
|
- self.brain = brain
|
|
|
|
- logger.debug("OrderAnalyser, Received order: %s" % self.order)
|
|
|
|
-
|
|
|
|
- def start(self, synapses_to_run=None, external_order=None):
|
|
|
|
- """
|
|
|
|
- This method matches the incoming messages to the signals/order sentences provided in the Brain.
|
|
|
|
-
|
|
|
|
- Note: we use named tuples:
|
|
|
|
- tuple_synapse_order = collections.namedtuple('tuple_synapse_matchingOrder',['synapse', 'order'])
|
|
|
|
- """
|
|
|
|
-
|
|
|
|
- synapse_order_tuple = collections.namedtuple('tuple_synapse_matchingOrder', ['synapse', 'order'])
|
|
|
|
- synapses_order_tuple_list = list()
|
|
|
|
-
|
|
|
|
- if synapses_to_run is not None and external_order is not None:
|
|
|
|
- for synapse in synapses_to_run:
|
|
|
|
- synapses_order_tuple_list.append(synapse_order_tuple(synapse=synapse,
|
|
|
|
- order=external_order))
|
|
|
|
-
|
|
|
|
- # if list of synapse is not provided, let's find one
|
|
|
|
- else: # synapses_to_run is None or external_order is None:
|
|
|
|
- # create a dict of synapses that have been launched
|
|
|
|
- logger.debug("[orderAnalyser.start]-> No Synapse provided, let's find one")
|
|
|
|
- synapses_order_tuple_list = self._find_synapse_to_run(brain=self.brain,
|
|
|
|
- settings=self.settings,
|
|
|
|
- order=self.order)
|
|
|
|
|
|
+ brain = None
|
|
|
|
+ settings = None
|
|
|
|
|
|
- # retrieve params
|
|
|
|
- synapses_launched = list()
|
|
|
|
- for tuple in synapses_order_tuple_list:
|
|
|
|
- logger.debug("[orderAnalyser.start]-> Grab the params")
|
|
|
|
- params = self._get_params_from_order(tuple.order, self.order)
|
|
|
|
-
|
|
|
|
- # Start a neuron list with params
|
|
|
|
- self._start_list_neurons(list_neurons=tuple.synapse.neurons,
|
|
|
|
- params=params,
|
|
|
|
- settings=self.settings)
|
|
|
|
- synapses_launched.append(tuple.synapse)
|
|
|
|
-
|
|
|
|
- # return the list of launched synapse
|
|
|
|
- return synapses_launched
|
|
|
|
|
|
+ @classmethod
|
|
|
|
+ def __init__(cls):
|
|
|
|
+ cls.settings = SettingLoader().settings
|
|
|
|
|
|
@classmethod
|
|
@classmethod
|
|
- def _find_synapse_to_run(cls, brain, settings, order):
|
|
|
|
|
|
+ def get_matching_synapse(cls, order, brain=None):
|
|
"""
|
|
"""
|
|
- Find the list of the synapse matching the order.
|
|
|
|
-
|
|
|
|
- Note: we use named tuples:
|
|
|
|
- tuple_synapse_order = collections.namedtuple('tuple_synapse_matchingOrder',['synapse', 'order'])
|
|
|
|
-
|
|
|
|
- :param brain: the brain
|
|
|
|
- :param settings: the settings
|
|
|
|
- :param order: the provided order to match
|
|
|
|
- :return: the list of synapses launched (named tuples)
|
|
|
|
|
|
+ Return the list of matching synapses from the given order
|
|
|
|
+ :param order: The user order
|
|
|
|
+ :param brain: The loaded brain
|
|
|
|
+ :return: The List of synapses matching the given order
|
|
"""
|
|
"""
|
|
|
|
+ cls.brain = brain
|
|
|
|
+ logger.debug("[OrderAnalyser] Received order: %s" % order)
|
|
|
|
+ if isinstance(order, str):
|
|
|
|
+ order = order.decode('utf-8')
|
|
|
|
|
|
- synapse_to_run = cls._get_matching_synapse_list(brain.synapses, order)
|
|
|
|
- if not synapse_to_run:
|
|
|
|
- Utils.print_info("No synapse match the captured order: %s" % order)
|
|
|
|
-
|
|
|
|
- if settings.default_synapse is not None:
|
|
|
|
- default_synapse = cls._get_default_synapse_from_sysnapses_list(brain.synapses,
|
|
|
|
- settings.default_synapse)
|
|
|
|
-
|
|
|
|
- if default_synapse is not None:
|
|
|
|
- logger.debug("Default synapse found %s" % default_synapse)
|
|
|
|
- Utils.print_info("Default synapse found: %s, running it" % default_synapse.name)
|
|
|
|
- tuple_synapse_order = collections.namedtuple('tuple_synapse_matchingOrder',
|
|
|
|
- ['synapse', 'order'])
|
|
|
|
- synapse_to_run.append(tuple_synapse_order(synapse=default_synapse,
|
|
|
|
- order=""))
|
|
|
|
-
|
|
|
|
- return synapse_to_run
|
|
|
|
|
|
+ # We use a namedtuple to associate the synapse and the signal of the synapse
|
|
|
|
+ synapse_order_tuple = collections.namedtuple('tuple_synapse_matchingOrder',
|
|
|
|
+ ['synapse', 'order'])
|
|
|
|
|
|
- @classmethod
|
|
|
|
- def _get_matching_synapse_list(cls, all_synapses_list, order_to_match):
|
|
|
|
- """
|
|
|
|
- Class method to return all the matching synapses with the order from the complete of synapses.
|
|
|
|
-
|
|
|
|
- Note: we use named tuples:
|
|
|
|
- tuple_synapse_matchingOrder = collections.namedtuple('tuple_synapse_matchingOrder',['synapse', 'order'])
|
|
|
|
|
|
+ list_match_synapse = list()
|
|
|
|
|
|
- :param all_synapses_list: the complete list of all synapses
|
|
|
|
- :param order_to_match: the order to match
|
|
|
|
- :type order_to_match: str
|
|
|
|
- :return: the list of matching synapses (named tuples)
|
|
|
|
- """
|
|
|
|
- tuple_synapse_order = collections.namedtuple('tuple_synapse_matchingOrder', ['synapse', 'order'])
|
|
|
|
- matching_synapses_list = list()
|
|
|
|
- for synapse in all_synapses_list:
|
|
|
|
|
|
+ # test each synapse from the brain
|
|
|
|
+ for synapse in cls.brain.synapses:
|
|
|
|
+ # we are only concerned by synapse with a order type of signal
|
|
for signal in synapse.signals:
|
|
for signal in synapse.signals:
|
|
if type(signal) == Order:
|
|
if type(signal) == Order:
|
|
- if cls.spelt_order_match_brain_order_via_table(signal.sentence, order_to_match):
|
|
|
|
- matching_synapses_list.append(tuple_synapse_order(synapse=synapse,
|
|
|
|
- order=signal.sentence))
|
|
|
|
- logger.debug("Order found! Run neurons: %s" % synapse.neurons)
|
|
|
|
|
|
+ if cls.spelt_order_match_brain_order_via_table(signal.sentence, order):
|
|
|
|
+ # the order match the synapse, we add it to the returned list
|
|
|
|
+ logger.debug("Order found! Run synapse name: %s" % synapse.name)
|
|
Utils.print_success("Order matched in the brain. Running synapse \"%s\"" % synapse.name)
|
|
Utils.print_success("Order matched in the brain. Running synapse \"%s\"" % synapse.name)
|
|
- return matching_synapses_list
|
|
|
|
-
|
|
|
|
- @classmethod
|
|
|
|
- def _get_params_from_order(cls, string_order, order_to_check):
|
|
|
|
- """
|
|
|
|
- Class method to get all params coming from a string order. Returns a dict of key/value.
|
|
|
|
-
|
|
|
|
- :param string_order: the string_order to check
|
|
|
|
- :param order_to_check: the order to match
|
|
|
|
- :type order_to_check: str
|
|
|
|
- :return: the dict key/value
|
|
|
|
- """
|
|
|
|
- params = dict()
|
|
|
|
- if Utils.is_containing_bracket(string_order):
|
|
|
|
- params = cls._associate_order_params_to_values(order_to_check, string_order)
|
|
|
|
- logger.debug("Parameters for order: %s" % params)
|
|
|
|
- return params
|
|
|
|
-
|
|
|
|
- @classmethod
|
|
|
|
- def _start_list_neurons(cls, list_neurons, params, settings):
|
|
|
|
- # start neurons
|
|
|
|
- for neuron in list_neurons:
|
|
|
|
- cls._start_neuron(neuron, params)
|
|
|
|
-
|
|
|
|
- @staticmethod
|
|
|
|
- def _start_neuron(neuron, params):
|
|
|
|
- """
|
|
|
|
- Associate params and Starts a neuron.
|
|
|
|
-
|
|
|
|
- :param neuron: the neuron to start
|
|
|
|
- :param params: the params to check and associate to the neuron args.
|
|
|
|
- """
|
|
|
|
-
|
|
|
|
- problem_in_neuron_found = False
|
|
|
|
- if isinstance(neuron.parameters, dict):
|
|
|
|
- # print neuron.parameters
|
|
|
|
- if "args" in neuron.parameters:
|
|
|
|
- logger.debug("The neuron waits for parameter")
|
|
|
|
- # check that the user added parameters to his order
|
|
|
|
- if params is None:
|
|
|
|
- # we don't raise an error and break the program but we don't run the neuron
|
|
|
|
- problem_in_neuron_found = True
|
|
|
|
- Utils.print_danger("Error: The neuron %s is waiting for argument. "
|
|
|
|
- "Argument found in bracket in the given order" % neuron.name)
|
|
|
|
- else:
|
|
|
|
- # we add wanted arguments the existing neuron parameter dict
|
|
|
|
- for arg in neuron.parameters["args"]:
|
|
|
|
- if arg in params:
|
|
|
|
- logger.debug("Parameter %s added to the current parameter "
|
|
|
|
- "of the neuron: %s" % (arg, neuron.name))
|
|
|
|
- neuron.parameters[arg] = params[arg]
|
|
|
|
- else:
|
|
|
|
- # we don't raise an error and break the program but
|
|
|
|
- # we don't run the neuron
|
|
|
|
- problem_in_neuron_found = True
|
|
|
|
- Utils.print_danger("Error: Argument \"%s\" not found in the"
|
|
|
|
- " order" % arg)
|
|
|
|
-
|
|
|
|
- # if no error detected, we run the neuron
|
|
|
|
- if not problem_in_neuron_found:
|
|
|
|
- NeuronLauncher.start_neuron(neuron)
|
|
|
|
- else:
|
|
|
|
- Utils.print_danger("A problem has been found in the Synapse.")
|
|
|
|
-
|
|
|
|
- @staticmethod
|
|
|
|
- def _associate_order_params_to_values(order, order_to_check):
|
|
|
|
- """
|
|
|
|
- Associate the variables from the order to the incoming user order
|
|
|
|
- :param order_to_check: the order to check incoming from the brain
|
|
|
|
- :type order_to_check: str
|
|
|
|
- :param order: the order from user
|
|
|
|
- :type order: str
|
|
|
|
- :return: the dict corresponding to the key / value of the params
|
|
|
|
- """
|
|
|
|
- logger.debug("[OrderAnalyser._associate_order_params_to_values] user order: %s, "
|
|
|
|
- "order to check: %s" % (order, order_to_check))
|
|
|
|
-
|
|
|
|
- list_word_in_order = Utils.remove_spaces_in_brackets(order_to_check).split()
|
|
|
|
-
|
|
|
|
- # get the order, defined by the first words before {{
|
|
|
|
- # /!\ Could be empty if order starts with double brace
|
|
|
|
- the_order = order_to_check[:order_to_check.find('{{')]
|
|
|
|
-
|
|
|
|
- # remove sentence before order which are sentences not matching anyway
|
|
|
|
- # Manage Upper/Lower case
|
|
|
|
- truncate_user_sentence = order[order.lower().find(the_order.lower()):]
|
|
|
|
- truncate_list_word_said = truncate_user_sentence.split()
|
|
|
|
-
|
|
|
|
- # make dict var:value
|
|
|
|
- dict_var = dict()
|
|
|
|
- for idx, ow in enumerate(list_word_in_order):
|
|
|
|
- if Utils.is_containing_bracket(ow):
|
|
|
|
- # remove bracket and grab the next value / stop value
|
|
|
|
- var_name = ow.replace("{{", "").replace("}}", "")
|
|
|
|
- stop_value = Utils.get_next_value_list(list_word_in_order[idx:])
|
|
|
|
- if stop_value is None:
|
|
|
|
- dict_var[var_name] = " ".join(truncate_list_word_said)
|
|
|
|
- break
|
|
|
|
- for word_said in truncate_list_word_said:
|
|
|
|
- if word_said == stop_value:
|
|
|
|
- break
|
|
|
|
- if var_name in dict_var:
|
|
|
|
- dict_var[var_name] += " " + word_said
|
|
|
|
- truncate_list_word_said = truncate_list_word_said[1:]
|
|
|
|
- else:
|
|
|
|
- dict_var[var_name] = word_said
|
|
|
|
- truncate_list_word_said = truncate_list_word_said[1:]
|
|
|
|
- return dict_var
|
|
|
|
-
|
|
|
|
|
|
+ list_match_synapse.append(synapse_order_tuple(synapse=synapse, order=signal.sentence))
|
|
|
|
+ return list_match_synapse
|
|
|
|
|
|
@classmethod
|
|
@classmethod
|
|
def spelt_order_match_brain_order_via_table(cls, order_to_analyse, user_said):
|
|
def spelt_order_match_brain_order_via_table(cls, order_to_analyse, user_said):
|
|
@@ -246,36 +64,20 @@ class OrderAnalyser:
|
|
:param user_said: String to compare to the order
|
|
:param user_said: String to compare to the order
|
|
:return: True if all string are present in the order
|
|
:return: True if all string are present in the order
|
|
"""
|
|
"""
|
|
- logger.debug("[spelt_order_match_brain_order_via_table] before formatting, "
|
|
|
|
- "order to analyse: %s, "
|
|
|
|
- "user sentence: %s"
|
|
|
|
- % (order_to_analyse, user_said))
|
|
|
|
- order_to_analyse, user_said = cls._format_sentences_to_analyse(order_to_analyse=order_to_analyse,
|
|
|
|
- user_said=user_said)
|
|
|
|
- list_word_user_said = user_said.split()
|
|
|
|
- split_order_without_bracket = cls._get_split_order_without_bracket(order_to_analyse)
|
|
|
|
-
|
|
|
|
- # if all words in the list of what the user said in in the list of word in the order
|
|
|
|
- return cls._counter_subset(split_order_without_bracket, list_word_user_said)
|
|
|
|
-
|
|
|
|
- @staticmethod
|
|
|
|
- def _format_sentences_to_analyse(order_to_analyse, user_said):
|
|
|
|
- """
|
|
|
|
- return formatted tuple of the order_to_analyse, user_said
|
|
|
|
- :param order_to_analyse: String order to test
|
|
|
|
- :param user_said: String to compare to the order
|
|
|
|
- :return: tuple of the order_to_analyse, user_said
|
|
|
|
- """
|
|
|
|
# Lowercase all incoming
|
|
# Lowercase all incoming
|
|
order_to_analyse = order_to_analyse.lower()
|
|
order_to_analyse = order_to_analyse.lower()
|
|
user_said = user_said.lower()
|
|
user_said = user_said.lower()
|
|
|
|
|
|
- logger.debug("[_format_sentences_to_analyse] formatted, "
|
|
|
|
|
|
+ logger.debug("[spelt_order_match_brain_order_via_table] "
|
|
"order to analyse: %s, "
|
|
"order to analyse: %s, "
|
|
"user sentence: %s"
|
|
"user sentence: %s"
|
|
% (order_to_analyse, user_said))
|
|
% (order_to_analyse, user_said))
|
|
|
|
|
|
- return order_to_analyse, user_said
|
|
|
|
|
|
+ list_word_user_said = user_said.split()
|
|
|
|
+ split_order_without_bracket = cls._get_split_order_without_bracket(order_to_analyse)
|
|
|
|
+
|
|
|
|
+ # if all words in the list of what the user said in in the list of word in the order
|
|
|
|
+ return cls._counter_subset(split_order_without_bracket, list_word_user_said)
|
|
|
|
|
|
@staticmethod
|
|
@staticmethod
|
|
def _get_split_order_without_bracket(order):
|
|
def _get_split_order_without_bracket(order):
|
|
@@ -306,23 +108,3 @@ class OrderAnalyser:
|
|
if n > c2[k]:
|
|
if n > c2[k]:
|
|
return False
|
|
return False
|
|
return True
|
|
return True
|
|
-
|
|
|
|
- @staticmethod
|
|
|
|
- def _get_default_synapse_from_sysnapses_list(all_synapses_list, default_synapse_name):
|
|
|
|
- """
|
|
|
|
- Static method to get the default synapse if it exists.
|
|
|
|
-
|
|
|
|
- :param all_synapses_list: the complete list of all synapses
|
|
|
|
- :param default_synapse_name: the synapse to find
|
|
|
|
- :return: the Synapse
|
|
|
|
- """
|
|
|
|
- default_synapse = None
|
|
|
|
- for synapse in all_synapses_list:
|
|
|
|
- if synapse.name == default_synapse_name:
|
|
|
|
- logger.debug("Default synapse found: %s" % synapse.name)
|
|
|
|
- default_synapse = synapse
|
|
|
|
- break
|
|
|
|
- if default_synapse is None:
|
|
|
|
- logger.debug("Default synapse not found")
|
|
|
|
- Utils.print_warning("Default synapse not found")
|
|
|
|
- return default_synapse
|
|
|