async def role_give(self, ctx, *args: typing.Union[discord.Role, discord.Member, str]): """ Used to create roles and assign roles. If new roles are passed in, they will be created. If new or existing roles and guild members are passed in, they will be created if applicable and assigned `-role give [roles] [users]` """ users = list(filter(lambda x: isinstance(x, discord.Member), args)) roles = list(filter(lambda x: isinstance(x, discord.Role), args)) new_roles = list(filter(lambda x: isinstance(x, str), args)) if len(roles) + len(new_roles) is 0: raise discord.MissingRequiredArgument(discord.Role) for new in new_roles: new = await ctx.guild.create_role(name=new) roles.append(new) if len(new_roles) is not 0: await ctx.send(embed=await Macro.send( Messages.rolesMade.format(", ".join(new_roles)))) if len(users) is 0: return for user in users: await user.add_roles(*roles) await ctx.send(embed=await Macro.send( Messages.rolesGiven.format(", ".join(map(str, users)), ", ".join( map(str, roles)))))
async def role_kill(self, ctx, *roles: typing.Union[discord.Role]): """ Delete roles from the guild. `-role kill <roles>` """ if len(roles) is 0: raise discord.MissingRequiredArgument(discord.Role) for role in roles: await role.delete() await ctx.channel.send(embed=await Macro.send( Messages.rolesKilled.format(", ".join(map(str, roles)))))
async def role_take(self, ctx, *args: typing.Union[discord.Role, discord.Member]): """ Removes roles from guild members. `-role take <roles> <users>` """ roles = list(filter(lambda x: isinstance(x, discord.Role), args)) members = list(filter(lambda x: isinstance(x, discord.Member), args)) if len(roles) is 0 or len(members) is 0: raise discord.MissingRequiredArgument( discord.Role if len(roles) is 0 else discord.Member) for member in members: await member.remove_roles(*roles) await ctx.channel.send(embed=await Macro.send( Messages.rolesTaken.format(", ".join(map(str, members)), ", ".join( map(str, roles)))))
async def parse_react_message(self, message: discord.Message, strict: bool) -> dict: content = message.content.replace("`", "").split("\n")[1:] result = {} # fill values for line in content: line = line.split(" ", 1) key = line[0] value = line[1] if key not in ( "type", "match", "sensitive", "triggers", "responses", "enabled", "users", "channels", "counter", ): raise InvalidReactionKey(key=key) # check invalid = False # fmt: off if key == "type" and value not in ("text", "image") \ or key == "match" and value not in ("full", "start", "end", "any") \ or key == "sensitive" and value not in ("true", "false") \ or key == "enabled" and value not in ("true", "false") \ or key == "triggers" and len(value) < 1 \ or key == "responses" and len(value) < 1: invalid = True # fmt: on if invalid: raise ReactionParsingException(key, value) # parse if key in ("sensitive", "enabled"): value = value == "true" elif key in ("triggers", "responses"): # convert to list value = shlex.split(value) elif key in ("users", "channels"): # convert to list of ints try: value = [int(x) for x in shlex.split(value)] except: raise ReactionParsingException(key, value) elif key == "counter": try: value = int(value) except: raise ReactionParsingException(key, value) result[key] = value if strict: # check if all required values are present for key in ("type", "match", "triggers", "response"): if key is None: raise discord.MissingRequiredArgument(param=key) return result