1
0
Fork 0
This repository has been archived on 2024-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
Administrator-py/extensions/rorec.py

296 lines
12 KiB
Python
Raw Permalink Normal View History

2020-07-23 21:31:42 +02:00
from discord.abc import GuildChannel
from discord.ext import commands
from discord import Embed, RawReactionActionEvent, RawBulkMessageDeleteEvent, RawMessageDeleteEvent, NotFound, \
2021-02-04 09:46:36 +01:00
InvalidArgument, HTTPException, TextChannel, Forbidden, Role, Message
2020-07-23 21:31:42 +02:00
from discord.ext.commands import BadArgument
2021-02-04 09:46:36 +01:00
from discord_slash import cog_ext, SlashContext, SlashCommandOptionType
from discord_slash.utils import manage_commands
2020-07-23 21:31:42 +02:00
2021-02-04 09:46:36 +01:00
from administrator import db, slash
from administrator.check import is_enabled, guild_only, has_permissions
2020-07-23 21:31:42 +02:00
from administrator.logger import logger
2021-02-04 09:46:36 +01:00
from administrator.utils import event_is_enabled, get_message_by_url
2020-07-23 21:31:42 +02:00
extension_name = "rorec"
logger = logger.getChild(extension_name)
class RoRec(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
2021-02-04 09:46:36 +01:00
slash.get_cog_commands(self)
2020-07-23 21:31:42 +02:00
def description(self):
return "Create role-reaction message to give role from a reaction add"
2020-07-23 21:31:42 +02:00
@staticmethod
2021-02-04 09:46:36 +01:00
async def get_message(session: db.Session, ctx: SlashContext, url: str) -> db.RoRec:
m = session.query(db.RoRec).filter(db.RoRec.message == (await get_message_by_url(ctx, url)).id and
db.RoRec.guild == ctx.guild.id).first()
2020-07-23 21:31:42 +02:00
if not m:
raise BadArgument()
else:
return m
2021-02-04 09:46:36 +01:00
async def try_emoji(self, msg: Message, emoji: str):
2020-07-23 21:31:42 +02:00
try:
2021-02-04 09:46:36 +01:00
await msg.add_reaction(emoji)
2020-07-23 21:31:42 +02:00
except (HTTPException, NotFound, InvalidArgument):
raise BadArgument()
else:
2021-02-04 09:46:36 +01:00
await (await msg.channel.fetch_message(msg.id)).remove_reaction(emoji, self.bot.user)
@cog_ext.cog_subcommand(base="rorec", name="new",
description="Create a new role-reaction message on the mentioned channel",
options=[
manage_commands.create_option("title", "The title",
SlashCommandOptionType.STRING, True),
manage_commands.create_option("channel", "The target channel",
SlashCommandOptionType.CHANNEL, True),
manage_commands.create_option("description", "The description",
SlashCommandOptionType.STRING, False),
manage_commands.create_option("one", "If only one role is packable",
SlashCommandOptionType.BOOLEAN, False)
])
@is_enabled()
2021-02-04 09:46:36 +01:00
@guild_only()
@has_permissions(manage_roles=True)
async def rorec_new(self, ctx: SlashContext, title: str, channel: GuildChannel, description: str = "",
2020-07-23 21:31:42 +02:00
one: bool = False):
2021-02-04 09:46:36 +01:00
if not isinstance(channel, TextChannel):
2020-07-23 21:31:42 +02:00
raise BadArgument()
embed = Embed(title=title, description=description)
embed.add_field(name="Roles", value="No role yet...")
message = await channel.send(embed=embed)
r = db.RoRec(message.id, channel.id, ctx.guild.id, one)
s = db.Session()
s.add(r)
s.commit()
2020-11-06 18:03:09 +01:00
s.close()
2021-02-04 09:46:36 +01:00
await ctx.send(content="\U0001f44d")
@cog_ext.cog_subcommand(base="rorec", name="edit",
description="Edit a role-reaction message title and description",
options=[
manage_commands.create_option("url", "The message url",
SlashCommandOptionType.STRING, True),
manage_commands.create_option("title", "The new title",
SlashCommandOptionType.STRING, True),
manage_commands.create_option("description", "The new description",
SlashCommandOptionType.STRING, False)
])
@is_enabled()
@guild_only()
@has_permissions(manage_roles=True)
async def rorec_edit(self, ctx: SlashContext, url: str, title: str, description: str = ""):
2020-07-23 21:31:42 +02:00
s = db.Session()
2021-02-04 09:46:36 +01:00
m = await self.get_message(s, ctx, url)
2020-07-23 21:31:42 +02:00
s.close()
message = await ctx.guild.get_channel(m.channel).fetch_message(m.message)
embed: Embed = message.embeds[0]
embed.title = title
embed.description = description
await message.edit(embed=embed)
2021-02-04 09:46:36 +01:00
await ctx.send(content="\U0001f44d")
@cog_ext.cog_subcommand(base="rorec", name="set",
description="Add/edit a emoji with linked roles",
options=[
manage_commands.create_option("url", "The message url",
SlashCommandOptionType.STRING, True),
manage_commands.create_option("emoji", "The emoji",
SlashCommandOptionType.STRING, True),
manage_commands.create_option("role", "The role",
SlashCommandOptionType.ROLE, True)
])
@is_enabled()
@guild_only()
@has_permissions(manage_roles=True)
async def rorec_set(self, ctx: SlashContext, url: str, emoji: str, role: Role):
await ctx.send(content="\U000023f3")
2020-07-23 21:31:42 +02:00
s = db.Session()
2021-02-04 09:46:36 +01:00
m = await self.get_message(s, ctx, url)
2020-07-23 21:31:42 +02:00
2021-02-04 09:46:36 +01:00
await ctx.delete()
msg = await ctx.channel.send("\U000023f3")
await self.try_emoji(msg, emoji)
2020-07-23 21:31:42 +02:00
data = m.get_data()
2021-02-04 09:46:36 +01:00
data[emoji] = list(map(lambda x: x.id, [role]))
2020-07-23 21:31:42 +02:00
m.set_data(data)
await self.rorec_update(m)
s.commit()
s.close()
2021-02-04 09:46:36 +01:00
await msg.edit(content="\U0001f44d")
@cog_ext.cog_subcommand(base="rorec", name="remove",
description="Remove a emoji of a role-reaction message",
options=[
manage_commands.create_option("url", "The message url",
SlashCommandOptionType.STRING, True),
manage_commands.create_option("emoji", "The emoji",
SlashCommandOptionType.STRING, True)
])
@is_enabled()
@guild_only()
@has_permissions(manage_roles=True)
async def rorec_remove(self, ctx: SlashContext, url: str, emoji: str):
await ctx.send(content="\U000023f3")
2020-07-23 21:31:42 +02:00
s = db.Session()
2021-02-04 09:46:36 +01:00
m = await self.get_message(s, ctx, url)
await ctx.delete()
msg = await ctx.channel.send("\U000023f3")
await self.try_emoji(msg, emoji)
2020-07-23 21:31:42 +02:00
data = m.get_data()
if emoji not in data:
raise BadArgument()
del data[emoji]
m.set_data(data)
await self.rorec_update(m)
s.commit()
s.close()
2021-02-04 09:46:36 +01:00
await msg.edit("\U0001f44d")
2020-07-23 21:31:42 +02:00
2021-02-04 09:46:36 +01:00
@cog_ext.cog_subcommand(base="rorec", name="reload",
description="Reload the message and the reactions",
options=[manage_commands.create_option("url", "The message url",
SlashCommandOptionType.STRING, True)])
@is_enabled()
@guild_only()
@has_permissions(manage_roles=True)
async def rorec_reload(self, ctx: SlashContext, url: str):
2020-07-23 21:31:42 +02:00
s = db.Session()
2021-02-04 09:46:36 +01:00
m = await self.get_message(s, ctx, url)
2020-07-23 21:31:42 +02:00
await self.rorec_update(m)
s.close()
2021-02-04 09:46:36 +01:00
await ctx.send(content="\U0001f44d")
2020-07-23 21:31:42 +02:00
2021-02-04 09:46:36 +01:00
@cog_ext.cog_subcommand(base="rorec", name="delete",
description="Remove a role-reaction message",
options=[manage_commands.create_option("url", "The message link",
SlashCommandOptionType.STRING, True)])
@is_enabled()
@guild_only()
@has_permissions(manage_roles=True)
async def rorec_delete(self, ctx: SlashContext, url: str):
msg = await get_message_by_url(ctx, url)
2020-07-23 21:31:42 +02:00
s = db.Session()
2021-02-04 09:46:36 +01:00
await self.get_message(s, ctx, url)
2020-07-23 21:31:42 +02:00
s.close()
2021-02-04 09:46:36 +01:00
await msg.delete()
await ctx.send(content="\U0001f44d")
2020-07-23 21:31:42 +02:00
async def rorec_update(self, m: db.RoRec):
channel = self.bot.get_channel(m.channel)
if not channel:
pass
message = await channel.fetch_message(m.message)
if not message:
pass
embed: Embed = message.embeds[0]
name = embed.fields[0].name
embed.remove_field(0)
value = ""
data = m.get_data()
await message.clear_reactions()
for d in data:
value += f"{d}: "
value += ", ".join(map(lambda x: self.bot.get_guild(m.guild).get_role(x).mention, data[d]))
value += "\n"
await message.add_reaction(d)
2021-02-04 09:46:36 +01:00
if not value:
value = "No role yet..."
2020-07-23 21:31:42 +02:00
embed.add_field(name=name, value=value)
await message.edit(embed=embed)
@commands.Cog.listener()
async def on_raw_message_delete(self, message: RawMessageDeleteEvent):
s = db.Session()
r = s.query(db.RoRec).filter(db.RoRec.message == message.message_id).first()
if r:
s.delete(r)
s.commit()
s.close()
@commands.Cog.listener()
async def on_raw_bulk_message_delete(self, messages: RawBulkMessageDeleteEvent):
s = db.Session()
for id in messages.message_ids:
r = s.query(db.RoRec).filter(db.RoRec.message == id).first()
if r:
s.delete(r)
s.commit()
s.close()
@commands.Cog.listener()
async def on_guild_channel_delete(self, channel: GuildChannel):
if isinstance(channel, TextChannel):
s = db.Session()
for r in s.query(db.RoRec).filter(db.RoRec.channel == channel.id).all():
s.delete(r)
s.commit()
s.close()
@commands.Cog.listener()
async def on_raw_reaction_add(self, payload: RawReactionActionEvent):
s = db.Session()
if payload.guild_id and not event_is_enabled(self.qualified_name, payload.guild_id, s):
return
2020-07-23 21:31:42 +02:00
m = s.query(db.RoRec).filter(db.RoRec.message == payload.message_id).first()
s.close()
if m and payload.member.id != self.bot.user.id:
data = m.get_data()
emoji = str(payload.emoji)
if emoji in data:
guild = self.bot.get_guild(payload.guild_id)
roles = [guild.get_role(r) for r in data[emoji]]
add = False
if m.one:
del data[emoji]
remove_roles = []
[remove_roles.extend(map(lambda x: guild.get_role(x), data[e])) for e in data]
await payload.member.remove_roles(*remove_roles, reason="Only one role-reaction message")
for r in filter(lambda x: x not in payload.member.roles, roles):
try:
await payload.member.add_roles(r, reason="Role-reaction message")
add = True
except Forbidden:
await payload.member.send("I don't have the permission to add a role to you !")
if not add:
try:
await payload.member.remove_roles(*roles, reason="Role-reaction message")
except Forbidden:
await payload.member.send("I don't have the permission to remove one of your roles !")
await (await self.bot.get_channel(payload.channel_id).fetch_message(payload.message_id))\
.remove_reaction(payload.emoji, payload.member)
def setup(bot):
logger.info(f"Loading...")
try:
bot.add_cog(RoRec(bot))
except Exception as e:
logger.error(f"Error loading: {e}")
else:
logger.info(f"Load successful")
def teardown(bot):
logger.info(f"Unloading...")
try:
bot.remove_cog("RoRec")
except Exception as e:
logger.error(f"Error unloading: {e}")
else:
logger.info(f"Unload successful")