jarvis-bot/jarvis/cogs/starboard.py

279 lines
8.1 KiB
Python

from discord import TextChannel
from discord.ext import commands
from discord_slash import SlashContext, cog_ext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.types import Star, Starboard
from jarvis.utils import build_embed
supported_images = [
"image/png",
"image/gif",
"image/jpeg",
"image/webp",
"image/svg",
]
class StarboardCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
@cog_ext.cog_subcommand(
base="starboard",
name="list",
description="Lists all Starboards",
)
@commands.has_permissions(administrator=True)
async def _list(self, ctx):
starboards = Starboard.get_many(guild=ctx.guild.id)
if starboards != []:
message = "Available Starboards:\n"
for s in starboards:
message += f"<#{s.channel}>\n"
await ctx.send(message)
else:
await ctx.send("No Starboards available.")
@cog_ext.cog_subcommand(
base="starboard",
name="create",
description="Create a starboard",
options=[
create_option(
name="channel",
description="Starboard channel",
option_type=7,
required=True,
),
],
)
@commands.has_permissions(administrator=True)
async def _create(self, ctx, channel: TextChannel):
if channel not in ctx.guild.channels:
await ctx.send(
"Channel not in guild. Choose an existing channel.",
hidden=True,
)
return
if not isinstance(channel, TextChannel):
await ctx.send("Channel must be a TextChannel", hidden=True)
return
exists = Starboard.get(channel=channel.id, guild=ctx.guild.id)
if exists:
await ctx.send(
f"Starboard already exists at {channel.mention}.", hidden=True
)
return
_ = Starboard(
guild=ctx.guild.id,
channel=channel.id,
admin=ctx.author.id,
).insert()
await ctx.send(
f"Starboard created. Check it out at {channel.mention}."
)
@cog_ext.cog_subcommand(
base="starboard",
name="delete",
description="Delete a starboard",
options=[
create_option(
name="channel",
description="Starboard channel",
option_type=7,
required=True,
),
],
)
@commands.has_permissions(administrator=True)
async def _delete(self, ctx, channel: TextChannel):
deleted = Starboard.get(
channel=channel.id, guild=ctx.guild.id
).delete()
if deleted:
_ = Star.delete_many(starboard=channel.id)
await ctx.send(
f"Starboard deleted from {channel.mention}.", hidden=True
)
else:
await ctx.send(
f"Starboard not found in {channel.mention}.", hidden=True
)
@cog_ext.cog_subcommand(
base="star",
name="add",
description="Star a message",
options=[
create_option(
name="message",
description="Message to star",
option_type=3,
required=True,
),
create_option(
name="starboard",
description="Starboard to send message to",
option_type=7,
required=True,
),
create_option(
name="channel",
description="Channel that has the message, "
+ "required if different than command message",
option_type=7,
required=False,
),
],
)
@commands.has_permissions(administrator=True)
async def _star_add(
self,
ctx: SlashContext,
message: str,
starboard: TextChannel,
channel: TextChannel = None,
):
if not channel:
channel = ctx.channel
exists = Starboard.get(channel=starboard.id, guild=ctx.guild.id)
if not exists:
await ctx.send(
f"Starboard does not exist in {starboard.mention}. "
+ "Please create it first",
hidden=True,
)
return
if message.startswith("https://"):
message = message.split("/")[-1]
message = await channel.fetch_message(int(message))
exists = Star.get(
message=message.id,
channel=message.channel.id,
guild=message.guild.id,
starboard=starboard.id,
)
if exists:
await ctx.send(
f"Message already sent to Starboard {starboard.mention}",
hidden=True,
)
return
count = len(
Star.get_many(guild=message.guild.id, starboard=starboard.id)
)
content = message.content
attachments = message.attachments
image_url = None
if attachments:
for attachment in attachments:
if attachment.content_type in supported_images:
image_url = attachment.url
break
if not content and image_url:
content = "\u200b"
embed = build_embed(
title=f"[#{count}] Click Here to view context",
description=content,
fields=[],
url=message.jump_url,
timestamp=message.created_at,
)
embed.set_author(
name=message.author.name,
url=message.jump_url,
icon_url=message.author.avatar_url,
)
embed.set_footer(
text=message.guild.name + " | " + message.channel.name
)
if image_url:
embed.set_image(url=image_url)
star = await starboard.send(embed=embed)
_ = Star(
index=count,
message=message.id,
channel=message.channel.id,
guild=message.guild.id,
starboard=starboard.id,
admin=ctx.author.id,
star=star.id,
).insert()
await ctx.send(
"Message saved to Starboard.\n" + f"See it in {starboard.mention}"
)
@cog_ext.cog_subcommand(
base="star",
name="delete",
description="Delete a starred message",
guild_ids=[
862402786116763668,
418094694325813248,
578757004059738142,
],
options=[
create_option(
name="id",
description="Star to delete",
option_type=4,
required=True,
),
create_option(
name="starboard",
description="Starboard to delete star from",
option_type=7,
required=True,
),
],
)
async def _star_get(
self,
ctx: SlashContext,
id: int,
starboard: TextChannel,
):
exists = Starboard.get(channel=starboard.id, guild=ctx.guild.id)
if not exists:
await ctx.send(
f"Starboard does not exist in {starboard.mention}. "
+ "Please create it first",
hidden=True,
)
return
star = Star.get(
starboard=starboard.id,
id=id,
guild=ctx.guild.id,
active=True,
)
if not star:
await ctx.send(f"No star exists with id {id}", hidden=True)
return
message = await starboard.fetch_message(star.star)
if message:
await message.delete()
star.active = False
star.update()
await ctx.send(f"Star {id} deleted")
def setup(bot):
bot.add_cog(StarboardCog(bot))