modified: bot.py
This commit is contained in:
325
bot.py
325
bot.py
@@ -1913,11 +1913,50 @@ async def listgiveaways(ctx):
|
|||||||
await ctx.send("You don't have permission to list giveaways.")
|
await ctx.send("You don't have permission to list giveaways.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Filter giveaways for this guild
|
|
||||||
server_giveaways = []
|
server_giveaways = []
|
||||||
|
|
||||||
|
# First, check memory giveaways
|
||||||
for giv_id, giveaway in giveaways.items():
|
for giv_id, giveaway in giveaways.items():
|
||||||
if giveaway.guild_id == guild_id and not giveaway.is_finished():
|
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:
|
if not server_giveaways:
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
@@ -1936,7 +1975,7 @@ async def listgiveaways(ctx):
|
|||||||
timestamp=datetime.now()
|
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
|
# Calculate remaining time
|
||||||
remaining = giveaway.end_time - datetime.now()
|
remaining = giveaway.end_time - datetime.now()
|
||||||
if remaining.total_seconds() > 0:
|
if remaining.total_seconds() > 0:
|
||||||
@@ -1967,7 +2006,11 @@ async def listgiveaways(ctx):
|
|||||||
if hasattr(giveaway, 'sponsor_display') and giveaway.sponsor_display:
|
if hasattr(giveaway, 'sponsor_display') and giveaway.sponsor_display:
|
||||||
giveaway_info += f"**Sponsor:** {giveaway.sponsor_display}\n"
|
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(
|
embed.add_field(
|
||||||
name=f"🎁 {giveaway.title}",
|
name=f"🎁 {giveaway.title}",
|
||||||
@@ -1982,10 +2025,279 @@ async def listgiveaways(ctx):
|
|||||||
inline=False
|
inline=False
|
||||||
)
|
)
|
||||||
|
|
||||||
embed.set_footer(text="Use /editgiveaway <id> <field> <value> to edit a giveaway")
|
# 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)
|
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 = {}
|
live_chats = {}
|
||||||
@@ -2419,6 +2731,9 @@ async def on_ready():
|
|||||||
# Initialize process management system
|
# Initialize process management system
|
||||||
await restore_active_processes_on_startup()
|
await restore_active_processes_on_startup()
|
||||||
|
|
||||||
|
# Load active giveaways from database
|
||||||
|
await load_active_giveaways()
|
||||||
|
|
||||||
# Start the process manager
|
# Start the process manager
|
||||||
if not process_manager.is_running():
|
if not process_manager.is_running():
|
||||||
process_manager.start()
|
process_manager.start()
|
||||||
|
|||||||
Reference in New Issue
Block a user