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
1 change: 1 addition & 0 deletions bot/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,7 @@ class VideoPermission(metaclass=YAMLGetter):
# Default role combinations
MODERATION_ROLES = Guild.moderation_roles
STAFF_ROLES = Guild.staff_roles
STAFF_PARTNERS_COMMUNITY_ROLES = STAFF_ROLES + [Roles.partners, Roles.python_community]

# Channel combinations
MODERATION_CHANNELS = Guild.moderation_channels
Expand Down
4 changes: 2 additions & 2 deletions bot/exts/info/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from rapidfuzz.utils import default_process

from bot import constants
from bot.constants import Channels, STAFF_ROLES
from bot.constants import Channels, STAFF_PARTNERS_COMMUNITY_ROLES
from bot.decorators import redirect_output
from bot.pagination import LinePaginator
from bot.utils.messages import wait_for_deletion
Expand Down Expand Up @@ -54,7 +54,7 @@ class CustomHelpCommand(HelpCommand):
def __init__(self):
super().__init__(command_attrs={"help": "Shows help for bot commands"})

@redirect_output(destination_channel=Channels.bot_commands, bypass_roles=STAFF_ROLES)
@redirect_output(destination_channel=Channels.bot_commands, bypass_roles=STAFF_PARTNERS_COMMUNITY_ROLES)
async def command_callback(self, ctx: Context, *, command: str = None) -> None:
"""Attempts to match the provided query with a valid command or cog."""
# the only reason we need to tamper with this is because d.py does not support "categories",
Expand Down
10 changes: 5 additions & 5 deletions bot/exts/info/information.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def get_extended_server_info(self, ctx: Context) -> str:
{python_general.mention} cooldown: {python_general.slowmode_delay}s
""")

@has_any_role(*constants.STAFF_ROLES)
@has_any_role(*constants.STAFF_PARTNERS_COMMUNITY_ROLES)
@command(name="roles")
async def roles_info(self, ctx: Context) -> None:
"""Returns a list of all roles and their corresponding IDs."""
Expand All @@ -115,7 +115,7 @@ async def roles_info(self, ctx: Context) -> None:

await LinePaginator.paginate(role_list, ctx, embed, empty=False)

@has_any_role(*constants.STAFF_ROLES)
@has_any_role(*constants.STAFF_PARTNERS_COMMUNITY_ROLES)
@command(name="role")
async def role_info(self, ctx: Context, *roles: Union[Role, str]) -> None:
"""
Expand Down Expand Up @@ -232,7 +232,7 @@ async def user_info(self, ctx: Context, user: MemberOrUser = None) -> None:
return

# Will redirect to #bot-commands if it fails.
if in_whitelist_check(ctx, roles=constants.STAFF_ROLES):
if in_whitelist_check(ctx, roles=constants.STAFF_PARTNERS_COMMUNITY_ROLES):
embed = await self.create_user_embed(ctx, user)
await ctx.send(embed=embed)

