Beispiel #1
0
    async def recolor(self, ctx, *, query):
        """Change the way a color looks."""
        colors = db.get(ctx.guild.id, "colors")

        try:
            before, after = query.split("|")
        except ValueError:
            raise UserInputError(
                "Command should be formatted as: $rename <color> | <hexcode>")

        # Find the correct color to remove. or dont.
        color = utils.color_lookup(before.strip(), colors)
        if not color:
            raise UserInputError("Couldn't find that color")

        after = after.strip()
        if not utils.validate_hex(after):
            raise UserInputError(
                "Invalid hexcode. Get help at https://htmlcolorcodes.com/")

        # adjust roles if color is changed
        if color["role"]:
            role = ctx.guild.get_role(color["role"])
            new_color = utils.to_rgb(after)
            await role.edit(color=discord.Color.from_rgb(*new_color))

        # update database
        db.guilds.update_one({
            "_id": ctx.guild.id,
            "colors": color
        }, {"$set": {
            "colors.$.hexcode": after
        }})

        await ctx.invoke(bot.get_command("colors"))
Beispiel #2
0
    async def rename_theme(self, ctx, *, query):
        """Rename a theme in the guild."""
        themes = db.get(ctx.guild.id, "themes")

        try:
            before, after = query.split("|")
        except ValueError:
            raise UserInputError(
                "Command should be formatted as: $t.rn <theme> | <name>")

        # Find the correct color to remove. or dont.
        theme = theme_lookup(before.strip(), themes)
        if not theme:
            raise UserInputError("Couldn't find that theme")

        after = after.strip()
        if not after:
            raise UserInputError(
                "Command should be formatted as: $rename <color> | <name>")

        db.guilds.update_one({
            "_id": ctx.guild.id,
            "themes": theme
        }, {"$set": {
            "themes.$.name": after
        }})
        await ctx.invoke(self.bot.get_command("themes"))
Beispiel #3
0
    async def rename_color(self, ctx, *, query):
        """Rename a color."""
        colors = db.get(ctx.guild.id, "colors")

        try:
            before, after = query.split("|")
        except ValueError:
            raise UserInputError(
                "Command should be formatted as: $rename <color> | <name>")

        # Find the correct color to remove. or dont.
        color = utils.color_lookup(before.strip(), colors)
        if not color:
            raise UserInputError("Couldn't find that color")

        after = after.strip()
        if not after:
            raise UserInputError(
                "Command should be formatted as: $rename <color> | <name>")

        # adjust roles if color is changed
        if color["role"]:
            role = ctx.guild.get_role(color["role"])
            await role.edit(name=after)

        # update database
        db.guilds.update_one({
            "_id": ctx.guild.id,
            "colors": color
        }, {"$set": {
            "colors.$.name": after
        }})

        await ctx.invoke(bot.get_command("colors"))
Beispiel #4
0
    async def color_user(self, ctx, member: discord.Member, *, cstring=""):
        """Color a specified user a specified color."""

        colors = db.get(ctx.guild.id, "colors")
        ucolor = utils.find_user_color(member, colors)

        if not colors:
            raise CommandError("There are no active colors")

        # to eliminate random coloring the same color
        if len(colors) > 1 and not cstring:
            exclusive_colors = [color for color in colors if color != ucolor]
            color = utils.color_lookup(cstring, exclusive_colors)
        else:
            color = utils.color_lookup(cstring, colors)

        if not color:
            raise CommandError("Color Not Found")

        if color == ucolor:
            raise CommandError(f"{member.name} already has that color")

        # attempt to uncolor and then color user
        if ucolor:
            await self.uncolor(member, ucolor)
        await self.color(member, color)

        embed = discord.Embed(
            title=f"{member.name} is {color['name']} {check_emoji()}",
            color=utils.discord_color(color)
        )
        await ctx.send(embed=embed)
Beispiel #5
0
    async def show_colors(self, ctx):
        """Display an image of equipped colors."""
        colors = db.get(ctx.guild.id, "colors")

        if not colors:
            return await ctx.send(embed=Embed(title="You have no colors"))

        await ctx.send(file=self.draw_colors(colors))
Beispiel #6
0
    async def convert(self, ctx, arg):
        """Find a color in a list of colors based on a query"""
        colors = db.get(ctx.guild.id, "colors")
        if not colors:
            raise CommandError("You have no active colors")

        color = color_lookup(arg, colors)
        if not color:
            raise CommandError("Color Not Found")

        return color
Beispiel #7
0
    async def convert(self, ctx, arg):
        themes = db.get(ctx.guild.id, "themes")

        if not themes:
            raise CommandError("You have no themes")

        theme = theme_lookup(arg, themes)
        if not theme:
            raise CommandError("Theme Not Found")

        return theme
