First official build of bot!

Co-authored-by: iakrules <64628083+iakrules@noreply.github.com>
This commit is contained in:
rzmk 2021-08-01 14:24:02 -04:00
parent 953c89ead0
commit 2b8e2345f9
32 changed files with 1164 additions and 383 deletions

View file

@ -1,162 +1,161 @@
import asyncio
import discord
from discord.ext import commands
import youtube_dl
import os
ffmpeg_options = {
'options': '-vn'
}
ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
self.title = data.get('title')
self.url = data.get('url')
@classmethod
async def from_url(cls, url, *, loop=None, stream=False):
loop = loop or asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))
if 'entries' in data:
# take first item from a playlist
data = data['entries'][0]
filename = data['url'] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
class MusicCog(commands.Cog):
def __init__(self, client):
self.client = client
# Commands
@commands.command()
async def play(self, ctx, url):
"""Streams from a url"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
try:
channel = ctx.author.voice.channel
await channel.connect()
except:
pass
async with ctx.typing():
player = await YTDLSource.from_url(url, loop=self.client.loop, stream=True)
ctx.voice_client.play(player, after=lambda e: print(f'Player error: {e}') if e else None)
await ctx.send(f'Now playing: {player.title}')
@play.error
async def play_error(self, ctx, error):
if isinstance(error, commands.MissingRequiredArgument):
voice = ctx.voice_client
if voice != None and voice.is_paused():
voice.resume()
else:
await ctx.send("Missing URL!")
@commands.command(aliases=['disconnect, dc'])
async def leave(self, ctx):
"""Disconnects bot from the voice channel"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
voice = ctx.voice_client
if voice is not None:
if voice.is_connected():
await voice.disconnect()
else:
await ctx.send("The bot is not connected to a voice channel.")
@commands.command()
async def volume(self, ctx, volume: int):
"""Changes the player's volume"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
if ctx.voice_client is None:
return await ctx.send("Not connected to a voice channel.")
ctx.voice_client.source.volume = volume / 100
await ctx.send(f"Changed volume to {volume}%")
@commands.command()
async def pause(self, ctx):
"""Pauses audio"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
voice = ctx.voice_client
if voice.is_playing():
voice.pause()
else:
await ctx.send("Currently no audio is playing.")
@commands.command()
async def resume(self, ctx):
"""Resumes currently paused audio"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
voice = ctx.voice_client
if voice.is_paused():
voice.resume()
else:
await ctx.send("The audio is not paused.")
@commands.command()
async def stop(self, ctx):
"""Stops and disconnects the bot from voice"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
voice = ctx.voice_client
if voice:
voice.stop()
@commands.command(aliases=['join'])
async def connect(self, ctx):
"""Connects bot to currently connected voice channel"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
channel = ctx.author.voice.channel
try:
await channel.connect()
except:
voice = ctx.voice_client
if voice.is_connected() and voice.channel != channel:
await voice.disconnect()
await channel.connect()
def setup(client):
client.add_cog(MusicCog(client))
import asyncio
import discord
from discord.ext import commands
import youtube_dl
import os
ffmpeg_options = {
'options': '-vn'
}
ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0' # Bind to ipv4 since ipv6 addresses cause issues sometimes
}
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
self.title = data.get('title')
self.url = data.get('url')
@classmethod
async def from_url(cls, url, *, loop=None, stream=False):
loop = loop or asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))
if 'entries' in data:
# Take first item from a playlist
data = data['entries'][0]
filename = data['url'] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
class AudioCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command()
async def play(self, ctx, url):
"""Streams from a url"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
try:
channel = ctx.author.voice.channel
await channel.connect()
except:
pass
async with ctx.typing():
player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True)
ctx.voice_client.play(player, after=lambda e: print(f'Player error: {e}') if e else None)
await ctx.send(f'Now playing: {player.title}')
@play.error
async def play_error(self, ctx, error):
if isinstance(error, commands.MissingRequiredArgument):
voice = ctx.voice_client
if voice != None and voice.is_paused():
voice.resume()
else:
await ctx.send("Missing URL!")
@commands.command(aliases=['disconnect, dc'])
async def leave(self, ctx):
"""Disconnects bot from the voice channel"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
voice = ctx.voice_client
if voice is not None:
if voice.is_connected():
await voice.disconnect()
else:
await ctx.send("The bot is not connected to a voice channel.")
@commands.command()
async def volume(self, ctx, volume: int):
"""Changes the player's volume"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
if ctx.voice_client is None:
return await ctx.send("Not connected to a voice channel.")
ctx.voice_client.source.volume = volume / 100
await ctx.send(f"Changed volume to {volume}%")
@commands.command()
async def pause(self, ctx):
"""Pauses audio"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
voice = ctx.voice_client
if voice.is_playing():
voice.pause()
else:
await ctx.send("Currently no audio is playing.")
@commands.command()
async def resume(self, ctx):
"""Resumes currently paused audio"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
voice = ctx.voice_client
if voice.is_paused():
voice.resume()
else:
await ctx.send("The audio is not paused.")
@commands.command()
async def stop(self, ctx):
"""Stops and disconnects the bot from voice"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
voice = ctx.voice_client
if voice:
voice.stop()
@commands.command(aliases=['join'])
async def connect(self, ctx):
"""Connects bot to currently connected voice channel"""
if ctx.author.voice is None:
return await ctx.send("You're not connected to a voice channel.")
channel = ctx.author.voice.channel
try:
await channel.connect()
except:
voice = ctx.voice_client
if voice.is_connected() and voice.channel != channel:
await voice.disconnect()
await channel.connect()
def setup(bot):
bot.add_cog(AudioCog(bot))

View file

@ -1,59 +1,56 @@
import os
import discord
import DiscordUtils
import datetime
from dateutil.parser import parse
import requests
from discord.ext import commands
class CalendarCog(commands.Cog):
def __init__(self, client):
self.client = client
# Commands
@commands.command()
async def events(self, ctx):
"""Gets all upcoming events from Google Calendar"""
# Check if environment variable exists
if not os.environ.get("GOOGLE_CALENDAR_ENDPOINT"):
return await ctx.send("No Google Calendar endpoint specified!")
# Get upcoming events data from calendar
current_time = datetime.datetime.utcnow()
formatted_time = current_time.isoformat("T") + "Z"
calendar = os.environ.get("GOOGLE_CALENDAR_ENDPOINT") + "&timeMin=" + formatted_time
data = requests.get(calendar).json()
# Check if there are any events
if not data["items"]:
return await ctx.send("There are no upcoming events!")
# Get all upcoming events as a list
list_of_events = data["items"]
embeds = []
for event in list_of_events:
# Create data set
title = event["summary"]
start_time = event["start"]["dateTime"]
description = "No description."
if "description" in event:
description = event["description"]
formatted_start_time = datetime.datetime.strftime(parse(start_time), format="%B %d, %Y")
# Create embed for single event and add to embeds list
embed = discord.Embed(color=ctx.author.color, title=title, description=description)
embed.add_field(name="Starts On", value=formatted_start_time, inline=True)
embeds.append(embed)
# Create paginator
paginator = DiscordUtils.Pagination.CustomEmbedPaginator(ctx)
paginator.add_reaction('⏮️', "first")
paginator.add_reaction('', "back")
paginator.add_reaction('', "next")
paginator.add_reaction('⏭️', "last")
await paginator.run(embeds)
def setup(client):
client.add_cog(CalendarCog(client))
import os
import discord
import DiscordUtils
import datetime
from dateutil.parser import parse
import requests
from discord.ext import commands
class CalendarCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command()
async def events(self, ctx):
"""Gets all upcoming events from Google Calendar"""
# Check if environment variable exists
if not os.environ.get("GOOGLE_CALENDAR_ENDPOINT"):
return await ctx.send("No Google Calendar endpoint specified!")
# Get upcoming events data from calendar
current_time = datetime.datetime.utcnow()
formatted_time = current_time.isoformat("T") + "Z"
calendar = os.environ.get("GOOGLE_CALENDAR_ENDPOINT") + "&timeMin=" + formatted_time
data = requests.get(calendar).json()
# Check if there are any events
if not data["items"]:
return await ctx.send("There are no upcoming events!")
# Get all upcoming events as a list
list_of_events = data["items"]
embeds = []
for event in list_of_events:
# Create data set
title = event["summary"]
start_time = event["start"]["dateTime"]
description = event["description"] if "description" in event else "No description."
formatted_start_time = datetime.datetime.strftime(parse(start_time), format="%B %d, %Y")
# Create embed for single event and add to embeds list
embed = discord.Embed(color=ctx.author.color, title=title, description=description)
embed.add_field(name="Starts On", value=formatted_start_time, inline=True)
embeds.append(embed)
# Create paginator
paginator = DiscordUtils.Pagination.CustomEmbedPaginator(ctx)
paginator.add_reaction('⏮️', "first")
paginator.add_reaction('', "back")
paginator.add_reaction('', "next")
paginator.add_reaction('⏭️', "last")
await paginator.run(embeds)
def setup(bot):
bot.add_cog(CalendarCog(bot))

30
cogs/info/infoCog.py Normal file
View file

@ -0,0 +1,30 @@
import discord
from discord.ext import commands
class InfoCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command(aliases=['botinfo'])
async def info(self, ctx):
embed = discord.Embed(
title=f"Rutgers Esports Bot <:RutgersEsports:608498339192766505>",
description=(
f'Rutgers Esports Bot is the official Discord bot\n'
'for handling all internal Rutgers Esports operations.\n\n'
'🔗 Check out Rutgers Esports '
'[here](https://linktr.ee/RutgersEsports).\n'
'🤖 To add this bot to your server use '
'[this link](https://bit.ly/rutgers-esports-bot).\n'
"⭐ Star our repo on GitHub [here](https://github.com/rutgersesports/discord-bot)."
),
color=0xC94949
)
embed.set_thumbnail(url=ctx.bot.user.avatar_url)
await ctx.send(embed=embed)
def setup(bot):
bot.add_cog(InfoCog(bot))

View file

@ -1,16 +1,16 @@
import discord
from discord.ext import commands
class PingCog(commands.Cog):
def __init__(self, client):
self.client = client
# Commands
@commands.command(aliases=['latency'])
async def ping(self, ctx):
"""Returns the bot client latency"""
await ctx.send(f'Pong! {round(self.client.latency * 1000)}ms')
def setup(client):
client.add_cog(PingCog(client))
import discord
from discord.ext import commands
class PingCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command(aliases=['latency'])
async def ping(self, ctx):
"""Returns the bot bot latency"""
await ctx.send(f'Pong! {round(self.bot.latency * 1000)}ms')
def setup(bot):
bot.add_cog(PingCog(bot))

35
cogs/info/serverCog.py Normal file
View file

@ -0,0 +1,35 @@
import discord
from discord.ext import commands
class ServerCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command(aliases=['server', 'sinfo'])
async def serverinfo(self, ctx):
"""Get information about the current server"""
guild = ctx.guild
roles = str(len(guild.roles))
emojis = str(len(guild.emojis))
vchannels = str(len(guild.voice_channels))
tchannels = str(len(guild.text_channels))
embed = discord.Embed(title='Server info', description=guild.name, color=ctx.guild.get_member(ctx.bot.user.id).color)
embed.set_thumbnail(url=guild.icon_url)
embed.add_field(name='ID', value=guild.id, inline=True)
embed.add_field(name='Owner', value=guild.owner, inline=True)
embed.add_field(name='Members', value=guild.member_count, inline=True)
embed.add_field(name='Text channels', value=tchannels, inline=True)
embed.add_field(name='Voice channels', value=vchannels, inline=True)
embed.add_field(name='Created on', value=guild.created_at.strftime('%B %d, %Y'), inline=True)
embed.add_field(name='Region', value=guild.region, inline=True)
embed.add_field(name='Roles', value=roles, inline=True)
embed.add_field(name='Verification', value=guild.verification_level, inline=True)
await ctx.send(embed=embed)
def setup(bot):
bot.add_cog(ServerCog(bot))

44
cogs/info/userCog.py Normal file
View file

@ -0,0 +1,44 @@
import discord
from discord.ext import commands
class UserCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command(aliases=['whois'])
async def userinfo(self, ctx, member: discord.Member = None):
"""Get information about a given user"""
# Gather data
member = ctx.author if not member else member
roles = [role for role in member.roles]
default_role = discord.utils.get(member.guild.roles, name='@everyone')
role_mentions = [f'{role.mention}' for role in sorted(member.roles, key=lambda x: x.position, reverse=True) if role != default_role]
all_perms = [x for x in dir(ctx.channel.permissions_for(member))]
permissions = []
for perm in all_perms:
perm_name = perm
if getattr(ctx.channel.permissions_for(member), perm_name) is True:
permissions.append(perm_name.title().replace("_", " ").replace("Tts", "TTS"))
# Create embed
embed = discord.Embed(description = member.mention, color = member.color, timestamp = ctx.message.created_at)
embed.set_author(name = member, icon_url = member.avatar_url)
embed.set_thumbnail(url = member.avatar_url)
embed.set_footer(text = member.id)
embed.add_field(name = 'Joined', value = member.joined_at.strftime('%a, %d %B %Y, %I:%M %p UTC'), inline=True)
embed.add_field(name = 'Registered', value = member.created_at.strftime('%a, %d %B %Y, %I:%M %p UTC'), inline=True)
embed.add_field(name=f'Roles [{len(roles)}]', value=", ".join(role_mentions)+f', {default_role}', inline=False)
embed.add_field(name=f'Permissions [{len(permissions)}]', value=", ".join(permissions), inline=False)
embed.add_field(name='Nickname', value=member.nick if hasattr(member, 'nick') else 'None', inline=True)
await ctx.send(embed = embed)
def setup(bot):
bot.add_cog(UserCog(bot))

View file

@ -1,61 +1,61 @@
import os
import discord
import DiscordUtils
import asyncio
from google.cloud import firestore
from discord.ext import commands
from dotenv import load_dotenv
load_dotenv()
class InventoryCog(commands.Cog):
def __init__(self, client):
self.client = client
# Commands
# Get a single item from inventory
@commands.command(aliases=['inv'])
@commands.is_owner()
async def inventory(self, ctx, arg1):
"""Get a single item from the inventory database"""
# Make single input embed
def single_embed(item, id):
embed = discord.Embed(title=item["item_name"], description=id)
if item["item_type"] != "": embed.add_field(name="Item Type", value=item["item_type"], inline=True)
if item["color"] != "": embed.add_field(name="Color", value=item["color"], inline=True)
if item["brand"] != "": embed.add_field(name="Brand", value=item["brand"], inline=True)
if item["model"] != "": embed.add_field(name="Model", value=item["model"], inline=True)
if item["size"] != "": embed.add_field(name="Size", value=item["size"], inline=True)
if item["quantity"] != "": embed.add_field(name="Quantity", value=item["quantity"], inline=True)
if item["box"] != "": embed.add_field(name="Box", value=item["box"], inline=True)
return embed
# Connect to Firestore DB inventory collection and get the item arg1 as doc
if "INVENTORY_PROJECT_ID" in os.environ and "GOOGLE_APPLICATION_CREDENTIALS" in os.environ:
try:
db = firestore.AsyncClient(project=os.environ.get("INVENTORY_PROJECT_ID"))
inventory_ref = db.collection("inventory").document(arg1)
doc = await inventory_ref.get()
if doc.exists:
await ctx.send(embed=single_embed(doc.to_dict(), doc.id))
else:
await ctx.send("That ID doesn't exist!")
except:
await ctx.send("The DB connection is not working.")
elif "INVENTORY_PROJECT_ID" not in os.environ and "GOOGLE_APPLICATION_CREDENTIALS" in os.environ:
await ctx.send("Inventory Project ID not found!")
elif "GOOGLE_APPLICATION_CREDENTIALS" not in os.environ:
await ctx.send("GAPP Credentials not found!")
@inventory.error
async def inventory_error(self, ctx, error):
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send("Missing required argument! (e.g. d!inventory __10000__)")
if isinstance(error, commands.NotOwner):
await ctx.send("You do not have permissions to run this command.")
def setup(client):
client.add_cog(InventoryCog(client))
import os
import discord
import DiscordUtils
import asyncio
from google.cloud import firestore
from discord.ext import commands
from dotenv import load_dotenv
load_dotenv()
class InventoryCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
# Get a single item from inventory
@commands.command(aliases=['inv'])
@commands.is_owner()
async def inventory(self, ctx, arg1):
"""Get a single item from the inventory database"""
# Make single input embed
def single_embed(item, id):
embed = discord.Embed(title=item["item_name"], description=id)
if item["item_type"] != "": embed.add_field(name="Item Type", value=item["item_type"], inline=True)
if item["color"] != "": embed.add_field(name="Color", value=item["color"], inline=True)
if item["brand"] != "": embed.add_field(name="Brand", value=item["brand"], inline=True)
if item["model"] != "": embed.add_field(name="Model", value=item["model"], inline=True)
if item["size"] != "": embed.add_field(name="Size", value=item["size"], inline=True)
if item["quantity"] != "": embed.add_field(name="Quantity", value=item["quantity"], inline=True)
if item["box"] != "": embed.add_field(name="Box", value=item["box"], inline=True)
return embed
# Connect to Firestore DB inventory collection and get the item arg1 as doc
if "INVENTORY_PROJECT_ID" in os.environ and "GOOGLE_APPLICATION_CREDENTIALS" in os.environ:
try:
db = firestore.AsyncClient(project=os.environ.get("INVENTORY_PROJECT_ID"))
inventory_ref = db.collection("inventory").document(arg1)
doc = await inventory_ref.get()
if doc.exists:
await ctx.send(embed=single_embed(doc.to_dict(), doc.id))
else:
await ctx.send("That ID doesn't exist!")
except:
await ctx.send("The DB connection is not working.")
elif "INVENTORY_PROJECT_ID" not in os.environ and "GOOGLE_APPLICATION_CREDENTIALS" in os.environ:
await ctx.send("Inventory Project ID not found!")
elif "GOOGLE_APPLICATION_CREDENTIALS" not in os.environ:
await ctx.send("GAPP Credentials not found!")
@inventory.error
async def inventory_error(self, ctx, error):
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send("Missing required argument! (e.g. d!inventory __10000__)")
if isinstance(error, commands.NotOwner):
await ctx.send("You do not have permissions to run this command.")
def setup(bot):
bot.add_cog(InventoryCog(bot))

View file

@ -0,0 +1,64 @@
import discord
from discord.ext import commands
class EmbedCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command()
async def embed(self, ctx, *, data):
"""Produces a customizable embed"""
# Split arguments into a list
data = data.split("%%")
# Set default channel to current channel where command is used
channel = ctx.channel
# Remove [''] surrounding possible channel argument input (slice value to just channel ID)
possible_channel = data[0].rstrip()[2:-1]
# Set channel if channel argument is given
try:
channel = await commands.TextChannelConverter().convert(ctx, possible_channel)
data.pop(0)
except Exception as e:
pass
# Check if user has permission to send in given channel
if not ctx.guild.get_member(ctx.author.id).permissions_in(channel).send_messages:
return await ctx.send(f"You don't have permission to send messages to {channel.mention}!")
# Add possible empty list values to deter IndexError for embed
data += [""] * (3-len(data))
# Create and send embed
embed = discord.Embed(
title=f"{data[0]}",
description=f"{data[1]}",
color=ctx.guild.get_member(ctx.bot.user.id).color
)
embed.set_footer(
text=f"{data[2]}"
)
await channel.send(embed=embed)
@embed.error
async def embed_error(self, ctx, error):
await ctx.send(
"Type the command in the following format:```.embed #channel_name %% title %% description %% footer```"
)
embed = discord.Embed(
title="Title",
description="Description",
color=ctx.guild.get_member(ctx.bot.user.id).color
)
embed.set_footer(
text="Footer"
)
await ctx.send(embed=embed)
def setup(bot):
bot.add_cog(EmbedCog(bot))

View file

@ -1,31 +1,31 @@
import discord
from discord.ext import commands
class ModerationCog(commands.Cog):
def __init__(self, client):
self.client = client
# Commands
@commands.command()
@commands.has_permissions(kick_members = True)
async def kick(self, ctx, member : commands.MemberConverter, *, reason="No reason provided."):
"""Kick a user from the server"""
try:
await member.kick(reason=reason)
await ctx.send(member.mention + " has been kicked.")
except:
await ctx.send(f"Unable to kick {member.mention}.\nIs {member.mention} at the same role level or higher than {self.client.user.name}?")
@commands.command()
@commands.has_permissions(ban_members = True)
async def ban(self, ctx, member : commands.MemberConverter, *, reason="No reason provided."):
"""Ban a user from the server"""
try:
await member.ban(reason=reason)
await ctx.send(member.mention + " has been banned.")
except:
await ctx.send(f"Unable to ban {member.mention}.\nIs {member.mention} at the same role level or higher than {self.client.user.name}?")
def setup(client):
client.add_cog(ModerationCog(client))
import discord
from discord.ext import commands
class ModerationCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command()
@commands.has_permissions(kick_members = True)
async def kick(self, ctx, member : commands.MemberConverter, *, reason="No reason provided."):
"""Kick a user from the server"""
try:
await member.kick(reason=reason)
await ctx.send(member.mention + " has been kicked.")
except:
await ctx.send(f"Unable to kick {member.mention}.\nIs {member.mention} at the same role level or higher than {self.bot.user.name}?")
@commands.command()
@commands.has_permissions(ban_members = True)
async def ban(self, ctx, member : commands.MemberConverter, *, reason="No reason provided."):
"""Ban a user from the server"""
try:
await member.ban(reason=reason)
await ctx.send(member.mention + " has been banned.")
except:
await ctx.send(f"Unable to ban {member.mention}.\nIs {member.mention} at the same role level or higher than {self.bot.user.name}?")
def setup(bot):
bot.add_cog(ModerationCog(bot))

View file

@ -0,0 +1,18 @@
import discord
from discord.ext import commands
class PruneCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command(aliases=['clear', 'prune'])
@commands.has_permissions(manage_messages=True)
async def purge(self, ctx, amount=10):
"""Removes a number of messages (10 by default)"""
await ctx.channel.purge(limit=amount+1)
await ctx.send(f'`{amount}` messages deleted.', delete_after=3)
def setup(bot):
bot.add_cog(PruneCog(bot))

23
cogs/owner/loaderCog.py Normal file
View file

@ -0,0 +1,23 @@
import discord
from discord.ext import commands
class LoaderCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.is_owner()
@commands.command()
async def load(self, ctx, extension):
"""Loads a cog"""
self.bot.load_extension(f'cogs.{extension}')
@commands.is_owner()
@commands.command()
async def unload(self, ctx, extension):
"""Unloads a cog"""
self.bot.unload_extension(f'cogs.{extension}')
def setup(bot):
bot.add_cog(LoaderCog(bot))

18
cogs/owner/sayCog.py Normal file
View file

@ -0,0 +1,18 @@
import discord
from discord.ext import commands
class SayCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command(aliases=['speak'])
@commands.is_owner()
async def say(self, ctx, *, content):
"""Lets the bot say given arguments"""
await ctx.message.delete()
await ctx.send(content)
def setup(bot):
bot.add_cog(SayCog(bot))

29
cogs/owner/statusCog.py Normal file
View file

@ -0,0 +1,29 @@
import discord
from discord.ext import commands
class StatusCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Commands
@commands.command(aliases=['botstatus', 'stat'])
@commands.is_owner()
async def status(self, ctx):
"""Gives bot statistics"""
# Total members of all servers bot is in
total_guild_users = 0
for guild in ctx.bot.guilds:
total_guild_users += guild.member_count
embed = discord.Embed(
title=f"Bot Status",
description=(f'`{ctx.bot.user.name}` is online.'
f'\nBot is in `{len(ctx.bot.guilds)}` guilds.'
f'\nGuilds have `{total_guild_users}` members.'),
color=ctx.guild.get_member(ctx.bot.user.id).color
)
await ctx.send(embed=embed)
def setup(bot):
bot.add_cog(StatusCog(bot))