info = { 'author': 'Jon Bergli Heier', 'title': 'WolframAlpha calculator', 'description': 'WolframAlpha calculator', } import urllib, urllib2, re from xml.etree.ElementTree import ElementTree whitespace_re = re.compile(r'\s+') unicode_re = re.compile(r'(\\:[\da-f]{4})') class Module(object): config_section = 'module/wacalc' def __init__(self, bot): self.irc = bot if self.irc: self.irc.register_keyword('!wacalc', self) if config.has_option(self.config_section, 'register_gcalc'): # Register gcalc trigger for the obsolete gcalc module self.irc.register_keyword('!gcalc', self) def keyword(self, nick, channel, kw, msg): target = channel if not channel == self.irc.nickname else nick.split('!')[0] if not len(msg.strip()): self.irc.msg(target, 'Usage: !wacalc query') return query = { 'appid': config.get(self.config_section, 'api_key'), 'format': 'plaintext', 'input': msg, } if config.has_option(self.config_section, 'location'): query['location'] = config.get(self.config_section, 'location') u = urllib2.urlopen('http://api.wolframalpha.com/v2/query?%s' % urllib.urlencode(query)) xmldoc = ElementTree() xmldoc.parse(u) xml = xmldoc.getroot() if xml.attrib['success'] != 'true': tips = xml.find('tips') dym = xml.find('didyoumeans') message = None if tips is not None and len(tips): message = 'Tip: %s' % tips[0].attrib['text'].encode('utf-8') elif dym is not None and len(dym): # TODO: sort by score message = 'Did you mean "%s"?' % dym[0].text.encode('utf-8') if message: message = 'No result (%s)' % message else: message = 'No result.' self.irc.msg(target, message) return right = None left = msg def pod_plaintext(pod): result = pod.find('subpod/plaintext') if result is not None and result.text is not None: text = result.text text = whitespace_re.sub(' ', text) text = unicode_re.sub(lambda match: unichr(int(match.group()[2:], 16)), text) return text.encode('utf-8') for pod in xml.findall('pod'): pod_id = pod.attrib['id'] if pod_id in ('Result', 'DecimalApproximation'): right = pod_plaintext(pod) elif pod_id == 'Input': left = pod_plaintext(pod) if left and right: self.irc.msg(target, '%s = %s' % (left, right)) else: self.irc.msg(target, 'Something failed.')