Skip to content

Commit

Permalink
Merge branch 'Cog-Creators:V3/develop' into use_exec_module
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuro-Rui authored Mar 2, 2024
2 parents 3e1b1ec + 9dc7462 commit d12f6e3
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 18 deletions.
5 changes: 1 addition & 4 deletions docs/cog_guides/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1475,9 +1475,6 @@ helpset maxpages

Set the maximum number of help pages sent in a server channel.

.. Note:: This setting does not apply to menu help.


If a help message contains more pages than this value, the help message will
be sent to the command author via DM. This is to help reduce spam in server
text channels.
Expand Down Expand Up @@ -4378,4 +4375,4 @@ uptime
**Description**

Shows Red's uptime.
Shows Red's uptime.
12 changes: 11 additions & 1 deletion redbot/cogs/alias/alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,15 @@ async def get_prefix(self, message: discord.Message) -> str:
raise ValueError("No prefix found.")

async def call_alias(self, message: discord.Message, prefix: str, alias: AliasEntry):
new_message = self.translate_alias_message(message, prefix, alias)
await self.bot.process_commands(new_message)

def translate_alias_message(self, message: discord.Message, prefix: str, alias: AliasEntry):
"""
Translates a discord message using an alias
for a command to a discord message using the
alias' base command.
"""
new_message = copy(message)
try:
args = alias.get_extra_args_from_alias(message, prefix)
Expand All @@ -163,7 +172,8 @@ async def call_alias(self, message: discord.Message, prefix: str, alias: AliasEn
new_message.content = "{}{} {}".format(
prefix, command, " ".join(args[trackform.max + 1 :])
).strip()
await self.bot.process_commands(new_message)

return new_message

async def paginate_alias_list(
self, ctx: commands.Context, alias_list: List[AliasEntry]
Expand Down
3 changes: 1 addition & 2 deletions redbot/cogs/alias/alias_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ def get_extra_args_from_alias(self, message: discord.Message, prefix: str) -> st
word = view.get_quoted_word()
if len(word) < view.index - prev:
word = "".join((view.buffer[prev], word, view.buffer[view.index - 1]))
extra.append(word)
view.skip_ws()
extra.append(word.strip(" "))
return extra

def to_json(self) -> dict:
Expand Down
6 changes: 3 additions & 3 deletions redbot/cogs/streams/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,10 @@ async def streamalert_list(self, ctx: commands.Context):
return

for channel_id, stream_platform in streams_list.items():
msg += f"** - #{ctx.guild.get_channel(channel_id)}**\n"
msg += f"- {ctx.guild.get_channel(channel_id).mention}\n"
for platform, streams in stream_platform.items():
msg += f"\t** - {platform}**\n"
msg += f"\t\t{humanize_list(streams)}\n"
msg += f" - **{platform}**\n"
msg += f" {humanize_list(streams)}\n"

for page in pagify(msg):
await ctx.send(page)
Expand Down
8 changes: 7 additions & 1 deletion redbot/core/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ async def interactive_config(red, token_set, prefix_set, *, print_header=True):
print(
"\nPick a prefix. A prefix is what you type before a "
"command. Example:\n"
"!help\n^ The exclamation mark is the prefix in this case.\n"
"!help\n^ The exclamation mark (!) is the prefix in this case.\n"
"The prefix can be multiple characters. You will be able to change it "
"later and add more of them.\nChoose your prefix:\n"
)
Expand All @@ -94,6 +94,12 @@ async def interactive_config(red, token_set, prefix_set, *, print_header=True):
"Prefixes cannot start with '/', as it conflicts with Discord's slash commands."
)
prefix = ""
if prefix and not confirm(
f'You chose "{prefix}" as your prefix. To run the help command,'
f" you will have to send:\n{prefix}help\n\n"
"Do you want to continue with this prefix?"
):
prefix = ""
if prefix:
await red._config.prefix.set([prefix])

Expand Down
21 changes: 17 additions & 4 deletions redbot/core/commands/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -856,23 +856,36 @@ async def send_pages(
if help_settings.use_menus.value >= HelpMenuSetting.buttons.value:
use_select = help_settings.use_menus.value == 3
select_only = help_settings.use_menus.value == 4
await SimpleMenu(
menu = SimpleMenu(
pages,
timeout=help_settings.react_timeout,
use_select_menu=use_select,
use_select_only=select_only,
).start(ctx)
)
# Send menu to DMs if max pages is 0
if help_settings.max_pages_in_guild == 0:
await menu.start_dm(ctx.author)
else:
await menu.start(ctx)

elif (
can_user_react_in(ctx.me, ctx.channel)
and help_settings.use_menus is HelpMenuSetting.reactions
):
use_DMs = help_settings.max_pages_in_guild == 0
destination = ctx.author if use_DMs else ctx.channel
# Specifically ensuring the menu's message is sent prior to returning
m = await (ctx.send(embed=pages[0]) if embed else ctx.send(pages[0]))
m = await (destination.send(embed=pages[0]) if embed else destination.send(pages[0]))
c = menus.DEFAULT_CONTROLS if len(pages) > 1 else {"\N{CROSS MARK}": menus.close_menu}
# Allow other things to happen during menu timeout/interaction.
if use_DMs:
menu_ctx = await ctx.bot.get_context(m)
# Monkeypatch so help listens for reactions from the original author, not the bot
menu_ctx.author = ctx.author
else:
menu_ctx = ctx
asyncio.create_task(
menus.menu(ctx, pages, c, message=m, timeout=help_settings.react_timeout)
menus.menu(menu_ctx, pages, c, message=m, timeout=help_settings.react_timeout)
)
# menu needs reactions added manually since we fed it a message
menus.start_adding_reactions(m, c.keys())
Expand Down
1 change: 1 addition & 0 deletions redbot/core/commands/requires.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ def decorator(func: "_CommandOrCoro") -> "_CommandOrCoro":
if user_perms is None:
func.__requires_user_perms__ = None
else:
_validate_perms_dict(user_perms)
if getattr(func, "__requires_user_perms__", None) is None:
func.__requires_user_perms__ = discord.Permissions.none()
func.__requires_user_perms__.update(**user_perms)
Expand Down
26 changes: 23 additions & 3 deletions redbot/core/core_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def entity_transformer(statement: str) -> str:
TokenConverter = commands.get_dict_converter(delims=[" ", ",", ";"])

MAX_PREFIX_LENGTH = 25
MINIMUM_PREFIX_LENGTH = 1


class CoreLogic:
Expand Down Expand Up @@ -2377,7 +2378,7 @@ async def slash_sync_error(self, ctx: commands.Context, error: commands.CommandE
await ctx.send(
_(
"You seem to be attempting to sync after recently syncing. Discord does not like it "
"when bots sync more often than neccecary, so this command has a cooldown. You "
"when bots sync more often than necessary, so this command has a cooldown. You "
"should enable/disable all commands you want to change first, and run this command "
"one time only after all changes have been made. "
)
Expand Down Expand Up @@ -4052,6 +4053,24 @@ async def _set_prefix(self, ctx: commands.Context, *prefixes: str):
_("Prefixes cannot start with '/', as it conflicts with Discord's slash commands.")
)
return
if any(len(x) < MINIMUM_PREFIX_LENGTH for x in prefixes):
await ctx.send(
_(
"Warning: A prefix is below the recommended length (1 character).\n"
"Do you want to continue?"
)
+ " (yes/no)"
)
pred = MessagePredicate.yes_or_no(ctx)
try:
await self.bot.wait_for("message", check=pred, timeout=30)
except asyncio.TimeoutError:
await ctx.send(_("Response timed out."))
return
else:
if pred.result is False:
await ctx.send(_("Cancelled."))
return
if any(len(x) > MAX_PREFIX_LENGTH for x in prefixes):
await ctx.send(
_(
Expand Down Expand Up @@ -4111,6 +4130,9 @@ async def _set_serverprefix(
_("Prefixes cannot start with '/', as it conflicts with Discord's slash commands.")
)
return
if any(len(x) < MINIMUM_PREFIX_LENGTH for x in prefixes):
await ctx.send(_("You cannot have a prefix shorter than 1 character."))
return
if any(len(x) > MAX_PREFIX_LENGTH for x in prefixes):
await ctx.send(_("You cannot have a prefix longer than 25 characters."))
return
Expand Down Expand Up @@ -4446,8 +4468,6 @@ async def helpset_pagecharlimt(self, ctx: commands.Context, limit: int):
async def helpset_maxpages(self, ctx: commands.Context, pages: int):
"""Set the maximum number of help pages sent in a server channel.
Note: This setting does not apply to menu help.
If a help message contains more pages than this value, the help message will
be sent to the command author via DM. This is to help reduce spam in server
text channels.
Expand Down
13 changes: 13 additions & 0 deletions redbot/core/utils/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,19 @@ async def start(self, ctx: Context, *, ephemeral: bool = False):
kwargs = await self.get_page(self.current_page)
self.message = await ctx.send(**kwargs, ephemeral=ephemeral)

async def start_dm(self, user: discord.User):
"""
Used to start displaying the menu in a direct message.
Parameters
----------
user: `discord.User`
The user that will be direct messaged by the bot.
"""
self.author = user
kwargs = await self.get_page(self.current_page)
self.message = await user.send(**kwargs)

async def get_page(self, page_num: int) -> Dict[str, Optional[Any]]:
try:
page = await self.source.get_page(page_num)
Expand Down
14 changes: 14 additions & 0 deletions redbot/pytest/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"empty_role",
"empty_user",
"member_factory",
"newline_message",
"user_factory",
"prefix",
"ctx",
]

Expand Down Expand Up @@ -142,6 +144,18 @@ def empty_message():
return mock_msg("No content.")


@pytest.fixture(scope="module")
def newline_message():
mock_msg = type("", (), {})()
mock_msg.content = "!test a\nb\nc"
return mock_msg


@pytest.fixture(scope="module")
def prefix():
return "!"


@pytest.fixture()
def ctx(empty_member, empty_channel, red):
mock_ctx = namedtuple("Context", "author guild channel message bot")
Expand Down
14 changes: 14 additions & 0 deletions tests/cogs/test_alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ async def test_add_guild_alias(alias, ctx):
assert alias_obj.name == "test"


async def test_translate_alias_message(alias, ctx, newline_message, prefix):
await create_test_guild_alias(alias, ctx)
alias_obj = await alias._aliases.get_alias(ctx.guild, "test")

translated_message = alias.translate_alias_message(newline_message, prefix, alias_obj)

original_content = newline_message.content.split(" ", 1)[1]
original_content = original_content.replace(" ", "")
new_content = translated_message.content.split(" ", 1)[1]
new_content = new_content.replace(" ", "")

assert new_content == original_content


async def test_delete_guild_alias(alias, ctx):
await create_test_guild_alias(alias, ctx)
alias_obj = await alias._aliases.get_alias(ctx.guild, "test")
Expand Down

0 comments on commit d12f6e3

Please sign in to comment.