class TemplateLogNode(TemplateAttribNode): def __init__(self): TemplateAttribNode.__init__(self) self._level = TemplateWordNode("debug") self._output = TemplateWordNode("logging") @property def level(self): return self._level @level.setter def level(self, level): self._level = level def resolve_to_string(self, client_context): resolved = self.resolve_children_to_string(client_context) output = self._output.resolve_to_string(client_context) level = self._level.resolve_to_string(client_context) if output == "logging": YLogger.debug(client_context, "[%s] resolved to [%s]", self.to_string(), resolved) if level == "debug": YLogger.debug(client_context, resolved) elif level == "warning": YLogger.warning(client_context, resolved) elif level == "error": YLogger.error(client_context, resolved) elif level == "info": YLogger.info(client_context, resolved) else: YLogger.info(client_context, resolved) else: print(resolved) return "" def to_string(self): return "[LOG level=%s]" % (self._level.to_string()) def set_attrib(self, attrib_name, attrib_value): if attrib_name != 'level' and attrib_name != 'output': raise ParserException("Invalid attribute name %s for this node", attrib_name) if attrib_name == 'level': if isinstance(attrib_value, TemplateWordNode): self._level = attrib_value else: self._level = TemplateWordNode(attrib_value) if attrib_name == 'output': if isinstance(attrib_value, TemplateWordNode): self._output = attrib_value else: self._output = TemplateWordNode(attrib_value) def to_xml(self, client_context): xml = "<log" if self._level is not None: xml += ' level="%s"' % self._level.to_xml(client_context) xml += ">" xml += self.children_to_xml(client_context) xml += "</log>" return xml ####################################################################################################### # LOG_EXPRESSION ::== <log>Message</log> # <log level="error|warning|debug|info">Message</log> # def parse_expression(self, graph, expression): self._parse_node_with_attribs(graph, expression, [["level", "debug"],["output", "logging"]])
class TemplateDateNode(TemplateAttribNode): def __init__(self, date_format=None, locale=None): TemplateAttribNode.__init__(self) if date_format is None: self._format = TemplateWordNode("%c") else: self._format = TemplateWordNode(date_format) self._locale = None if locale is not None: self._locale = TemplateWordNode(locale) @property def date_format(self): return self._format @date_format.setter def date_format(self, fmt): if isinstance(fmt, TemplateNode): self._format = fmt else: self._format = TemplateWordNode(str(fmt)) @property def locale(self): return self._locale @locale.setter def locale(self, lcl): if isinstance(lcl, TemplateNode): self._locale = lcl else: self._locale = TemplateWordNode(str(lcl)) def _set_locate(self, client_context): local_locale = self._locale.resolve_to_string(client_context) locale.setlocale(locale.LC_TIME, local_locale) return local_locale def resolve_to_string(self, client_context): time_now = datetime.datetime.now() local_time = None if self._locale is not None: local_time = locale.setlocale(locale.LC_TIME) local_locale = "" resolved = "" try: if self._locale is not None: local_locale = self._set_locate(client_context) resolved_format = self._format.resolve_to_string(client_context) resolved = time_now.strftime(resolved_format) except Exception as exep: YLogger.exception(self, "Failed to set locale to [%s]", exep, local_locale) finally: if local_time is not None: locale.setlocale(locale.LC_TIME, local_time) YLogger.debug(client_context, "[%s] resolved to [%s]", self.to_string(), resolved) return resolved def to_string(self): if self._locale is None: return "[DATE format=%s]" % self._format.to_string() else: return "[DATE format=%s locale=%s]" % (self._format.to_string(), self._locale.to_string()) def set_attrib(self, attrib_name, attrib_value): if attrib_name == 'format': if isinstance(attrib_value, TemplateNode): self._format = attrib_value else: self._format = TemplateWordNode(attrib_value) elif attrib_name == 'locale': if isinstance(attrib_value, TemplateNode): self._locale = attrib_value else: self._locale = TemplateWordNode(attrib_value) else: raise ParserException("Invalid attribute name %s for this node" % (attrib_name)) def to_xml(self, client_context): if self._locale is None: xml = '<date format="%s" >' % self._format.to_xml(client_context) else: xml = '<date format="%s" locale="%s">' % (self._format.to_xml(client_context), self._locale.to_xml(client_context)) xml += self.children_to_xml(client_context) xml += "</date>" return xml ####################################################################################################### # DATE_ATTRIBUTES ::== (format="LISP_DATE_FORMAT") | (jformat="JAVA DATE FORMAT") # DATE_ATTRIBUTE_TAG ::== <format>TEMPLATE_EXPRESSION</format> | <jformat>TEMPLATE_EXPRESSION</jformat> # DATE_EXPRESSION ::== <date( DATE_ATTRIBUTES)*/> | <date>(DATE_ATTRIBUTE_TAG)</date> # Pandorabots supports three extension attributes to the date element in templates: # locale # format # timezone def parse_expression(self, graph, expression): self._parse_node_with_attribs(graph, expression, [["format", "%c"], ["locale", None]])
class TemplateIntervalNode(TemplateNode): def __init__(self, date_format="%c", style="days"): TemplateNode.__init__(self) self._interval_from = None self._interval_to = None if isinstance(date_format, str): self._format = TemplateWordNode(date_format) else: self._format = date_format if isinstance(style, str): self._style = TemplateWordNode(style) else: self._style = style @property def format(self): return self._format @format.setter def format(self, format): self._format = format @property def interval_from(self): return self._interval_from @interval_from.setter def interval_from(self, interval_from): self._interval_from = interval_from @property def interval_to(self): return self._interval_to @interval_to.setter def interval_to(self, interval_to): self._interval_to = interval_to @property def style(self): return self._style @style.setter def style(self, style): self._style = style def resolve(self, bot, clientid): try: format_str = self._format.resolve(bot, clientid) from_str = self.interval_from.resolve(bot, clientid) from_time = datetime.datetime.strptime(from_str, format_str) to_str = self.interval_to.resolve(bot, clientid) to_time = datetime.datetime.strptime(to_str, format_str) style = self._style.resolve(bot, clientid) diff = to_time - from_time difference = relativedelta(to_time, from_time) if style == "years": resolved = str(difference.years) elif style == "months": resolved = str(difference.months) elif style == "weeks": resolved = str(difference.weeks) elif style == "days": resolved = str(diff.days) elif style == "hours": resolved = str(difference.hours) elif style == "minutes": resolved = str(difference.minutes) elif style == "seconds": resolved = str(difference.seconds) elif style == "microseconds": resolved = str(difference.microseconds) elif style == "ymd": resolved = "%d years, %d months, %d days" % \ (difference.years, difference.months, difference.days) elif style == "hms": resolved = "%d hours, %d minutes, %d seconds" % \ (difference.hours, difference.minutes, difference.seconds) elif style == "ymdhms": resolved = "%d years, %d months, %d days, %d hours, %d minutes, %d seconds" % \ (difference.years, difference.months, difference.days, difference.hours, difference.minutes, difference.seconds) else: logging.error("Unknown interval style [%s]", style) resolved = "" logging.debug("[INTERVAL] resolved to [%s]", resolved) return resolved except Exception as excep: logging.exception(excep) return "" def to_string(self): return "[INTERVAL]" def to_xml(self, bot, clientid): xml = '<interval' xml += ' format="%s"' % self._format.to_xml(bot, clientid) xml += ' style="%s"' % self._style.to_xml(bot, clientid) xml += '>' xml += '<from>' xml += self._interval_from.to_xml(bot, clientid) xml += '</from>' xml += '<to>' xml += self._interval_to.to_xml(bot, clientid) xml += '</to>' xml += '</interval>' return xml
class TemplateSystemNode(TemplateAttribNode): def __init__(self): TemplateAttribNode.__init__(self) self._timeout = TemplateWordNode("0") @property def timeout(self): return self._timeout @timeout.setter def timeout(self, timeout): self._timeout = TemplateWordNode(str(timeout)) def resolve_to_string(self, client_context): if client_context.brain.configuration.overrides.allow_system_aiml is True: command = self.resolve_children_to_string(client_context) process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) result = [] for line in process.stdout.readlines(): byte_string = line.decode("utf-8") result.append(byte_string.strip()) process.wait() resolved = " ".join(result) else: YLogger.warning(client_context, "System command node disabled in config") resolved = "" YLogger.debug(client_context, "[%s] resolved to [%s]", self.to_string(), resolved) return resolved def to_string(self): return "[SYSTEM timeout=%s]" % (self._timeout.to_string()) def set_attrib(self, attrib_name, attrib_value): if attrib_name != 'timeout': raise ParserException("Invalid attribute name [%s] for this node" % attrib_name) YLogger.warning(self, "System node timeout attrib currently ignored") self._timeout = attrib_value def to_xml(self, client_context): xml = "<system" timeout = self._timeout.to_xml(client_context) if timeout != "0": xml += ' timeout="%s"' % timeout xml += ">" xml += self.children_to_xml(client_context) xml += "</system>" return xml ####################################################################################################### # SYSTEM_EXPRESSION ::== # <system( TIMEOUT_ATTRIBUTE)>TEMPLATE_EXPRESSION</system> | # <system><timeout>TEMPLATE_EXPRESSION</timeout></system> # TIMEOUT_ATTRIBUTE :== timeout=”NUMBER” def parse_expression(self, graph, expression): self._parse_node_with_attrib(graph, expression, "timeout", "0")
class TemplateIntervalNode(TemplateNode): def __init__(self, date_format="%c", style="days"): TemplateNode.__init__(self) self._interval_from = None self._interval_to = None if isinstance(date_format, str): self._format = TemplateWordNode(date_format) else: self._format = date_format if isinstance(style, str): self._style = TemplateWordNode(style) else: self._style = style @property def format(self): return self._format @format.setter def format(self, format): self._format = format @property def interval_from(self): return self._interval_from @interval_from.setter def interval_from(self, interval_from): self._interval_from = interval_from @property def interval_to(self): return self._interval_to @interval_to.setter def interval_to(self, interval_to): self._interval_to = interval_to @property def style(self): return self._style @style.setter def style(self, style): self._style = style def resolve(self, bot, clientid): try: format_str = self._format.resolve(bot, clientid) from_str = self.interval_from.resolve(bot, clientid) from_time = datetime.datetime.strptime(from_str, format_str) to_str = self.interval_to.resolve(bot, clientid) to_time = datetime.datetime.strptime(to_str, format_str) style = self._style.resolve(bot, clientid) diff = to_time - from_time difference = relativedelta(to_time, from_time) if style == "years": resolved = str(difference.years) elif style == "months": resolved = str(difference.months) elif style == "weeks": resolved = str(difference.weeks) elif style == "days": resolved = str(diff.days) elif style == "hours": resolved = str(difference.hours) elif style == "minutes": resolved = str(difference.minutes) elif style == "seconds": resolved = str(difference.seconds) elif style == "microseconds": resolved = str(difference.microseconds) elif style == "ymd": resolved = "%d years, %d months, %d days" % \ (difference.years, difference.months, difference.days) elif style == "hms": resolved = "%d hours, %d minutes, %d seconds" % \ (difference.hours, difference.minutes, difference.seconds) elif style == "ymdhms": resolved = "%d years, %d months, %d days, %d hours, %d minutes, %d seconds" % \ (difference.years, difference.months, difference.days, difference.hours, difference.minutes, difference.seconds) else: logging.error("Unknown interval style [%s]", style) resolved = "" logging.debug("[INTERVAL] resolved to [%s]", resolved) return resolved except Exception as excep: logging.exception(excep) return "" def to_string(self): return "[INTERVAL]" def to_xml(self, bot, clientid): xml = '<interval' xml += ' format="%s"' % self._format.to_xml(bot, clientid) xml += ' style="%s"' % self._style.to_xml(bot, clientid) xml += '>' xml += '<from>' xml += self._interval_from.to_xml(bot, clientid) xml += '</from>' xml += '<to>' xml += self._interval_to.to_xml(bot, clientid) xml += '</to>' xml += '</interval>' return xml