From b6e10928f0e19a61bd514b49be6506c9ab939c13 Mon Sep 17 00:00:00 2001 From: gammafn Date: Thu, 1 Apr 2021 09:05:59 -0500 Subject: [PATCH 1/4] Rewrite wa: - Work around upstream bug when result has only one pod - Add !wafull alias to output all result --- modules/wa.py | 53 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/modules/wa.py b/modules/wa.py index feacfde..1638741 100644 --- a/modules/wa.py +++ b/modules/wa.py @@ -7,6 +7,10 @@ from modules.common.module import BotModule class MatrixModule(BotModule): app_id = '' + def matrix_start(self, bot): + super().matrix_start(bot) + self.add_module_aliases(bot, ['wafull']) + async def matrix_message(self, bot, room, event): args = event.body.split() if len(args) == 3: @@ -25,18 +29,21 @@ class MatrixModule(BotModule): query = event.body[len(args[0])+1:] client = wolframalpha.Client(self.app_id) - answer = query + ': ' - try: - res = client.query(query) - result = "?SYNTAX ERROR" - if res['@success']=='true': - pod0=res['pod'][0]['subpod']['plaintext'] - pod1=res['pod'][1] - if (('definition' in pod1['@title'].lower()) or ('result' in pod1['@title'].lower()) or (pod1.get('@primary','false') == 'true')): - result = pod1['subpod']['plaintext'] - answer += result + "\n" - except Exception as exc: - answer = "Wolfram Alpha has technical difficulty: " + str(exc) + res = client.query(query) + result = "?SYNTAX ERROR" + if res['@success']: + self.logger.debug(f"room: {room.name} sender: {event.sender} sent a valid query to wa") + else: + self.logger.info(f"wa error: {res['@error']}") + primary, items, fallback = self.parse_api_response(res) + if len(items) and 'full' in args[0]: + answer = '\n'.join(items) + elif primary: + answer = query + ': ' + primary + elif fallback: + answer = query + ': ' + fallback + else: + answer = 'Could not find response for ' + query await bot.send_text(room, answer) else: @@ -52,5 +59,27 @@ class MatrixModule(BotModule): if data.get("app_id"): self.app_id = data["app_id"] + def parse_api_response(self, res, key='plaintext'): + fallback = None + primary = None + items = list() + # workaround for bug in upstream wa package + if hasattr(res['pod'], 'get'): + res['pod'] = [res['pod']] + for pod in res['pod']: + title = pod['@title'].lower() + if 'input' in title: + continue + for sub in pod.subpods: + print(sub) + item = sub.get(key) + if not item: + continue + items.append(item) + fallback = fallback or item + if ('definition' in title) or ('result' in title) or pod.get('@primary'): + primary = primary or item + return (primary, items, fallback) + def help(self): return ('Wolfram Alpha search') From 0e69efcc11c91205e704cf7e6cbe12db9fea4e7f Mon Sep 17 00:00:00 2001 From: gammafn Date: Tue, 6 Apr 2021 00:04:18 -0500 Subject: [PATCH 2/4] Rewrite !wa to use html output --- modules/wa.py | 80 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/modules/wa.py b/modules/wa.py index 1638741..3d581b7 100644 --- a/modules/wa.py +++ b/modules/wa.py @@ -1,6 +1,6 @@ import urllib.request import wolframalpha - +from html import escape from modules.common.module import BotModule @@ -19,7 +19,6 @@ class MatrixModule(BotModule): self.app_id = args[2] bot.save_settings() await bot.send_text(room, 'App id set') - print('Appid', self.app_id) return if len(args) > 1: @@ -35,17 +34,16 @@ class MatrixModule(BotModule): self.logger.debug(f"room: {room.name} sender: {event.sender} sent a valid query to wa") else: self.logger.info(f"wa error: {res['@error']}") - primary, items, fallback = self.parse_api_response(res) - if len(items) and 'full' in args[0]: - answer = '\n'.join(items) - elif primary: - answer = query + ': ' + primary - elif fallback: - answer = query + ': ' + fallback + short, full = self.parse_api_response(res) + if full[0] and 'full' in args[0]: + html, plain = full + elif short[0]: + html, plain = short else: - answer = 'Could not find response for ' + query - - await bot.send_text(room, answer) + print(short) + plain = 'Could not find response for ' + query + html = plain + await bot.send_html(room, html, plain) else: await bot.send_text(room, 'Usage: !wa ') @@ -59,27 +57,55 @@ class MatrixModule(BotModule): if data.get("app_id"): self.app_id = data["app_id"] - def parse_api_response(self, res, key='plaintext'): - fallback = None + def parse_api_response(self, res): + htmls = [] + texts = [] primary = None - items = list() - # workaround for bug in upstream wa package + fallback = None + + # workaround for bug(?) in upstream wa package if hasattr(res['pod'], 'get'): res['pod'] = [res['pod']] for pod in res['pod']: - title = pod['@title'].lower() - if 'input' in title: + pod_htmls = [] + pod_texts = [] + spods = pod.get('subpod') + if not spods: continue - for sub in pod.subpods: - print(sub) - item = sub.get(key) - if not item: + + # workaround for bug(?) in upstream wa package + if hasattr(spods, 'get'): + spods = [spods] + for spod in spods: + title = spod.get('@title') + text = spod.get('plaintext') + if not text: continue - items.append(item) - fallback = fallback or item - if ('definition' in title) or ('result' in title) or pod.get('@primary'): - primary = primary or item - return (primary, items, fallback) + + if title: + html = f'{escape(title)}: {escape(text)}' + text = f'title: text' + else: + html = escape(text) + plain = text + pod_htmls += [f'
  • {s}
  • ' for s in html.split('\n')] + pod_texts += [f'- {s}' for s in text.split('\n')] + + if pod_texts: + title = pod.get('@title') + pod_html = '\n'.join([f'

    {escape(title)}\n

      '] + pod_htmls + ['

    ']) + pod_text = '\n'.join([title] + pod_texts) + htmls.append(pod_html) + texts.append(pod_text) + if not primary and self.is_primary(pod): + primary = (pod_html, pod_text) + else: + fallback = fallback or (pod_html, pod_text) + + return (primary or fallback, ('\n'.join(htmls), '\n'.join(texts))) + + def is_primary(self, pod): + return pod.get('@primary') or 'Definition' in pod.get('@title') or 'Result' in pod.get('@title') def help(self): return ('Wolfram Alpha search') From f0aa5530dbac218f6e6834e6bb8deb0e52043e11 Mon Sep 17 00:00:00 2001 From: gammafn Date: Tue, 6 Apr 2021 12:39:07 -0500 Subject: [PATCH 3/4] docstring for parse_api_response --- modules/wa.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/wa.py b/modules/wa.py index 3d581b7..e2b955e 100644 --- a/modules/wa.py +++ b/modules/wa.py @@ -58,6 +58,13 @@ class MatrixModule(BotModule): self.app_id = data["app_id"] def parse_api_response(self, res): + """Parses the pods from wa and prepares texts to send to matrix + + :param res: the result from wolframalpha.Client + :type res: dict + :return: a tuple of tuples: ((primary_html, primary_plaintext), (full_html, full_plaintext)) + :rtype: tuple + """ htmls = [] texts = [] primary = None From 3fcce6c6118281c853b4e087a6e8aa5d9e13d7fa Mon Sep 17 00:00:00 2001 From: gammafn Date: Tue, 6 Apr 2021 12:39:24 -0500 Subject: [PATCH 4/4] Add !wafull to readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 632c9f7..a30dd19 100644 --- a/README.md +++ b/README.md @@ -337,11 +337,12 @@ You'll need to get an appid from https://products.wolframalpha.com/simple-api/do Examples: * !wa 1+1 -* !wa airspeed of unladen swallow +* !wafull airspeed of unladen swallow Commands: -* !wa [query] - Query wolfram alpha +* !wa [query] - Query wolfram alpha and return the primary pod. +* !wafull [query] - Query wolfram alpha and return all pods. * !wa appid [appid] - Set appid (must be done as bot owner) ### OGN Field Log (FLOG)