From 5e78385a7eaf1f7592f4b965f30f93fdabfd3d3f Mon Sep 17 00:00:00 2001 From: Zodiac Date: Fri, 14 Feb 2025 19:31:09 -0800 Subject: [PATCH] add more admin functionality --- plugins/services/administration.py | 376 ++++++++++++++++++++++++++++- plugins/upload.py | 2 +- 2 files changed, 372 insertions(+), 6 deletions(-) diff --git a/plugins/services/administration.py b/plugins/services/administration.py index 9dfc116..21a7fc3 100644 --- a/plugins/services/administration.py +++ b/plugins/services/administration.py @@ -1,19 +1,34 @@ # -*- coding: utf-8 -*- """ -IRC Bot Plugins: Voice, Kick, and Ban Management +IRC Bot Plugins: Join, Part, Nickname, Message, Topic, Invite, Voice, Kick, Ban, Op, and Mute Management -This module provides three IRC bot plugins: -1. `VoicePlugin`: Handles granting and revoking voice (+v) privileges. -2. `KickPlugin`: Handles kicking users from the channel. -3. `BanPlugin`: Handles banning and unbanning users. +This module provides multiple IRC bot plugins: +1. `JoinPlugin`: Handles joining specific channels. +2. `PartPlugin`: Handles leaving specific channels. +3. `NickPlugin`: Handles changing the bot's nickname. +4. `MessagePlugin`: Handles sending messages. +5. `TopicPlugin`: Handles changing the channel topic. +6. `InvitePlugin`: Handles inviting users to a channel. +7. `VoicePlugin`: Handles granting and revoking voice (+v) privileges. +8. `KickPlugin`: Handles kicking users from the channel. +9. `BanPlugin`: Handles banning and unbanning users. +10. `OpPlugin`: Handles granting and removing operator privileges. +11. `MutePlugin`: Handles muting and unmuting users. All commands require **admin** permissions. Features: +- Join and leave specific channels. +- Change the bot's nickname. +- Send messages to users or channels. +- Change the channel topic. +- Invite users to channels. - Voice a single user or all users in a channel. - Devoice a single user or all users. - Kick users with optional reasons. - Ban and unban users. +- Grant and remove operator privileges. +- Mute and unmute users. Author: Zodiac (Modified for verbose logging by bot.log) """ @@ -23,6 +38,233 @@ import irc3 from irc3.plugins.command import command +@irc3.plugin +class JoinPlugin: + """A plugin to join specific IRC channels.""" + + def __init__(self, bot): + """ + Initialize the JoinPlugin. + + Args: + bot (irc3.IrcBot): The IRC bot instance. + """ + self.bot = bot + + @command(permission='admin') + async def join(self, mask, target, args): + """ + Join a specific channel. + + Usage: + %%join + """ + channel = args.get('') + if channel: + self.bot.log.info("Request to join channel %s", channel) + await self.join_channel(channel) + + async def join_channel(self, channel): + """ + Join a specific channel. + + Args: + channel (str): The IRC channel to join. + """ + self.bot.log.info("Joining channel %s", channel) + self.bot.send(f'JOIN {channel}') + + +@irc3.plugin +class PartPlugin: + """A plugin to leave specific IRC channels.""" + + def __init__(self, bot): + """ + Initialize the PartPlugin. + + Args: + bot (irc3.IrcBot): The IRC bot instance. + """ + self.bot = bot + + @command(permission='admin') + async def part(self, mask, target, args): + """ + Leave a specific channel. + + Usage: + %%part + """ + channel = args.get('') + if channel: + self.bot.log.info("Request to leave channel %s", channel) + await self.part_channel(channel) + + async def part_channel(self, channel): + """ + Leave a specific channel. + + Args: + channel (str): The IRC channel to leave. + """ + self.bot.log.info("Leaving channel %s", channel) + self.bot.send(f'PART {channel}') + + +@irc3.plugin +class NickPlugin: + """A plugin to change the bot's nickname.""" + + def __init__(self, bot): + """ + Initialize the NickPlugin. + + Args: + bot (irc3.IrcBot): The IRC bot instance. + """ + self.bot = bot + + @command(permission='admin') + async def nick(self, mask, target, args): + """ + Change the bot's nickname. + + Usage: + %%nick + """ + newnick = args.get('') + if newnick: + self.bot.log.info("Request to change nickname to %s", newnick) + await self.change_nick(newnick) + + async def change_nick(self, newnick): + """ + Change the bot's nickname. + + Args: + newnick (str): The new nickname for the bot. + """ + self.bot.log.info("Changing nickname to %s", newnick) + self.bot.send(f'NICK {newnick}') + + +@irc3.plugin +class MessagePlugin: + """A plugin to send messages to users or channels.""" + + def __init__(self, bot): + """ + Initialize the MessagePlugin. + + Args: + bot (irc3.IrcBot): The IRC bot instance. + """ + self.bot = bot + + @command(permission='admin') + async def msg(self, mask, target, args): + """ + Send a message to a user or channel. + + Usage: + %%msg + """ + msg_target = args.get('') + message = args.get('') + if msg_target and message: + self.bot.log.info("Request to send message to %s: %s", msg_target, message) + await self.send_message(msg_target, message) + + async def send_message(self, msg_target, message): + """ + Send a message to a user or channel. + + Args: + msg_target (str): The target user or channel. + message (str): The message to send. + """ + self.bot.log.info("Sending message to %s: %s", msg_target, message) + self.bot.send(f'PRIVMSG {msg_target} :{message}') + + +@irc3.plugin +class TopicPlugin: + """A plugin to change the topic of an IRC channel.""" + + def __init__(self, bot): + """ + Initialize the TopicPlugin. + + Args: + bot (irc3.IrcBot): The IRC bot instance. + """ + self.bot = bot + + @command(permission='admin') + async def topic(self, mask, target, args): + """ + Change the topic of a channel. + + Usage: + %%topic + """ + newtopic = args.get('') + if newtopic: + self.bot.log.info("Request to change topic to %s in %s", newtopic, target) + await self.change_topic(target, newtopic) + + async def change_topic(self, target, newtopic): + """ + Change the topic of a channel. + + Args: + target (str): The IRC channel. + newtopic (str): The new topic for the channel. + """ + self.bot.log.info("Changing topic in channel %s to %s", target, newtopic) + self.bot.send(f'TOPIC {target} :{newtopic}') + + +@irc3.plugin +class InvitePlugin: + """A plugin to invite users to an IRC channel.""" + + def __init__(self, bot): + """ + Initialize the InvitePlugin. + + Args: + bot (irc3.IrcBot): The IRC bot instance. + """ + self.bot = bot + + @command(permission='admin') + async def invite(self, mask, target, args): + """ + Invite a user to a channel. + + Usage: + %%invite + """ + nick = args.get('') + channel = args.get('') + if nick and channel: + self.bot.log.info("Request to invite %s to channel %s", nick, channel) + await self.invite_user(nick, channel) + + async def invite_user(self, nick, channel): + """ + Invite a user to a channel. + + Args: + nick (str): The nickname of the user. + channel (str): The IRC channel. + """ + self.bot.log.info("Inviting user %s to channel %s", nick, channel) + self.bot.send(f'INVITE {nick} {channel}') + + @irc3.plugin class VoicePlugin: """A plugin to manage voice (+v) privileges in an IRC channel.""" @@ -228,3 +470,127 @@ class BanPlugin: """ self.bot.log.info("Unbanning user %s in channel %s", nick, target) self.bot.send(f'MODE {target} -b {nick}') + + +@irc3.plugin +class OpPlugin: + """A plugin to grant and remove operator privileges in an IRC channel.""" + + def __init__(self, bot): + """ + Initialize the OpPlugin. + + Args: + bot (irc3.IrcBot): The IRC bot instance. + """ + self.bot = bot + + @command(permission='admin') + async def op(self, mask, target, args): + """ + Grant operator privileges to a specific user. + + Usage: + %%op + """ + nick = args.get('') + if nick: + self.bot.log.info("Request to grant operator privileges to %s in %s", nick, target) + await self.give_op(target, nick) + + @command(permission='admin') + async def deop(self, mask, target, args): + """ + Remove operator privileges from a specific user. + + Usage: + %%deop + """ + nick = args.get('') + if nick: + self.bot.log.info("Request to remove operator privileges from %s in %s", nick, target) + await self.remove_op(target, nick) + + async def give_op(self, target, nick): + """ + Grant operator privileges to a specific user. + + Args: + target (str): The IRC channel. + nick (str): The nickname of the user. + """ + self.bot.log.info("Granting operator privileges to user %s in channel %s", nick, target) + self.bot.send(f'MODE {target} +o {nick}') + + async def remove_op(self, target, nick): + """ + Remove operator privileges from a specific user. + + Args: + target (str): The IRC channel. + nick (str): The nickname of the user. + """ + self.bot.log.info("Removing operator privileges from user %s in channel %s", nick, target) + self.bot.send(f'MODE {target} -o {nick}') + + +@irc3.plugin +class MutePlugin: + """A plugin to mute and unmute users in an IRC channel.""" + + def __init__(self, bot): + """ + Initialize the MutePlugin. + + Args: + bot (irc3.IrcBot): The IRC bot instance. + """ + self.bot = bot + + @command(permission='admin') + async def mute(self, mask, target, args): + """ + Mute a specific user in the channel. + + Usage: + %%mute + """ + nick = args.get('') + if nick: + self.bot.log.info("Request to mute user %s in channel %s", nick, target) + await self.mute_user(target, nick) + + @command(permission='admin') + async def unmute(self, mask, target, args): + """ + Unmute a specific user in the channel. + + Usage: + %%unmute + """ + nick = args.get('') + if nick: + self.bot.log.info("Request to unmute user %s in channel %s", nick, target) + await self.unmute_user(target, nick) + + async def mute_user(self, target, nick): + """ + Mute a specific user in the channel. + + Args: + target (str): The IRC channel. + nick (str): The nickname of the user. + """ + self.bot.log.info("Muting user %s in channel %s", nick, target) + self.bot.send(f'MODE {target} +q {nick}') + + async def unmute_user(self, target, nick): + """ + Unmute a specific user in the channel. + + Args: + target (str): The IRC channel. + nick (str): The nickname of the user. + """ + self.bot.log.info("Unmuting user %s in channel %s", nick, target) + self.bot.send(f'MODE {target} -q {nick}') diff --git a/plugins/upload.py b/plugins/upload.py index e611ef4..8e80f7e 100644 --- a/plugins/upload.py +++ b/plugins/upload.py @@ -131,7 +131,7 @@ class UploadPlugin: self.bot.log.error(f"YouTube search error: {e}") return None - @command + @command(permission='view', aliases=['u'], public=True) async def upload(self, mask, target, args): """ Upload a file to hardfiles.org (Max 500MB).