90 lines
3.5 KiB
Python
90 lines
3.5 KiB
Python
![]() |
# -*- 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())
|