diff --git a/commands/generate_role_color_images.py b/commands/generate_role_color_images.py index 2df39b3..8bc4cfb 100644 --- a/commands/generate_role_color_images.py +++ b/commands/generate_role_color_images.py @@ -8,65 +8,100 @@ import os import io from math import floor, ceil from moderation.loader import ModerationBase, ADMIN_ROLE_ID -from commands.role_color import DEBUG, COLOR_ROLE_NAMES, FONTS_PATH +import importlib +import sys class ColorImageGen(commands.Cog): def __init__(self, bot): self.bot = bot + # Import and get fresh references on initialization + self._reload_config() + + def _reload_config(self): + """Reload configuration from role_color module""" + # Force reload the role_color module to get fresh values + if 'commands.role_color' in sys.modules: + role_color_module = importlib.reload(sys.modules['commands.role_color']) + else: + import commands.role_color as role_color_module + + # Store as instance variables + self.DEBUG = role_color_module.DEBUG + self.COLOR_ROLE_NAMES = role_color_module.COLOR_ROLE_NAMES + self.FONTS_PATH = role_color_module.FONTS_PATH - @commands.command(name="colorlist") + @commands.command(name="generateimages") @commands.has_role(ADMIN_ROLE_ID) async def generate_list(self, ctx): + # Reload config to get latest values + self._reload_config() + try: # boring setup guild = ctx.guild i = 0 color_roles = [] - + # Styling - font_path_ttf = os.path.join(self.FONTS_PATH, f"Renogare-Regular.otf") - FONT_SIZE = 80 + font_path_ttf = os.path.join(self.FONTS_PATH, "Renogare-Regular.otf") + FONT_SIZE = 300 font = ImageFont.truetype(font_path_ttf, FONT_SIZE) - COLUMN_SIZE = 4 - X_PADDING_PER_WORD = 100 + COLUMN_SIZE = 5 + X_PADDING_PER_COLUMN = 100 X_PADDING = 200 Y_PADDING = 10 - + # Check longest length temp_draw = ImageDraw.Draw(Image.new("RGBA", (1, 1))) longest_length = 0 - for color_role_name in self.COLOR_ROLE_NAMES: color_role = discord.utils.get(guild.roles, name=color_role_name) color_roles.append(color_role) - if not color_role: await ctx.send(f"⚠️ The role **{color_role_name}** doesn't exist on this server.") return text = f"{i + 1}. {color_role_name}" - if longest_length < temp_draw.textlength(text, font=font): longest_length = temp_draw.textlength(text, font=font) + if longest_length < temp_draw.textlength(text, font=font): + longest_length = temp_draw.textlength(text, font=font) i += 1 - + # Draw the actual image - img_width, img_height = int((longest_length + X_PADDING) * (ceil(len(self.COLOR_ROLE_NAMES) / COLUMN_SIZE))), COLUMN_SIZE * (FONT_SIZE + Y_PADDING) + 20 + img_width = int((longest_length + X_PADDING) * (ceil(len(self.COLOR_ROLE_NAMES) / COLUMN_SIZE))) + img_height = COLUMN_SIZE * (FONT_SIZE + Y_PADDING) + 20 img = Image.new("RGBA", (img_width, img_height)) draw = ImageDraw.Draw(img) + i = 0 - for color_role in color_roles: x_pos = (longest_length * (floor(i / COLUMN_SIZE))) if i >= COLUMN_SIZE: - x_pos += X_PADDING_PER_WORD * floor(i / COLUMN_SIZE) + x_pos += X_PADDING_PER_COLUMN * floor(i / COLUMN_SIZE) text = f"{i + 1}. {color_role.name}" - draw.text((x_pos, (FONT_SIZE + Y_PADDING) * (i % COLUMN_SIZE)), text, font=font, fill=color_role.color.to_rgb()) + draw.text( + (x_pos, (FONT_SIZE + Y_PADDING) * (i % COLUMN_SIZE)), + text, + font=font, + fill=color_role.color.to_rgb() + ) i += 1 - # Send message + # Get path to media directory (parent of commands/) + media_dir = Path(__file__).resolve().parent.parent / "media" + media_dir.mkdir(exist_ok=True) # Create media folder if it doesn't exist + + # Save to file (overwrites if exists) + output_path = media_dir / "colorimage.png" + img.save(output_path, format="PNG") + + # Also send as message for preview buffer = io.BytesIO() img.save(buffer, format="PNG") buffer.seek(0) - await ctx.send(file=discord.File(buffer, "color_roles.png")) + await ctx.send( + f"✅ Color image generated and saved to `{output_path}`", + file=discord.File(buffer, "colorimage.png") + ) except Exception as e: print(f"[ERROR] /color list\n{traceback.format_exc()}") @@ -74,4 +109,4 @@ class ColorImageGen(commands.Cog): await ctx.send(msg) async def setup(bot): - await bot.add_cog(ColorImageGen(bot)) + await bot.add_cog(ColorImageGen(bot)) \ No newline at end of file diff --git a/commands/role_color.py b/commands/role_color.py index 6342bc3..225c2fb 100644 --- a/commands/role_color.py +++ b/commands/role_color.py @@ -65,7 +65,7 @@ class ColorRoles(commands.Cog): if not isinstance(member, discord.Member): member = guild.get_member(interaction.user.id) or await guild.fetch_member(interaction.user.id) - color_roles = [r for r in member.roles if r.name in COLOR_ROLES] + color_roles = [r for r in member.roles if r.name in COLOR_ROLE_NAMES] if not color_roles: await interaction.followup.send( @@ -85,7 +85,7 @@ class ColorRoles(commands.Cog): msg = f"❌ Error: `{e}`" if DEBUG else "❌ Something went wrong." await interaction.followup.send(msg, ephemeral=True) - @color_group.command(name="list", description="Show all available color images (visual palette).") + @color_group.command(name="list", description="Show all available role colors") async def list_colors(self, interaction: discord.Interaction): await interaction.response.defer(ephemeral=False) try: @@ -94,38 +94,53 @@ class ColorRoles(commands.Cog): if not media_dir.exists(): raise FileNotFoundError(f"Media folder not found: {media_dir}") - # Look for specific color image files only - color_image_files = [] - for filename in ["colorimage1.png", "colorimage2.png"]: - img_path = media_dir / filename - if img_path.exists(): - color_image_files.append(img_path) + # Look for the generated color image + img_path = media_dir / "colorimage.png" - if not color_image_files: - raise FileNotFoundError(f"Color images not found in {media_dir}") - - # Send first embed with first image - file1 = discord.File(color_image_files[0], filename=color_image_files[0].name) - embed1 = discord.Embed( - title="🎨 Available Color Roles (Part 1)", - description="Use `/color set` to pick one!", - color=discord.Color.purple() - ) - embed1.set_image(url=f"attachment://{color_image_files[0].name}") - - await interaction.followup.send(embed=embed1, file=file1, ephemeral=False) - - # Send second embed with second image if it exists - if len(color_image_files) > 1: - file2 = discord.File(color_image_files[1], filename=color_image_files[1].name) - embed2 = discord.Embed( - title="🎨 Available Color Roles (Part 2)", - description="More colors to choose from!", + if not img_path.exists(): + # Fallback to old images if colorimage.png doesn't exist + color_image_files = [] + for filename in ["colorimage1.png", "colorimage2.png"]: + fallback_path = media_dir / filename + if fallback_path.exists(): + color_image_files.append(fallback_path) + + if not color_image_files: + await interaction.followup.send( + "⚠️ No color images found. An admin needs to run `!generateimages` first.", + ephemeral=True + ) + return + + # Send old format with multiple images + file1 = discord.File(color_image_files[0], filename=color_image_files[0].name) + embed1 = discord.Embed( + title="🎨 Available Color Roles (Part 1)", + description="Use `/color set` to pick one!", color=discord.Color.purple() ) - embed2.set_image(url=f"attachment://{color_image_files[1].name}") + embed1.set_image(url=f"attachment://{color_image_files[0].name}") + await interaction.followup.send(embed=embed1, file=file1, ephemeral=False) - await interaction.followup.send(embed=embed2, file=file2, ephemeral=False) + if len(color_image_files) > 1: + file2 = discord.File(color_image_files[1], filename=color_image_files[1].name) + embed2 = discord.Embed( + title="🎨 Available Color Roles (Part 2)", + description="More colors to choose from!", + color=discord.Color.purple() + ) + embed2.set_image(url=f"attachment://{color_image_files[1].name}") + await interaction.followup.send(embed=embed2, file=file2, ephemeral=False) + else: + # Send the generated colorimage.png + file = discord.File(img_path, filename="colorimage.png") + embed = discord.Embed( + title="🎨 Available Color Roles", + description="Use `/color set` to pick one!", + color=discord.Color.purple() + ) + embed.set_image(url="attachment://colorimage.png") + await interaction.followup.send(embed=embed, file=file, ephemeral=False) except Exception as e: print(f"[ERROR] /color list\n{traceback.format_exc()}") diff --git a/media/colorimage.png b/media/colorimage.png new file mode 100644 index 0000000..fa3f34d Binary files /dev/null and b/media/colorimage.png differ diff --git a/media/colorimage1.png b/media/colorimage1.png deleted file mode 100644 index 18789db..0000000 Binary files a/media/colorimage1.png and /dev/null differ diff --git a/media/colorimage2.png b/media/colorimage2.png deleted file mode 100644 index 6bd92fd..0000000 Binary files a/media/colorimage2.png and /dev/null differ