1
1
import asyncio
2
2
import os
3
- import re
4
3
from collections .abc import Awaitable , Mapping
5
4
from pathlib import Path
6
5
from typing import Any , get_type_hints
@@ -103,17 +102,21 @@ def _add_command_field(embed: discord.Embed, command: commands.Command[Any, Any,
103
102
async def _create_select_options (
104
103
self ,
105
104
command_categories : dict [str , dict [str , str ]],
106
- cog_groups : list [str ],
107
105
menu : ViewMenu ,
108
106
) -> dict [discord .SelectOption , list [Page ]]:
107
+ """
108
+ Creates select options for the help menu by iterating over the keys in the
109
+ cached command categories. This approach ensures that even categories without
110
+ a corresponding folder (e.g. "extra") are included.
111
+ """
109
112
select_options : dict [discord .SelectOption , list [Page ]] = {}
110
-
111
113
prefix : str = await self ._get_prefix ()
112
114
115
+ # Iterate over the keys in command_categories
113
116
tasks : list [Awaitable [tuple [str , Page ]]] = [
114
117
self ._create_page (cog_group , command_categories , menu , prefix )
115
- for cog_group in cog_groups
116
- if cog_group in command_categories and any (command_categories [cog_group ].values ())
118
+ for cog_group in command_categories
119
+ if any (command_categories [cog_group ].values ())
117
120
]
118
121
119
122
select_options_data : list [tuple [str , Page ]] = await asyncio .gather (* tasks )
@@ -132,6 +135,9 @@ async def _create_select_options(
132
135
emoji = category_emoji_map .get (cog_group , "❓" )
133
136
select_options [discord .SelectOption (label = cog_group .capitalize (), emoji = emoji )] = [page ]
134
137
138
+ logger .info (f"Select options: { select_options } " )
139
+ logger .info (f"Cached categories: { self ._category_cache } " )
140
+
135
141
return select_options
136
142
137
143
async def _create_page (
@@ -148,7 +154,6 @@ async def _create_page(
148
154
149
155
sorted_commands : list [tuple [str , str ]] = sorted (command_categories [cog_group ].items ())
150
156
description : str = "\n " .join (f"**`{ prefix } { cmd } `** | { command_list } " for cmd , command_list in sorted_commands )
151
-
152
157
embed .description = description
153
158
page : Page = Page (embed = embed )
154
159
menu .add_page (embed )
@@ -169,8 +174,8 @@ async def _add_cog_pages(
169
174
) -> None :
170
175
"""Adds pages for each cog category to the help menu."""
171
176
command_categories = await self ._get_command_categories (mapping )
172
- cog_groups = self . _get_cog_groups ()
173
- select_options = await self ._create_select_options (command_categories , cog_groups , menu )
177
+ # Instead of using filesystem folders, iterate over cached categories.
178
+ select_options = await self ._create_select_options (command_categories , menu )
174
179
self ._add_navigation_and_selection (menu , select_options )
175
180
176
181
async def _get_command_categories (
@@ -185,6 +190,7 @@ async def _get_command_categories(
185
190
186
191
for cog , mapping_commands in mapping .items ():
187
192
if cog and len (mapping_commands ) > 0 :
193
+ # Attempt to extract the group using the cog's module name.
188
194
cog_group = self ._extract_cog_group (cog ) or "extra"
189
195
command_categories .setdefault (cog_group , {})
190
196
for command in mapping_commands :
@@ -204,9 +210,15 @@ def _get_cog_groups() -> list[str]:
204
210
205
211
@staticmethod
206
212
def _extract_cog_group (cog : commands .Cog ) -> str | None :
207
- """Extracts the cog group from a cog's string representation."""
208
- if match := re .search (r"<cogs\.([^\.]+)\..*>" , str (cog )):
209
- return match [1 ]
213
+ """
214
+ Extracts the cog group using the cog's module attribute.
215
+ For example, if a cog's module is 'tux.cogs.admin.some_cog', this returns 'admin'.
216
+ """
217
+ module = getattr (cog , "__module__" , "" )
218
+ parts = module .split ("." )
219
+ # Assuming the structure is: tux.cogs.<group>...
220
+ if len (parts ) >= 3 and parts [1 ].lower () == "cogs" :
221
+ return parts [2 ].lower ()
210
222
return None
211
223
212
224
# Sending Help Messages
0 commit comments