async def cmd_nocolour(self, message): """Makes a set role set to no colour""" if self.is_running or message.guild != self.guild: return await self.role.edit(colour=Colour.default())
def __init__(self, msg, options={}, titleTxt="", desc="", col=None, timeout=None, footerTxt="", img="", thumb="", icon="", authorName="", targetMember=None, targetRole=None): if footerTxt == "" and timeout is not None: footerTxt = "This menu will expire in " + bbUtil.td_format_noYM( timeout.expiryDelta) + "." # discord.message self.msg = msg # Dict of bbUtil.dumbEmoji: ReactionMenuOption self.options = options self.titleTxt = titleTxt self.desc = desc self.col = col if col is not None else Colour.default() self.footerTxt = footerTxt self.img = img self.thumb = thumb self.icon = icon self.authorName = authorName self.timeout = timeout self.targetMember = targetMember self.targetRole = targetRole self.saveable = False
def predict_colour(rcode: str) -> Colour: colour = Colour.default() if rcode == "0": colour = Colour.dark_green() elif rcode == "1": colour = Colour.dark_red() return colour
def create_command_embed(command: Command): fullcommand = get_command_params(command) docstring = command.callback.__doc__ or '' description = f'{command.help}\n{docstring}' embed = Embed(title=f'`{fullcommand}`', description=description, colour=Colour.default()) questionmark = EMOJIS[':grey_question:'] embed.set_author(name=f'{questionmark} Command help') return embed
async def simpleEmbed(ctx, *, args): notify = Notify(ctx=ctx, title='Embed') args = params.split(args) if not len(args) > 2: if len(args) == 2: notify.success(content=args[0], title=args[1], color=Colour.default()) else: notify.success(content=args[0], title='') else: notify.error( content=f'Bad Usage\nExample: {cfg["prefix"]}embed Message;;Title')
def get_top_role_color(member): """ Tries to get member top role color and if fails return Embed.Empty - This makes it work in DMs. If the top role has default role color then returns green color (marking success) """ try: color = member.top_role.color if color == Colour.default(): return Colour.green() else: return member.top_role.color except AttributeError: # Fix for DMs return Embed.Empty
def toDict(self) -> dict: """Serialize this ReactionMenu into dictionary format for saving to file. This is a base, concrete implementation that saves all information required to recreate a ReactionMenu instance; when extending ReactionMenu, you will likely wish to overload this method, using super.toDict as a base for your implementation. For an example, see ReactionPollMenu.toDict This method relies on your chosen ReactionMenuOption objects having a concrete, SAVEABLE toDict method. If any option in the menu is unsaveable, the menu becomes unsaveable. """ optionsDict = {} for reaction in self.options: optionsDict[reaction.sendable] = self.options[reaction].toDict() data = {"channel": self.msg.channel.id, "msg": self.msg.id, "options": optionsDict, "type": self.__class__.__name__, "guild": self.msg.channel.guild.id} if self.titleTxt != "": data["titleTxt"] = self.titleTxt if self.desc != "": data["desc"] = self.desc if self.col != Colour.default(): data["col"] = self.col.to_rgb() if self.footerTxt != "": data["footerTxt"] = self.footerTxt if self.img != "": data["img"] = self.img if self.thumb != "": data["thumb"] = self.thumb if self.icon != "": data["icon"] = self.icon if self.authorName != "": data["authorName"] = self.authorName if self.timeout != None: data["timeout"] = self.timeout.expiryTime.timestamp() if self.targetMember is not None: data["targetMember"] = self.targetMember.id if self.targetRole is not None: data["targetRole"] = self.targetRole.id return data
def toDict(self): optionsDict = {} for reaction in self.options: optionsDict[reaction.sendable] = self.options[reaction].toDict() data = { "channel": self.msg.channel.id, "msg": self.msg.id, "options": optionsDict, "type": self.__class__.__name__, "guild": self.msg.channel.guild.id } if self.titleTxt != "": data["titleTxt"] = self.titleTxt if self.desc != "": data["desc"] = self.desc if self.col != Colour.default(): data["col"] = self.col.to_rgb() if self.footerTxt != "": data["footerTxt"] = self.footerTxt if self.img != "": data["img"] = self.img if self.thumb != "": data["thumb"] = self.thumb if self.icon != "": data["icon"] = self.icon if self.authorName != "": data["authorName"] = self.authorName if self.timeout != None: data["timeout"] = self.timeout.expiryTime.timestamp() if self.targetMember is not None: data["targetMember"] = self.targetMember.id if self.targetRole is not None: data["targetRole"] = self.targetRole.id return data
async def fromDict(rmDict: dict) -> ReactionDuelChallengeMenu: """⚠ ReactionDuelChallengeMenus are not currently saveable. Do not use this method. When implemented, this function will construct a new ReactionDuelChallengeMenu from a dictionary-serialized representation - The opposite of ReactionDuelChallengeMenu.toDict. :param dict rmDict: A dictionary containg all information needed to construct the required ReactionDuelChallengeMenu :raise NotImplementedError: Always. """ raise NotImplementedError( "Attempted to call fromDict on a non-saveable reaction menu") dcGuild = bbGlobals.client.get_guild(rmDict["guild"]) msg = await dcGuild.get_channel(rmDict["channel"] ).fetch_message(rmDict["msg"]) reactionRoles = {} for reaction in rmDict["options"]: reactionRoles[bbUtil.dumbEmojiFromStr(reaction)] = dcGuild.get_role( rmDict["options"][reaction]["role"]) timeoutTT = None if "timeout" in rmDict: expiryTime = datetime.utcfromtimestamp(rmDict["timeout"]) bbGlobals.reactionMenusTTDB.scheduleTask( TimedTask.TimedTask( expiryTime=expiryTime, expiryFunction=ReactionMenu.removeEmbedAndOptions, expiryFunctionArgs=msg.id)) return ReactionDuelChallengeMenu( msg, reactionRoles, dcGuild, titleTxt=rmDict["titleTxt"] if "titleTxt" in rmDict else "", desc=rmDict["desc"] if "desc" in rmDict else "", col=Colour.from_rgb(rmDict["col"][0], rmDict["col"][1], rmDict["col"][2]) if "col" in rmDict else Colour.default(), footerTxt=rmDict["footerTxt"] if "footerTxt" in rmDict else "", img=rmDict["img"] if "img" in rmDict else "", thumb=rmDict["thumb"] if "thumb" in rmDict else "", icon=rmDict["icon"] if "icon" in rmDict else "", authorName=rmDict["authorName"] if "authorName" in rmDict else "", timeout=timeoutTT, targetMember=dcGuild.get_member(rmDict["targetMember"]) if "targetMember" in rmDict else None, targetRole=dcGuild.get_role(rmDict["targetRole"]) if "targetRole" in rmDict else None)
async def cmd_randomwave(self, message, cycles='1'): """Makes a set role cycle through random colours once per second""" if self.is_running or message.guild != self.guild: return self.is_running = True cycles = self.get_cycles(cycles) for _ in range(len(self.colours) * cycles): await asyncio.gather(self.role.edit(colour=Colour.random()), asyncio.sleep(1)) await self.role.edit(colour=Colour.default()) self.is_running = False
async def change_color(self, ctx, colour: typing.Optional[discord.Colour]): """ Change Role Color for Users """ guild = self.bot.get_guild(self.bot.config['server']) member = guild.get_member(ctx.author.id) highest_role = member.roles[-1] if colour is None: colour = Colour.default() if highest_role.id in self.bot.config['group_roles'].values(): await ctx.send( f'Cannot change color for Group "{highest_role.name}"!') else: await highest_role.edit(colour=colour) await ctx.send(f'Updated color for "{highest_role.name}"!')
async def cmd_vaporwave(self, message, cycles='1'): """Makes a set role cycle through a list of colours once per minute""" if self.is_running or message.guild != self.guild: return self.is_running = True cycles = self.get_cycles(cycles) for colour in self.colours * cycles: await asyncio.gather(self.role.edit(colour=colour), asyncio.sleep(60)) await self.role.edit(colour=Colour.default()) self.is_running = False
async def fromDict(rmDict: dict) -> ReactionRolePicker: """Reconstruct a ReactionRolePicker from its dictionary-serialized representation. :param dict rmDict: A dictionary containing all information needed to construct the desired ReactionRolePicker :return: A new ReactionRolePicker object as described in rmDict :rtype: ReactionRolePicker """ dcGuild = bbGlobals.client.get_guild(rmDict["guild"]) msg = await dcGuild.get_channel(rmDict["channel"] ).fetch_message(rmDict["msg"]) reactionRoles = {} for reaction in rmDict["options"]: reactionRoles[bbUtil.dumbEmojiFromStr(reaction)] = dcGuild.get_role( rmDict["options"][reaction]["role"]) timeoutTT = None if "timeout" in rmDict: expiryTime = datetime.utcfromtimestamp(rmDict["timeout"]) bbGlobals.reactionMenusTTDB.scheduleTask( TimedTask.TimedTask(expiryTime=expiryTime, expiryFunction=ReactionMenu.markExpiredMenu, expiryFunctionArgs=msg.id)) return ReactionRolePicker( msg, reactionRoles, dcGuild, titleTxt=rmDict["titleTxt"] if "titleTxt" in rmDict else "", desc=rmDict["desc"] if "desc" in rmDict else "", col=Colour.from_rgb(rmDict["col"][0], rmDict["col"][1], rmDict["col"][2]) if "col" in rmDict else Colour.default(), footerTxt=rmDict["footerTxt"] if "footerTxt" in rmDict else "", img=rmDict["img"] if "img" in rmDict else "", thumb=rmDict["thumb"] if "thumb" in rmDict else "", icon=rmDict["icon"] if "icon" in rmDict else "", authorName=rmDict["authorName"] if "authorName" in rmDict else "", timeout=timeoutTT, targetMember=dcGuild.get_member(rmDict["targetMember"]) if "targetMember" in rmDict else None, targetRole=dcGuild.get_role(rmDict["targetRole"]) if "targetRole" in rmDict else None)
def __init__(self, name="new_role", permissions=None, colour=None, hoist=False, mentionable=False, reason=None, position=1, **kwargs): super().__init__(**kwargs) self.name: str = name if isinstance(permissions, PermissionDescription): permissions = Permissions(**permissions.to_dict()) self.permissions: Permissions = permissions or Permissions() self.colour: Colour = colour or Colour.default() self.hoist: bool = hoist self.mentionable: bool = mentionable self.reason: str = reason self.position: int = position # only when editing
async def fromDict(rmDict): options = {} for emojiName in rmDict["options"]: emoji = bbUtil.dumbEmojiFromStr(emojiName) options[emoji] = ReactionMenu.DummyReactionMenuOption( rmDict["options"][emojiName], emoji) msg = await bbGlobals.client.get_guild(rmDict["guild"]).get_channel( rmDict["channel"]).fetch_message(rmDict["msg"]) timeoutTT = None if "timeout" in rmDict: expiryTime = datetime.utcfromtimestamp(rmDict["timeout"]) bbGlobals.reactionMenusTTDB.scheduleTask( TimedTask.TimedTask(expiryTime=expiryTime, expiryFunction=printAndExpirePollResults, expiryFunctionArgs=msg.id)) return ReactionPollMenu( msg, options, timeoutTT, multipleChoice=rmDict["multipleChoice"] if "multipleChoice" in rmDict else False, titleTxt=rmDict["titleTxt"] if "titleTxt" in rmDict else "", desc=rmDict["desc"] if "desc" in rmDict else "", col=Colour.from_rgb(rmDict["col"][0], rmDict["col"][1], rmDict["col"][2]) if "col" in rmDict else Colour.default(), footerTxt=rmDict["footerTxt"] if "footerTxt" in rmDict else "", img=rmDict["img"] if "img" in rmDict else "", thumb=rmDict["thumb"] if "thumb" in rmDict else "", icon=rmDict["icon"] if "icon" in rmDict else "", authorName=rmDict["authorName"] if "authorName" in rmDict else "", targetMember=dcGuild.get_member(rmDict["targetMember"]) if "targetMember" in rmDict else None, targetRole=dcGuild.get_role(rmDict["targetRole"]) if "targetRole" in rmDict else None, owningBBUser=bbGlobals.usersDB.getUser(rmDict["owningBBUser"]) if "owningBBUser" in rmDict and bbGlobals.usersDB.userIDExists(rmDict["owningBBUser"]) else None)
def __init__(self, msg : Message, options={}, titleTxt="", desc="", col=None, timeout=None, footerTxt="", img="", thumb="", icon="", authorName="", targetMember=None, targetRole=None): """ :param discord.Message msg: the message where this menu is embedded :param options: A dictionary storing all of the menu's options and their behaviour (Default {}) :type options: dict[bbUtil.dumbEmoji, ReactionMenuOption] :param str titleTxt: The content of the embed title (Default "") :param str desc: he content of the embed description; appears at the top below the title (Default "") :param discord.Colour col: The colour of the embed's side strip (Default None) :param str footerTxt: Secondary description appearing in darker font at the bottom of the embed (Default time until menu expiry if timeout is not None, "" otherwise) :param str img: URL to a large icon appearing as the content of the embed, left aligned like a field (Default "") :param str thumb: URL to a larger image appearing to the right of the title (Default "") :param str icon: URL to a smaller image to the left of authorName. AuthorName is required for this to be displayed. (Default "") :param str authorName: Secondary, smaller title for the embed (Default "") :param TimedTask timeout: The TimedTask responsible for expiring this menu (Default None) :param discord.Member targetMember: The only discord.Member that is able to interact with this menu. All other reactions are ignored (Default None) :param discord.Role targetRole: In order to interact with this menu, users must possess this role. All other reactions are ignored (Default None) """ if footerTxt == "" and timeout is not None: footerTxt = "This menu will expire in " + bbUtil.td_format_noYM(timeout.expiryDelta) + "." # discord.message self.msg = msg # Dict of bbUtil.dumbEmoji: ReactionMenuOption self.options = options self.titleTxt = titleTxt self.desc = desc self.col = col if col is not None else Colour.default() self.footerTxt = footerTxt self.img = img self.thumb = thumb self.icon = icon self.authorName = authorName self.timeout = timeout self.targetMember = targetMember self.targetRole = targetRole
async def fromDict(rmDict): dcGuild = bbGlobals.client.get_guild(rmDict["guild"]) msg = await dcGuild.get_channel(rmDict["channel"] ).fetch_message(rmDict["msg"]) reactionRoles = {} for reaction in rmDict["options"]: reactionRoles[bbUtil.dumbEmojiFromStr(reaction)] = dcGuild.get_role( rmDict["options"][reaction]["role"]) timeoutTT = None if "timeout" in rmDict: expiryTime = datetime.utcfromtimestamp(rmDict["timeout"]) bbGlobals.reactionMenusTTDB.scheduleTask( TimedTask.TimedTask(expiryTime=expiryTime, expiryFunction=removeEmbedAndOptions, expiryFunctionArgs=msg.id)) return ReactionRolePicker( msg, reactionRoles, dcGuild, titleTxt=rmDict["titleTxt"] if "titleTxt" in rmDict else "", desc=rmDict["desc"] if "desc" in rmDict else "", col=Colour.from_rgb(rmDict["col"][0], rmDict["col"][1], rmDict["col"][2]) if "col" in rmDict else Colour.default(), footerTxt=rmDict["footerTxt"] if "footerTxt" in rmDict else "", img=rmDict["img"] if "img" in rmDict else "", thumb=rmDict["thumb"] if "thumb" in rmDict else "", icon=rmDict["icon"] if "icon" in rmDict else "", authorName=rmDict["authorName"] if "authorName" in rmDict else "", timeout=timeoutTT, targetMember=dcGuild.get_member(rmDict["targetMember"]) if "targetMember" in rmDict else None, targetRole=dcGuild.get_role(rmDict["targetRole"]) if "targetRole" in rmDict else None)
async def fromDict(rmDict : dict) -> ReactionPollMenu: """Reconstruct a ReactionPollMenu object from its dictionary-serialized representation - the opposite of ReactionPollMenu.toDict :param dict rmDict: A dictionary containing all information needed to recreate the desired ReactionPollMenu :return: A new ReactionPollMenu object as described in rmDict :rtype: ReactionPollMenu """ options = {} for emojiName in rmDict["options"]: emoji = bbUtil.dumbEmojiFromStr(emojiName) options[emoji] = ReactionMenu.DummyReactionMenuOption(rmDict["options"][emojiName], emoji) msg = await bbGlobals.client.get_guild(rmDict["guild"]).get_channel(rmDict["channel"]).fetch_message(rmDict["msg"]) timeoutTT = None if "timeout" in rmDict: expiryTime = datetime.utcfromtimestamp(rmDict["timeout"]) bbGlobals.reactionMenusTTDB.scheduleTask(TimedTask.TimedTask(expiryTime=expiryTime, expiryFunction=printAndExpirePollResults, expiryFunctionArgs=msg.id)) return ReactionPollMenu(msg, options, timeoutTT, multipleChoice=rmDict["multipleChoice"] if "multipleChoice" in rmDict else False, titleTxt=rmDict["titleTxt"] if "titleTxt" in rmDict else "", desc=rmDict["desc"] if "desc" in rmDict else "", col=Colour.from_rgb(rmDict["col"][0], rmDict["col"][1], rmDict["col"][2]) if "col" in rmDict else Colour.default(), footerTxt=rmDict["footerTxt"] if "footerTxt" in rmDict else "", img=rmDict["img"] if "img" in rmDict else "", thumb=rmDict["thumb"] if "thumb" in rmDict else "", icon=rmDict["icon"] if "icon" in rmDict else "", authorName=rmDict["authorName"] if "authorName" in rmDict else "", targetMember=msg.guild.get_member(rmDict["targetMember"]) if "targetMember" in rmDict else None, targetRole=msg.guild.get_role(rmDict["targetRole"]) if "targetRole" in rmDict else None, owningBBUser=bbGlobals.usersDB.getUser(rmDict["owningBBUser"]) if "owningBBUser" in rmDict and bbGlobals.usersDB.userIDExists(rmDict["owningBBUser"]) else None)
# Show more verbose output in moderation channels for infractions and nominations if is_mod_channel(ctx.channel): fields.append(await self.user_messages(user)) fields.append(await self.expanded_user_infraction_counts(user)) fields.append(await self.user_nomination_counts(user)) else: fields.append(await self.basic_user_infraction_counts(user)) # Let's build the embed now embed = Embed(title=name, description=" ".join(badges)) for field_name, field_content in fields: embed.add_field(name=field_name, value=field_content, inline=False) embed.set_thumbnail(url=user.avatar_url_as(static_format="png")) embed.colour = user.colour if user.colour != Colour.default( ) else Colour.blurple() return embed async def basic_user_infraction_counts( self, user: MemberOrUser) -> Tuple[str, str]: """Gets the total and active infraction counts for the given `member`.""" infractions = await self.bot.api_client.get('bot/infractions', params={ 'hidden': 'False', 'user__id': str(user.id) }) total_infractions = len(infractions) active_infractions = sum(infraction['active']
async def process_reaction_event(self, payload: RawReactionActionEvent) -> None: """ Process Reaction event. Checks: * Emoji is in the list. * User has a menu opened. * State of menu needs to be valid. """ emoji = str(payload.emoji) if emoji not in EMOJIS or \ payload.user_id not in self.tasks or \ self.tasks[payload.user_id]['details']['state'] == 0: return ctx = self.tasks[payload.user_id]["info"]["ctx"] old_state = self.tasks[payload.user_id]["details"]["state"] log.debug(f'processing {emoji} for {ctx.author.id}') if emoji == "❎": # Close menu await self.close(ctx) return elif emoji == "✅": type_ = self.tasks[ctx.author.id]['details']['type'] if self.bot.planner.check_passed_date(self.tasks[ctx.author.id]["details"]["headers"]["date"]): log.debug(f'{ctx.author.id} tried to add/edit passed assignment.') await self.close(ctx, "Cannot add/edit already passed assignment.") return title = self.tasks[ctx.author.id]["details"]["headers"]["title"] description = self.tasks[ctx.author.id]["details"]["headers"]["description"] date = self.tasks[ctx.author.id]["details"]["headers"]["date"] image_url = self.tasks[ctx.author.id]["details"]["image"] if all( (title == "Untitled", description == "No Description Provied", date == "Unknown", image_url == "Not Attached") ): log.debug(f'{ctx.author.id} tried to add/edit to invalid assignement.') await self.close(ctx, "Invalid Assignment") return try: ret = await self.bot.planner.add( ctx.guild.id, title = title, description = description, date = date, image_url = image_url, key = self.tasks[ctx.author.id]['details']['key'] ) except Exception: text = f"Unable to {type_} Assignment, Problem has been reported." log.warning(f'something went wrong while {ctx.author.id} add/edit in homework menu') log.warning(traceback.format_exc()) await self.bot.log(__name__, f"An Exception were found while finishing adding assignment\n```py\n{traceback.format_exc()}\n```", True) colour = Colour.default() else: text = f"Successfully Added Assignment with key `{ ret }`" if type_ == 'add' \ else "Successfully Edited Assignment." colour = Colour.teal() log.debug(f'{ctx.author.id} add/edit new assignment and passed in successfully.') await self.close(ctx, text, colour) return elif emoji == "1️⃣": self.tasks[payload.user_id]["details"]["state"] = 1 elif emoji == "2️⃣": self.tasks[payload.user_id]["details"]["state"] = 2 elif emoji == "3️⃣": self.tasks[payload.user_id]["details"]["state"] = 3 elif emoji == "4️⃣": self.tasks[payload.user_id]["details"]["state"] = 4 if old_state != self.tasks[payload.user_id]["details"]["state"]: # update if the state changed. await self.update_embed(ctx)
def get_member_color(member) -> Colour: """Get the final rendered color of a guild member as of its highest role.""" return getattr(subscript(member.roles, -1), 'colour', None) or Colour.default()