Beispiel #8
0
    async def show_themes_in_detail(self, ctx):
        """Shows a detailed, textbased view of your themes."""
        themes = db.get(ctx.guild.id, "themes")
        themes_embed = Embed(title="Themes in Detail", description="")
        for theme in themes:
            colors = [
                f"**{color['name']}**: {color['hexcode']}"
                for color in theme["colors"]
            ]
            themes_embed.add_field(name=theme["name"], value="\n".join(colors))

        await ctx.send(embed=themes_embed)
Beispiel #9
0
    async def show_themes(self, ctx):
        """Draw the guild's themes and send in channel."""
        themes = db.get(ctx.guild.id, "themes")

        if not themes:
            return await ctx.send(embed=Embed(title="You have no themes"))

        theme_files = self.draw_themes(themes)

        # create and send catalog
        catalog = Catalog(theme_files)
        await catalog.send(ctx.channel)
Beispiel #10
0
    async def color_server(self, ctx, *, color: utils.ColorConverter = None):
        """Gather all of the uncolored users and assigns them a color"""

        output_suppressed = ctx.guild.id in cfg.suppress_output
        colors = db.get(ctx.guild.id, "colors")  # Fetch colors

        if not colors:
            raise CommandError("There are no active colors")

        cfg.heavy_command_active.add(ctx.guild.id)  # begin heavy command

        # get uncolored members
        uncolored = [member for member in ctx.guild.members
                     if not utils.find_user_color(member, colors)]

        # Send working message
        if not output_suppressed:
            embed = discord.Embed(title=f"Creating Roles {loading_emoji()}")
            msg = await ctx.send(embed=embed)

        # color generator for splashing
        colors = [color] if color else colors  # One color needed if color arg
        index = random.randrange(len(colors))  # random index in colors
        sliced_colors = colors[index:] + colors[:index]

        # Loop over all colors that will be applied and create roles
        for color in sliced_colors[:len(uncolored)]:
            if not color["role"]:
                role = await self.create_role(ctx.guild, color)
                color["role"] = role.id

        # Send progress update
        if not output_suppressed:
            embed = discord.Embed(
                title=f"Coloring {len(uncolored)} People {loading_emoji()}",
                description=f"This will take around {len(uncolored)} seconds"
            )
            await msg.edit(embed=embed)

        # Loop and color every member sleeping a bit inbetween
        for color, member in zip(cycle(sliced_colors), uncolored):
            await self.color(member, color)
            await asyncio.sleep(1)

        cfg.heavy_command_active.discard(ctx.guild.id)

        # Send success message
        if not output_suppressed:
            embed = discord.Embed(
                title=f"Colored {len(uncolored)} members {check_emoji()}",
                color=discord.Color.green()
            )
            await msg.edit(embed=embed)
Beispiel #11
0
    async def uncolorme(self, ctx):
        """Display an image of equipped colors."""
        colors = db.get(ctx.guild.id, "colors")
        ucolor = utils.find_user_color(ctx.author, colors)

        # remove color
        if ucolor:
            await self.uncolor(ctx.author, ucolor)
            response = f"You have been uncolored {check_emoji()}"
        else:
            response = "You don't have a color"

        await ctx.send(embed=discord.Embed(title=response))
Beispiel #12
0
    async def show_colors_in_detail(self, ctx):
        """Show what the database thinks colors are (For testing/support)."""
        colors = db.get(ctx.guild.id, "colors")
        cinfo = Embed(title="Detailed Color Info", description="")
        for color in colors:
            members = [bot.get_user(id).name for id in color["members"]]
            cinfo.add_field(
                name=color["name"],
                value=
                f"**ROLE:** {color['role']}\n**MEMBERS({len(members)}):** {', '.join(members)}"
            )

        await ctx.send(embed=cinfo)
Beispiel #13
0
    async def uncolor_server(self, ctx):
        """Remove all colors but not delete them."""

        colors = db.get(ctx.guild.id, "colors")
        cfg.heavy_command_active.add(ctx.guild.id)  # begin heavy command

        # Remove every role associated with a color
        for color in colors:
            if color["role"]:
                role = ctx.guild.get_role(color["role"])
                await role.delete()

        cfg.heavy_command_active.discard(ctx.guild.id)  # end heavy cmd

        # Send success message
        if ctx.guild.id not in cfg.suppress_output:
            embed = discord.Embed(title=f"Everyone has been uncolored {check_emoji()}",
                                  color=discord.Color.green())
            await ctx.send(embed=embed)
Beispiel #14
0
    async def clear_colors(self, ctx):
        """Removes all active colors."""
        colors = db.get(ctx.guild.id, "colors")

        if ctx.guild.id not in cfg.suppress_output:
            msg = await ctx.send(embed=discord.Embed(
                title=f"Clearing colors {loading_emoji()}"))

        # remove roles
        for color in colors:
            if color["role"]:
                role = ctx.guild.get_role(color["role"])
                await role.delete()
                await asyncio.sleep(0.25)

        db.guilds.update_one({"_id": ctx.guild.id}, {"$set": {"colors": []}})
        if ctx.guild.id not in cfg.suppress_output:
            await msg.edit(
                embed=discord.Embed(title=f"Colors Removed {check_emoji()}",
                                    color=discord.Color.green()))
