1
0
Fork 0

Merge pull request #2 from flifloo/speak_reaction

Speak reaction
This commit is contained in:
Ethanell 2020-04-09 18:45:55 +02:00 committed by GitHub
commit 3839ba1981
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,5 @@
from discord.ext import commands from discord.ext import commands
from discord import Member, VoiceState, Embed from discord import Member, VoiceState, Embed, Reaction, Guild
from discord.ext.commands import CommandNotFound from discord.ext.commands import CommandNotFound
from bot_bde.logger import logger from bot_bde.logger import logger
@ -18,119 +18,22 @@ class Speak(commands.Cog):
self.lastSpeaker = None self.lastSpeaker = None
self.reaction = [] self.reaction = []
self.lastReaction = None self.lastReaction = None
self.voice_message = None
@commands.group("speak", pass_context=True) @commands.group("speak", pass_context=True)
@commands.guild_only() @commands.guild_only()
async def speak(self, ctx: commands.Context): async def speak(self, ctx: commands.Context):
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
if ctx.subcommand_passed: raise CommandNotFound
raise CommandNotFound
elif ctx.author.voice is None or ctx.author.voice.channel is None:
await (await ctx.send("Your not in a voice channel !")).delete(delay=30)
elif self.voice_chan is None:
await (await ctx.send("Voice channel not set !")).delete(delay=30)
elif ctx.author.voice.channel.id != self.voice_chan:
await (await ctx.send("Your not in the good voice channel !")).delete(delay=30)
elif ctx.author.id in self.waiting:
await ctx.message.add_reaction("\u274C")
else:
self.waiting.append(ctx.author.id)
await ctx.message.add_reaction("\U0001f44d")
@speak.group("react", pass_context=True)
@commands.guild_only()
async def speak_react(self, ctx: commands.Context):
if ctx.author.voice is None or ctx.author.voice.channel is None or self.voice_chan is None or \
ctx.author.voice.channel.id != self.voice_chan or ctx.author.id in self.reaction or \
self.lastSpeaker is None or self.lastSpeaker == ctx.author.id:
await ctx.message.add_reaction("\u274C")
else:
self.reaction.append(ctx.author.id)
await ctx.message.add_reaction("\U0001f44d")
@speak.group("remove", pass_context=True)
@commands.guild_only()
async def speak_remove(self, ctx: commands.Context):
if len(ctx.message.mentions) != 0:
if self.voice_chan and ctx.guild.get_channel(self.voice_chan).permissions_for(ctx.author).mute_members:
for speaker in ctx.message.mentions:
self.waiting.remove(speaker.id)
await ctx.message.add_reaction("\U0001f44d")
else:
await ctx.message.add_reaction("\u274C")
elif ctx.author.id in self.waiting:
self.waiting.remove(ctx.author.id)
await ctx.message.add_reaction("\U0001f44d")
else:
await ctx.message.add_reaction("\u274C")
@speak.group("list", pass_context=True)
@commands.guild_only()
async def speak_list(self, ctx: commands.Context):
if ctx.author.voice.channel is None or not self.voice_chan:
await ctx.message.add_reaction("\u274C")
else:
embed = Embed(title="Waiting list")
if len(self.reaction) != 0:
for i, reaction in enumerate(self.reaction):
embed.add_field(name=f"Reaction N°{i+1}", value=ctx.guild.get_member(reaction).display_name,
inline=False)
for i, speaker in enumerate(self.waiting):
embed.add_field(name=f"{i+1}", value=ctx.guild.get_member(speaker).display_name, inline=False)
await ctx.send(embed=embed, delete_after=60)
@speak.group("next", pass_context=True)
@commands.guild_only()
async def speak_next(self, ctx: commands.Context):
if not self.voice_chan or not ctx.guild.get_channel(self.voice_chan).permissions_for(ctx.author).mute_members:
await ctx.message.add_reaction("\u274C")
else:
if self.lastReaction:
self.reaction.remove(self.lastReaction)
if self.strict:
await ctx.guild.get_member(self.lastReaction).edit(mute=True)
if self.lastSpeaker and len(self.reaction) == 0:
self.waiting.remove(self.lastSpeaker)
if self.strict:
await ctx.guild.get_member(self.lastSpeaker).edit(mute=True)
if len(self.reaction) != 0 and self.lastSpeaker is not None:
user: Member = ctx.guild.get_member(self.reaction[0])
self.lastReaction = self.reaction[0]
await ctx.send(f"{user.mention} react on {ctx.guild.get_member(self.lastSpeaker).mention} speak !")
if self.strict:
await user.edit(mute=False)
elif len(self.waiting) != 0:
user: Member = ctx.guild.get_member(self.waiting[0])
self.lastSpeaker = self.waiting[0]
self.lastReaction = None
await ctx.send(f"It's {user.mention} turn")
if self.strict:
await user.edit(mute=False)
else:
self.lastSpeaker = None
self.lastReaction = None
await ctx.send("Nobody left !")
@speak.group("help", pass_context=True) @speak.group("help", pass_context=True)
@commands.guild_only() @commands.guild_only()
async def speak_help(self, ctx: commands.Context): async def speak_help(self, ctx: commands.Context):
embed = Embed(title="Speak help") embed = Embed(title="Speak help")
embed.add_field(name="speak", value="Join the waiting list", inline=False)
embed.add_field(name="speak react", value="Be the next to speak to react and debate with the current speaker",
inline=False)
embed.add_field(name="speak remove [@pepole, @...]",
value="Remove yourself or mentioned person from the waiting list", inline=False)
embed.add_field(name="speak list", value="Show the waiting list", inline=False)
embed.add_field(name="speak setup [strict]", embed.add_field(name="speak setup [strict]",
value="Set your current voice channel as the speak channel, you cant add the argument `strict` " value="Set your current voice channel as the speak channel", inline=False)
"to mute everyone except you and the current speaker", inline=False)
embed.add_field(name="speak next",
value="Give the turn to the next waiter, if strict mode is enabled the last person get muted "
"and the next unmuted", inline=False)
embed.add_field(name="speak mute", value="Mute everyone on the speak channel except you", inline=False) embed.add_field(name="speak mute", value="Mute everyone on the speak channel except you", inline=False)
embed.add_field(name="speak unmute", value="Unmute everyone on the speak channel except you", inline=False) embed.add_field(name="speak unmute", value="Unmute everyone on the speak channel except you", inline=False)
embed.add_field(name="speak clear", value="Clear the speak by unmute everyone and forget the list & channel",
inline=False)
await ctx.send(embed=embed) await ctx.send(embed=embed)
@speak.group("setup", pass_context=True) @speak.group("setup", pass_context=True)
@ -139,36 +42,21 @@ class Speak(commands.Cog):
if not ctx.author.voice.channel.permissions_for(ctx.author).mute_members: if not ctx.author.voice.channel.permissions_for(ctx.author).mute_members:
await ctx.message.add_reaction("\u274C") await ctx.message.add_reaction("\u274C")
else: else:
if len(args) != 0:
if args[0] == "strict":
self.strict = True
for client in ctx.author.voice.channel.members:
if client != ctx.author and not client.bot and \
not (self.lastSpeaker and client.id == self.lastSpeaker) and \
not (self.reaction and client.id == self.lastReaction):
await client.edit(mute=True)
else:
raise CommandNotFound
self.voice_chan = ctx.author.voice.channel.id self.voice_chan = ctx.author.voice.channel.id
await ctx.message.add_reaction("\U0001f44d") embed = Embed(title="Speak \U0001f508")
embed.add_field(name="Waiting list \u23f3", value="Nobody", inline=False)
@speak.group("clear", pass_context=True) embed.add_field(name="Reactions",
@commands.guild_only() value="\U0001f5e3 speak !\n"
async def speak_clear(self, ctx: commands.Context): "\u2757 react to speaker\n"
speak_channel = ctx.guild.get_channel(self.voice_chan) "\u27A1 Next\n"
if not self.voice_chan or not speak_channel.permissions_for(ctx.author).mute_members: "\U0001F512 Strict\n"
await ctx.message.add_reaction("\u274C") "\u274C clear the speak\n"
else: "Remove your reaction to remove from list",
self.waiting = [] inline=False)
self.lastSpeaker = None self.voice_message = await ctx.send(embed=embed)
self.reaction = [] for reaction in ["\U0001f5e3", "\u2757", "\u27A1", "\U0001F512", "\u274C"]:
self.lastReaction = None await self.voice_message.add_reaction(reaction)
for client in speak_channel.members: self.voice_message = await self.voice_message.channel.fetch_message(self.voice_message.id)
if not client.bot:
await client.edit(mute=False)
self.strict = False
self.voice_chan = None
await ctx.message.add_reaction("\U0001f44d")
@speak.group("mute", pass_context=True) @speak.group("mute", pass_context=True)
@commands.guild_only() @commands.guild_only()
@ -210,6 +98,140 @@ class Speak(commands.Cog):
async def cog_after_invoke(self, ctx: commands.Context): async def cog_after_invoke(self, ctx: commands.Context):
await ctx.message.delete(delay=30) await ctx.message.delete(delay=30)
@commands.Cog.listener()
async def on_reaction_add(self, reaction: Reaction, user: Member):
if not user.bot:
if reaction.message.id == self.voice_message.id:
if str(reaction.emoji) == "\U0001f5e3":
await self.speak_action(reaction, user)
elif str(reaction.emoji) == "\u2757":
await self.speak_react_action(reaction, user)
elif str(reaction.emoji) == "\u27A1":
await self.speak_next_action(reaction, user)
elif str(reaction.emoji) in ["\U0001F512", "\U0001F513"]:
await self.speak_strict_action(reaction, user)
elif str(reaction.emoji) == "\u274C":
await self.speak_clear_action(reaction, user)
else:
await reaction.remove(user)
await self.update_list(reaction.message.channel.guild)
async def speak_action(self, reaction: Reaction, user: Member):
if user.voice is None or user.voice.channel is None or \
self.voice_chan is None or \
user.voice.channel.id != self.voice_chan or \
user.id in self.waiting:
await reaction.remove(user)
else:
self.waiting.append(user.id)
async def speak_react_action(self, reaction: Reaction, user: Member):
if user.voice is None or user.voice.channel is None or self.voice_chan is None or \
user.voice.channel.id != self.voice_chan or user.id in self.reaction or \
self.lastSpeaker is None or self.lastSpeaker == user.id:
await reaction.remove(user)
else:
self.reaction.append(user.id)
async def speak_next_action(self, reaction: Reaction, user: Member):
await reaction.remove(user)
if self.voice_chan and \
reaction.message.guild.get_channel(self.voice_chan).permissions_for(user).mute_members:
if self.lastReaction:
user: Member = reaction.message.guild.get_member(self.lastReaction)
self.reaction.remove(self.lastReaction)
if self.strict:
await user.edit(mute=True)
await self.voice_message.reactions[1].remove(user)
if self.lastSpeaker and len(self.reaction) == 0:
user: Member = reaction.message.guild.get_member(self.lastSpeaker)
self.waiting.remove(self.lastSpeaker)
if self.strict:
await user.edit(mute=True)
await self.voice_message.reactions[0].remove(user)
if len(self.reaction) != 0 and self.lastSpeaker is not None:
user: Member = reaction.message.guild.get_member(self.reaction[0])
self.lastReaction = self.reaction[0]
await reaction.message.channel.send(
f"{user.mention} react on {reaction.message.guild.get_member(self.lastSpeaker).mention} speak !")
if self.strict:
await user.edit(mute=False)
elif len(self.waiting) != 0:
user: Member = reaction.message.guild.get_member(self.waiting[0])
self.lastSpeaker = self.waiting[0]
self.lastReaction = None
await reaction.message.channel.send(f"It's {user.mention} turn")
if self.strict:
await user.edit(mute=False)
else:
self.lastSpeaker = None
self.lastReaction = None
await reaction.message.channel.send("Nobody left !")
async def speak_strict_action(self, reaction: Reaction, user: Member):
if not self.voice_chan or \
not reaction.message.guild.get_channel(self.voice_chan).permissions_for(user).mute_members:
await reaction.remove(user)
else:
replace = ["\U0001F512", "\U0001F513"] if not self.strict else ["\U0001F513", "\U0001F512"]
self.strict = not self.strict
if self.strict:
for client in user.voice.channel.members:
if client != user and not client.bot and \
not (self.lastSpeaker and client.id == self.lastSpeaker) and \
not (self.reaction and client.id == self.lastReaction):
await client.edit(mute=True)
embed = self.voice_message.embeds[0]
field = embed.fields[1]
embed.remove_field(1)
embed.add_field(name=field.name, value=field.value.replace(replace[0], replace[1]), inline=False)
await self.voice_message.edit(embed=embed)
self.voice_message = await self.voice_message.channel.fetch_message(self.voice_message.id)
await reaction.remove(user)
async def speak_clear_action(self, reaction: Reaction, user: Member):
speak_channel = reaction.message.guild.get_channel(self.voice_chan)
if not self.voice_chan or not speak_channel.permissions_for(user).mute_members:
await reaction.remove(user)
else:
self.waiting = []
self.lastSpeaker = None
self.reaction = []
self.lastReaction = None
for client in speak_channel.members:
if not client.bot:
await client.edit(mute=False)
self.strict = False
self.voice_chan = None
await self.voice_message.delete()
@commands.Cog.listener()
async def on_reaction_remove(self, reaction: Reaction, user: Member):
if not user.bot:
if reaction.message.id == self.voice_message.id:
if str(reaction.emoji) == "\U0001f5e3" and user.id in self.waiting and user.id != self.lastSpeaker:
self.waiting.remove(user.id)
elif str(reaction.emoji) == "\u2757" and user.id in self.reaction and user.id != self.lastReaction:
self.reaction.remove(user.id)
await self.update_list(reaction.message.channel.guild)
async def update_list(self, guild: Guild):
persons = []
if len(self.reaction) != 0:
for i, reaction in enumerate(self.reaction):
persons.append(f"Reaction N°{i+1}: {guild.get_member(reaction).display_name}")
for i, speaker in enumerate(self.waiting):
persons.append(f"{i+1}: {guild.get_member(speaker).display_name}")
if len(persons) == 0:
persons = "Nobody"
else:
persons = "\n".join(persons)
embed = self.voice_message.embeds[0]
field = embed.fields[0]
embed.remove_field(0)
embed.insert_field_at(0, name=field.name, value=persons, inline=True)
await self.voice_message.edit(embed=embed)
@commands.Cog.listener() @commands.Cog.listener()
async def on_command_error(self, ctx: commands.Context, error): async def on_command_error(self, ctx: commands.Context, error):
if ctx.invoked_with == extension_name or \ if ctx.invoked_with == extension_name or \