1
0
Fork 0
mirror of synced 2024-04-29 10:12:29 +12:00
Bonfire/cogs/mod.py

164 lines
5.9 KiB
Python

from discord.ext import commands
import asyncio
import utils
import typing
import discord
class Moderation(commands.Cog):
"""Moderation commands, things that help control a server...but not the settings of the server"""
@commands.command()
@commands.guild_only()
@utils.can_run(kick_members=True)
async def kick(self, ctx, member: discord.Member, *, reason=None):
"""Used to kick a member from this server
EXAMPLE: !kick @Member
RESULT: They're kicked from the server?"""
try:
await member.kick(reason=reason)
await ctx.send("\N{OK HAND SIGN}")
except discord.Forbidden:
await ctx.send("But I can't, muh permissions >:c")
@commands.command()
@commands.guild_only()
@utils.can_run(ban_members=True)
async def unban(self, ctx, member_id: int):
"""Used to unban a member from this server
Due to the fact that I cannot find a user without being in a server with them
only the ID should be provided
EXAMPLE: !unban 353217589321750912
RESULT: That dude be unbanned"""
# Lets only accept an int for this method, in order to ensure only an ID is provided
# Due to that though, we need to ensure a string is passed as the member's ID
try:
await ctx.bot.http.unban(member_id, ctx.guild.id)
await ctx.send("\N{OK HAND SIGN}")
except discord.Forbidden:
await ctx.send("But I can't, muh permissions >:c")
except discord.HTTPException:
await ctx.send("Sorry, I failed to unban that user!")
@commands.command()
@commands.guild_only()
@utils.can_run(ban_members=True)
async def ban(
self, ctx, member: typing.Union[discord.Member, discord.Object], *, reason=None
):
"""Used to ban a member
This can be used to ban someone preemptively as well.
Provide the ID of the user and this should ban them without them being in the server
EXAMPLE: !ban 531251325312
RESULT: That dude be banned"""
try:
await ctx.guild.ban(member, reason=reason)
except discord.Forbidden:
await ctx.send("But I can't, muh permissions >:c")
except discord.HTTPException:
await ctx.send("Sorry, I failed to ban that user!")
else:
await ctx.send("\N{OK HAND SIGN}")
@commands.command()
@commands.guild_only()
@utils.can_run(manage_messages=True)
async def purge(self, ctx, limit: int = 100):
"""This command is used to a purge a number of messages from the channel
EXAMPLE: !purge 50
RESULT: -50 messages in this channel"""
if not ctx.message.channel.permissions_for(
ctx.message.guild.me
).manage_messages:
await ctx.send("I do not have permission to delete messages...")
return
try:
await ctx.message.channel.purge(limit=limit, before=ctx.message)
await ctx.message.delete()
except discord.HTTPException:
try:
await ctx.message.channel.send(
"Detected messages that are too far "
"back for me to delete; I can only bulk delete messages"
" that are under 14 days old."
)
except discord.Forbidden:
pass
@commands.command()
@commands.guild_only()
@utils.can_run(manage_messages=True)
async def prune(self, ctx, *specifications):
"""This command can be used to prune messages from certain members
Mention any user you want to prune messages from; if no members are mentioned, the messages removed will be mine
If no limit is provided, then 100 will be used. This is also the max limit we can use
EXAMPLE: !prune 50
RESULT: 50 of my messages are removed from this channel"""
# We can only get logs from 100 messages at a time, so make sure we are not above that threshold
limit = 100
for x in specifications:
try:
limit = int(x)
if limit <= 100:
break
else:
limit = 100
except (TypeError, ValueError):
continue
# If no members are provided, assume we're trying to prune our own messages
members = ctx.message.mentions
roles = ctx.message.role_mentions
if len(members) == 0:
members = [ctx.message.guild.me]
# Our check for if a message should be deleted
def check(m):
if m.author in members:
return True
if any(r in m.author.roles for r in roles):
return True
return False
# If we're not setting the user to the bot, then we're deleting someone elses messages
# To do so, we need manage_messages permission, so check if we have that
if not ctx.message.channel.permissions_for(
ctx.message.guild.me
).manage_messages:
await ctx.send("I do not have permission to delete messages...")
return
# Since logs_from will give us any message, not just the user's we need
# We'll increment count, and stop deleting messages if we hit the limit.
count = 0
async for msg in ctx.message.channel.history(before=ctx.message):
if check(msg):
try:
await msg.delete()
count += 1
except discord.HTTPException:
pass
if count >= limit:
break
msg = await ctx.send("{} messages succesfully deleted".format(count))
await asyncio.sleep(5)
try:
await msg.delete()
await ctx.message.delete()
except discord.HTTPException:
pass
def setup(bot):
bot.add_cog(Moderation(bot))