Merge pull request #130 from xPMo/wa-fixes

Fix !wa module
This commit is contained in:
Ville Ranki 2021-04-06 20:59:15 +03:00 committed by GitHub
commit 2bc62c7a37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 18 deletions

View File

@ -337,11 +337,12 @@ You'll need to get an appid from https://products.wolframalpha.com/simple-api/do
Examples: Examples:
* !wa 1+1 * !wa 1+1
* !wa airspeed of unladen swallow * !wafull airspeed of unladen swallow
Commands: 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) * !wa appid [appid] - Set appid (must be done as bot owner)
### OGN Field Log (FLOG) ### OGN Field Log (FLOG)

View File

@ -1,12 +1,16 @@
import urllib.request import urllib.request
import wolframalpha import wolframalpha
from html import escape
from modules.common.module import BotModule from modules.common.module import BotModule
class MatrixModule(BotModule): class MatrixModule(BotModule):
app_id = '' 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): async def matrix_message(self, bot, room, event):
args = event.body.split() args = event.body.split()
if len(args) == 3: if len(args) == 3:
@ -15,7 +19,6 @@ class MatrixModule(BotModule):
self.app_id = args[2] self.app_id = args[2]
bot.save_settings() bot.save_settings()
await bot.send_text(room, 'App id set') await bot.send_text(room, 'App id set')
print('Appid', self.app_id)
return return
if len(args) > 1: if len(args) > 1:
@ -25,20 +28,22 @@ class MatrixModule(BotModule):
query = event.body[len(args[0])+1:] query = event.body[len(args[0])+1:]
client = wolframalpha.Client(self.app_id) client = wolframalpha.Client(self.app_id)
answer = query + ': ' res = client.query(query)
try: result = "?SYNTAX ERROR"
res = client.query(query) if res['@success']:
result = "?SYNTAX ERROR" self.logger.debug(f"room: {room.name} sender: {event.sender} sent a valid query to wa")
if res['@success']=='true': else:
pod0=res['pod'][0]['subpod']['plaintext'] self.logger.info(f"wa error: {res['@error']}")
pod1=res['pod'][1] short, full = self.parse_api_response(res)
if (('definition' in pod1['@title'].lower()) or ('result' in pod1['@title'].lower()) or (pod1.get('@primary','false') == 'true')): if full[0] and 'full' in args[0]:
result = pod1['subpod']['plaintext'] html, plain = full
answer += result + "\n" elif short[0]:
except Exception as exc: html, plain = short
answer = "Wolfram Alpha has technical difficulty: " + str(exc) else:
print(short)
await bot.send_text(room, answer) plain = 'Could not find response for ' + query
html = plain
await bot.send_html(room, html, plain)
else: else:
await bot.send_text(room, 'Usage: !wa <query>') await bot.send_text(room, 'Usage: !wa <query>')
@ -52,5 +57,62 @@ class MatrixModule(BotModule):
if data.get("app_id"): if data.get("app_id"):
self.app_id = data["app_id"] 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
fallback = None
# workaround for bug(?) in upstream wa package
if hasattr(res['pod'], 'get'):
res['pod'] = [res['pod']]
for pod in res['pod']:
pod_htmls = []
pod_texts = []
spods = pod.get('subpod')
if not spods:
continue
# 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
if title:
html = f'<strong>{escape(title)}</strong>: {escape(text)}'
text = f'title: text'
else:
html = escape(text)
plain = text
pod_htmls += [f'<li>{s}</li>' 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'<p><strong>{escape(title)}</strong>\n<ul>'] + pod_htmls + ['</ul></p>'])
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): def help(self):
return ('Wolfram Alpha search') return ('Wolfram Alpha search')