Update Url Title Plugin to allow max 1 post per 5 seconds

This commit is contained in:
Zodiac 2025-02-19 14:08:16 -08:00
parent e09f4e970c
commit 9901f02b2a

View File

@ -12,7 +12,7 @@ Features:
- Built-in exclusion of YouTube URLs to avoid conflicts with dedicated YouTube plugins - Built-in exclusion of YouTube URLs to avoid conflicts with dedicated YouTube plugins
- Error handling for network and parsing operations - Error handling for network and parsing operations
- Proper resource cleanup through session management - Proper resource cleanup through session management
- Queue-based processing system for better flow control - Queue-based processing system with strict rate limiting
Dependencies: Dependencies:
- aiohttp: For asynchronous HTTP requests - aiohttp: For asynchronous HTTP requests
@ -25,6 +25,7 @@ Date: 2025-02-14
""" """
import re import re
import time
import aiohttp import aiohttp
import ircstyle import ircstyle
from lxml import html from lxml import html
@ -46,6 +47,7 @@ class URLTitlePlugin:
session (aiohttp.ClientSession): Persistent HTTP session for making web requests session (aiohttp.ClientSession): Persistent HTTP session for making web requests
url_pattern (re.Pattern): Compiled regex for URL detection in messages url_pattern (re.Pattern): Compiled regex for URL detection in messages
queue (Queue): Processing queue for URL handling tasks queue (Queue): Processing queue for URL handling tasks
last_processed (float): Timestamp of last successful URL processing
""" """
def __init__(self, bot): def __init__(self, bot):
@ -54,6 +56,7 @@ class URLTitlePlugin:
self.session = aiohttp.ClientSession(loop=self.bot.loop) self.session = aiohttp.ClientSession(loop=self.bot.loop)
self.url_pattern = re.compile(r"https?://[^\s<>\"']+|www\.[^\s<>\"']+") self.url_pattern = re.compile(r"https?://[^\s<>\"']+|www\.[^\s<>\"']+")
self.queue = Queue() self.queue = Queue()
self.last_processed = 0 # Initialize to epoch start
self.bot.create_task(self.process_queue()) self.bot.create_task(self.process_queue())
@event(irc3.rfc.PRIVMSG) @event(irc3.rfc.PRIVMSG)
@ -68,14 +71,24 @@ class URLTitlePlugin:
self.queue.put_nowait((target, url)) self.queue.put_nowait((target, url))
async def process_queue(self): async def process_queue(self):
"""Process URLs from the queue asynchronously.""" """Process URLs from the queue with strict 5-second cooldown between requests."""
while True: while True:
target, url = await self.queue.get() target, url = await self.queue.get()
try: try:
current_time = time.time()
elapsed = current_time - self.last_processed
if elapsed < 5:
self.bot.log.info(f"Rate limited: Waiting {5 - elapsed:.1f}s to process {url}")
continue
title = await self.fetch_title(url) title = await self.fetch_title(url)
if title: if title:
formatted_message = self.format_message(title, url) formatted_message = self.format_message(title, url)
await self.bot.privmsg(target, formatted_message) await self.bot.privmsg(target, formatted_message)
self.last_processed = time.time() # Update after successful processing
except Exception as e: except Exception as e:
self.bot.log.error(f"Error processing URL {url}: {e}") self.bot.log.error(f"Error processing URL {url}: {e}")
finally: finally:
@ -113,4 +126,4 @@ class URLTitlePlugin:
def __del__(self): def __del__(self):
"""Ensure proper cleanup when the plugin is destroyed.""" """Ensure proper cleanup when the plugin is destroyed."""
self.bot.create_task(self.close()) self.bot.create_task(self.close())