async def snapshot_role(ctx, role: discord.Role, group: RoleGroup = None): """Adds role to the internal database""" if role.is_bot_managed() or role.is_integration() or role.is_premium_subscriber(): logger.info(f"Skipping role '{role}' as it's system role") raise commands.BadArgument(f"Role '{role}' is a system role") if not utils.can_manage_role(ctx.guild.me, role): logger.info(f"Skipping role '{role}' as bot cannot manage it") raise commands.BadArgument(f"Bot cannot manage role '{role}'") if await Role.exists(name=role.name): logger.info(f"Skipping role '{role}' as it already exists") raise commands.BadArgument(f"Role '{role}' already exists in DB") group = group or (await RoleGroup.get_or_create(name=utils.snapshot_role_group))[0] number = await db_utils.get_max_number(Role) await db_utils.reshuffle(Role, number) db_role = Role(name=role.name, color=role.color.value, number=number, archived=False, assignable=False, mentionable=role.mentionable, group=group) await db_role.save()
async def update_guilds_roles(self): to_update = await Role.exclude(archived=True) to_remove = await Role.filter(archived=True).values_list("name", flat=True) for guild in self.bot.guilds: me = guild.me if not me.guild_permissions.manage_roles: logger.warning(f"Don't have 'manage roles' permissions in '{guild}'") continue position = me.top_role.position for db_role in to_update: role = discord.utils.get(guild.roles, name=db_role.name) if role is not None and not utils.can_manage_role(me, role): logger.warning(f"Can't manage role '{db_role.name}' at '{guild}'") continue position = max(position - 1, 1) await self._setup_role(guild, role, db_role, position) for name in to_remove: role = discord.utils.get(guild.roles, name=name) if role is not None: try: await role.delete() except (discord.errors.Forbidden, discord.errors.HTTPException): logger.warning(f"Failed delete role {name} at {guild}")
async def role_assign(self, ctx: SlashContext, role: discord.Role, member: discord.Member = None): """Assign specified role to you or specified member""" if member and not isinstance(member, discord.Member): raise commands.BadArgument(f"Failed to get member '{member}' info!") if not isinstance(role, discord.Role): raise commands.BadArgument(f"Failed to get role '{role}' info!") await ctx.defer(hidden=True) member = member or ctx.author logger.info(f"{self.format_caller(ctx)} trying to assign '{role}' to {member}") if role in member.roles: await ctx.send(f"Looks like {self.member_mention(ctx, member).lower()} already have {role.mention} role ;)", allowed_mentions=discord.AllowedMentions.none(), hidden=True) return try: db_role = await Role.get(name=role.name) except exceptions.DoesNotExist: logger.warning(f"Role with name '{role}'' not found in database") raise commands.BadArgument(f"Role {role.mention} is not in bots database! " f"You probably shouldn't use that role") if (member != ctx.author or db_role.name == utils.bot_manager_role or not db_role.assignable) \ and not await has_server_perms_from_ctx(ctx): # MissingPermissions expects an array of permissions logger.info(f"{self.format_caller(ctx)} don't have permissions to assign '{role}' to {member}") raise commands.MissingPermissions([utils.bot_manager_role]) if not utils.can_manage_role(ctx.guild.me, role): await ctx.send(f"Sorry, I cannot manage role {role.mention}", allowed_mentions=discord.AllowedMentions.none(), hidden=True) return group = await db_role.group if group.exclusive: logger.info(f"Removing roles, conflicting with {role} (if any)") await self.remove_conflicting_roles(ctx, member, group) await member.add_roles(role) logger.info(f"Assigned role '{role}' to {member}") await ctx.send(f"Assigned role {role.mention} to {member.mention}", allowed_mentions=discord.AllowedMentions.none(), hidden=True )
async def crew_join(self, ctx: SlashContext, crew, join=True): # todo all """Receive crew roles to get pings when LynxGriffin is streaming or updating comics!""" logger.info(f"{ctx.author} trying to {'join' if join else 'leave'} {crew}") if not self.has_crews: raise commands.CheckFailure(f"Sorry, but this command is unavailable as there is no crew roles in DB.") await ctx.defer(hidden=True) db_role = await Role.get(id=crew) role = discord.utils.get(ctx.guild.roles, name=db_role.name) if role is None: logger.warning(f"Role with name '{db_role.name}' in not a valid role for {ctx.guild}") raise commands.CheckFailure( f"Sorry, but this command is unavailable as there is no **{db_role.name}** role " f"on this server yet.") if not utils.can_manage_role(ctx.guild.me, role): await ctx.send(f"Sorry, I cannot manage role {role.mention}", allowed_mentions=discord.AllowedMentions.none(), hidden=True) return member = ctx.author if join: if role in member.roles: logger.info(f"{ctx.author} already in {db_role.name}") await ctx.send(f"Do you need **more** pings, {member.mention}? You're already in {role.mention}", allowed_mentions=discord.AllowedMentions(users=True, roles=False), hidden=True) else: await member.add_roles(role) logger.info(f"{ctx.author} joined {db_role.name}") await ctx.send(f"Welcome to the {role.mention}! Enjoy your pings ;)", allowed_mentions=discord.AllowedMentions.none(), hidden=True) else: if role not in member.roles: logger.info(f"{ctx.author} is not in {db_role.name}") await ctx.send(f"You're not in the {role.mention}? Never have been 🔫", allowed_mentions=discord.AllowedMentions.none(), hidden=True) else: await member.remove_roles(role) logger.info(f"{ctx.author} left {db_role.name}") await ctx.send("Goodbye o7", hidden=True)
async def role_unassign(self, ctx: SlashContext, role: discord.Role, member: discord.Member = None): """Remove specified role from you or specified member""" if member and not isinstance(member, discord.Member): raise commands.BadArgument(f"Failed to get member '{member}' info!") if not isinstance(role, discord.Role): raise commands.BadArgument(f"Failed to get role '{role}' info!") await ctx.defer(hidden=True) member = member or ctx.author logger.info(f"{self.format_caller(ctx)} trying to remove role '{role}' from {member}") if role not in member.roles: await ctx.send(f"Looks like {self.member_mention(ctx, member).lower()} " f"don't have {role.mention} role anyways ;)", allowed_mentions=discord.AllowedMentions.none(), hidden=True) return try: db_role = await Role.get(name=role.name) except exceptions.DoesNotExist: logger.warning(f"Role with name '{role.name}' not found in database") raise commands.BadArgument(f"Role {role.mention} is not in bots database!" f"You probably shouldn't touch that role") if (member != ctx.author or not db_role.assignable) and not await has_server_perms_from_ctx(ctx): logger.info(f"{self.format_caller(ctx)} don't have permissions to remove '{role}' from {member}") # MissingPermissions expects an array of permissions raise commands.MissingPermissions([utils.bot_manager_role]) if not utils.can_manage_role(ctx.guild.me, role): await ctx.send(f"Sorry, I cannot manage role {role.mention}", allowed_mentions=discord.AllowedMentions.none(), hidden=True) return await member.remove_roles(role) logger.info(f"Removed role '{role}' from {member}") await ctx.send(f"Removed role {role.mention} from {member.mention}", allowed_mentions=discord.AllowedMentions.none(), hidden=True )