""" 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 (async)" __help__ = """
!ud – Urban Dictionary
"""