"""
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('[', '').replace(']', '')
example = html.escape(example).replace('[', '').replace(']', '')
header = f"📖 Urban Dictionary: {safe_term}"
if index and total:
header += f" (Definition {index}/{total})"
msg = f"""{header}
Definition:
{definition}
"""
if example.strip():
msg += f"""Example:
{example}
"""
msg += f"""Author: {safe_author} | 👍 {thumbs_up} 👎 {thumbs_down}
View on Urban Dictionary"""
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"
__help__ = """!ud – Urban Dictionary
!ud random, !ud <term> top, !ud <term> <index>
"""