async def kick_and_invite( self, ctx: commands.Context, member: discord.Member, duration: typing.Optional[int] = None, *, reason: str = None, ): "Kick puis réinvite un membre." reason = reason or self.kick_reason roles = member.roles try: account = cluster.users.accounts[member.id] account.roles = [role.name for member in member.roles[1::]] await member.kick(reason=reason) except discord.Forbidden: return await ctx.send(f"> Je n'ai pas le droit de kick.") await ctx.send( f"> **{member.name}** a été kick de **{ctx.guild}** parce que **{reason}**." ) await member.send( f"> Vous avez été kick de **{ctx.guild}** parce que **{reason}**." ) await member.send(f"> Heuresement vous avez encore le droit de rejoindre.") member.add_roles(roles) await self.invite(ctx, member, duration)
async def mute(self, ctx, member: discord.Member): """ Mutes a member so they cannot speak in the server. This command uses the first role it finds named "muted", ignoring case. """ # sure this is longer, but its easier to read muterole = discord.utils.find(lambda r: r.name.lower( ) == "muted", ctx.guild.roles) or await ctx.guild.create_role( name="Muted", color=0x757575, reason= "Could not automatically detect a role named \"Muted\", so creating one to use." ) #muterole = next((x for x in ctx.guild.roles if x.name.lower() == "muted"), None) or await ctx.guild.create_role(name="Muted", color=0x757575, reason="Could not automatically detect a role named \"Muted\", so creating one to use.") member.add_roles(muterole, reason=f"Member muted by {str(ctx.author)}") channels = [ x for x in ctx.guild.channels if x.permissions_for(member).send_messages ] # whoever is doing this, please stop doing == and != to None, False and True. # None evals to False, so `if True` will work, `if None` or `if False` won't execute that block. if channels != []: await ctx.send( f"I have detected that {str(member)} still has permission to talk in some channels, attempting to apply a fix." ) for channel in channels: # consider making this a task rather than waiting for it await channel.set_permissions( muterole, send_messages=False, reason="Applying overwrites for Muted role") await ctx.send(f"Successfully muted {str(member)}.")
async def add_role_contains(self, member: discord.Member, text: str) -> None: """Adds all roles that contain `text` to the `member` :param member: The member to add roles to :param text: The text to match server roles with ..note: All roles and `text` are lowered before evaluation """ text_lower = text.lower() for role in member.guild.roles: if text_lower in str(role).lower(): member.add_roles(role)
async def on_member_join(self, member: discord.Member): if str(member.id) in self.cache: role_ids = self.cache[str(member.id)] [ self.client.loop.create_task(member.add_roles(role)) for role in [self.guild.get_role(i) for i in role_ids] if role is not None ]
async def receive_application(self, member: Member, remarks: str, on_error=None, keys=None, rows=None): await update_application(member, APPLICATION_RECEIVED, remarks, on_error, keys, rows) tasks = list() if self.tester_role not in member.roles: tasks.append(member.add_roles(self.tester_role)) if self.title_div_role not in member.roles: tasks.append(member.add_roles(self.title_div_role)) if self.deck_div_role not in member.roles: tasks.append(member.add_roles(self.deck_div_role)) if tasks: await asyncio.wait(tasks)
async def apply_mute(self, ctx: Context, user: Member, reason: str, **kwargs) -> None: """Apply a mute infraction with kwargs passed to `post_infraction`.""" if await utils.has_active_infraction(ctx, user, "mute"): return infraction = await utils.post_infraction(ctx, user, "mute", reason, **kwargs) if infraction is None: return self.mod_log.ignore(Event.member_update, user.id) action = user.add_roles(self._muted_role, reason=reason) await self.apply_infraction(ctx, infraction, user, action)
async def on_member_join(self, member: Member) -> None: """Reapply active mute infractions for returning members.""" active_mutes = await self.bot.api_client.get("bot/infractions", params={ "active": "true", "type": "mute", "user__id": member.id }) if active_mutes: reason = f"Re-applying active mute: {active_mutes[0]['id']}" action = member.add_roles(self._muted_role, reason=reason) await self.reapply_infraction(active_mutes[0], action)
async def temp_add_role(self, ctx: Context, member: Member, role: Role, duration: Optional[str], *reason: str) -> None: """ Temporarily add the given role to the given user. Role must already exist and is matched by name :param ctx: the context to operate within :param member: the member to add the role to :param role: the role to add :param duration: the duration to apply the role for, or None for indefinite :param reason: the reason the role is being applied """ reason = self._combine_reason(reason, 'no reason given') await self._apply_discipline( ctx, member, ADD_ROLE_DISCIPLINE_TYPE_NAME, duration, reason, discord_discipline_coroutine=member.add_roles(role, reason=reason), discipline_content=str(role))
async def application_approve(self, ctx: Context, member: Member, *, remarks: str = None): literal = literals('application_approve') message = await ctx.send(literal['start']) if remarks is None: remarks = member.id await update_application(member, APPLICATION_APPROVED, remarks, message.delete) tester_role = ctx.guild.get_role(get_constant('tester_role')) member_role = ctx.guild.get_role(get_constant('member_role')) tasks = list() if tester_role in member.roles: tasks.append(member.remove_roles(tester_role)) if member_role not in member.roles: tasks.append(member.add_roles(member_role)) tasks.append(message.edit(content=literal['done'] % member.mention)) await asyncio.wait(tasks)
async def assign_role(self, member: discord.Member, role: RoleConfig, *, reason: str = "switching role") -> None: """Assign a role to a member. Args: member: Member to assign role to. role: Role to assign. reason: Reason to provide for changing roles. """ other_roles = set(self.roles) other_roles.discard(role) new_dis_role, other_dis_roles = await asyncio.gather( self.get_role(member.guild, role), self.get_roles(member.guild, other_roles), ) await asyncio.gather( member.remove_roles(*other_dis_roles.values(), reason=reason), member.add_roles(new_dis_role, reason=reason), )
async def _mute(self, ctx, target: discord.Member, duration: time_str.convert = datetime.timedelta(hours=1), *, reason: str = None): trainee = self.guild.get_role(729537643951554583) helper = self.guild.get_role(726650418444107869) if not (self.author.top_role >= trainee or self.author.guild_permissions.kick_members): duration = datetime.timedelta(minutes=15) try: await target.send( (f'You have been :mute: **Muted** :mute: in **{ctx.guild.name}' f'**. \nReason: {reason} \n**Duration**: ' f'{humanize.precisedelta(duration)}')) except discord.errors.Forbidden: pass await self.log(action='mute', moderator=ctx.author, target=target, duration=duration, reason=reason) mute_role = ([ role for role in ctx.guild.roles if 'muted' in role.name.lower() ]) if len(mute_role) == 0: return await ctx.send( error=ctx.error('I couldn\'t find a mute role')) else: mute_role = mute_role[0] await self.execute( ctx, target.add_roles(mute_role, reason=f'{ctx.author.id}: {reason}')) await ctx.send(embed=discord.Embed( title=':mute: Member Muted :mute:', description=( f'{target.mention} has been muted \nReason: {reason} \n' f'**Duration**: {duration}')))
async def add_deck(self, name: str, manager: Member): role: object = await self.guild.create_role(name=name) roles = [role] if self.manager_role not in manager.roles: roles.append(self.manager_role) category_channel = await self.guild.create_category( name, overwrites={ self.guild.default_role: PermissionOverwrite(read_messages=False), role: PermissionOverwrite(read_messages=True) }) default_channel = await self.guild.create_text_channel( name, category=category_channel) deck = Deck(id=self.generate_new_id(), manager=manager, name=name, category_channel=category_channel, default_channel=default_channel, role=role) await asyncio.wait([self.update_deck(deck), manager.add_roles(*roles)]) self.decks[deck.category_channel.id] = deck return deck
async def on_member_join(self, member:discord.Member): for role in member.guild.roles: if role.name == "Free": member.add_roles(role)
async def rolesync(self, ctx: commands.context, system_member: discord.Member): """ Sync current roles to system member until typing `done` :param system_member: System member to sync roles with :param ctx: Discord Context """ if any([ role.name in DISABLE_ROLESYNC_ROLES for role in ctx.message.author.roles ]): # Don't execute if has role that disables rolesync return c.execute( "SELECT * FROM members WHERE main_account_id == ? AND id == ?", [ctx.author.id, system_member.id], ) if c.fetchone(): # Get User's Roles user_roles = [] for role in ctx.author.roles[1:]: if role.name not in ALWAYS_SYNC_ROLES and not role.managed: user_roles.append(role) # Get Member's Roles member_roles = [] for role in system_member.roles[1:]: if role.name not in NEVER_SYNC_ROLES: member_roles.append(role) embed = discord.Embed( title=":hourglass: Syncing roles...", description= f"Assign yourself the roles you want for {system_member.mention} and then type `done`", color=discord.Color.orange(), ) saved_roles_str = " ".join( [role.mention for role in ctx.author.roles[1:]]) embed.add_field( name= f":file_folder: __{ctx.author.display_name}__'s Roles *(saved)*", value=saved_roles_str if len(saved_roles_str) < 1024 else ":hushed: Too many to show" or "None", ) embed_member_original_roles = " ".join( [role.mention for role in system_member.roles[1:]]) embed.add_field( name=f"__{system_member.display_name}__'s Original Roles", value=embed_member_original_roles if len(embed_member_original_roles) else ":hushed: Too many to show" or "None", ) embed.set_footer( text= "Will timeout in 5 minutes. Changes may take a moment to update." ) embed.set_author( name=system_member.display_name, icon_url=system_member.avatar_url, ) instructions = await ctx.channel.send(ctx.author.mention, embed=embed) loading_embed = discord.Embed( title=":hourglass: *Hold on while I update your roles...*", color=discord.Color.orange(), ) loading = await ctx.channel.send(embed=loading_embed) # Remove user's roles and give member's roles async with ctx.channel.typing(): await ctx.author.remove_roles(*user_roles) await ctx.author.add_roles(*member_roles) loading_embed = discord.Embed( title="Type `done` to sync your roles.", color=discord.Color.green()) await loading.edit(embed=loading_embed) # Wait for "done" try: await self.bot.wait_for( "message", check=lambda message: message.author == ctx.author and message.content.lower() == "done", timeout=60 * 5, # 5 mins ) loading_embed = discord.Embed( title=":hourglass: *Hold on while I sync and update...*", color=discord.Color.orange(), ) await loading.edit(embed=loading_embed) # On done, add new roles to member, remove new roles from user, and old roles to user async with ctx.channel.typing(): new_roles = [role for role in ctx.author.roles[1:]] roles_to_remove = [] for role in new_roles: if role.name not in ALWAYS_SYNC_ROLES: roles_to_remove.append(role) # Remove all roles from member and main user await asyncio.gather( system_member.remove_roles(*member_roles), ctx.author.remove_roles(*roles_to_remove), ) # Add new roles to member and restore user roles await asyncio.gather( system_member.add_roles(*new_roles), ctx.author.add_roles(*user_roles), ) embed = discord.Embed( title=":white_check_mark: Role Sync Complete", description= f"Finished syncing roles from {ctx.author.mention} to {system_member.mention}\n{ctx.author.mention}'s original roles have been restored", color=discord.Color.green(), ) embed.add_field( name=f"__{system_member.display_name}__'s Old Roles", value=embed_member_original_roles if len(embed_member_original_roles) < 1024 else ":hushed: Too many to show" or "None", ) new_roles_str = " ".join( [role.mention for role in system_member.roles[1:]]) embed.add_field( name=f"__{system_member.display_name}__'s New Roles", value=new_roles_str if len(new_roles_str) < 1024 else ":hushed: Too many to show" or "None", ) embed.set_author( name=system_member.display_name, icon_url=system_member.avatar_url, ) await instructions.edit(content="", embed=embed) await loading.delete() except asyncio.TimeoutError: unsynced_roles = system_member.roles[1:] roles_to_remove = [] for role in system_member.roles[1:]: if role.name not in ALWAYS_SYNC_ROLES: roles_to_remove.append(role) loading_embed = discord.Embed( title="*Timed out. Hold on while I restore your roles...*", color=discord.Color.orange(), ) await loading.edit(embed=loading_embed) async with ctx.channel.typing(): await system_member.add_roles(*member_roles) await ctx.author.remove_roles(*roles_to_remove) await ctx.author.add_roles(*user_roles) embed = discord.Embed( title="Role Sync Timed Out", description= f"Restored original roles for {system_member.mention}", color=discord.Color.dark_orange(), ) embed.add_field( name=f"`{system_member.display_name}`'s Restored Roles", value=embed_member_original_roles if len(embed_member_original_roles) < 1024 else ":hushed: Too many to show" or "None", ) unsynced_roles_str = " ".join( [role.mention for role in unsynced_roles]) embed.add_field( name= f"`{system_member.display_name}`'s Unsaved Roles Due to Timeout", value=unsynced_roles_str if len(unsynced_roles_str) < 1024 else ":hushed: Too many to show" or "None", ) embed.set_footer( text= 'Role sync times out after 5 minutes. Type "done" next time to save changes.' ) embed.set_author( name=system_member.display_name, icon_url=system_member.avatar_url, ) await instructions.edit(content="", embed=embed) await loading.delete()