Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

January 2021 Update #37

Merged
merged 12 commits into from
Mar 25, 2021
18 changes: 8 additions & 10 deletions cogs/channels.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import os
import discord
from discord.ext import commands
from discord import utils

import discord.emoji
from discord import utils
from discord.ext import commands

from embed import default_embed


class Channels(commands.Cog):
Expand All @@ -21,9 +23,7 @@ def get_news_role(ctx, channel: discord.TextChannel = None):
async def leaderboard(self, ctx):
sbhadr marked this conversation as resolved.
Show resolved Hide resolved
roles = [(r.name, len(r.members)) for r in ctx.guild.roles if 'news' in r.name]
roles.sort(key=lambda x: x[1], reverse=True)
embed = discord.Embed()
embed.set_author(name="Subscriber Leaderboards",
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
embed = default_embed('Subscriber Leaderboards')
for i, r in enumerate(roles):
embed.add_field(name=f"{i + 1}. {r[0]}", value=f"**Subscribers:** {r[1]}")
await ctx.send(embed=embed)
Expand Down Expand Up @@ -56,11 +56,9 @@ async def subscribe(self, ctx, channel: discord.TextChannel = None):
async def poll(self, ctx, *, args):
role = self.get_news_role(ctx)
await role.edit(mentionable=True)
await ctx.send(f'{role.mention}')
await ctx.send(role.mention)
await role.edit(mentionable=False)
embed = discord.Embed(Title="Poll")
embed.set_author(name="Poll",
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
embed = default_embed('Poll', title='Poll')
hasEmojis = ((args.find('[') and args.find(']')) != -1) # Regex?

if hasEmojis:
Expand Down
35 changes: 12 additions & 23 deletions cogs/logging.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,39 @@
import os
import discord

from discord import TextChannel
from discord.ext import commands

from embed import footer_embed


class Logging(commands.Cog):

def __init__(self, bot):
self.bot = bot
self.log_ch: TextChannel = self.bot.get_channel(int(os.getenv("MESSAGE_LOGS_CHANNEL")))

# Message Logging
@commands.Cog.listener()
async def on_message_delete(self, message):
channel = self.bot.get_channel(int(os.getenv("MESSAGE_LOGS_CHANNEL"))) # message-logs channel
emb = footer_embed(message, 'Message (Delete)', message.author.avatar_url)

# Avoid duplicate channel; i.e message delete from log channel
if message.channel == channel:
if message.channel == self.log_ch:
return

# Check Audit logs to find out who deleted the message
entries = await message.guild.audit_logs(limit=None, action=discord.AuditLogAction.message_delete).flatten()
base_entry = entries[0]

emb = discord.Embed()
emb.set_author(name="Message (Delete)",
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
emb.set_footer(text=f'{message.author}\t\t\t\t\t\tTimestamp: {message.created_at}',
icon_url=message.author.avatar_url)
emb.add_field(name="Message", value=message.content)
await channel.send(embed=emb)
await self.log_ch.send(embed=emb)

@commands.Cog.listener()
async def on_message_edit(self, before, after):
channel = self.bot.get_channel(int(os.getenv("MESSAGE_LOGS_CHANNEL"))) # message-logs channel

# If message data is malformed or blank, return
if (before.content == "") or (after.content == ""):
return

emb = discord.Embed()
emb.set_author(name="Message (Edit)",
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
emb.set_footer(text=f'{before.author}\t\t\t\t\t\tTimestamp: {after.created_at}',
icon_url=before.author.avatar_url)
emb.add_field(name="Before", value=(before.content), inline=False)
emb.add_field(name="After", value=(after.content), inline=False)
await channel.send(embed=emb)
emb = footer_embed(after, 'Message (Edit)', before.author.avatar_url)
emb.add_field(name="Before", value=before.content, inline=False)
emb.add_field(name="After", value=after.content, inline=False)
await self.log_ch.send(embed=emb)


def setup(bot):
Expand Down
3 changes: 2 additions & 1 deletion cogs/maintenance.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ async def reload(self, ctx, *, name: str):
await ctx.send(f'Error: {error}')
else:
await ctx.send(f'Reloaded: {name}')

@commands.command()
@commands.has_role("Moderator")
async def restart(self, ctx):
await self.bot.logout()


def setup(bot):
bot.add_cog(Maintenance(bot))
190 changes: 66 additions & 124 deletions cogs/moderation.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
import os

import discord
from discord.ext import commands
from discord import utils
from discord.ext import commands

import embed
from .data import Data

db = Data() # Initialize database


def prepare_action(ctx, name: str):
role = utils.get(ctx.guild.roles, name=name)
# Create default embed
emb = embed.footer_embed(ctx.message, 'Moderation')
channel = ctx.message.channel
return role, emb, channel


def process_action(ctx, title, emb, member: discord.Member, msg, duration=None):
emb.add_field(name=title, value=f'{member.mention} ({member.id})', inline=False)
if duration:
emb.add_field(name='Duration', value=f'{duration}', inline=False)
emb.add_field(name="Reason", value=f'{msg}', inline=False)
emb.add_field(name="Moderator",
value=ctx.message.author.mention,
inline=False)
# Add data to database
# (Action, Duration, Reason, Moderator, Target, Date)
db.modEntry.insert(title, duration, msg, ctx.message.author.id, member.id,
ctx.message.created_at)


class Moderation(commands.Cog):

def __init__(self, bot):
self.bot = bot
self.log_ch: discord.TextChannel = self.bot.get_channel(int(os.getenv("MODERATION_LOGS_CHANNEL")))

@commands.command()
@commands.has_role("Moderator")
Expand All @@ -21,123 +47,54 @@ async def ping_library_developers(self, ctx, title, *, message):
await role.edit(mentionable=False)

@commands.command()
@commands.has_role("Library Developer" or "Moderator")
@commands.has_any_role("Library Developer", "Moderator")
async def mute(self, ctx, member: discord.Member, duration, *, message):
role = utils.get(ctx.guild.roles, name="Muted")
channel = ctx.message.channel
log_channel = self.bot.get_channel(int(os.getenv("MODERATION_LOGS_CHANNEL"))) # moderation-logs channel

# Create default embed
emb = discord.Embed()
emb.set_author(name="Moderation",
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
emb.set_footer(text=f'\t\t\t\t\t\t\tTimestamp: {ctx.message.created_at}')
role, emb, channel = prepare_action(ctx, 'Muted')

# If Moderator invokes, mute from server and not just channel
if ((utils.get(ctx.guild.roles, name="Moderator") in ctx.message.author.roles)):
emb.add_field(name="Mute (Server)", value=f'{member.mention} ({member.id})', inline=False)
emb.add_field(name="Duration", value=f'{duration}', inline=False)
emb.add_field(name="Reason", value=f'{message}', inline=False)
emb.add_field(name="Moderator",
value=f'{ctx.message.author}#{ctx.message.author.discriminator} ({ctx.message.author.id})',
inline=False)
if utils.get(ctx.guild.roles, name='Moderator') in ctx.message.author.roles:
process_action(ctx, 'Mute (Server)', emb, member, message, duration)
await member.add_roles(role)

# Add data to database
# (Action, Duration, Reason, Moderator, Target, Date)
db.modEntry.insert("Mute (Server)", duration, message, ctx.message.author.id, member.id,
ctx.message.created_at)

# If Library Developer invokes, mute from channel and not server
elif ((utils.get(ctx.guild.roles, name="Library Developer") in ctx.message.author.roles) and (
if ((utils.get(ctx.guild.roles, name="Library Developer") in ctx.message.author.roles) and (
channel.category.name == "libraries" or channel.category.name == "frameworks")):
emb.add_field(name="Mute (Channel)", value=f'{member.mention} ({member.id})', inline=False)
emb.add_field(name="Duration", value=f'n/a', inline=False)
emb.add_field(name="Reason", value=f'n/a', inline=False)
emb.add_field(name="Moderator",
value=f'{ctx.message.author}#{ctx.message.author.discriminator} ({ctx.message.author.id})',
inline=False)
process_action(ctx, 'Mute (Channel)', emb, member, 'n/a')
await channel.set_permissions(member, read_messages=True, send_messages=False)

# Add data to database
# (Action, Duration, Reason, Moderator, Target, Date)
db.modEntry.insert("Mute (Channel)", duration, message, ctx.message.author.id, member.id,
ctx.message.created_at)

await ctx.message.add_reaction('👍')
await log_channel.send(embed=emb)
await self.log_ch.send(embed=emb)

@commands.command()
@commands.has_role("Library Developer" or "Moderator")
@commands.has_any_role("Library Developer", "Moderator")
async def unmute(self, ctx, member: discord.Member, *, message):
role = utils.get(ctx.guild.roles, name="Muted")
channel = ctx.message.channel
log_channel = self.bot.get_channel(int(os.getenv("MODERATION_LOGS_CHANNEL"))) # moderation-logs channel

# Create default embed
emb = discord.Embed()
emb.set_author(name="Moderation",
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
emb.set_footer(text=f'\t\t\t\t\t\t\tTimestamp: {ctx.message.created_at}')
role, emb, channel = prepare_action(ctx, 'Muted')

# If Moderator invokes, unmute from server and not just channel
if ((utils.get(ctx.guild.roles, name="Moderator") in ctx.message.author.roles)):
emb.add_field(name="Unmute (Server)", value=f'{member.mention} ({member.id})', inline=False)
emb.add_field(name="Reason", value=f'{message}', inline=False)
emb.add_field(name="Moderator",
value=f'{ctx.message.author}#{ctx.message.author.discriminator} ({ctx.message.author.id})',
inline=False)
if utils.get(ctx.guild.roles, name="Moderator") in ctx.message.author.roles:
process_action(ctx, 'Unmute (Server)', emb, member, message)
await member.remove_roles(role)

# Add data to database
# (Action, Duration, Reason, Moderator, Target, Date)
db.modEntry.insert("Unmute (Server)", None, message, ctx.message.author.id, member.id,
ctx.message.created_at)

# If Library Developer invokes, unmute from channel and not server
elif ((utils.get(ctx.guild.roles, name="Library Developer") in ctx.message.author.roles) and (
channel.category.name == "libraries" or channel.category.name == "frameworks")):
emb.add_field(name="Unmute (Channel)", value=f'{member.mention} ({member.id})', inline=False)
emb.add_field(name="Reason", value=f'{message}', inline=False)
emb.add_field(name="Moderator",
value=f'{ctx.message.author}#{ctx.message.author.discriminator} ({ctx.message.author.id})',
inline=False)
process_action(ctx, 'Unmute (Channel)', emb, member, message)
await channel.set_permissions(member, overwrite=None)

# Add data to database
# (Action, Duration, Reason, Moderator, Target, Date)
db.modEntry.insert("Unmute (Channel)", None, message, ctx.message.author.id, member.id,
ctx.message.created_at)

await ctx.message.add_reaction('👍')
await log_channel.send(embed=emb)
await self.log_ch.send(embed=emb)

@commands.command()
@commands.has_role("Library Developer" or "Moderator")
@commands.has_role("Moderator")
async def warn(self, ctx, member: discord.Member, *, message):
channel = ctx.message.channel
log_channel = self.bot.get_channel(int(os.getenv("MODERATION_LOGS_CHANNEL"))) # moderation-logs channel

# Create default embed
emb = discord.Embed()
emb.set_author(name="Moderation",
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
emb.set_footer(text=f'\t\t\t\t\t\t\tTimestamp: {ctx.message.created_at}')
emb.add_field(name="Warn", value=f'{member.mention} ({member.id})', inline=False)
emb.add_field(name="Reason", value=f'{message}', inline=False)
emb.add_field(name="Moderator",
value=f'{ctx.message.author}#{ctx.message.author.discriminator} ({ctx.message.author.id})',
inline=False)

# Add data to database
# (Action, Duration, Reason, Moderator, Target, Date)
db.modEntry.insert("Warn", None, message, ctx.message.author.id, member.id, ctx.message.created_at)
_, emb, channel = prepare_action(ctx, '')
process_action(ctx, 'Warn', emb, member, message)

await ctx.message.add_reaction('👍')
await log_channel.send(embed=emb)
await self.log_ch.send(embed=emb)

@commands.command()
@commands.has_role("Library Developer" or "Moderator")
@commands.has_any_role("Library Developer", "Moderator")
async def infractions(self, ctx, member: discord.Member):
i = 0

Expand All @@ -149,14 +106,12 @@ async def infractions(self, ctx, member: discord.Member):
await ctx.send(f'User "{member.id}" has no infractions.')
return

emb = discord.Embed()
emb.set_author(name="Moderation",
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
emb.set_footer(text=f'\t\t\t\t\t\t\tTimestamp: {ctx.message.created_at}')
_, emb, _ = prepare_action(ctx, '')

for case in query:
emb.add_field(name=f'Case Number: {case["index"]}',
value=f'Action: {case["action"]}\nDuration: {case["duration"]}\nUser: {case["target"]}\nReason: {case["reason"]}\nModerator: {case["moderator"]}\n Date: {case["date"]}',
value=f'Action: {case["action"]}\nDuration: {case["duration"]}\nUser: {case["target"]}\n'
f'Reason: {case["reason"]}\nModerator: {case["moderator"]}\n Date: {case["date"]}',
inline=False)
if i >= 25:
await ctx.send(embed=emb)
Expand Down Expand Up @@ -184,37 +139,24 @@ async def duration(self, ctx, id, *, _duration):

@commands.command()
@commands.has_role("Moderator")
async def clean(self, ctx, amount, member: discord.Member = None):
log_channel = self.bot.get_channel(int(os.getenv("MODERATION_LOGS_CHANNEL"))) # moderation-logs channel
emb = discord.Embed()
emb.set_author(name="Moderation",
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
emb.set_footer(text=f'\t\t\t\t\t\t\tTimestamp: {ctx.message.created_at}')

# If specific memeber is not specified
if not member:
emb.add_field(name="Message (Clean)", value=f'<#{ctx.message.channel.id}>', inline=False)
emb.add_field(name="Amount", value=f'{amount}', inline=False)
emb.add_field(name="Moderator",
value=f'{ctx.message.author}#{ctx.message.author.discriminator} ({ctx.message.author.id})',
inline=False)
await ctx.message.channel.purge(limit=int(amount) + 1)
await log_channel.send(embed=emb)
return

# If specific member is specified
emb.add_field(name="Message (Clean)", value=f'<#{ctx.message.channel.id}>', inline=False)
emb.add_field(name="Amount", value=f'{amount}', inline=False)
emb.add_field(name="From", value=f'{member.mention} ({member.id})', inline=False)
emb.add_field(name="Moderator",
value=f'{ctx.message.author}#{ctx.message.author.discriminator} ({ctx.message.author.id})',
inline=False)

def is_member(message):
return message.author.id == member.id

await ctx.message.channel.purge(limit=int(amount) + 1, check=is_member)
await log_channel.send(embed=emb)
async def clean(self, ctx, amount: int, member: discord.Member = None):
_, emb, ch = prepare_action(ctx, '')
emb.add_field(name='Message (Clean)', value=ch.mention, inline=False)

if member:
emb.add_field(name="From", value=member.mention, inline=False)

def is_member(message):
return message.author.id == member.id

msgs = await ctx.message.channel.purge(limit=amount + 1, check=is_member)
amount = len(msgs) - 1
# If specific member is not specified
else:
await ctx.message.channel.purge(limit=amount + 1)
emb.insert_field_at(1, name="Amount", value=str(amount), inline=False)
emb.add_field(name="Moderator", value=ctx.message.author.mention, inline=False)
await self.log_ch.send(embed=emb)


def setup(bot):
Expand Down
4 changes: 2 additions & 2 deletions cogs/tagging.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ async def tag(self, ctx, name=None):
return
emb = discord.Embed()
emb.set_footer(text=f'\t\t\t\t\t\t\tTimestamp: {result["date"]}',
icon_url="https://cdn.discordapp.com/attachments/336577284322623499/683028692133216300/ac6e275e1f638f4e19af408d8440e1d1.png")
icon_url='https://avatars1.githubusercontent.com/u/42101452?s=200&v=4')
sbhadr marked this conversation as resolved.
Show resolved Hide resolved
emb.add_field(name=f'{name}', value=result["content"], inline=False)
await ctx.send(embed=emb)
else:
result = db.taggingEntry.fetch_all(ctx.message.channel.id)
i = 0
if len(result) == 0:
await ctx.send(f'Tags in this channel "<#{ctx.message.channel.id}>" does not exist.')
await ctx.send(f'Tags in this channel "{ctx.channel.mention}" does not exist.')
return
emb = discord.Embed(title="Available tags for channel")
for entry in result:
Expand Down
Loading