Files
FunguyBot/plugins/urbandictionary.py
T

93 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Urban Dictionary definitions.
"""
import logging
import aiohttp
import simplematrixbotlib as botlib
import html
from plugins.common import html_escape
URBAN_API_URL = "https://api.urbandictionary.com/v0/define"
RANDOM_API_URL = "https://api.urbandictionary.com/v0/random"
def format_definition(term, definition, example, author, thumbs_up, thumbs_down, permalink, index=None, total=None):
safe_term = html_escape(term)
safe_author = html_escape(author)
# definition and example may contain [word] markup, we'll just escape all HTML
definition = html.escape(definition).replace('[', '<strong>').replace(']', '</strong>')
example = html.escape(example).replace('[', '<em>').replace(']', '</em>')
header = f"<strong>📖 Urban Dictionary: {safe_term}</strong>"
if index and total:
header += f" (Definition {index}/{total})"
msg = f"""{header}
<strong>Definition:</strong><br>{definition}<br>"""
if example.strip():
msg += f"""<strong>Example:</strong><br><em>{example}</em><br>"""
msg += f"""<strong>Author:</strong> {safe_author} | 👍 {thumbs_up} 👎 {thumbs_down}<br>
<a href="{permalink}">View on Urban Dictionary</a>"""
return msg
async def handle_command(room, message, bot, prefix, config):
match = botlib.MessageMatch(room, message, bot, prefix)
if match.is_not_from_this_bot() and match.prefix() and match.command("ud"):
args = match.args()
try:
if len(args) == 0:
# random
async with aiohttp.ClientSession() as session:
async with session.get(RANDOM_API_URL, timeout=10) as resp:
resp.raise_for_status()
data = await resp.json()
if not data.get('list'):
await bot.api.send_text_message(room.room_id, "No random definition found.")
return
entry = data['list'][0]
msg = format_definition(entry['word'], entry['definition'], entry.get('example',''),
entry['author'], entry['thumbs_up'], entry['thumbs_down'],
entry['permalink'])
await bot.api.send_markdown_message(room.room_id, msg)
return
# Search
index = None
search_term = ' '.join(args)
if args[-1].isdigit():
index = int(args[-1])
search_term = ' '.join(args[:-1])
if not search_term:
await bot.api.send_text_message(room.room_id, "Usage: !ud [term] [index]")
return
async with aiohttp.ClientSession() as session:
async with session.get(URBAN_API_URL, params={'term': search_term}, timeout=10) as resp:
resp.raise_for_status()
data = await resp.json()
definitions = data.get('list', [])
if not definitions:
await bot.api.send_text_message(room.room_id, f"No definition for '{html_escape(search_term)}'")
return
total = len(definitions)
if index is None:
index = 1
if index < 1 or index > total:
await bot.api.send_text_message(room.room_id, f"Index out of range (1-{total})")
return
entry = definitions[index - 1]
msg = format_definition(entry['word'], entry['definition'], entry.get('example',''),
entry['author'], entry['thumbs_up'], entry['thumbs_down'],
entry['permalink'], index, total)
await bot.api.send_markdown_message(room.room_id, msg)
except aiohttp.ClientError as e:
await bot.api.send_text_message(room.room_id, f"Error: {e}")
except Exception as e:
await bot.api.send_text_message(room.room_id, f"Error: {str(e)}")
__version__ = "1.0.1"
__author__ = "Funguy Bot"
__description__ = "Urban Dictionary definitions (async)"
__help__ = """<details><summary><strong>!ud</strong> Urban Dictionary</summary>
<ul><li><code>!ud</code> random, <code>!ud &lt;term&gt;</code> top, <code>!ud &lt;term&gt; &lt;index&gt;</code></li></ul></details>"""