g1mp/plugins/urban_dictionary.py

90 lines
3.5 KiB
Python
Raw Normal View History

2025-02-13 04:55:42 +00:00
# -*- coding: utf-8 -*-
from irc3.plugins.command import command
from irc3.compat import Queue
import irc3
import aiohttp
@irc3.plugin
class UrbanDictionaryPlugin:
"""
A plugin to search Urban Dictionary for terms and post results to IRC.
This plugin uses a queue to manage asynchronous search requests and ensures
proper resource cleanup when unloaded.
"""
def __init__(self, bot):
self.bot = bot
self.queue = Queue() # Queue for managing search requests
self.session = None # aiohttp session initialized lazily
self.bot.loop.create_task(self._process_queue()) # Start queue processor
@command(permission='view', aliases=['ud'], public=True)
def urban(self, mask, target, args):
"""
Search Urban Dictionary for a term.
%%urban <term>...
"""
term = ' '.join(args['<term>'])
if not term:
return "Please provide a term to search."
# Enqueue the search request
self.queue.put_nowait((term, target))
return f"\x02Searching Urban Dictionary\x02 for '\x034{term}\x03'..."
async def _process_queue(self):
"""
Process search requests from the queue asynchronously.
This method runs indefinitely, processing one request at a time.
"""
while True:
try:
# Get the next search request
term, target = await self.queue.get()
# Ensure the session is initialized
if self.session is None or self.session.closed:
self.session = aiohttp.ClientSession(loop=self.bot.loop)
# Fetch data from Urban Dictionary API
url = f"https://api.urbandictionary.com/v0/define?term={term}"
async with self.session.get(url) as response:
if response.status != 200:
self.bot.privmsg(target, f"\x02Error:\x02 Failed to fetch definition for '\x034{term}\x03'.")
continue
data = await response.json()
if not data.get('list'):
self.bot.privmsg(target, f"\x02No definition found\x02 for '\x034{term}\x03'.")
continue
# Extract the first result
result = data['list'][0]
definition = result['definition'].replace('\n', ' ').strip()
example = result['example'].replace('\n', ' ').strip()
permalink = result['permalink']
# Format the response with colors and bold
response_message = (
f"\x02[{term}]\x02 \x033{definition}\x03 | "
f"Example: \x0312{example}\x03 | "
f"More: \x032{permalink}\x03"
)
# Send the response to the IRC channel
self.bot.privmsg(target, response_message)
except Exception as e:
self.bot.privmsg(target, f"\x02Error:\x02 An unexpected error occurred: {str(e)}")
finally:
# Mark the task as done
self.queue.task_done()
def __unload__(self):
"""
Cleanup when the plugin is unloaded.
Ensures that the aiohttp session is properly closed to avoid resource leaks.
"""
if self.session and not self.session.closed:
self.bot.loop.create_task(self.session.close())