Esempio n. 1
0
    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())
Esempio n. 2
0
    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
Esempio n. 3
0
 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
Esempio n. 4
0
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
Esempio n. 5
0
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')
Esempio n. 6
0
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
Esempio n. 7
0
    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
Esempio n. 8
0
    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)
Esempio n. 10
0
    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
Esempio n. 11
0
    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}"!')
Esempio n. 12
0
    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
Esempio n. 13
0
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)
Esempio n. 14
0
 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)
Esempio n. 16
0
    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)
Esempio n. 18
0
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)
Esempio n. 19
0
        # 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']
Esempio n. 20
0
    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)
Esempio n. 21
0
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()