g1mp/plugins/urban_dictionary.py

128 lines
4.6 KiB
Python
Raw Normal View History

2025-02-13 04:55:42 +00:00
# -*- coding: utf-8 -*-
2025-02-13 06:35:15 +00:00
"""
IRC3 Bot Plugin: Urban Dictionary Search
This plugin for an IRC bot allows users to search for terms on Urban Dictionary and post the results to an IRC channel.
It uses aiohttp for asynchronous HTTP requests and a queue to manage search requests.
Features:
- Asynchronously fetches definitions from Urban Dictionary.
- Enqueues search requests and processes them one at a time.
- Formats and posts the definition, example, and permalink to the IRC channel.
Usage:
======
To use this module, load it as a plugin in your IRC bot configuration.
Example:
@command
def urban(self, mask, target, args):
%%urban <term>...
Author: Zodiac
Date: 2025-02-12
"""
2025-02-13 04:55:42 +00:00
import irc3
import aiohttp
2025-02-13 06:35:15 +00:00
from irc3.plugins.command import command
from irc3.compat import Queue
2025-02-13 04:55:42 +00:00
@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):
2025-02-13 06:35:15 +00:00
"""
Initialize the plugin with bot reference.
Args:
bot (irc3.IrcBot): The IRC bot instance.
"""
2025-02-13 04:55:42 +00:00
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.
2025-02-13 06:35:15 +00:00
Args:
mask (str): The user mask (nickname@host) of the command issuer.
target (str): The channel or user where the command was issued.
args (dict): Command arguments.
Usage:
2025-02-13 04:55:42 +00:00
%%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())