Skip to content

Commit 0ded28e

Browse files
Refactor help command
1 parent 6de5aee commit 0ded28e

File tree

1 file changed

+113
-63
lines changed

1 file changed

+113
-63
lines changed

src/cogs/help_command.py

Lines changed: 113 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from discord import app_commands
33
from discord.ext import commands
44

5-
from src.utils import Embeds, Error
5+
from src.utils import Embeds, Error, ViewPageScroller
6+
from typing import Optional, List
67

78

89
class Help(commands.Cog):
@@ -32,75 +33,124 @@ async def on_ready(self):
3233
@app_commands.describe(
3334
query = 'Module\'s or Command\'s name'
3435
)
35-
@commands.cooldown(1, 15)
36-
async def help(self, ctx: commands.Context, query: str = None):
37-
"""Shows all modules of that bot"""
38-
39-
embed = Embeds(
40-
title = 'Commands',
41-
description = f'Use `/help <module>` or `/help <command>` for more information about that module or command\n\u200d'
42-
)
43-
embed.color = discord.Color.blurple()
44-
36+
@commands.cooldown(1, 15, commands.BucketType.user)
37+
async def help(self, ctx: commands.Context, *, query: Optional[str] = None):
38+
"""
39+
**Help command of the bot**
40+
41+
> **Arguments**
42+
```
43+
query | string | default=None
44+
```
45+
46+
> **Example**
47+
```
48+
/help
49+
/help ping
50+
```
51+
"""
52+
embed_data: dict[str, list[list]] = {}
53+
page_limit = 1
54+
55+
async def load_cog_commands(cog, cmds):
56+
if str(self.client.cogs[cog].__doc__).startswith('hidden'): return
57+
if not cog in embed_data:
58+
embed_data[cog] = [[]]
59+
60+
for i in cmds:
61+
if i.hidden or str(i.help).startswith('hidden') or not await i.can_run(ctx): continue
62+
if len(embed_data[cog][-1]) >= page_limit:
63+
embed_data[cog].append([i])
64+
else:
65+
embed_data[cog][-1].append(i)
66+
67+
4568
if not query:
46-
available_cogs = []
47-
for cog in self.client.cogs:
48-
available_commands = []
49-
for cmd in self.client.get_cog(cog).walk_commands():
50-
if not cmd.hidden and not str(cmd.help).startswith('hidden') and await cmd.can_run(ctx):
51-
available_commands.append(cmd)
52-
53-
if len(available_commands) > 0:
54-
available_cogs.append(cog)
55-
56-
embed.add_field(
57-
name = 'Modules',
58-
value = '\n\u200d\n'.join(
59-
f'**{cog}**\n```{str(self.client.cogs[cog].__doc__).lstrip().rstrip()}```' for cog in available_cogs if (
60-
not str(self.client.cogs[cog].__doc__).startswith('hidden')
61-
)
62-
),
63-
inline = False
64-
)
69+
for cogname in self.client.cogs:
70+
if str(self.client.cogs[cogname].__doc__).startswith('hidden'): continue # Skip hidden cogs
71+
72+
cog = self.client.get_cog(cogname)
73+
if cog:
74+
await load_cog_commands(cogname, cog.walk_commands())
6575

6676
else:
67-
found = False
68-
async def add_to_embed(cmd):
69-
if await cmd.can_run(ctx):
70-
embed.add_field(
71-
name = f'/{cmd.qualified_name}',
72-
value = f'{str(cmd.help).lstrip().rstrip()}\n‍',
73-
inline = False
74-
)
75-
76-
for cog in self.client.cogs:
77-
if query.lower() == cog.lower() and not str(self.client.cogs[cog].__doc__).startswith('hidden'):
78-
embed.description += f'\n**{cog}\'s commands**\n\u200d'
79-
available_commands_cog = []
80-
81-
for cmd in self.client.get_cog(cog).walk_commands():
82-
if (not cmd.hidden and not str(cmd.help).startswith('hidden')) and await cmd.can_run(ctx):
83-
available_commands_cog.append(cmd)
84-
85-
if len(available_commands_cog) > 0:
86-
for i in available_commands_cog: await add_to_embed(i)
87-
found = True
77+
query = ''.join(query)
78+
for cogname in self.client.cogs:
79+
if query.lower() == cogname.lower() and not str(self.client.cogs[cogname].__doc__).startswith('hidden'):
80+
cog = self.client.get_cog(cogname)
81+
if not cog: continue
82+
83+
await load_cog_commands(cogname, cog.walk_commands())
8884
break
8985

90-
elif not str(self.client.cogs[cog].__doc__).startswith('hidden'):
91-
for cmd in self.client.get_cog(cog).walk_commands():
92-
if (not cmd.hidden and not str(cmd.help).startswith('hidden')):
93-
if query.lower().strip() in cmd.qualified_name.lower().strip():
94-
found = True
95-
await add_to_embed(cmd)
86+
elif not str(self.client.cogs[cogname].__doc__).startswith('hidden'):
87+
cog = self.client.get_cog(cogname)
88+
if not cog: continue
89+
90+
for cmd in cog.walk_commands():
91+
if query.lower().strip() in cmd.qualified_name.lower().strip():
92+
await load_cog_commands(cogname, [cmd])
93+
94+
95+
if not embed_data:
96+
raise Error(
97+
description = f'Unable to locate module or command' + ((query and f'[{query}]') or '')
98+
)
99+
100+
else: #clean up
101+
cleaned = []
102+
for cogName, pages in embed_data.items():
103+
for page in pages:
104+
cleaned.append([cogName, list(page)])
105+
106+
107+
#Setup embed screen navigation
108+
def load_page(data: tuple):
109+
if not self.client.user:
110+
raise Error('Client not logged in!')
111+
112+
embed = Embeds(
113+
title = 'Commands',
114+
description = f'Use `/help <module>` or `/help <command>` for more information about that module or command\n\n**{data[0]}\'s commands**\n\u200d'
115+
)
116+
embed.color = discord.Color.blurple()
117+
embed.set_author(name = self.client.user.name, icon_url = self.client.user.display_avatar)
118+
119+
for i in data[1]:
120+
embed.add_field(
121+
name = f'/{i.qualified_name}',
122+
value = f'{str(i.help).lstrip().rstrip()}\n‍',
123+
inline = False
124+
)
125+
126+
return embed
127+
128+
scroll_embed = ViewPageScroller(
129+
ownerid = ctx.author.id,
130+
load_page = load_page,
131+
pages = cleaned,
132+
timeout = 180
133+
)
134+
135+
await scroll_embed.send_message(ctx)
136+
96137

97-
if found: break
98-
if not found:
99-
raise Error(description = f'Unable to locate module or command [{query}]')
138+
@help.autocomplete('query')
139+
async def help_autocomplete(self, ctx, current: str) -> List[app_commands.Choice[str]]:
140+
data = []
141+
command_names = []
142+
for i in self.client.commands:
143+
if i.hidden or str(i.help).startswith('hidden'): continue
144+
command_names += list(i.aliases) + [i.name]
100145

101-
await ctx.reply(embed = embed)
146+
for name in [cog for cog in self.client.cogs if not str(self.client.cogs[cog].__doc__).startswith('hidden')] + command_names:
147+
if current.lower() in name.lower():
148+
data.append(app_commands.Choice(
149+
name = name,
150+
value = name
151+
))
152+
return data[0:24]
102153

103154

104-
async def setup(client: commands.Bot):
155+
async def setup(client):
105156
await client.add_cog(Help(client))
106-

0 commit comments

Comments
 (0)