modified: bot.py

This commit is contained in:
SimolZimol
2025-10-09 13:00:11 +02:00
parent 6cd187b950
commit 688e034039

323
bot.py
View File

@@ -1913,11 +1913,50 @@ async def listgiveaways(ctx):
await ctx.send("You don't have permission to list giveaways.")
return
# Filter giveaways for this guild
server_giveaways = []
# First, check memory giveaways
for giv_id, giveaway in giveaways.items():
if giveaway.guild_id == guild_id and not giveaway.is_finished():
server_giveaways.append((giv_id, giveaway))
server_giveaways.append((giv_id, giveaway, "memory"))
# Also check active_processes table for giveaways not in memory
try:
active_processes = get_active_processes(process_type="giveaway", guild_id=guild_id)
for process in active_processes:
process_uuid = process["uuid"]
# Skip if already in memory
if str(process_uuid) in giveaways:
continue
# Check if process is still active and not expired
if process["status"] == "active" and process["end_time"] > datetime.now():
try:
# Create a temporary giveaway object from process data
guild = ctx.guild
channel = guild.get_channel(process["channel_id"])
if channel:
# Create minimal context
class MinimalContext:
def __init__(self, channel):
self.channel = channel
self.guild = channel.guild
temp_ctx = MinimalContext(channel)
temp_giveaway = Giveaway.from_process_data(temp_ctx, process["data"])
temp_giveaway.end_time = process["end_time"]
temp_giveaway.process_uuid = process_uuid
server_giveaways.append((str(process_uuid), temp_giveaway, "database"))
except Exception as e:
logger.error(f"Error creating temp giveaway from process {process_uuid}: {e}")
except Exception as e:
logger.error(f"Error fetching active processes for giveaways: {e}")
if not server_giveaways:
embed = discord.Embed(
@@ -1936,7 +1975,7 @@ async def listgiveaways(ctx):
timestamp=datetime.now()
)
for giv_id, giveaway in server_giveaways[:10]: # Limit to 10 for readability
for giv_id, giveaway, source in server_giveaways[:10]: # Limit to 10 for readability
# Calculate remaining time
remaining = giveaway.end_time - datetime.now()
if remaining.total_seconds() > 0:
@@ -1967,7 +2006,11 @@ async def listgiveaways(ctx):
if hasattr(giveaway, 'sponsor_display') and giveaway.sponsor_display:
giveaway_info += f"**Sponsor:** {giveaway.sponsor_display}\n"
giveaway_info += f"**ID:** `{giv_id[:8]}...`"
# Add source indicator
source_emoji = "💾" if source == "database" else "🧠"
source_text = "DB" if source == "database" else "MEM"
giveaway_info += f"**ID:** `{giv_id[:8]}...` {source_emoji}"
embed.add_field(
name=f"🎁 {giveaway.title}",
@@ -1982,10 +2025,279 @@ async def listgiveaways(ctx):
inline=False
)
# Add helpful footer
db_count = sum(1 for _, _, source in server_giveaways if source == "database")
if db_count > 0:
embed.set_footer(text=f"💾 = Loaded from DB | Use /editgiveaway <id> <field> <value> to edit | Use /loadgiveaway <id> to load into memory")
else:
embed.set_footer(text="Use /editgiveaway <id> <field> <value> to edit a giveaway")
await ctx.send(embed=embed)
@client.hybrid_command()
async def loadgiveaway(ctx, giveaway_id: str):
"""Load a giveaway from database into memory (Only available for admins)"""
guild_id = ctx.guild.id
user_data = load_user_data_sync(ctx.author.id, guild_id)
if user_data["permission"] < 5:
await ctx.send("You don't have permission to load giveaways.")
return
try:
# Find giveaway in active_processes
active_processes = get_active_processes(process_type="giveaway", guild_id=guild_id)
matching_process = None
for process in active_processes:
if str(process["uuid"]).startswith(giveaway_id) or giveaway_id in str(process["uuid"]):
matching_process = process
break
if not matching_process:
await ctx.send(f"❌ No giveaway found with ID starting with `{giveaway_id}`")
return
process_uuid = matching_process["uuid"]
# Check if already loaded in memory
if str(process_uuid) in giveaways:
await ctx.send(f" Giveaway `{str(process_uuid)[:8]}...` is already loaded in memory.")
return
# Create giveaway object and load into memory
guild = ctx.guild
channel = guild.get_channel(matching_process["channel_id"])
if not channel:
await ctx.send(f"❌ Original channel not found. Cannot load giveaway.")
return
# Create minimal context
class MinimalContext:
def __init__(self, channel):
self.channel = channel
self.guild = channel.guild
temp_ctx = MinimalContext(channel)
giveaway = Giveaway.from_process_data(temp_ctx, matching_process["data"])
giveaway.end_time = matching_process["end_time"]
giveaway.process_uuid = process_uuid
# Restore participants from stored data
stored_participants = matching_process["data"].get("participants", [])
for participant_data in stored_participants:
try:
user = await client.fetch_user(participant_data["id"])
giveaway.participants.append(user)
except Exception as e:
logger.error(f"Could not fetch participant {participant_data}: {e}")
# Load into memory
giveaways[str(process_uuid)] = giveaway
# Success message
embed = discord.Embed(
title="✅ Giveaway Loaded",
description=f"Successfully loaded giveaway into memory!",
color=0x00ff00,
timestamp=datetime.now()
)
embed.add_field(name="🎁 Title", value=giveaway.title, inline=True)
embed.add_field(name="🆔 ID", value=f"`{str(process_uuid)[:8]}...`", inline=True)
embed.add_field(name="👥 Participants", value=f"{len(giveaway.participants)}", inline=True)
remaining = giveaway.end_time - datetime.now()
if remaining.total_seconds() > 0:
embed.add_field(name="⏰ Time Left", value=f"<t:{int(giveaway.end_time.timestamp())}:R>", inline=True)
else:
embed.add_field(name="⏰ Status", value="⚠️ Expired (will process soon)", inline=True)
embed.set_footer(text="Giveaway is now fully functional in memory")
await ctx.send(embed=embed)
logger.info(f"Loaded giveaway {str(process_uuid)[:8]} into memory by {ctx.author.id}")
except Exception as e:
logger.error(f"Error loading giveaway: {e}")
await ctx.send(f"❌ Error loading giveaway: {str(e)}")
@client.hybrid_command()
async def loadallgiveaways(ctx):
"""Load all giveaways from database into memory (Only available for admins)"""
guild_id = ctx.guild.id
user_data = load_user_data_sync(ctx.author.id, guild_id)
if user_data["permission"] < 5:
await ctx.send("You don't have permission to load giveaways.")
return
try:
# Get all active giveaway processes for this guild
active_processes = get_active_processes(process_type="giveaway", guild_id=guild_id)
if not active_processes:
await ctx.send("📋 No giveaways found in database.")
return
loaded_count = 0
already_loaded = 0
failed_count = 0
failed_details = []
embed = discord.Embed(
title="🔄 Loading Giveaways...",
description="Processing giveaways from database...",
color=0xffaa00,
timestamp=datetime.now()
)
message = await ctx.send(embed=embed)
for process in active_processes:
process_uuid = process["uuid"]
# Skip if already in memory
if str(process_uuid) in giveaways:
already_loaded += 1
continue
try:
# Get channel
guild = ctx.guild
channel = guild.get_channel(process["channel_id"])
if not channel:
failed_count += 1
failed_details.append(f"Channel not found for {str(process_uuid)[:8]}...")
continue
# Create minimal context
class MinimalContext:
def __init__(self, channel):
self.channel = channel
self.guild = channel.guild
temp_ctx = MinimalContext(channel)
giveaway = Giveaway.from_process_data(temp_ctx, process["data"])
giveaway.end_time = process["end_time"]
giveaway.process_uuid = process_uuid
# Restore participants
stored_participants = process["data"].get("participants", [])
for participant_data in stored_participants:
try:
user = await client.fetch_user(participant_data["id"])
giveaway.participants.append(user)
except:
pass # Skip invalid participants
# Load into memory
giveaways[str(process_uuid)] = giveaway
loaded_count += 1
except Exception as e:
failed_count += 1
failed_details.append(f"{str(process_uuid)[:8]}...: {str(e)[:50]}")
logger.error(f"Failed to load giveaway {process_uuid}: {e}")
# Final result
embed = discord.Embed(
title="✅ Giveaway Loading Complete",
color=0x00ff00,
timestamp=datetime.now()
)
embed.add_field(name="✅ Loaded", value=f"{loaded_count} giveaways", inline=True)
embed.add_field(name=" Already in Memory", value=f"{already_loaded} giveaways", inline=True)
embed.add_field(name="❌ Failed", value=f"{failed_count} giveaways", inline=True)
if failed_details:
embed.add_field(name="📋 Failed Details", value="\n".join(failed_details[:5]), inline=False)
if len(failed_details) > 5:
embed.add_field(name="", value=f"... and {len(failed_details) - 5} more", inline=False)
embed.set_footer(text="All available giveaways have been processed")
await message.edit(embed=embed)
logger.info(f"Loaded {loaded_count} giveaways into memory by {ctx.author.id}")
except Exception as e:
logger.error(f"Error loading all giveaways: {e}")
await ctx.send(f"❌ Error loading giveaways: {str(e)}")
async def load_active_giveaways():
"""Load all active giveaways from database into memory on startup"""
try:
# Get all active giveaway processes
active_processes = get_active_processes(process_type="giveaway")
if not active_processes:
logger.info("No active giveaways found in database")
return
loaded_count = 0
failed_count = 0
for process in active_processes:
try:
process_uuid = process["uuid"]
# Skip if already in memory
if str(process_uuid) in giveaways:
continue
# Get guild and channel
guild_id = process["guild_id"]
channel_id = process["channel_id"]
guild = client.get_guild(guild_id)
if not guild:
failed_count += 1
continue
channel = guild.get_channel(channel_id)
if not channel:
failed_count += 1
continue
# Create minimal context
class MinimalContext:
def __init__(self, channel):
self.channel = channel
self.guild = channel.guild
temp_ctx = MinimalContext(channel)
giveaway = Giveaway.from_process_data(temp_ctx, process["data"])
giveaway.end_time = process["end_time"]
giveaway.process_uuid = process_uuid
# Restore participants
stored_participants = process["data"].get("participants", [])
for participant_data in stored_participants:
try:
user = await client.fetch_user(participant_data["id"])
giveaway.participants.append(user)
except:
pass # Skip invalid participants
# Load into memory
giveaways[str(process_uuid)] = giveaway
loaded_count += 1
except Exception as e:
failed_count += 1
logger.error(f"Failed to load giveaway {process.get('uuid', 'unknown')}: {e}")
if loaded_count > 0:
logger.info(f"Loaded {loaded_count} active giveaways into memory")
if failed_count > 0:
logger.warning(f"Failed to load {failed_count} giveaways")
except Exception as e:
logger.error(f"Error loading active giveaways: {e}")
# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
live_chats = {}
@@ -2419,6 +2731,9 @@ async def on_ready():
# Initialize process management system
await restore_active_processes_on_startup()
# Load active giveaways from database
await load_active_giveaways()
# Start the process manager
if not process_manager.is_running():
process_manager.start()