def resolve_element_evals(self, client_context, element): new_element = ET.Element(element.tag) new_element.text = TextUtils.strip_whitespace(element.text) for child in element: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'eval': eval_str = ET.tostring(child, 'utf-8').decode('ascii') eval_str = TextUtils.strip_whitespace(eval_str) str_val = "<template>%s</template>" % eval_str template = ET.fromstring(str_val) ast = client_context.brain.aiml_parser.template_parser.parse_template_expression( template) resolved = ast.resolve(client_context) new_element.text += " " + resolved else: new_element.append(child) new_element.text = new_element.text.upper() if element.tail is not None: new_element.tail = TextUtils.strip_whitespace(element.tail) return new_element
def test_get_tabs(self): tabs = TextUtils.get_tabs(0) self.assertEqual(tabs, "") tabs = TextUtils.get_tabs(1, tabs="\t") self.assertEqual(tabs, "\t") tabs = TextUtils.get_tabs(5, tabs="\t") self.assertEqual(tabs, "\t\t\t\t\t")
def test_strip_all_whitespace(self): self.assertEquals("", TextUtils.strip_all_whitespace("")) self.assertEquals("", TextUtils.strip_all_whitespace(" ")) self.assertEquals("", TextUtils.strip_all_whitespace("\t")) self.assertEquals("", TextUtils.strip_all_whitespace("\n")) self.assertEquals("", TextUtils.strip_all_whitespace("\r")) self.assertEquals("", TextUtils.strip_all_whitespace("\r\t\n")) self.assertEquals("test", TextUtils.strip_all_whitespace("\r\t\ntest\r\t\n")) self.assertEquals("testtest", TextUtils.strip_all_whitespace("\r\t\ntest test\r\t\n")) self.assertEquals("testtest", TextUtils.strip_all_whitespace("\r\t\ntest\n\r\ttest\r\t\n"))
def node_from_element(self, element, userid="*"): node_name = TextUtils.tag_from_text(element.tag) if self._pattern_factory.exists(node_name) is False: raise ParserException("Unknown node name [%s]"%node_name) text = None if element.text is not None: text = TextUtils.strip_whitespace(element.text) node_class_instance = self._pattern_factory.new_node_class(node_name) node_instance = node_class_instance(element.attrib, text, userid) return node_instance
def add_that_to_node(self, that_element, base_node, userid="*"): try: current_node = self._pattern_factory.new_node_class('that')(userid) current_node = base_node.add_that(current_node) head_text = self.get_text_from_element(that_element) if head_text is not None: current_node = self._parse_text(TextUtils.strip_whitespace(head_text), current_node) added_child = False for sub_element in that_element: new_node = self.node_from_element(sub_element) current_node = current_node.add_child(new_node) tail_text = self.get_tail_from_element(sub_element) if tail_text is not None: current_node = self._parse_text(tail_text, current_node) added_child = True if head_text is None: if added_child is False: raise ParserException("That node text is empty", xml_element=that_element) return current_node except ParserException as parser_excep: parser_excep.xml_element = that_element raise parser_excep
def parse_expression(self, graph, expression): if 'text' in expression.attrib: self._text = graph.get_word_node(expression.attrib['text']) if 'url' in expression.attrib: self._url = graph.get_word_node(expression.attrib['url']) if 'postback' in expression.attrib: self._postback = graph.get_word_node(expression.attrib['postback']) head_text = self.get_text_from_element(expression) self.parse_text(graph, head_text) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'text': self._text = self.parse_children_as_word_node(graph, child) elif tag_name == 'url': self._url = self.parse_children_as_word_node(graph, child) elif tag_name == 'postback': self._postback = self.parse_children_as_word_node(graph, child) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text)
def parse_type3_condition(self, graph, expression): for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name in ['name', 'var', 'bot']: pass elif tag_name == 'li': list_item = TemplateConditionListItemNode() name, var_type = self.get_condition_name(child) list_item._name = name list_item._var_type = var_type list_item._value = self.get_condition_value(graph, child) self.children.append(list_item) list_item.parse_text(graph, self.get_text_from_element(child)) for sub_pattern in child: if sub_pattern.tag in ['name', 'var', 'bot', 'value']: pass elif sub_pattern.tag == 'loop': list_item.loop = True else: graph.parse_tag_expression(sub_pattern, list_item) tail_text = self.get_tail_from_element(sub_pattern) list_item.parse_text(graph, tail_text) else: raise ParserException("Invalid element <%s> in condition element" % (tag_name), xml_element=expression)
def _parse_node_with_attribs(self, graph, expression): self._name = TextUtils.tag_from_text(expression.tag) for attrib_name in expression.attrib: attrib_value = expression.attrib[attrib_name] if "<" in attrib_value and ">" in attrib_value: start = attrib_value.find("<") end = attrib_value.rfind(">") front = attrib_value[:start] middle = attrib_value[start:end + 1] back = attrib_value[end + 1:] root = TemplateNode() root.append(TemplateWordNode(front)) xml = ET.fromstring(middle) xml_node = TemplateNode() graph.parse_tag_expression(xml, xml_node) root.append(xml_node) root.append(TemplateWordNode(back)) self.set_attrib(attrib_name, root) else: self.set_attrib(attrib_name, TemplateWordNode(attrib_value)) self.parse_text(graph, self.get_text_from_element(expression)) for child in expression: graph.parse_tag_expression(child, self) self.parse_text(graph, self.get_tail_from_element(child))
def parse_expression(self, graph, expression): name_found = False if 'name' in expression.attrib: self.name = self.parse_attrib_value_as_word_node( graph, expression, 'name') name_found = True self.parse_text(graph, self.get_text_from_element(expression)) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'name': self.name = self.parse_children_as_word_node(graph, child) self.local = False name_found = True else: graph.parse_tag_expression(child, self) self.parse_text(graph, self.get_tail_from_element(child)) if name_found is False: raise ParserException("Name not found in bot", xml_element=expression)
def parse_expression(self, graph, expression): if 'image' in expression.attrib: self._image = graph.get_word_node(expression.attrib['image']) if 'title' in expression.attrib: self._title = graph.get_word_node(expression.attrib['title']) if 'subtitle' in expression.attrib: self._subtitle = graph.get_word_node(expression.attrib['subtitle']) head_text = self.get_text_from_element(expression) self.parse_text(graph, head_text) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'image': self._image = self.parse_children_as_word_node(graph, child) elif tag_name == 'title': self._title = self.parse_children_as_word_node(graph, child) elif tag_name == 'subtitle': self._subtitle = self.parse_children_as_word_node(graph, child) elif tag_name == 'button': button_class = graph.get_node_class_by_name("button") button = button_class() button.parse_expression(graph, child) self._buttons.append(button) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text)
def parse_expression(self, graph, expression): if 'subj' in expression.attrib: self._subj = graph.get_word_node(expression.attrib['subj']) if 'pred' in expression.attrib: self._pred = graph.get_word_node(expression.attrib['pred']) if 'obj' in expression.attrib: self._obj = graph.get_word_node(expression.attrib['obj']) head_text = self.get_text_from_element(expression) self.parse_text(graph, head_text) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'subj': self._subj = self.parse_children_as_word_node(graph, child) elif tag_name == 'pred': self._pred = self.parse_children_as_word_node(graph, child) elif tag_name == 'obj': self._obj = self.parse_children_as_word_node(graph, child) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text)
def test_tag_and_namespace_from_text(self): tag, name = TextUtils.tag_and_namespace_from_text("") self.assertIsNotNone(tag) self.assertEquals("", tag) self.assertIsNone(name) tag, name = TextUtils.tag_and_namespace_from_text("text") self.assertIsNotNone(tag) self.assertEquals("text", tag) self.assertIsNone(name) tag, name = TextUtils.tag_and_namespace_from_text("{http://alicebot.org/2001/AIML}aiml ") self.assertIsNotNone(tag) self.assertEquals("aiml", tag) self.assertIsNotNone(name) self.assertEquals("{http://alicebot.org/2001/AIML}", name)
def get_text_from_element(self, element): text = element.text if text is not None: text = TextUtils.strip_whitespace(text) if text == "": return None return text return None
def parse_expression(self, graph, expression): if 'format' in expression.attrib: self.interval_format = graph.get_word_node(expression.attrib['format']) head_text = self.get_text_from_element(expression) self.parse_text(graph, head_text) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'format': self.interval_format = graph.get_word_node(self.get_text_from_element(child)) elif tag_name == 'style': node = graph.get_base_node() node.parse_text(graph, self.get_text_from_element(child)) for sub_child in child: graph.parse_tag_expression(sub_child, node) node.parse_text(graph, self.get_text_from_element(child)) self.style = node elif tag_name == 'from': node = graph.get_base_node() node.parse_text(graph, self.get_text_from_element(child)) for sub_child in child: graph.parse_tag_expression(sub_child, node) node.parse_text(graph, self.get_text_from_element(child)) self.interval_from = node elif tag_name == 'to': node = graph.get_base_node() node.parse_text(graph, self.get_text_from_element(child)) for sub_child in child: graph.parse_tag_expression(sub_child, node) node.parse_text(graph, self.get_text_from_element(child)) self.interval_to = node else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text) if self.interval_format is None: YLogger.warning(self, "Interval node, format missing, defaulting to 'c%%'!") self.interval_format = "%c" if self.style is None: YLogger.warning(self, "style node, format missing, defaulting to 'days'!") self.style = "days" if self.interval_from is None: YLogger.warning(self, "interval_from node, format missing !") if self.interval_to is None: YLogger.warning(self, "interval_to node, format missing !")
def parse_tag_expression(self, expression, branch): tag_name = TextUtils.tag_from_text(expression.tag) if self._template_factory.exists(tag_name): if tag_name == "condition": node_instance = self._template_factory.new_node_class( tag_name)() else: node_instance = self._template_factory.new_node_class( tag_name)() node_instance.parse_expression(self, expression) branch.children.append(node_instance) else: self.parse_unknown_as_xml_node(expression, branch)
def parse_query(self, graph, query_name, query): for child in query: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'subj': if child.text is not None and child.text.startswith("?"): if child.text not in self.vars: YLogger.debug( self, "Variable [%s] defined in query element [%s], but not in vars!", child.text, tag_name) self.vars.append(child.text) subj = self.parse_children_as_word_node(graph, child) elif tag_name == 'pred': if child.text is not None and child.text.startswith("?"): if child.text not in self.vars: YLogger.debug( self, "Variable [%s] defined in query element [%s], but not in vars!", child.text, tag_name) self.vars.append(child.text) pred = self.parse_children_as_word_node(graph, child) elif tag_name == 'obj': if child.text is not None and child.text.startswith("?"): if child.text not in self.vars: YLogger.debug( self, "Variable [%s] defined in query element [%s], but not in vars!", child.text, tag_name) self.vars.append(child.text) obj = self.parse_children_as_word_node(graph, child) else: YLogger.warning(self, "Unknown tag name [%s] in select query", tag_name) if subj is None: raise ParserException("<subj> element missing from select query") if pred is None: raise ParserException("<pred> element missing from select query") if obj is None: raise ParserException("<obj> element missing from select query") if query_name == "q": self._queries.append(Query(subj, pred, obj)) else: self._queries.append(NotQuery(subj, pred, obj))
def resolve_to_string(self, client_context): xml = "<%s" % self._name for attrib_name in self._attribs: if isinstance(self._attribs[attrib_name], str): attrib_value = self._attribs[attrib_name] else: attrib_value = self._attribs[attrib_name].resolve( client_context) escaped = TextUtils.html_escape(attrib_value) escaped = escaped.replace(" ", "") xml += ' %s="%s"' % (attrib_name, escaped) xml += ">" xml += self.resolve_children_to_string(client_context) xml += "</%s>" % self._name return xml
def _parse_text(self, pattern_text, current_node, userid="*"): stripped = pattern_text.strip() words = self._aiml_parser.brain.nlp.tokenizer.texts_to_words(stripped) for word in words: if word != '': # Blank nodes add no value, ignore them word = TextUtils.strip_whitespace(word) new_node = self.node_from_text(word, userid=userid) current_node = current_node.add_child(new_node) return current_node
def to_xml(self, client_context): xml = "<%s" % self._name for attrib_name in self._attribs: if isinstance(self._attribs[attrib_name], str): attrib_value = self._attribs[attrib_name] else: attrib_value = self._attribs[attrib_name].resolve( client_context) escaped = TextUtils.html_escape(attrib_value) xml += ' %s="%s"' % (attrib_name, escaped) xml += ">" child_xml = self.children_to_xml(client_context) xml += child_xml xml += "</%s>" % self._name return xml
def parse_expression(self, graph, expression): head_text = self.get_text_from_element(expression) self.parse_text(graph, head_text) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'item': item = self.parse_children_as_word_node(graph, child) self._items.append(item) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text)
def parse_expression(self, graph, expression): head_text = self.get_text_from_element(expression) self.parse_text(graph, head_text) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'card': card_class = graph.get_node_class_by_name("card") card = card_class() card.parse_expression(graph, child) self._cards.append(card) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text)
def parse_expression(self, graph, expression): if 'seconds' in expression.attrib: self._seconds = graph.get_word_node(expression.attrib['text']) head_text = self.get_text_from_element(expression) self.parse_text(graph, head_text) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'seconds': self._seconds = self.parse_children_as_word_node(graph, child) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text)
def parse_expression(self, graph, expression): li_found = False for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'li': li_found = True li_node = graph.get_base_node() self.children.append(li_node) li_node.parse_template_node(graph, child) else: raise ParserException("Unsupported random child tag: %s" % (tag_name), xml_element=expression) if li_found is False: raise ParserException("No li children of random element!", xml_element=expression)
def parse_expression(self, graph, expression): variables = expression.findall('./vars') if variables: if len(variables) > 1: YLogger.warning( self, "Multiple <vars> found in select tag, using first") self.parse_vars(variables[0].text) queries = expression.findall('./*') for query in queries: tag_name = TextUtils.tag_from_text(query.tag) if tag_name == 'q' or tag_name == 'notq': self.parse_query(graph, tag_name, query) if self.children: raise ParserException( "<select> node should not contain child text, use <select><vars></vars><q></q></select> only" )
def parse_expression(self, graph, expression): for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'category': parsed = graph.aiml_parser.parse_category(child, namespace=None, topic_element=None, add_to_graph=False) learn_category = LearnCategory(parsed[0], parsed[1], parsed[2], parsed[3]) self.children.append(learn_category) elif tag_name == 'topic': raise ParserException("Not supported yet") else: raise ParserException("Invalid tag [%s] found in <learn>" % tag_name)
def parse_expression(self, graph, expression): if 'path' in expression.attrib: self.path = expression.attrib['path'] head_text = self.get_text_from_element(expression) self.parse_text(graph, head_text) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'path': self.path = self.get_text_from_element(child) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text) if self.path is None: raise ParserException("EXTENSION node, path attribute missing !")
def parse_type1_condition(self, graph, expression): self.parse_text(graph, self.get_text_from_element(expression)) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name in ['name', 'var', 'bot', 'value']: pass elif tag_name == 'li': raise ParserException("li element not allowed as child of condition element", xml_element=expression) elif tag_name == 'loop': raise ParserException("This type of condition cannot have <loop /> element", xml_element=expression) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text)
def parse_expression(self, graph, expression): name_found = False var_found = False if 'name' in expression.attrib: self.name = self.parse_attrib_value_as_word_node(graph, expression, 'name') self.local = False name_found = True if 'var' in expression.attrib: self.name = self.parse_attrib_value_as_word_node(graph, expression, 'var') self.local = True var_found = True for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'name': self.name = self.parse_children_as_word_node(graph, child) self.local = False name_found = True elif tag_name == 'var': self.name = self.parse_children_as_word_node(graph, child) self.local = True var_found = True elif tag_name == "tuple": self._tuples = self.parse_children_as_word_node(graph, child) if name_found is False and var_found is False: raise ParserException("Invalid get, missing either name or var", xml_element=expression) if name_found is True and var_found is True: raise ParserException("Get node has both name AND var values", xml_element=expression)
def parse_expression(self, graph, expression): if 'host' in expression.attrib: YLogger.warning( self, "'host' attrib not supported in sraix, moved to config, see documentation" ) if 'botid' in expression.attrib: YLogger.warning( self, "'botid' attrib not supported in sraix, moved to config, see documentation" ) if 'hint' in expression.attrib: YLogger.warning( self, "'hint' attrib not supported in sraix, moved to config, see documentation" ) if 'apikey' in expression.attrib: YLogger.warning( self, "'apikey' attrib not supported in sraix, moved to config, see documentation" ) if 'service' in expression.attrib: self.service = expression.attrib['service'] head_text = self.get_text_from_element(expression) self.parse_text(graph, head_text) for child in expression: tag_name = TextUtils.tag_from_text(child.tag) if tag_name == 'host': YLogger.warning( self, "'host' element not supported in sraix, moved to config, see documentation" ) elif tag_name == 'botid': YLogger.warning( self, "'botid' element not supported in sraix, moved to config, see documentation" ) elif tag_name == 'hint': YLogger.warning( self, "'hint' element not supported in sraix, moved to config, see documentation" ) elif tag_name == 'apikey': YLogger.warning( self, "'apikey' element not supported in sraix, moved to config, see documentation" ) elif tag_name == 'service': self.service = self.get_text_from_element(child) else: graph.parse_tag_expression(child, self) tail_text = self.get_tail_from_element(child) self.parse_text(graph, tail_text) if self.service is None: raise ParserException("SRAIX node, service attribute missing !")
import os from programr.utils.text.text import TextUtils from programr.utils.geo.google import GoogleMaps from programr.utils.license.keys import LicenseKeys if __name__ == '__main__': license_keys = LicenseKeys() license_keys.load_license_key_file( os.path.dirname(__file__) + TextUtils.replace_path_seperator( '/../../../../bots/y-bot/config/license.keys')) # Only to be used to create test data for unit aiml_tests googlemaps = GoogleMaps(license_keys) # Running these tools drops test files into the geocode test folder googlemaps.store_get_latlong_for_location_to_file( "KY3 9UR", TextUtils.replace_path_seperator( "../../../test/utils/geo/google_latlong.json")) googlemaps.store_get_distance_between_addresses_as_file( "Edinburgh", "Kinghorn", TextUtils.replace_path_seperator( "../../../test/utils/geo/distance.json")) googlemaps.store_get_directions_between_addresses_as_file( "Edinburgh", "Kinghorn", TextUtils.replace_path_seperator( "../../../test/utils/geo/directions.json")) googlemaps.store_get_latlong_for_location_to_file(