Beispiel #15
0
    async def add_color(self, ctx, hexcode, *, name=""):
        """Add a color to the database colors."""
        colors = db.get(ctx.guild.id, "colors")

        if len(colors) >= cfg.color_limit:
            raise CommandError(f"Color Limit Reached ({len(colors)}/50)")

        if not utils.validate_hex(hexcode):
            raise UserInputError(
                f"Invalid hexcode. Get help at https://htmlcolorcodes.com/")

        if "|" in name or len(name) > 100:
            raise UserInputError(
                "Color names must be shorter than 100 characters and cannot include `|`"
            )

        if name in [color["name"] for color in colors]:
            raise UserInputError("Cannot have duplicate color names")

        # auto name if name not given
        if not name:
            name = f"Color {len(colors) + 1}"

        # change black color because #000000 in discord is transparent
        if hexcode in {"#000000", "#000"}:
            hexcode = "#000001"

        # create and add color
        new_color = {
            "name": name,
            "hexcode": hexcode,
            "role": None,
            "members": []
        }

        # update database
        db.guilds.update_one({"_id": ctx.guild.id},
                             {"$push": {
                                 "colors": new_color
                             }})
        await ctx.invoke(bot.get_command("colors"))  # show new set
Beispiel #16
0
    async def import_colors(self, ctx, *, name):
        """Save a preset as a theme."""
        themes = db.get(ctx.guild.id, "themes")

        if len(themes) >= cfg.theme_limit:
            raise CommandError(f"Theme Limit Reached ({len(themes)}/10)")

        # Read in preset as dict
        name = name.replace(" ", "")
        try:
            with open(f"assets{sep}presets{sep}{name.lower()}.json"
                      ) as preset_data:
                preset = json.load(preset_data)
        except FileNotFoundError:
            raise UserInputError("Could not find that preset")

        db.guilds.update_one({"_id": ctx.guild.id},
                             {"$push": {
                                 "themes": preset
                             }})

        if ctx.guild.id not in cfg.suppress_output:
            await ctx.invoke(self.bot.get_command("themes"))
Beispiel #17
0
    async def load_theme(self, ctx, *, themename):
        """Change the active colors to a theme."""

        themes = db.get(ctx.guild.id, "themes")
        theme = theme_lookup(themename, themes)

        output_suppressed = ctx.guild.id in cfg.suppress_output

        if not theme:
            raise UserInputError("Could not find that theme")

        if not output_suppressed:
            embed = discord.Embed(title=f"Clearing Colors {loading_emoji()}")
            msg = await ctx.send(embed=embed)

        # Supress output from clear_colors and prevent other commands from modifying colors
        cfg.heavy_command_active.add(ctx.guild.id)
        cfg.suppress_output.add(ctx.guild.id)
        await ctx.invoke(self.bot.get_command("clear_colors"))  # clear colors

        if not output_suppressed:
            cfg.suppress_output.discard(ctx.guild.id)

            # Progress update
            embed = discord.Embed(title=f"Creating Roles {loading_emoji()}")
            await msg.edit(embed=embed)

        # kind of a monster and probably impractical but it works
        # keeps only colors that have members that can be found
        owned_colors = [
            color for color in theme["colors"] if color["members"] and all([
                ctx.guild.get_member(member_id)
                for member_id in color["members"]
            ])
        ]

        # Update colors in db
        colors = deepcopy(theme["colors"])
        for color in colors:
            color["role"] = None
            color["members"] = []

        db.guilds.update_one({"_id": ctx.guild.id},
                             {"$set": {
                                 "colors": colors
                             }})

        cm_pairs = []  # Color and Member pairs
        for color in owned_colors:
            # create role
            role = await ColorAssignment.create_role(ctx.guild, color)
            color["role"] = role.id

            # add to color member pair
            for member_id in color["members"]:
                cm_pairs.append((color, ctx.guild.get_member(member_id)))

        # Progress update
        if not output_suppressed:
            embed = discord.Embed(title=f"Applying Color {loading_emoji()}")
            await msg.edit(embed=embed)

        # loop and apply colors
        for color, member in cm_pairs:
            await ColorAssignment.color(member, color)
            await asyncio.sleep(1)

        cfg.heavy_command_active.discard(ctx.guild.id)

        # report success
        if ctx.guild.id not in cfg.suppress_output:
            success_embed = discord.Embed(
                title=f"Loaded {theme['name']} {check_emoji()}",
                color=discord.Color.green())
            await msg.edit(embed=success_embed)
            await ctx.invoke(self.bot.get_command("colors"))