OrderAnalyser.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. # if the order contains bracket, we get parameters said by the user
  35. params = None
  36. if self._is_containing_bracket(signal.sentence):
  37. params = self._associate_order_params_to_values(signal.sentence)
  38. logger.debug("Parameters for order: %s" % params)
  39. for neuron in synapse.neurons:
  40. if isinstance(neuron.parameters, dict):
  41. if "args" in neuron.parameters:
  42. print "the neuron wait for parameter"
  43. # check that the user added parameters to his order
  44. if params is None:
  45. # TODO: raise an error and break the program?
  46. Utils.print_danger("Error: The neuron %s is waiting for argument. "
  47. "Argument found in bracket in the given order" % neuron.name)
  48. else:
  49. # we add wanted arguments the existing neuron parameter dict
  50. for arg in neuron.parameters["args"]:
  51. if arg in params:
  52. logger.debug("Parameter %s added to the current parameter "
  53. "of the neuron: %s" % (arg, neuron.name))
  54. neuron.parameters[arg] = params[arg]
  55. else:
  56. # TODO: raise an error and break the program?
  57. Utils.print_danger("Error: Argument \"%s\" not found in the"
  58. " order" % arg)
  59. # neuron.parameters = dict(neuron.parameters.items() + params.items())
  60. print neuron.parameters
  61. NeuroneLauncher.start_neurone(neuron)
  62. if not synapses_found:
  63. Utils.print_info("No synapse match the captured order: %s" % self.order)
  64. def _spelt_order_match_brain_order(self, order_to_test):
  65. """
  66. test if the current order match the order spelt by the user
  67. :param order_to_test:
  68. :return:
  69. """
  70. # TODO : In "order_to_test" should we remove double brace and variable name before checking to optimise the cosine ?
  71. user_vector = text_to_vector(self.order)
  72. order_vector = text_to_vector(order_to_test)
  73. cosine = get_cosine(user_vector, order_vector)
  74. logger.debug("the cosine : %s, pour user_vector: %s , order_vector: %s" % (cosine, self.order, order_to_test))
  75. return cosine >= 0.9
  76. def _associate_order_params_to_values(self, order_to_check):
  77. """
  78. Associate the variables from the order to the incoming user order
  79. :param order: the order to check
  80. :return: the dict corresponding to the key / value of the params
  81. """
  82. # Remove white spaces (if any) between the variable and the double brace then split
  83. list_word_in_order = re.sub('\s+(?=[^\{\{\}\}]*\}\})', '', order_to_check).split()
  84. # get the order, defined by the first words before {{
  85. # /!\ Could be empty if order starts with double brace
  86. the_order = order_to_check[:order_to_check.find('{{')]
  87. # remove sentence before order which are sentences not matching anyway
  88. truncate_user_sentence = self.order[self.order.find(the_order):]
  89. truncate_list_word_said = truncate_user_sentence.split()
  90. # make dict var:value
  91. dictVar = {}
  92. for idx, ow in enumerate(list_word_in_order):
  93. if self._is_containing_bracket(ow):
  94. # remove bracket and grab the next value / stop value
  95. varname = ow.replace("{{", "").replace("}}", "")
  96. stopValue = self._get_next_value_list(list_word_in_order[idx:])
  97. if stopValue is None:
  98. dictVar[varname] = " ".join(truncate_list_word_said)
  99. break
  100. for word_said in truncate_list_word_said:
  101. if word_said == stopValue: break
  102. if varname in dictVar:
  103. dictVar[varname] += " " + word_said
  104. truncate_list_word_said = truncate_list_word_said[1:]
  105. else:
  106. dictVar[varname] = word_said
  107. truncate_list_word_said = truncate_list_word_said[1:]
  108. return dictVar
  109. @staticmethod
  110. def _is_containing_bracket(sentence):
  111. # print "sentence to test %s" % sentence
  112. pattern = r"{{|}}"
  113. # prog = re.compile(pattern)
  114. bool = re.search(pattern, sentence)
  115. if bool is not None:
  116. return True
  117. return False
  118. @staticmethod
  119. def _get_next_value_list(list):
  120. ite = list.__iter__()
  121. next(ite, None)
  122. return next(ite, None)