Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion bot/cogs/information.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import colorsys
import logging
import textwrap
import typing

from discord import CategoryChannel, Colour, Embed, Member, TextChannel, VoiceChannel
from discord import CategoryChannel, Colour, Embed, Member, Role, TextChannel, VoiceChannel, utils
from discord.ext.commands import Bot, Cog, Context, command

from bot.constants import Channels, Emojis, MODERATION_ROLES, STAFF_ROLES
Expand Down Expand Up @@ -42,6 +44,52 @@ async def roles_info(self, ctx: Context) -> None:

await ctx.send(embed=embed)

@with_role(*MODERATION_ROLES)
@command(name="role")
async def role_info(self, ctx: Context, *roles: typing.Union[Role, str]) -> None:
"""
Return information on a role or list of roles.

To specify multiple roles just add to the arguments, delimit roles with spaces in them using quotation marks.
"""
parsed_roles = []

for role_name in roles:
if isinstance(role_name, Role):
# Role conversion has already succeeded
parsed_roles.append(role_name)
continue

role = utils.find(lambda r: r.name.lower() == role_name.lower(), ctx.guild.roles)

if not role:
await ctx.send(f":x: Could not convert `{role_name}` to a role")
continue

parsed_roles.append(role)

for role in parsed_roles:
embed = Embed(
title=f"{role.name} info",
colour=role.colour,
)

embed.add_field(name="ID", value=role.id, inline=True)

embed.add_field(name="Colour (RGB)", value=f"#{role.colour.value:0>6x}", inline=True)

h, s, v = colorsys.rgb_to_hsv(*role.colour.to_rgb())

embed.add_field(name="Colour (HSV)", value=f"{h:.2f} {s:.2f} {v}", inline=True)

embed.add_field(name="Member count", value=len(role.members), inline=True)

embed.add_field(name="Position", value=role.position)

embed.add_field(name="Permission code", value=role.permissions.value, inline=True)

await ctx.send(embed=embed)

@command(name="server", aliases=["server_info", "guild", "guild_info"])
async def server_info(self, ctx: Context) -> None:
"""Returns an embed full of server information."""
Expand Down
48 changes: 48 additions & 0 deletions tests/cogs/test_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from discord import (
CategoryChannel,
Colour,
Permissions,
Role,
TextChannel,
VoiceChannel,
)
Expand Down Expand Up @@ -66,6 +68,52 @@ def test_roles_info_command(cog, ctx):
assert embed.footer.text == "Total roles: 1"


def test_role_info_command(cog, ctx):
dummy_role = MagicMock(spec=Role)
dummy_role.name = "Dummy"
dummy_role.colour = Colour.blurple()
dummy_role.id = 112233445566778899
dummy_role.position = 10
dummy_role.permissions = Permissions(0)
dummy_role.members = [ctx.author]

admin_role = MagicMock(spec=Role)
admin_role.name = "Admin"
admin_role.colour = Colour.red()
admin_role.id = 998877665544332211
admin_role.position = 3
admin_role.permissions = Permissions(0)
admin_role.members = [ctx.author]

ctx.guild.roles = [dummy_role, admin_role]

cog.role_info.can_run = AsyncMock()
cog.role_info.can_run.return_value = True

coroutine = cog.role_info.callback(cog, ctx, dummy_role, admin_role)

assert asyncio.run(coroutine) is None

assert ctx.send.call_count == 2

(_, dummy_kwargs), (_, admin_kwargs) = ctx.send.call_args_list

dummy_embed = dummy_kwargs["embed"]
admin_embed = admin_kwargs["embed"]

assert dummy_embed.title == "Dummy info"
assert dummy_embed.colour == Colour.blurple()

assert dummy_embed.fields[0].value == str(dummy_role.id)
assert dummy_embed.fields[1].value == f"#{dummy_role.colour.value:0>6x}"
assert dummy_embed.fields[2].value == "0.63 0.48 218"
assert dummy_embed.fields[3].value == "1"
assert dummy_embed.fields[4].value == "10"
assert dummy_embed.fields[5].value == "0"

assert admin_embed.title == "Admin info"
assert admin_embed.colour == Colour.red()

# There is no argument passed in here that we can use to test,
# so the return value would change constantly.
@patch('bot.cogs.information.time_since')
Expand Down