async def unban(self, guild_id: int, member_id: int, duration: Optional[float], reason: str='Auto') -> None: await self.wait_until_ready() if duration is not None: await asyncio.sleep(duration - time()) guild = self.get_guild(guild_id) if guild: guild_config = await self.db.get_guild_config(guild_id) log_channel: Optional[discord.TextChannel] = self.get_channel(tryint(guild_config.modlog.member_unban)) current_time = datetime.utcnow() offset = guild_config.time_offset current_time += timedelta(hours=offset) current_time_fmt = current_time.strftime('%H:%M:%S') try: await guild.unban(discord.Object(member_id), reason=reason) except discord.NotFound: pass else: if log_channel: user = self.get_user(member_id) name = getattr(user, 'name', '(no name)') await log_channel.send(f"`{current_time_fmt}` {name} ({member_id}) has been unbanned. Reason: {reason}") # set db pull: Dict[str, Any] = {'$pull': {'tempbans': {'member': str(member_id)}}} if duration is not None: pull['$pull']['tempbans']['time'] = duration await self.db.update_guild_config(guild_id, pull)
async def send_log(self, ctx: commands.Context, *args) -> None: guild_config = await self.bot.db.get_guild_config(ctx.guild.id) offset = guild_config.time_offset current_time = (ctx.message.created_at + timedelta(hours=offset)).strftime('%H:%M:%S') modlogs = DBDict( { i: tryint(guild_config.modlog[i]) for i in guild_config.modlog if i }, default=DEFAULT['modlog']) try: if ctx.command.name == 'purge': fmt = f'`{current_time}` {ctx.author} purged {args[0]} messages in **#{ctx.channel.name}**' if args[1]: fmt += f', from {args[1]}' await ctx.bot.get_channel(modlogs.message_purge).send(fmt) elif ctx.command.name == 'kick': fmt = f'`{current_time}` {ctx.author} kicked {args[0]} ({args[0].id}), reason: {args[1]}' await ctx.bot.get_channel(modlogs.member_kick).send(fmt) elif ctx.command.name == 'softban': fmt = f'`{current_time}` {ctx.author} softbanned {args[0]} ({args[0].id}), reason: {args[1]}' await ctx.bot.get_channel(modlogs.member_softban).send(fmt) elif ctx.command.name == 'ban': name = getattr(args[0], 'name', '(no name)') if args[2]: fmt = f'`{current_time}` {ctx.author} tempbanned {name} ({args[0].id}), reason: {args[1]} for {format_timedelta(args[2])}' else: fmt = f'`{current_time}` {ctx.author} banned {name} ({args[0].id}), reason: {args[1]}' await ctx.bot.get_channel(modlogs.member_ban).send(fmt) elif ctx.command.name == 'unban': name = getattr(args[0], 'name', '(no name)') fmt = f'`{current_time}` {ctx.author} unbanned {name} ({args[0].id}), reason: {args[1]}' await ctx.bot.get_channel(modlogs.member_unban).send(fmt) elif ctx.command.qualified_name == 'warn add': fmt = f'`{current_time}` {ctx.author} warned #{args[2]} {args[0]} ({args[0].id}), reason: {args[1]}' await ctx.bot.get_channel(modlogs.member_warn).send(fmt) elif ctx.command.qualified_name == 'warn remove': fmt = f'`{current_time}` {ctx.author} has deleted warn #{args[0]} - {args[1]}' await ctx.bot.get_channel(modlogs.member_warn).send(fmt) elif ctx.command.name == 'lockdown': fmt = f'`{current_time}` {ctx.author} has {"enabled" if args[0] else "disabled"} lockdown for {args[1].mention}' await ctx.bot.get_channel(modlogs.channel_lockdown).send(fmt) elif ctx.command.name == 'slowmode': fmt = f'`{current_time}` {ctx.author} has enabled slowmode for {args[0].mention} for {args[1]}' await ctx.bot.get_channel(modlogs.channel_slowmode).send(fmt) else: raise NotImplementedError( f'{ctx.command.name} not implemented for commands/send_log' ) except AttributeError: # channel not found [None.send()] pass
async def unmute(self, guild_id: int, member_id: int, duration: Optional[float], reason: str = 'Auto') -> None: await self.wait_until_ready() if duration is not None: await asyncio.sleep(duration - time()) try: member = self.get_guild(guild_id).get_member(member_id) member.guild.id except AttributeError: member = None if member: guild_config = await self.db.get_guild_config(guild_id) mute_role: Optional[discord.Role] = discord.utils.get( member.guild.roles, id=int(guild_config.mute_role)) log_channel: Optional[discord.TextChannel] = self.get_channel( tryint(guild_config.modlog.member_unmute)) current_time = datetime.utcnow() offset = guild_config.time_offset current_time += timedelta(hours=offset) current_time_fmt = current_time.strftime('%H:%M:%S') if member: if mute_role in member.roles: await member.remove_roles(mute_role) if log_channel: await log_channel.send( f"`{current_time_fmt}` {member} ({member.id}) has been unmuted. Reason: {reason}" ) else: if log_channel: await log_channel.send( f"`{current_time_fmt}` Tried to unmute {member} ({member.id}), member not in server" ) # set db pull: Dict[str, Any] = {'$pull': {'mutes': {'member': str(member_id)}}} if duration is not None: pull['$pull']['mutes']['time'] = duration await self.db.update_guild_config(guild_id, pull)
async def mute(self, actor: discord.Member, member: discord.Member, delta: timedelta, reason: str, modify_db: bool=True) -> None: """Mutes a ``member`` for ``delta``""" guild_config = await self.db.get_guild_config(member.guild.id) mute_role = discord.utils.get(member.guild.roles, id=int(guild_config.mute_role or 0)) if not mute_role: # mute role mute_role = discord.utils.get(member.guild.roles, name='Muted') if not mute_role: # existing mute role not found, let's create one mute_role = await member.guild.create_role( name='Muted', color=discord.Color(0x818689), reason='Attempted to mute user but role did not exist' ) for tc in member.guild.text_channels: try: await tc.set_permissions(mute_role, send_messages=False, reason='Attempted to mute user but role did not exist') except discord.Forbidden: pass for vc in member.guild.voice_channels: try: await vc.set_permissions(mute_role, speak=False, reason='Attempted to mute user but role did not exist') except discord.Forbidden: pass await self.db.update_guild_config(member.guild.id, {'$set': {'mute_role': str(mute_role.id)}}) await member.add_roles(mute_role) # mute complete, log it log_channel: discord.TextChannel = self.get_channel(tryint(guild_config.modlog.member_mute)) if log_channel: current_time = datetime.utcnow() offset = guild_config.time_offset current_time += timedelta(hours=offset) current_time_fmt = current_time.strftime('%H:%M:%S') await log_channel.send(f"`{current_time_fmt}` {actor} has muted {member} ({member.id}), reason: {reason} for {format_timedelta(delta)}") if delta: duration = delta.total_seconds() # log complete, save to DB if duration is not None: duration += time() if modify_db: await self.db.update_guild_config(member.guild.id, {'$push': {'mutes': {'member': str(member.id), 'time': duration}}}) self.loop.create_task(self.unmute(member.guild.id, member.id, duration))
async def on_raw_reaction_remove(self, payload: discord.RawReactionActionEvent) -> None: """Remove reaction roles""" reaction_roles = (await self.bot.db.get_guild_config(payload.guild_id)).reaction_roles emoji_id = payload.emoji.id or str(payload.emoji) msg_roles = list(filter(lambda r: int(r.message_id) == payload.message_id and tryint(r.emoji_id) == emoji_id, reaction_roles)) if len(msg_roles) == 1: guild = self.bot.get_guild(payload.guild_id) member = guild.get_member(payload.user_id) role = guild.get_role(int(msg_roles[0].role_id)) await member.remove_roles(role, reason='Reaction Role')