Expand Down Expand Up @@ -455,9 +455,9 @@ def format_fields(self, mapping: Mapping[str, Any], field_width: Optional[int] =
# remove trailing whitespace
return out.rstrip()

@cooldown_with_role_bypass(2, 60 * 3, BucketType.member, bypass_roles=constants.STAFF_ROLES)
@cooldown_with_role_bypass(2, 60 * 3, BucketType.member, bypass_roles=constants.STAFF_PARTNERS_COMMUNITY_ROLES)
@group(invoke_without_command=True)
@in_whitelist(channels=(constants.Channels.bot_commands,), roles=constants.STAFF_ROLES)
@in_whitelist(channels=(constants.Channels.bot_commands,), roles=constants.STAFF_PARTNERS_COMMUNITY_ROLES)
async def raw(self, ctx: Context, *, message: Message, json: bool = False) -> None:
"""Shows information about the raw API response."""
if ctx.author not in message.channel.members:
Expand Down
13 changes: 8 additions & 5 deletions bot/exts/moderation/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
from discord.ext import commands

from bot.bot import Bot
from bot.constants import Colours, Emojis, Guild, MODERATION_ROLES, Roles, STAFF_ROLES, VideoPermission
from bot.constants import (
Colours, Emojis, Guild, MODERATION_ROLES, Roles,
STAFF_PARTNERS_COMMUNITY_ROLES, VideoPermission
)
from bot.converters import Expiry
from bot.pagination import LinePaginator
from bot.utils.scheduling import Scheduler
Expand Down Expand Up @@ -193,17 +196,17 @@ async def revokestream(self, ctx: commands.Context, member: discord.Member) -> N
@commands.command(aliases=('lstream',))
@commands.has_any_role(*MODERATION_ROLES)
async def liststream(self, ctx: commands.Context) -> None:
"""Lists all non-staff users who have permission to stream."""
non_staff_members_with_stream = [
"""Lists all users who aren't staff, partners or members of the python community and have stream permissions."""
non_staff_partners_community_members_with_stream = [
member
for member in ctx.guild.get_role(Roles.video).members
if not any(role.id in STAFF_ROLES for role in member.roles)
if not any(role.id in STAFF_PARTNERS_COMMUNITY_ROLES for role in member.roles)
]

# List of tuples (UtcPosixTimestamp, str)
# So that the list can be sorted on the UtcPosixTimestamp before the message is passed to the paginator.
streamer_info = []
for member in non_staff_members_with_stream:
for member in non_staff_partners_community_members_with_stream:
if revoke_time := await self.task_cache.get(member.id):
# Member only has temporary streaming perms
revoke_delta = Arrow.utcfromtimestamp(revoke_time).humanize()
Expand Down
4 changes: 2 additions & 2 deletions bot/exts/utils/ping.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from discord.ext import commands

from bot.bot import Bot
from bot.constants import Channels, STAFF_ROLES, URLs
from bot.constants import Channels, STAFF_PARTNERS_COMMUNITY_ROLES, URLs
from bot.decorators import in_whitelist

DESCRIPTIONS = (
Expand All @@ -23,7 +23,7 @@ def __init__(self, bot: Bot) -> None:
self.bot = bot

@commands.command()
@in_whitelist(channels=(Channels.bot_commands,), roles=STAFF_ROLES)
@in_whitelist(channels=(Channels.bot_commands,), roles=STAFF_PARTNERS_COMMUNITY_ROLES)
async def ping(self, ctx: commands.Context) -> None:
"""
Gets different measures of latency within the bot.
Expand Down
14 changes: 9 additions & 5 deletions bot/exts/utils/reminders.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
from discord.ext.commands import Cog, Context, Greedy, group

from bot.bot import Bot
from bot.constants import Guild, Icons, MODERATION_ROLES, POSITIVE_REPLIES, Roles, STAFF_ROLES
from bot.constants import (
Guild, Icons, MODERATION_ROLES, POSITIVE_REPLIES,
Roles, STAFF_PARTNERS_COMMUNITY_ROLES
)
from bot.converters import Duration, UserMentionOrID
from bot.pagination import LinePaginator
from bot.utils.checks import has_any_role_check, has_no_roles_check
Expand Down Expand Up @@ -111,7 +114,7 @@ async def _check_mentions(ctx: Context, mentions: t.Iterable[Mentionable]) -> t.

If mentions aren't allowed, also return the type of mention(s) disallowed.
"""
if await has_no_roles_check(ctx, *STAFF_ROLES):
if await has_no_roles_check(ctx, *STAFF_PARTNERS_COMMUNITY_ROLES):
return False, "members/roles"
elif await has_no_roles_check(ctx, *MODERATION_ROLES):
return all(isinstance(mention, discord.Member) for mention in mentions), "roles"
Expand All @@ -137,7 +140,7 @@ def get_mentionables(self, mention_ids: t.List[int]) -> t.Iterator[Mentionable]:
"""Converts Role and Member ids to their corresponding objects if possible."""
guild = self.bot.get_guild(Guild.id)
for mention_id in mention_ids:
if (mentionable := (guild.get_member(mention_id) or guild.get_role(mention_id))):
if mentionable := (guild.get_member(mention_id) or guild.get_role(mention_id)):
yield mentionable

def schedule_reminder(self, reminder: dict) -> None:
Expand Down Expand Up @@ -226,8 +229,9 @@ async def new_reminder(

Expiration is parsed per: http://strftime.org/
"""
# If the user is not staff, we need to verify whether or not to make a reminder at all.
if await has_no_roles_check(ctx, *STAFF_ROLES):
# If the user is not staff, partner or part of the python community,
# we need to verify whether or not to make a reminder at all.
if await has_no_roles_check(ctx, *STAFF_PARTNERS_COMMUNITY_ROLES):

# If they don't have permission to set a reminder in this channel
if ctx.channel.id not in WHITELISTED_CHANNELS:
Expand Down
12 changes: 7 additions & 5 deletions bot/exts/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from discord.utils import snowflake_time

from bot.bot import Bot
from bot.constants import Channels, MODERATION_ROLES, Roles, STAFF_ROLES
from bot.constants import Channels, MODERATION_ROLES, Roles, STAFF_PARTNERS_COMMUNITY_ROLES
from bot.converters import Snowflake
from bot.decorators import in_whitelist
from bot.pagination import LinePaginator
Expand Down Expand Up @@ -49,20 +49,22 @@ def __init__(self, bot: Bot):
self.bot = bot

@command()
@in_whitelist(channels=(Channels.bot_commands, Channels.discord_py), roles=STAFF_ROLES)
@in_whitelist(channels=(Channels.bot_commands, Channels.discord_py), roles=STAFF_PARTNERS_COMMUNITY_ROLES)
async def charinfo(self, ctx: Context, *, characters: str) -> None:
"""Shows you information on up to 50 unicode characters."""
match = re.match(r"<(a?):(\w+):(\d+)>", characters)
if match:
return await messages.send_denial(
await messages.send_denial(
ctx,
"**Non-Character Detected**\n"
"Only unicode characters can be processed, but a custom Discord emoji "
"was found. Please remove it and try again."
)
return

if len(characters) > 50:
return await messages.send_denial(ctx, f"Too many characters ({len(characters)}/50)")
await messages.send_denial(ctx, f"Too many characters ({len(characters)}/50)")
return

def get_info(char: str) -> Tuple[str, str]:
digit = f"{ord(char):x}"
Expand Down Expand Up @@ -156,7 +158,7 @@ async def zen(self, ctx: Context, *, search_value: Union[int, str, None] = None)
await ctx.send(embed=embed)

@command(aliases=("snf", "snfl", "sf"))
@in_whitelist(channels=(Channels.bot_commands,), roles=STAFF_ROLES)
@in_whitelist(channels=(Channels.bot_commands,), roles=STAFF_PARTNERS_COMMUNITY_ROLES)
async def snowflake(self, ctx: Context, *snowflakes: Snowflake) -> None:
"""Get Discord snowflake creation time."""
if not snowflakes:
Expand Down
4 changes: 2 additions & 2 deletions tests/bot/exts/info/test_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ async def test_regular_user_can_explicitly_target_themselves(self, create_embed,
@unittest.mock.patch("bot.exts.info.information.Information.create_user_embed")
async def test_staff_members_can_bypass_channel_restriction(self, create_embed, constants):
"""Staff members should be able to bypass the bot-commands channel restriction."""
constants.STAFF_ROLES = [self.moderator_role.id]
constants.STAFF_PARTNERS_COMMUNITY_ROLES = [self.moderator_role.id]
ctx = helpers.MockContext(author=self.moderator, channel=helpers.MockTextChannel(id=200))

await self.cog.user_info(self.cog, ctx)
Expand All @@ -519,7 +519,7 @@ async def test_staff_members_can_bypass_channel_restriction(self, create_embed,
async def test_moderators_can_target_another_member(self, create_embed, constants):
"""A moderator should be able to use `!user` targeting another user."""
constants.MODERATION_ROLES = [self.moderator_role.id]
constants.STAFF_ROLES = [self.moderator_role.id]
constants.STAFF_PARTNERS_COMMUNITY_ROLES = [self.moderator_role.id]
ctx = helpers.MockContext(author=self.moderator, channel=helpers.MockTextChannel(id=50))

await self.cog.user_info(self.cog, ctx, self.target)
Expand Down