async def unban(self, ctx, user: BannedUser, *, reason: Reason = None): """Unbans a user previously banned in this guild. Sends the user a DM and logs this action to the guild's modlog if configured to do so. """ ban, banned_in_guild = user user = ban.user reason, note, audit_reason = reason or (None, None, None) audit_reason = audit_reason or Reason.format_reason(ctx) # actually unban them if banned_in_guild: await self._do_unban(guild=ctx.guild, user=user, mod=ctx.author, reason=reason, note=note, audit_reason=audit_reason) await ctx.send(f"{PRAY} Unbanned **{user}**.") # remove infraction from database if one was found but they're not banned. else: count = await modlog.deactivate_infractions( ctx.guild.id, user.id, 'ban') p = await self.bot.prefix(ctx.message) s, these = ('s', 'these') if count != 1 else ('', 'this') await ctx.send( f"{TICK_YELLOW} This user does not seem to be in this guild's ban list, " f"but I found {count} active ban infraction{s} in my database.\n" f"I marked {these} infraction{s} as inactive to account for this discrepancy. " f"`{p}history {user.id}` should now show no active bans.")
async def unmute(self, ctx, user: MutedUser, *, reason: Reason = None): """Unmutes a user using the guild's configured mute role. Sends the user a DM and logs this action to the guild's modlog if configured to do so. """ user, has_role = user reason, note, audit_reason = reason or (None, None, None) audit_reason = audit_reason or Reason.format_reason(ctx) # actually unmute them if has_role: delivered = await self._do_unmute(guild=ctx.guild, user=user, mod=ctx.author, reason=reason, note=note, audit_reason=audit_reason) await ctx.send(f"{PRAY} Unmuted **{user}**. {notified(delivered)}") # remove infraction from database if one was found but they're not muted. else: count = await modlog.deactivate_infractions( ctx.guild.id, user.id, 'mute') p = await self.bot.prefix(ctx.message) _s, _these = ('s', 'these') if count > 1 else ('', 'this') await ctx.send( f"{TICK_YELLOW} This user does not seem to have this guild's mute role, " f"but I found {count} active mute infraction{_s} in my database.\n" f"I marked {_these} infraction{_s} as inactive to account for this discrepancy. " f"`{p}history {user.id}` should now show no active mutes.")
async def mute(self, ctx, user: discord.Member, duration: Optional[Duration], *, reason: Reason = None): """Mutes a user using the guild's configured mute role. Sends the user a DM and logs this action to the guild's modlog if configured to do so. """ reason, note, audit_reason = reason or (None, None, None) audit_reason = audit_reason or Reason.format_reason(ctx) dt = exact_timedelta(duration) if duration else "permanent" try: muted_user, has_role = await MutedUser().convert(ctx, str(user.id)) except commands.BadArgument: muted_user, has_role = None, None # if already muted, edit the duration if muted_user and has_role: # first make sure they have an infraction. it's hard to edit an infraction that doesn't exist. if await modlog.has_active_infraction(ctx.guild.id, user.id, 'mute'): i, edited, old = await self._do_mute_duration_edit( guild=ctx.guild, user=user, new_duration=duration, edited_by=ctx.author) old = exact_timedelta(old) if old else 'permanent' await ctx.send(f"{TICK_YELLOW} User is already muted (#{i})" + (f", changed duration instead ({old} -> {dt})." if edited else '.')) # just kidding, we couldn't find an infraction. let's see if they want to create one. # note: we ask for a confirmation so things don't break when two infractions go through simultaneously else: await ctx.confirm_action( f"{TICK_YELLOW} This user appears to have this guild's mute role, " f"but does not have any active mute infractions. " f"Would you like to create an infraction? (y/n)") await LogEvent('mute', ctx.guild, user, ctx.author, reason, note, duration).dispatch() await ctx.send(OK_HAND) # otherwise, mute the user like normal else: delivered = await self._do_mute(guild=ctx.guild, user=user, mod=ctx.author, reason=reason, note=note, audit_reason=audit_reason, duration=duration) await ctx.send( f"{OK_HAND} Muted **{user}** ({dt}). {notified(delivered)}")
async def massmute(self, ctx, users: commands.Greedy[MentionOrUserID], duration: Optional[Duration], *, reason: Reason = None): """Mutes a set of members. User IDs or mentions must be provided. Users are not sent a DM notification, and this action is logged in a single message.""" reason, note, audit_reason = reason or (None, None, None) audit_reason = audit_reason or Reason.format_reason(ctx) await self._do_mass_mute(ctx, users, ctx.author, reason, note, audit_reason, duration)
async def kick(self, ctx, user: discord.Member, *, reason: Reason = None): """Kicks a user from the guild. Sends the user a DM and logs this action to the guild's modlog if configured to do so. """ reason, note, audit_reason = reason or (None, None, None) audit_reason = audit_reason or Reason.format_reason(ctx) delivered = await self._do_kick(guild=ctx.guild, user=user, mod=ctx.author, reason=reason, note=note, audit_reason=audit_reason) await ctx.send(f"{CLAP} Kicked **{user}**. {notified(delivered)}")
async def mban_file(self, ctx, *, reason: Reason = None): reason, note, audit_reason = reason or (None, None, None) audit_reason = audit_reason or Reason.format_reason(ctx) try: users = [ discord.Object(int(i)) for i in ( await ctx.message.attachments[0].read()).decode().split() ] except IndexError: raise ModerationError( "You need to attach a file to use this command!") except (TypeError, ValueError): raise ModerationError("Invalid file type.") await self._do_mass_ban(ctx, users, ctx.author, reason, note, audit_reason)
async def ban(self, ctx, user: UserID, duration: Optional[Duration], *, reason: Reason = None): """Bans a user from the guild. This will also work if the user is not in the server. Sends the user a DM and logs this action to the guild's modlog if configured to do so. """ reason, note, audit_reason = reason or (None, None, None) audit_reason = audit_reason or Reason.format_reason(ctx) dt = exact_timedelta(duration) if duration else "permanent" try: banned_user, banned_in_guild = await BannedUser().convert( ctx, str(user.id)) except commands.BadArgument: banned_user, banned_in_guild = None, None # if already banned, edit the duration if banned_user and banned_in_guild: # first make sure they have an infraction. it's hard to edit an infraction that doesn't exist. if await modlog.has_active_infraction(ctx.guild.id, user.id, 'ban'): i, edited, old = await self._do_ban_duration_edit( guild=ctx.guild, user=user, new_duration=duration, edited_by=ctx.author) old = exact_timedelta(old) if old else 'permanent' await ctx.send(f"{TICK_YELLOW} User is already banned (#{i})" + (f", changed duration instead ({old} -> {dt})." if edited else '.')) # just kidding, we couldn't find an infraction. let's see if they want to create one. # note: we ask for a confirmation so things don't break when two infractions go through simultaneously else: await ctx.confirm_action( f"{TICK_YELLOW} This user appears to be banned from this guild, " f"but does not have any active ban infractions. " f"Would you like to create an infraction? (y/n)") await LogEvent('ban', ctx.guild, user, ctx.author, reason, note, duration).dispatch() await ctx.send(OK_HAND) # we didn't seem to find anything weird, so let's just ban! else: user, delivered, force = await self._do_ban( guild=ctx.guild, user=user, mod=ctx.author, reason=reason, note=note, audit_reason=audit_reason, duration=duration) banned = 'Forcebanned' if force else 'Banned' await ctx.send( f"{HAMMER} {banned} **{user}** ({dt}). {notified(delivered)}")