tickets_plus.ext.checks
Tickets+ decorators for use with discord.py app commands.
A set of decorators for use with discord.py application commands.
These are generally Tickets Plus specific checks.
They require the client to be a tickets_plus.bot.TicketsPlusBot instance.
Though some may work with any discord.ext.commands.Bot instance.
Typical usage example:
from discord import app_commands from tickets_plus.ext import checks @app_commands.command() @checks.is_owner_check() async def command(interaction: discord.Interaction): ...
1"""Tickets+ decorators for use with discord.py app commands. 2 3A set of decorators for use with discord.py application commands. 4These are generally Tickets Plus specific checks. 5They require the client to be a `tickets_plus.bot.TicketsPlusBot` instance. 6Though some may work with any `discord.ext.commands.Bot` instance. 7 8Typical usage example: 9 ```py 10 from discord import app_commands 11 from tickets_plus.ext import checks 12 13 @app_commands.command() 14 @checks.is_owner_check() 15 async def command(interaction: discord.Interaction): 16 ... 17 ``` 18""" 19# License: EPL-2.0 20# SPDX-License-Identifier: EPL-2.0 21# Copyright (c) 2021-present The Tickets+ Contributors 22# This Source Code may also be made available under the following 23# Secondary Licenses when the conditions for such availability set forth 24# in the Eclipse Public License, v. 2.0 are satisfied: GPL-3.0-only OR 25# If later approved by the Initial Contributor, GPL-3.0-or-later. 26 27import discord 28from discord import app_commands 29 30from tickets_plus.ext import exceptions 31 32 33def is_owner_check(): 34 """A check for owner only commands. 35 36 We need to create our own check because the default one doesn't work with 37 application commands. 38 39 Returns: 40 `discord.app_commands.check`: The check. 41 It's a decorator, so you can use it like this: 42 ```py 43 @app_commands.command() 44 @is_owner_check() 45 async def command(interaction: discord.Interaction): 46 ... 47 ``` 48 """ 49 50 async def is_owner(interaction: discord.Interaction) -> bool: 51 """Checks if interaction user is an owner. 52 53 The actual check. It's a coroutine, so it can be awaited. 54 55 Args: 56 interaction: The interaction to check. 57 58 Returns: 59 `bool`: Whether the user is an owner or not. 60 Doesn't return if the user is not an owner. 61 62 Raises: 63 `tickets_plus.exceptions.TicketsCheckFailure`: Requirements not met. 64 Raised if the user is not an owner. This is according to the 65 discord.py convention. 66 """ 67 app = await interaction.client.application_info() 68 if app.team: 69 # Split to avoid errors ie AttributeError 70 if interaction.user in app.team.members: 71 return True 72 if interaction.user == app.owner: 73 return True 74 raise exceptions.TicketsCheckFailure("You do not have permission to do this.") 75 76 return app_commands.check(is_owner) 77 78 79def is_staff_check(): 80 """A staff check using the database. 81 82 We need to create our own check, so we can use the database. 83 84 Returns: 85 `discord.app_commands.check`: The check. 86 It's a decorator, so you can use it like this: 87 ```py 88 @app_commands.command() 89 @is_staff_check() 90 async def command(interaction: discord.Interaction): 91 ... 92 ``` 93 """ 94 95 async def is_staff(interaction: discord.Interaction) -> bool: 96 """Checks if interaction user is staff. 97 98 The actual check. It's a coroutine, so it can be awaited. 99 100 Args: 101 interaction: The interaction to check. 102 103 Returns: 104 bool: Whether the user is staff or not. 105 Doesn't return if the user is not staff. 106 107 Raises: 108 `tickets_plus.exceptions.TicketsCheckFailure`: Requirements not met. 109 Raised if the user is not staff. This is according to the 110 discord.py convention. 111 """ 112 if interaction.guild is None: 113 return False 114 app = await interaction.client.application_info() 115 if app.team: 116 # Bot owners are always staff, split to avoid errors 117 if interaction.user in app.team.members: 118 return True 119 if interaction.user == app.owner: 120 return True 121 async with interaction.client.get_connection() as conn: # type: ignore 122 staff_roles = await conn.get_all_staff_roles(interaction.guild_id) 123 for role in staff_roles: 124 parsed_role = interaction.guild.get_role(role.role_id) 125 if parsed_role in interaction.user.roles: # type: ignore 126 # Already checked for member 127 return True 128 raise exceptions.TicketsCheckFailure("You do not have" 129 " permission to do this here.") 130 131 return app_commands.check(is_staff)
def
is_owner_check():
34def is_owner_check(): 35 """A check for owner only commands. 36 37 We need to create our own check because the default one doesn't work with 38 application commands. 39 40 Returns: 41 `discord.app_commands.check`: The check. 42 It's a decorator, so you can use it like this: 43 ```py 44 @app_commands.command() 45 @is_owner_check() 46 async def command(interaction: discord.Interaction): 47 ... 48 ``` 49 """ 50 51 async def is_owner(interaction: discord.Interaction) -> bool: 52 """Checks if interaction user is an owner. 53 54 The actual check. It's a coroutine, so it can be awaited. 55 56 Args: 57 interaction: The interaction to check. 58 59 Returns: 60 `bool`: Whether the user is an owner or not. 61 Doesn't return if the user is not an owner. 62 63 Raises: 64 `tickets_plus.exceptions.TicketsCheckFailure`: Requirements not met. 65 Raised if the user is not an owner. This is according to the 66 discord.py convention. 67 """ 68 app = await interaction.client.application_info() 69 if app.team: 70 # Split to avoid errors ie AttributeError 71 if interaction.user in app.team.members: 72 return True 73 if interaction.user == app.owner: 74 return True 75 raise exceptions.TicketsCheckFailure("You do not have permission to do this.") 76 77 return app_commands.check(is_owner)
A check for owner only commands.
We need to create our own check because the default one doesn't work with application commands.
Returns:
discord.app_commands.check: The check. It's a decorator, so you can use it like this:@app_commands.command() @is_owner_check() async def command(interaction: discord.Interaction): ...
def
is_staff_check():
80def is_staff_check(): 81 """A staff check using the database. 82 83 We need to create our own check, so we can use the database. 84 85 Returns: 86 `discord.app_commands.check`: The check. 87 It's a decorator, so you can use it like this: 88 ```py 89 @app_commands.command() 90 @is_staff_check() 91 async def command(interaction: discord.Interaction): 92 ... 93 ``` 94 """ 95 96 async def is_staff(interaction: discord.Interaction) -> bool: 97 """Checks if interaction user is staff. 98 99 The actual check. It's a coroutine, so it can be awaited. 100 101 Args: 102 interaction: The interaction to check. 103 104 Returns: 105 bool: Whether the user is staff or not. 106 Doesn't return if the user is not staff. 107 108 Raises: 109 `tickets_plus.exceptions.TicketsCheckFailure`: Requirements not met. 110 Raised if the user is not staff. This is according to the 111 discord.py convention. 112 """ 113 if interaction.guild is None: 114 return False 115 app = await interaction.client.application_info() 116 if app.team: 117 # Bot owners are always staff, split to avoid errors 118 if interaction.user in app.team.members: 119 return True 120 if interaction.user == app.owner: 121 return True 122 async with interaction.client.get_connection() as conn: # type: ignore 123 staff_roles = await conn.get_all_staff_roles(interaction.guild_id) 124 for role in staff_roles: 125 parsed_role = interaction.guild.get_role(role.role_id) 126 if parsed_role in interaction.user.roles: # type: ignore 127 # Already checked for member 128 return True 129 raise exceptions.TicketsCheckFailure("You do not have" 130 " permission to do this here.") 131 132 return app_commands.check(is_staff)
A staff check using the database.
We need to create our own check, so we can use the database.
Returns:
discord.app_commands.check: The check. It's a decorator, so you can use it like this:@app_commands.command() @is_staff_check() async def command(interaction: discord.Interaction): ...