System Cogs
These Cogs provide general system functionality and help features.
Architecture
classDiagram
class HelpCog {
+bot : Bot
+help(interaction)
}
class HelpView {
+selected_command : str
+_build_content()
}
class ExamplesCog {
+sample_data : list
+colors(interaction)
+pagination(interaction)
+buttons(interaction)
}
class ButtonsView {
+primary(interaction, button)
+secondary(interaction, button)
+setup()
}
HelpCog ..> HelpView : creates
ExamplesCog ..> ButtonsView : creates
ExamplesCog ..> PaginatedView : creates
Help System
The help command (/help) opens a dynamic view allowing users to browse different help topics. It fully supports Internationalization (i18n).
The topic list is built from COMMAND_TEXTS in src.util.translations, keyed by the
real command name, and every entry has an answer behind it in HELP_ANSWERS. A test
asserts that both dictionaries hold the same keys, so a command cannot be listed in the
help without an explanation, and the help cannot advertise a command that does not exist.
The Help Cog
src.oscar.cogs.help.Help
Bases: Cog
Class for the help cog.
Source code in src/oscar/cogs/help.py
| def __init__(self, bot: commands.Bot):
self.bot: commands.Bot = bot
logger.info("Loaded Help cog")
|
contacts(interaction: Interaction)
Command to display key contact persons at FIN and OVGU.
Source code in src/oscar/cogs/help.py
| @app_commands.command(
name=locale_str("contacts", de="ansprechpartner"),
description=locale_str(
"Key contacts at the FIN and the OVGU, with a link to their page",
de="Wichtige Ansprechpartner der FIN und OVGU, mit Link zur Seite",
),
)
async def contacts(self, interaction: discord.Interaction):
""" Command to display key contact persons at FIN and OVGU."""
await open_contacts(interaction)
|
elearning
async
elearning(interaction: Interaction)
Command to display guide on faculty learning management systems.
Source code in src/oscar/cogs/help.py
| @app_commands.command(
name=locale_str("elearning", de="lms"),
description=locale_str(
"The university portals: eLearning, LSF, module handbook, GitLab",
de="Lernplattformen der OVGU: eLearning, LSF, Modulhandbuch, GitLab",
),
)
async def elearning(self, interaction: discord.Interaction):
"""Command to display guide on faculty learning management systems."""
await open_platforms(interaction)
|
help
async
help(interaction: Interaction)
Command to open the help dialog.
Source code in src/oscar/cogs/help.py
| @app_commands.command(description="Hilfe zu allen Befehlen (help for every command)")
async def help(self, interaction: discord.Interaction):
""" Command to open the help dialog."""
# \/ important (makes the bot say its thinking)
_ = await interaction.response.defer(
ephemeral=True
)
# the help opened in english for everybody, whatever they had picked in /start
language: LanguageCode = get_user_language(interaction.user.id)
await interaction.followup.send(view=HelpView(language), ephemeral=True)
|
Module Setup
src.oscar.cogs.help.setup
async
Setup the Help cog.
Source code in src/oscar/cogs/help.py
| async def setup(bot: commands.Bot):
""" Setup the Help cog."""
await bot.add_cog(Help(bot))
|
Help View
The view logic implementing the dropdown menu and language toggle.
src.oscar.cogs.help.HelpView
HelpView(default_language: LanguageCode = LanguageCode.EN)
Bases: TranslatedView
Help view that extends TranslatedView for language switching.
It answers two different kinds of question. "What does this command do" comes
from COMMAND_TEXTS, "why does this not work" comes from FAQ_QUESTIONS. Both
selects are shown at once, and picking in one clears the other, so exactly one
answer is on screen.
Source code in src/oscar/cogs/help.py
| def __init__(self, default_language: LanguageCode = LanguageCode.EN):
# set before the base class builds the content, they are read while building
self.selected_command: str | None = None
self.selected_question: str | None = None
self.opened: str | None = None
super().__init__(default_language)
|
_build_content
Build the help view content with current language.
Source code in src/oscar/cogs/help.py
| @override
def _build_content(self):
"""Build the help view content with current language."""
_ = self.add_item(
item=Container(
Section[LayoutView](
TextDisplay(f"# {HELP_LANGUAGES['help'][self.language_code]}"),
accessory=self._create_language_toggle(),
),
Separator(),
ActionRow(self._open_select()),
ActionRow(self._command_select()),
ActionRow(self._faq_select()),
Separator(),
TextDisplay(self._answer()),
accent_color=0x4378D5,
),
)
|
Examples
A playground Cog (src.oscar.cogs.examples) useful for developers to test UI capabilities and copy-paste reference implementations.
Included Commands:
* /colors: Displays all valid Discord ANSI color codes for embeds.
* /pagination: Generates 64 sample items to test the PaginatedView navigation.
* /buttons: Displays all button styles (Primary, Secondary, Success, Danger, Link, Premium).
src.oscar.cogs.examples.Examples
Bases: Cog
Cog Class holding various examples
Source code in src/oscar/cogs/examples.py
| def __init__(self, bot: commands.Bot):
self.bot: commands.Bot = bot
logger.info("Loaded Examples cog")
# Generate sample data (64 items as requested)
self.sample_data: list[dict[str, int|str]] = []
statuses = ["Active", "Inactive", "Pending", "Error"]
for i in range(1, 65): # Example 1 to 64
self.sample_data.append({
"id": i,
"name": f"Example {i}",
"value": f"Val_{i:03d}",
"status": statuses[(i - 1) % len(statuses)]
})
|
buttons(interaction: Interaction, enabled: bool = True)
Slash command to display all possible discord embed button styles
Source code in src/oscar/cogs/examples.py
| @app_commands.command(name = 'buttons',description = 'Display all possible button styles')
@app_commands.describe(enabled = 'Weather the buttons are enabled or disabled')
async def buttons(self, interaction: discord.Interaction, enabled:bool = True):
"""Slash command to display all possible discord embed button styles"""
await ButtonsView(interaction=interaction, enabled=enabled).setup()
|
colors
async
colors(interaction: Interaction)
Slash command to display all possible text and background colors
Source code in src/oscar/cogs/examples.py
| @app_commands.command(name='colors', description='display all text and background colors')
async def colors(self, interaction: discord.Interaction):
"""Slash command to display all possible text and background colors"""
embed: discord.Embed = discord.Embed(
title='Text Colors',
# pylint: disable=C0301 # (line-too-long)
url='https://www.pythondiscord.com/pages/guides/python-guides/discord-messages-with-colors/',
description="""
To be able to send a colored text, you need to use the ansi language for your code block and provide a prefix of this format before writing your text:
```
\\u001b[{format};{color}m
```
All possible formats are:
```ansi
• 0: \u001b[0;00mNormal\u001b[0m
• 1: \u001b[1;00mBold\u001b[0m
• 4: \u001b[4;00mUnderline\u001b[0m
```
All possible colors are:
```ansi
\u001b[1;30;40m Text \u001b[1;30;41m Text \u001b[1;30;42m Text \u001b[1;30;43m Text \u001b[1;30;44m Text \u001b[1;30;45m Text \u001b[1;30;46m Text \u001b[1;30;47m Text
\u001b[1;31;40m Text \u001b[1;31;41m Text \u001b[1;31;42m Text \u001b[1;31;43m Text \u001b[1;31;44m Text \u001b[1;31;45m Text \u001b[1;31;46m Text \u001b[1;31;47m Text
\u001b[1;32;40m Text \u001b[1;32;41m Text \u001b[1;32;42m Text \u001b[1;32;43m Text \u001b[1;32;44m Text \u001b[1;32;45m Text \u001b[1;32;46m Text \u001b[1;32;47m Text
\u001b[1;33;40m Text \u001b[1;33;41m Text \u001b[1;33;42m Text \u001b[1;33;43m Text \u001b[1;33;44m Text \u001b[1;33;45m Text \u001b[1;33;46m Text \u001b[1;33;47m Text
\u001b[1;34;40m Text \u001b[1;34;41m Text \u001b[1;34;42m Text \u001b[1;34;43m Text \u001b[1;34;44m Text \u001b[1;34;45m Text \u001b[1;34;46m Text \u001b[1;34;47m Text
\u001b[1;35;40m Text \u001b[1;35;41m Text \u001b[1;35;42m Text \u001b[1;35;43m Text \u001b[1;35;44m Text \u001b[1;35;45m Text \u001b[1;35;46m Text \u001b[1;35;47m Text
\u001b[1;36;40m Text \u001b[1;36;41m Text \u001b[1;36;42m Text \u001b[1;36;43m Text \u001b[1;36;44m Text \u001b[1;36;45m Text \u001b[1;36;46m Text \u001b[1;36;47m Text
\u001b[1;37;40m Text \u001b[1;37;41m Text \u001b[1;37;42m Text \u001b[1;37;43m Text \u001b[1;37;44m Text \u001b[1;37;45m Text \u001b[1;37;46m Text \u001b[1;37;47m Text
```
"""
)
_ =await interaction.response.send_message(embed=embed)
|
pagination(interaction: Interaction)
Slash command to display paginated data
Source code in src/oscar/cogs/examples.py
| @app_commands.command(
name = 'pagination',
description = 'Display paginated data with navigation buttons'
)
async def pagination(self, interaction: discord.Interaction):
"""Slash command to display paginated data"""
await PaginatedView(
interaction = interaction,
total_pages = 4,
get_page = get_pagination_embed
).setup()
|
Module Setup
Warning: This Cog is currently disabled in the code (commented out in setup).
src.oscar.cogs.examples.setup
async
Setup the Examples cog.
Source code in src/oscar/cogs/examples.py
| async def setup(bot: commands.Bot): # pylint: disable=unused-argument
""" Setup the Examples cog."""
|
Local Helper Classes
Example implementations of UI elements used within the commands above.
ButtonsView(interaction: Interaction, enabled: bool = True)
Bases: View
Class for displaying each button type
Source code in src/oscar/cogs/examples.py
| def __init__(self, interaction: discord.Interaction, enabled: bool = True):
self.interaction: Interaction[Client] = interaction
self.enabled: bool = enabled
super().__init__(timeout=300) # doesn't accept new interaction after <timeout> seconds
link_button: Button[LayoutView] = Button(
emoji = '5️⃣',
label = 'link / _url_',
style = discord.ButtonStyle.link,
url = 'https://github.com/combifightet',
disabled=not self.enabled
)
_ = self.add_item(link_button)
premium_button: Button[LayoutView] = Button(
style = discord.ButtonStyle.premium,
sku_id = 1416080458093170820, # 'buy me a coffe'
disabled = not self.enabled
)
_ = self.add_item(premium_button)
|
primary(_interaction: Interaction, _button: Button[LayoutView])
Empty example callback
Source code in src/oscar/cogs/examples.py
| @discord.ui.button(
emoji='1️⃣',
label='primary / _blurple_',
style=discord.ButtonStyle.primary
)
async def primary(self, _interaction: discord.Interaction, _button: Button[LayoutView]):
""" Empty example callback"""
|
secondary(_interaction: Interaction, _button: Button[LayoutView])
Empty example callback
Source code in src/oscar/cogs/examples.py
| @discord.ui.button(
emoji='2️⃣',
label='secondary / _grey_ /_gray_',
style=discord.ButtonStyle.secondary)
async def secondary(self, _interaction: discord.Interaction, _button: Button[LayoutView]):
""" Empty example callback"""
|
success(_interaction: Interaction, _button: Button[LayoutView])
Empty example callback
Source code in src/oscar/cogs/examples.py
| @discord.ui.button(
emoji='3️⃣',
label='success / _green_',
style=discord.ButtonStyle.success
)
async def success(self, _interaction: discord.Interaction, _button: Button[LayoutView]):
""" Empty example callback"""
|
danger(_interaction: Interaction, _button: Button[LayoutView])
Empty example callback
Source code in src/oscar/cogs/examples.py
| @discord.ui.button(
emoji='4️⃣',
label='danger / _red_',
style=discord.ButtonStyle.danger
)
async def danger(self, _interaction: discord.Interaction, _button: Button[LayoutView]):
""" Empty example callback"""
|
Setup button states and embed
Source code in src/oscar/cogs/examples.py
| async def setup(self):
""" Setup button states and embed"""
# Set the disabled state of all buttons after initialization
for item in self.children:
if isinstance(item, Button):
item.disabled = not self.enabled
embed:discord.Embed = discord.Embed(
colour=0xac91b4,
title='Buttons - Example',
description='A small Embed to display all 6 different button types',
)
_ = embed.set_author(
name='Combifightet',
url='https://github.com/combifightet',
icon_url='https://avatars.githubusercontent.com/u/47188809'
)
_ = await self.interaction.response.send_message(embed=embed, view=self)
|