mirror of
https://github.com/Paillat-dev/discord-progress-bar.git
synced 2026-01-02 01:06:18 +00:00
Refactor async initialization in ProgressBarManager (#16)
Co-authored-by: openhands <openhands@all-hands.dev> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Paillat <me@paillat.dev>
This commit is contained in:
35
README.md
35
README.md
@@ -79,24 +79,21 @@ from discord_progress_bar import ProgressBarManager
|
|||||||
# Create a Discord bot with emoji caching enabled
|
# Create a Discord bot with emoji caching enabled
|
||||||
bot = discord.Bot(cache_app_emojis=True)
|
bot = discord.Bot(cache_app_emojis=True)
|
||||||
|
|
||||||
progress_bar_manager = None
|
# Create the progress bar manager (doesn't load emojis yet)
|
||||||
progress_bar = None
|
progress_manager = ProgressBarManager(bot)
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_ready():
|
async def on_ready():
|
||||||
"""Initialize the ProgressBarManager when the bot is ready."""
|
"""Load emojis when the bot is ready."""
|
||||||
global progress_bar_manager, progress_bar
|
await progress_manager.load()
|
||||||
|
print(f"Logged in as {bot.user}")
|
||||||
|
|
||||||
# Initialize the progress bar manager
|
@bot.command()
|
||||||
progress_bar_manager = await ProgressBarManager(bot)
|
|
||||||
# Get a progress bar with the "green" style
|
|
||||||
progress_bar = await progress_bar_manager.progress_bar("green")
|
|
||||||
|
|
||||||
@bot.slash_command()
|
|
||||||
async def show_progress(ctx, percent: float = 0.5):
|
async def show_progress(ctx, percent: float = 0.5):
|
||||||
"""Display a progress bar with the specified percentage."""
|
"""Display a progress bar with the specified percentage."""
|
||||||
|
|
||||||
await ctx.respond(f"Progress: {progress_bar.partial(percent)}")
|
progress_bar = await progress_manager.progress_bar("green", length=10)
|
||||||
|
await ctx.send(f"Progress: {progress_bar.partial(percent)}")
|
||||||
|
|
||||||
# Run your bot
|
# Run your bot
|
||||||
bot.run("YOUR_TOKEN")
|
bot.run("YOUR_TOKEN")
|
||||||
@@ -233,14 +230,22 @@ This is required for the `ProgressBarManager` to properly load and manage emojis
|
|||||||
|
|
||||||
### Progress Bar Manager Initialization
|
### Progress Bar Manager Initialization
|
||||||
|
|
||||||
Initialize the `ProgressBarManager` after your bot is ready:
|
Create a `ProgressBarManager` instance when your bot starts, and load emojis in the
|
||||||
|
`on_ready` event:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@discord.Cog.listener()
|
# Create the manager (doesn't load emojis yet)
|
||||||
async def on_ready(self) -> None:
|
progress_manager = ProgressBarManager(bot)
|
||||||
self.progress_bar_manager = await ProgressBarManager(self.bot)
|
|
||||||
|
@bot.event
|
||||||
|
async def on_ready():
|
||||||
|
"""Load emojis from the server after the bot is ready."""
|
||||||
|
await progress_manager.load()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This approach ensures that your bot can properly initialize and load emojis once it's
|
||||||
|
connected to Discord.
|
||||||
|
|
||||||
### Custom Progress Bar Styles
|
### Custom Progress Bar Styles
|
||||||
|
|
||||||
You can create custom progress bar styles by providing your own emoji images:
|
You can create custom progress bar styles by providing your own emoji images:
|
||||||
|
|||||||
@@ -17,22 +17,27 @@ bot = discord.Bot(cache_app_emojis=True)
|
|||||||
class MyCog(discord.Cog):
|
class MyCog(discord.Cog):
|
||||||
def __init__(self, bot: discord.Bot) -> None:
|
def __init__(self, bot: discord.Bot) -> None:
|
||||||
self.bot: discord.Bot = bot
|
self.bot: discord.Bot = bot
|
||||||
self.progress_bar_manager: ProgressBarManager
|
self.progress_bar_manager: ProgressBarManager = ProgressBarManager(self.bot)
|
||||||
self.progress_bar: ProgressBar
|
self.progress_bar: ProgressBar | None = None
|
||||||
|
|
||||||
@discord.Cog.listener()
|
@discord.Cog.listener()
|
||||||
async def on_ready(self) -> None:
|
async def on_ready(self) -> None:
|
||||||
print(f"Logged in as {bot.user} (ID: {bot.user.id})") # pyright: ignore [reportOptionalMemberAccess]
|
print(f"Logged in as {bot.user} (ID: {bot.user.id})") # pyright: ignore [reportOptionalMemberAccess]
|
||||||
print("------")
|
print("------")
|
||||||
self.progress_bar_manager = await ProgressBarManager(self.bot)
|
await self.progress_bar_manager.load()
|
||||||
self.progress_bar = await self.progress_bar_manager.progress_bar("green", length=10)
|
self.progress_bar = await self.progress_bar_manager.progress_bar("green", length=10)
|
||||||
print("Progress bar manager loaded.")
|
print("Progress bar manager loaded.")
|
||||||
|
|
||||||
@discord.slash_command() # pyright: ignore [reportUntypedFunctionDecorator]
|
@discord.slash_command() # pyright: ignore [reportUntypedFunctionDecorator]
|
||||||
async def get_progress_bar(self, ctx: discord.ApplicationContext, percent: float | None = None) -> None:
|
async def get_progress_bar(self, ctx: discord.ApplicationContext, percent: float | None = None) -> None:
|
||||||
"""Send a progress bar message."""
|
"""Send a progress bar message."""
|
||||||
if percent is None:
|
if not self.progress_bar:
|
||||||
|
await ctx.respond("Progress bar manager is not loaded yet.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if percent is None or percent > 1:
|
||||||
percent = 1
|
percent = 1
|
||||||
|
|
||||||
await ctx.respond(f"Progress: {self.progress_bar.partial(percent)}")
|
await ctx.respond(f"Progress: {self.progress_bar.partial(percent)}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Self, cast
|
from typing import cast
|
||||||
|
|
||||||
import aiofile
|
import aiofile
|
||||||
import aiohttp
|
import aiohttp
|
||||||
@@ -67,20 +67,25 @@ class ProgressBarManager:
|
|||||||
def __init__(self, bot: discord.Bot) -> None:
|
def __init__(self, bot: discord.Bot) -> None:
|
||||||
self._bot: discord.Bot = bot
|
self._bot: discord.Bot = bot
|
||||||
self._emojis: dict[str, ProgressBarEmojiMapping] = defaultdict(dict)
|
self._emojis: dict[str, ProgressBarEmojiMapping] = defaultdict(dict)
|
||||||
|
self._loaded: bool = False
|
||||||
async def __new__(cls, bot: discord.Bot) -> Self:
|
|
||||||
obj = super().__new__(cls)
|
|
||||||
obj.__init__(bot)
|
|
||||||
await obj.load()
|
|
||||||
return obj
|
|
||||||
|
|
||||||
async def load(self) -> None:
|
async def load(self) -> None:
|
||||||
await self._bot.wait_until_ready()
|
"""Load emojis from the Discord server.
|
||||||
|
|
||||||
|
This method should be called after the bot is ready.
|
||||||
|
Typically called in your bot's on_ready event.
|
||||||
|
"""
|
||||||
for emoji in self._bot.app_emojis:
|
for emoji in self._bot.app_emojis:
|
||||||
if emoji.name.startswith("pb_"):
|
if emoji.name.startswith("pb_"):
|
||||||
key: str = emoji.name.split("_")[1]
|
key: str = emoji.name.split("_")[1]
|
||||||
part: ProgressBarPart = cast("ProgressBarPart", int(emoji.name.split("_")[2]))
|
part: ProgressBarPart = cast("ProgressBarPart", int(emoji.name.split("_")[2]))
|
||||||
self._emojis[key][part] = emoji
|
self._emojis[key][part] = emoji
|
||||||
|
self._loaded = True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def loaded(self) -> bool:
|
||||||
|
"""Check if the manager has been loaded."""
|
||||||
|
return self._loaded
|
||||||
|
|
||||||
async def create_emojis_from_urls(self, name: str, emojis: ProgressBarUrlMapping) -> None:
|
async def create_emojis_from_urls(self, name: str, emojis: ProgressBarUrlMapping) -> None:
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
@@ -107,9 +112,27 @@ class ProgressBarManager:
|
|||||||
self._emojis[name][key] = emoji
|
self._emojis[name][key] = emoji
|
||||||
|
|
||||||
async def progress_bar(self, name: str, *, length: int = 5) -> ProgressBar:
|
async def progress_bar(self, name: str, *, length: int = 5) -> ProgressBar:
|
||||||
|
"""Get a progress bar by name.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: The name of the progress bar.
|
||||||
|
length: The length of the progress bar (default is 5).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A ProgressBar instance with the specified emojis.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the progress bar is not found
|
||||||
|
RuntimeError: If the manager is not loaded.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not self.loaded:
|
||||||
|
raise RuntimeError("ProgressBarManager has not been loaded yet. Call load() first.")
|
||||||
|
|
||||||
if name not in self._emojis:
|
if name not in self._emojis:
|
||||||
if default := DEFAULT_PROGRESS_BARS.get(name):
|
if default := DEFAULT_PROGRESS_BARS.get(name):
|
||||||
await self.create_emojis_from_urls(name, default)
|
await self.create_emojis_from_urls(name, default)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Progress bar {name} not found.")
|
raise ValueError(f"Progress bar {name} not found.")
|
||||||
|
|
||||||
return ProgressBar(self._emojis[name], length=length)
|
return ProgressBar(self._emojis[name], length=length)
|
||||||
|
|||||||
Reference in New Issue
Block a user