got generate image command working and updated role color.py to read from the new image

This commit is contained in:
Lilac-Rose
2025-11-30 15:46:59 +01:00
parent 7372edf312
commit 31d13fcfef
5 changed files with 99 additions and 49 deletions

View File

@@ -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))

View File

@@ -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()}")

BIN
media/colorimage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB