OrderAnalyser.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import re
  2. from core.Utils import Utils
  3. from core.ConfigurationManager.BrainLoader import BrainLoader
  4. from core.Models import Order
  5. from core.NeuroneLauncher import NeuroneLauncher
  6. from Cosine import *
  7. import logging
  8. logging.basicConfig()
  9. logger = logging.getLogger("jarvis")
  10. class OrderAnalyser:
  11. def __init__(self, order, main_controller=None, brain_file=None):
  12. """
  13. Class used to load brain and run neuron attached to the received order
  14. :param order: spelt order
  15. :param main_controller
  16. :param brain_file: To override the default brain.yml file
  17. """
  18. self.main_controller = main_controller
  19. self.order = order
  20. if brain_file is None:
  21. self.brain = BrainLoader.get_brain()
  22. else:
  23. self.brain = BrainLoader.get_brain(file_path=brain_file)
  24. logger.debug("Receiver order: %s" % self.order)
  25. def start(self):
  26. synapses_found = False
  27. for synapse in self.brain.synapses:
  28. for signal in synapse.signals:
  29. if type(signal) == Order:
  30. if self._spelt_order_match_brain_order(signal.sentence):
  31. synapses_found = True
  32. logger.debug("Order found! Run neurons: %s" % synapse.neurons)
  33. Utils.print_success("Order matched in the brain. Running synapse \"%s\"" % synapse.name)
  34. params = {}
  35. if self._is_containing_bracket(signal.sentence):
  36. params = self._associate_order_params_to_values(signal.sentence)
  37. for neuron in synapse.neurons:
  38. NeuroneLauncher.start_neurone(neuron, params)
  39. if not synapses_found:
  40. Utils.print_info("No synapse match the captured order: %s" % self.order)
  41. def _spelt_order_match_brain_order(self, order_to_test):
  42. """
  43. test if the current order match the order spelt by the user
  44. :param order_to_test:
  45. :return:
  46. """
  47. # TODO : In "order_to_test" should we remove double brace and variable name before checking to optimise the cosine ?
  48. user_vector = text_to_vector(self.order)
  49. order_vector = text_to_vector(order_to_test)
  50. cosine = get_cosine(user_vector, order_vector)
  51. logger.debug("the cosine : %s, pour user_vector: %s , order_vector: %s" % (cosine, self.order, order_to_test))
  52. return cosine >= 0.5
  53. def _associate_order_params_to_values(self, order_to_check):
  54. """
  55. Associate the variables from the order to the incoming user order
  56. :param order: the order to check
  57. :return: the dict corresponding to the key / value of the params
  58. """
  59. # Remove white spaces (if any) between the variable and the double brace then split
  60. list_word_in_order = re.sub('\s+(?=[^\{\{\}\}]*\}\})', '', order_to_check).split()
  61. # get the order, defined by the first words before {{
  62. # /!\ Could be empty if order starts with double brace
  63. the_order = order_to_check[:order_to_check.find('{{')]
  64. # remove sentence before order which are sentences not matching anyway
  65. truncate_user_sentence = self.order[self.order.find(the_order):]
  66. truncate_list_word_said = truncate_user_sentence.split()
  67. # make dict var:value
  68. dictVar = {}
  69. for idx, ow in enumerate(list_word_in_order):
  70. if self._is_containing_bracket(ow):
  71. # remove bracket and grab the next value / stop value
  72. varname = ow.replace("{{", "").replace("}}", "")
  73. stopValue = self._get_next_value_list(list_word_in_order[idx:])
  74. if stopValue is None:
  75. dictVar[varname] = " ".join(truncate_list_word_said)
  76. break
  77. for word_said in truncate_list_word_said:
  78. if word_said == stopValue: break
  79. if varname in dictVar:
  80. dictVar[varname] += " " + word_said
  81. truncate_list_word_said = truncate_list_word_said[1:]
  82. else:
  83. dictVar[varname] = word_said
  84. truncate_list_word_said = truncate_list_word_said[1:]
  85. return dictVar
  86. @staticmethod
  87. def _is_containing_bracket(sentence):
  88. # print "sentence to test %s" % sentence
  89. pattern = r"{{|}}"
  90. # prog = re.compile(pattern)
  91. bool = re.search(pattern, sentence)
  92. if bool is not None:
  93. return True
  94. return False
  95. @staticmethod
  96. def _get_next_value_list(list):
  97. ite = list.__iter__()
  98. next(ite, None)
  99. return next(ite, None)