import asyncio import irc3 from irc3.plugins.command import command @irc3.plugin class GoatPlugin: def __init__(self, bot): self.bot = bot # Dictionary to keep track of running tasks for each target (channel) self.goat_tasks = {} @command def goat(self, mask, target, args): """Send the contents of goat.txt line by line to the channel and resend when reaching the end. %%goat [] """ # Get the optional nick argument (it may be None or an empty string) nick = args.get("") # Do not provide a default value here # If a goat task is already running on the target, notify and exit. if target in self.goat_tasks: self.bot.privmsg(target, "A goat task is already running.") return try: with open('goat.txt', 'r', encoding='utf-8') as file: lines = file.readlines() except Exception as e: self.bot.privmsg(target, f"Error reading goat.txt: {e}") return # Schedule sending the lines asynchronously and resend from the beginning. task = self.bot.loop.create_task(self.send_lines(target, nick, lines)) self.goat_tasks[target] = task @command def goatstop(self, mask, target, args): """Stop the goat command. %%goatstop """ if target in self.goat_tasks: task = self.goat_tasks.pop(target) task.cancel() self.bot.privmsg(target, "Goat task stopped.") else: self.bot.privmsg(target, "No goat task is currently running.") async def send_lines(self, target, nick, lines): message_count = 0 try: while True: for line in lines: stripped_line = line.strip() # If nick is provided and non-empty, prepend it to the message. if nick: msg = f"{nick} : {stripped_line}" else: msg = stripped_line self.bot.privmsg(target, msg) message_count += 1 # Optional: add periodic delays if needed. # if message_count % 1000 == 0: # await asyncio.sleep(5) await asyncio.sleep(0.007) except asyncio.CancelledError: self.bot.privmsg(target, "Goat task cancelled.") raise