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_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)