modified: bot.py
This commit is contained in:
560
bot.py
560
bot.py
@@ -1,4 +1,4 @@
|
||||
__version__ = "dev-0.9.4"
|
||||
__version__ = "dev-0.9.5"
|
||||
__all__ = ["Discordbot-chatai (Discord)"]
|
||||
__author__ = "SimolZimol"
|
||||
|
||||
@@ -12,8 +12,12 @@ import requests
|
||||
import asyncio
|
||||
import base64
|
||||
import mysql.connector
|
||||
import mysql.connector.pooling
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import random
|
||||
import hashlib
|
||||
from datetime import datetime, timedelta
|
||||
import concurrent.futures
|
||||
from gtts import gTTS
|
||||
@@ -466,6 +470,362 @@ def save_global_permission(user_id, permission_level):
|
||||
|
||||
#-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
# Active Processes System - Robust system for storing and managing active processes
|
||||
def create_active_process(process_type, guild_id, channel_id=None, user_id=None, target_id=None,
|
||||
start_time=None, end_time=None, status="active", data=None, metadata=None):
|
||||
"""Creates a new active process entry in the database"""
|
||||
connection = None
|
||||
cursor = None
|
||||
try:
|
||||
connection = connect_to_database()
|
||||
cursor = connection.cursor()
|
||||
process_uuid = uuid.uuid4()
|
||||
|
||||
insert_query = """
|
||||
INSERT INTO active_processes (uuid, process_type, guild_id, channel_id, user_id, target_id,
|
||||
start_time, end_time, status, data, metadata, created_at)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
"""
|
||||
|
||||
current_time = datetime.now()
|
||||
start_time = start_time or current_time
|
||||
|
||||
# Serialize data and metadata as JSON
|
||||
data_json = json.dumps(data) if data else None
|
||||
metadata_json = json.dumps(metadata) if metadata else None
|
||||
|
||||
cursor.execute(insert_query, (
|
||||
str(process_uuid), process_type, guild_id, channel_id, user_id, target_id,
|
||||
start_time, end_time, status, data_json, metadata_json, current_time
|
||||
))
|
||||
connection.commit()
|
||||
|
||||
logger.info(f"Created active process: {process_type} with UUID: {process_uuid}")
|
||||
return process_uuid
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating active process: {e}")
|
||||
if connection:
|
||||
connection.rollback()
|
||||
raise e
|
||||
finally:
|
||||
if cursor:
|
||||
cursor.close()
|
||||
if connection:
|
||||
close_database_connection(connection)
|
||||
|
||||
def get_active_processes(process_type=None, guild_id=None, status="active"):
|
||||
"""Retrieves active processes from the database with optional filters"""
|
||||
connection = None
|
||||
cursor = None
|
||||
try:
|
||||
connection = connect_to_database()
|
||||
cursor = connection.cursor()
|
||||
|
||||
query = "SELECT * FROM active_processes WHERE status = %s"
|
||||
params = [status]
|
||||
|
||||
if process_type:
|
||||
query += " AND process_type = %s"
|
||||
params.append(process_type)
|
||||
|
||||
if guild_id:
|
||||
query += " AND guild_id = %s"
|
||||
params.append(guild_id)
|
||||
|
||||
query += " ORDER BY created_at ASC"
|
||||
|
||||
cursor.execute(query, params)
|
||||
results = cursor.fetchall()
|
||||
|
||||
processes = []
|
||||
for row in results:
|
||||
process = {
|
||||
"uuid": row[0],
|
||||
"process_type": row[1],
|
||||
"guild_id": row[2],
|
||||
"channel_id": row[3],
|
||||
"user_id": row[4],
|
||||
"target_id": row[5],
|
||||
"start_time": row[6],
|
||||
"end_time": row[7],
|
||||
"status": row[8],
|
||||
"data": json.loads(row[9]) if row[9] else None,
|
||||
"metadata": json.loads(row[10]) if row[10] else None,
|
||||
"created_at": row[11],
|
||||
"updated_at": row[12]
|
||||
}
|
||||
processes.append(process)
|
||||
|
||||
return processes
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error retrieving active processes: {e}")
|
||||
return []
|
||||
finally:
|
||||
if cursor:
|
||||
cursor.close()
|
||||
if connection:
|
||||
close_database_connection(connection)
|
||||
|
||||
def update_process_status(process_uuid, status, data=None, metadata=None):
|
||||
"""Updates the status and optionally data/metadata of an active process"""
|
||||
connection = None
|
||||
cursor = None
|
||||
try:
|
||||
connection = connect_to_database()
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Prepare update fields
|
||||
update_fields = ["status = %s", "updated_at = %s"]
|
||||
params = [status, datetime.now()]
|
||||
|
||||
if data is not None:
|
||||
update_fields.append("data = %s")
|
||||
params.append(json.dumps(data))
|
||||
|
||||
if metadata is not None:
|
||||
update_fields.append("metadata = %s")
|
||||
params.append(json.dumps(metadata))
|
||||
|
||||
params.append(str(process_uuid))
|
||||
|
||||
update_query = f"UPDATE active_processes SET {', '.join(update_fields)} WHERE uuid = %s"
|
||||
cursor.execute(update_query, params)
|
||||
connection.commit()
|
||||
|
||||
logger.info(f"Updated process {process_uuid} status to: {status}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating process status: {e}")
|
||||
if connection:
|
||||
connection.rollback()
|
||||
return False
|
||||
finally:
|
||||
if cursor:
|
||||
cursor.close()
|
||||
if connection:
|
||||
close_database_connection(connection)
|
||||
|
||||
def delete_process(process_uuid):
|
||||
"""Deletes a process from the database"""
|
||||
connection = None
|
||||
cursor = None
|
||||
try:
|
||||
connection = connect_to_database()
|
||||
cursor = connection.cursor()
|
||||
|
||||
delete_query = "DELETE FROM active_processes WHERE uuid = %s"
|
||||
cursor.execute(delete_query, (str(process_uuid),))
|
||||
connection.commit()
|
||||
|
||||
logger.info(f"Deleted process: {process_uuid}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error deleting process: {e}")
|
||||
if connection:
|
||||
connection.rollback()
|
||||
return False
|
||||
finally:
|
||||
if cursor:
|
||||
cursor.close()
|
||||
if connection:
|
||||
close_database_connection(connection)
|
||||
|
||||
def cleanup_expired_processes():
|
||||
"""Cleans up expired processes and marks them as completed"""
|
||||
connection = None
|
||||
cursor = None
|
||||
try:
|
||||
connection = connect_to_database()
|
||||
cursor = connection.cursor()
|
||||
|
||||
current_time = datetime.now()
|
||||
|
||||
# Find expired processes
|
||||
select_query = """
|
||||
SELECT uuid, process_type, data FROM active_processes
|
||||
WHERE status = 'active' AND end_time IS NOT NULL AND end_time <= %s
|
||||
"""
|
||||
cursor.execute(select_query, (current_time,))
|
||||
expired_processes = cursor.fetchall()
|
||||
|
||||
# Update expired processes
|
||||
if expired_processes:
|
||||
update_query = """
|
||||
UPDATE active_processes
|
||||
SET status = 'expired', updated_at = %s
|
||||
WHERE status = 'active' AND end_time IS NOT NULL AND end_time <= %s
|
||||
"""
|
||||
cursor.execute(update_query, (current_time, current_time))
|
||||
connection.commit()
|
||||
|
||||
logger.info(f"Marked {len(expired_processes)} processes as expired")
|
||||
|
||||
return expired_processes
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error cleaning up expired processes: {e}")
|
||||
return []
|
||||
finally:
|
||||
if cursor:
|
||||
cursor.close()
|
||||
if connection:
|
||||
close_database_connection(connection)
|
||||
|
||||
# Process Management Task
|
||||
@tasks.loop(minutes=1)
|
||||
async def process_manager():
|
||||
"""Main task that manages all active processes"""
|
||||
try:
|
||||
# Clean up expired processes first
|
||||
expired_processes = cleanup_expired_processes()
|
||||
|
||||
# Handle expired processes
|
||||
for uuid_str, process_type, data_json in expired_processes:
|
||||
await handle_expired_process(uuid_str, process_type, json.loads(data_json) if data_json else {})
|
||||
|
||||
# Check for processes that need handling
|
||||
active_processes = get_active_processes(status="active")
|
||||
|
||||
for process in active_processes:
|
||||
if process["end_time"] and datetime.now() >= process["end_time"]:
|
||||
await handle_process_completion(process)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error in process manager: {e}")
|
||||
|
||||
async def handle_expired_process(process_uuid, process_type, data):
|
||||
"""Handles different types of expired processes"""
|
||||
try:
|
||||
if process_type == "giveaway":
|
||||
await handle_expired_giveaway(process_uuid, data)
|
||||
elif process_type == "mute":
|
||||
await handle_expired_mute(process_uuid, data)
|
||||
elif process_type == "ban":
|
||||
await handle_expired_ban(process_uuid, data)
|
||||
# Add more process types as needed
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error handling expired process {process_uuid}: {e}")
|
||||
|
||||
async def handle_expired_giveaway(process_uuid, data):
|
||||
"""Handles expired giveaway processes"""
|
||||
try:
|
||||
giveaway_id = data.get("giveaway_id")
|
||||
if giveaway_id and giveaway_id in giveaways:
|
||||
giveaway = giveaways[giveaway_id]
|
||||
|
||||
# Execute giveaway ending logic
|
||||
winners = giveaway.pick_winners()
|
||||
if winners:
|
||||
winner_mentions = ", ".join([winner.mention for winner in winners])
|
||||
await giveaway.ctx.send(f"🎉 Congratulations to the winners of the giveaway '{giveaway.title}'! The winners are: {winner_mentions}")
|
||||
|
||||
# Process winners
|
||||
for i, winner in enumerate(winners):
|
||||
try:
|
||||
winner_uuid = giveaway.winner_uuids[i]
|
||||
assign_winner_to_uuid(winner_uuid, winner.id)
|
||||
|
||||
await winner.send(f"🎁 Congratulations! You won the giveaway '{giveaway.title}'!\n"
|
||||
f"Please claim your prize using the following link: {GIVEAWAY_WEBSITE_URL}{giveaway.guild_id}/{winner_uuid}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing winner {winner.name}: {e}")
|
||||
else:
|
||||
await giveaway.ctx.send(f"The giveaway '{giveaway.title}' has ended, but there were no participants.")
|
||||
|
||||
# Clean up
|
||||
del giveaways[giveaway_id]
|
||||
update_process_status(process_uuid, "completed")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error handling expired giveaway {process_uuid}: {e}")
|
||||
|
||||
async def handle_expired_mute(process_uuid, data):
|
||||
"""Handles expired mute processes - placeholder for future implementation"""
|
||||
try:
|
||||
# TODO: Implement mute removal logic
|
||||
guild_id = data.get("guild_id")
|
||||
user_id = data.get("user_id")
|
||||
|
||||
logger.info(f"Mute expired for user {user_id} in guild {guild_id}")
|
||||
update_process_status(process_uuid, "completed")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error handling expired mute {process_uuid}: {e}")
|
||||
|
||||
async def handle_expired_ban(process_uuid, data):
|
||||
"""Handles expired ban processes - placeholder for future implementation"""
|
||||
try:
|
||||
# TODO: Implement ban removal logic
|
||||
guild_id = data.get("guild_id")
|
||||
user_id = data.get("user_id")
|
||||
|
||||
logger.info(f"Ban expired for user {user_id} in guild {guild_id}")
|
||||
update_process_status(process_uuid, "completed")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error handling expired ban {process_uuid}: {e}")
|
||||
|
||||
async def handle_process_completion(process):
|
||||
"""Generic handler for process completion"""
|
||||
try:
|
||||
await handle_expired_process(process["uuid"], process["process_type"], process["data"] or {})
|
||||
except Exception as e:
|
||||
logger.error(f"Error in process completion handler: {e}")
|
||||
|
||||
async def restore_active_processes_on_startup():
|
||||
"""Restores active processes when the bot starts up"""
|
||||
try:
|
||||
logger.info("Restoring active processes from database...")
|
||||
|
||||
# Get all active processes
|
||||
processes = get_active_processes(status="active")
|
||||
|
||||
restored_count = 0
|
||||
for process in processes:
|
||||
try:
|
||||
if process["process_type"] == "giveaway":
|
||||
await restore_giveaway_process(process)
|
||||
restored_count += 1
|
||||
# Add more process types as needed
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error restoring process {process['uuid']}: {e}")
|
||||
|
||||
logger.info(f"Successfully restored {restored_count} active processes")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error restoring active processes: {e}")
|
||||
|
||||
async def restore_giveaway_process(process):
|
||||
"""Restores a giveaway process from the database"""
|
||||
try:
|
||||
data = process["data"] or {}
|
||||
giveaway_id = data.get("giveaway_id")
|
||||
|
||||
if giveaway_id:
|
||||
# Check if giveaway is still valid and not expired
|
||||
if process["end_time"] and datetime.now() < process["end_time"]:
|
||||
# Create a minimal giveaway object for restoration
|
||||
# Note: This is a simplified restoration - full ctx recreation may not be possible
|
||||
logger.info(f"Restored giveaway process {giveaway_id} from database")
|
||||
|
||||
# Start the process manager if it's not already running
|
||||
if not process_manager.is_running():
|
||||
process_manager.start()
|
||||
else:
|
||||
# Mark as expired if past end time
|
||||
update_process_status(process["uuid"], "expired")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error restoring giveaway process: {e}")
|
||||
|
||||
#-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
async def update_all_users(batch_size=20, pause_duration=1):
|
||||
connection = connect_to_database()
|
||||
cursor = connection.cursor()
|
||||
@@ -656,9 +1016,80 @@ class Giveaway:
|
||||
self.winner_uuids = create_winner_slots_in_db(self.guild_id, self.platform, self.title, self.num_winners, self.game_key)
|
||||
logger.info(f"Created giveaway '{self.title}' with {len(self.winner_uuids)} winner slots: {[str(uuid) for uuid in self.winner_uuids]}")
|
||||
|
||||
# Create process entry in active_processes table
|
||||
self.process_uuid = None
|
||||
self.create_process_entry()
|
||||
|
||||
def create_process_entry(self):
|
||||
"""Creates an entry in the active_processes table for this giveaway"""
|
||||
try:
|
||||
giveaway_data = {
|
||||
"giveaway_id": len(giveaways) + 1, # Will be set properly when added to giveaways dict
|
||||
"platform": self.platform,
|
||||
"prize": self.prize,
|
||||
"num_winners": self.num_winners,
|
||||
"title": self.title,
|
||||
"subtitle": self.subtitle,
|
||||
"winner_uuids": [str(uuid) for uuid in self.winner_uuids],
|
||||
"prize_uuid": str(self.prize_uuid),
|
||||
"game_key": self.game_key
|
||||
}
|
||||
|
||||
giveaway_metadata = {
|
||||
"duration": self.duration,
|
||||
"channel_id": self.ctx.channel.id,
|
||||
"author_id": self.ctx.author.id
|
||||
}
|
||||
|
||||
self.process_uuid = create_active_process(
|
||||
process_type="giveaway",
|
||||
guild_id=self.guild_id,
|
||||
channel_id=self.ctx.channel.id,
|
||||
user_id=self.ctx.author.id,
|
||||
start_time=datetime.now(),
|
||||
end_time=self.end_time,
|
||||
status="active",
|
||||
data=giveaway_data,
|
||||
metadata=giveaway_metadata
|
||||
)
|
||||
|
||||
logger.info(f"Created process entry for giveaway '{self.title}' with process UUID: {self.process_uuid}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating process entry for giveaway: {e}")
|
||||
|
||||
def update_process_data(self, giveaway_id):
|
||||
"""Updates the process data with the actual giveaway ID"""
|
||||
try:
|
||||
if self.process_uuid:
|
||||
current_processes = get_active_processes()
|
||||
for process in current_processes:
|
||||
if process["uuid"] == str(self.process_uuid):
|
||||
data = process["data"] or {}
|
||||
data["giveaway_id"] = giveaway_id
|
||||
update_process_status(self.process_uuid, "active", data=data)
|
||||
logger.info(f"Updated process data for giveaway {giveaway_id}")
|
||||
break
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating process data: {e}")
|
||||
|
||||
def add_participant(self, user):
|
||||
if user not in self.participants:
|
||||
self.participants.append(user)
|
||||
|
||||
# Update process data with participant count
|
||||
try:
|
||||
if self.process_uuid:
|
||||
current_processes = get_active_processes()
|
||||
for process in current_processes:
|
||||
if process["uuid"] == str(self.process_uuid):
|
||||
data = process["data"] or {}
|
||||
data["participant_count"] = len(self.participants)
|
||||
update_process_status(self.process_uuid, "active", data=data)
|
||||
break
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating participant count: {e}")
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -677,6 +1108,15 @@ class Giveaway:
|
||||
logger.info(f"Selected {len(winners)} winners: {[winner.name for winner in winners]}")
|
||||
return winners
|
||||
|
||||
def complete_giveaway(self):
|
||||
"""Marks the giveaway process as completed"""
|
||||
try:
|
||||
if self.process_uuid:
|
||||
update_process_status(self.process_uuid, "completed")
|
||||
logger.info(f"Marked giveaway process {self.process_uuid} as completed")
|
||||
except Exception as e:
|
||||
logger.error(f"Error completing giveaway process: {e}")
|
||||
|
||||
@client.hybrid_command()
|
||||
async def startgiveaway(ctx, platform: str, prize: str, num_winners: int, title: str, subtitle: str, duration: str):
|
||||
"""Creates a new giveaway, only available for admins."""
|
||||
@@ -701,6 +1141,9 @@ async def startgiveaway(ctx, platform: str, prize: str, num_winners: int, title:
|
||||
giveaway_id = len(giveaways) + 1
|
||||
giveaways[giveaway_id] = giveaway
|
||||
|
||||
# Update the process data with the actual giveaway ID
|
||||
giveaway.update_process_data(giveaway_id)
|
||||
|
||||
button = Button(label="Participate", style=discord.ButtonStyle.green, custom_id=f"giveaway_{giveaway_id}")
|
||||
view = View()
|
||||
view.add_item(button)
|
||||
@@ -714,7 +1157,9 @@ async def startgiveaway(ctx, platform: str, prize: str, num_winners: int, title:
|
||||
embed.set_footer(text=f"Giveaway ends at {end_time.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
await ctx.send(embed=embed, view=view)
|
||||
|
||||
check_giveaway.start(giveaway_id)
|
||||
# Start the process manager if it's not already running
|
||||
if not process_manager.is_running():
|
||||
process_manager.start()
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -852,39 +1297,7 @@ async def setlocalpermission(ctx, permission_level: int):
|
||||
else:
|
||||
await ctx.send("You do not have permission to set local permissions.")
|
||||
|
||||
@tasks.loop(minutes=1)
|
||||
async def check_giveaway(giveaway_id):
|
||||
giveaway = giveaways.get(giveaway_id)
|
||||
|
||||
if giveaway and giveaway.is_finished():
|
||||
check_giveaway.stop()
|
||||
|
||||
winners = giveaway.pick_winners()
|
||||
if winners:
|
||||
winner_mentions = ", ".join([winner.mention for winner in winners])
|
||||
await giveaway.ctx.send(f"🎉 Congratulations to the winners of the giveaway '{giveaway.title}'! The winners are: {winner_mentions}")
|
||||
|
||||
# Verwende die bereits erstellten UUIDs und weise sie den tatsächlichen Gewinnern zu
|
||||
logger.info(f"Processing {len(winners)} winners for giveaway '{giveaway.title}'")
|
||||
for i, winner in enumerate(winners):
|
||||
try:
|
||||
user_data = load_user_data_sync(winner.id, giveaway.guild_id)
|
||||
# Verwende die bereits beim Erstellen generierte UUID
|
||||
winner_uuid = giveaway.winner_uuids[i] # i-te UUID für i-ten Gewinner
|
||||
logger.info(f"Assigning winner {i+1}/{len(winners)}: {winner.name} (ID: {winner.id}) to existing UUID: {winner_uuid}")
|
||||
|
||||
# Verknüpfe die bereits vorhandene UUID mit dem tatsächlichen Gewinner
|
||||
assign_winner_to_uuid(winner_uuid, winner.id)
|
||||
|
||||
await winner.send(f"🎁 Congratulations! You won the giveaway '{giveaway.title}'!\n"
|
||||
f"Please claim your prize using the following link: {GIVEAWAY_WEBSITE_URL}{giveaway.guild_id}/{winner_uuid}")
|
||||
logger.info(f"Sent winner notification with UUID: {winner_uuid}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing winner {winner.name}: {e}")
|
||||
else:
|
||||
await giveaway.ctx.send(f"The giveaway '{giveaway.title}' has ended, but there were no participants.")
|
||||
|
||||
del giveaways[giveaway_id]
|
||||
# Old check_giveaway task removed - now handled by process_manager
|
||||
|
||||
@client.event
|
||||
async def on_interaction(interaction):
|
||||
@@ -1151,8 +1564,17 @@ background_data = read_background_data("background_data.txt")
|
||||
|
||||
@client.event
|
||||
async def on_ready():
|
||||
# Start background tasks
|
||||
client.loop.create_task(process_ai_queue())
|
||||
client.loop.create_task(process_live_chat_queue()) # Starte die Queue-Verarbeitung
|
||||
|
||||
# Initialize process management system
|
||||
await restore_active_processes_on_startup()
|
||||
|
||||
# Start the process manager
|
||||
if not process_manager.is_running():
|
||||
process_manager.start()
|
||||
|
||||
logger.info("Bot is ready!")
|
||||
logger.info(f"Logged in as: {client.user.name}")
|
||||
logger.info(f"Client ID: {client.user.id}")
|
||||
@@ -1573,6 +1995,74 @@ async def toggle_feature(ctx, feature: str, state: str):
|
||||
|
||||
await ctx.send("Please specify 'on' or 'off'.")
|
||||
|
||||
@client.hybrid_command()
|
||||
async def processes(ctx, action: str = "list", process_type: str = None):
|
||||
"""Manages active processes. Actions: list, cleanup, status"""
|
||||
guild_id = ctx.guild.id
|
||||
user_perms = load_user_data_sync(ctx.author.id, guild_id)
|
||||
|
||||
if user_perms["permission"] < 8: # Only admins can manage processes
|
||||
await ctx.send("You don't have permission to manage processes.")
|
||||
return
|
||||
|
||||
if action.lower() == "list":
|
||||
processes = get_active_processes(process_type=process_type, guild_id=guild_id)
|
||||
|
||||
if not processes:
|
||||
await ctx.send("No active processes found.")
|
||||
return
|
||||
|
||||
embed = discord.Embed(title="Active Processes", color=0x00ff00)
|
||||
|
||||
for process in processes[:10]: # Limit to 10 processes
|
||||
process_info = f"Type: {process['process_type']}\n"
|
||||
process_info += f"Status: {process['status']}\n"
|
||||
|
||||
if process['end_time']:
|
||||
time_left = process['end_time'] - datetime.now()
|
||||
if time_left.total_seconds() > 0:
|
||||
process_info += f"Time left: {time_left}\n"
|
||||
else:
|
||||
process_info += "**EXPIRED**\n"
|
||||
|
||||
if process['data']:
|
||||
data = process['data']
|
||||
if 'title' in data:
|
||||
process_info += f"Title: {data['title']}\n"
|
||||
if 'participant_count' in data:
|
||||
process_info += f"Participants: {data['participant_count']}\n"
|
||||
|
||||
embed.add_field(
|
||||
name=f"{process['process_type'].title()} - {process['uuid'][:8]}...",
|
||||
value=process_info,
|
||||
inline=True
|
||||
)
|
||||
|
||||
if len(processes) > 10:
|
||||
embed.set_footer(text=f"Showing 10 of {len(processes)} processes")
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
elif action.lower() == "cleanup":
|
||||
expired = cleanup_expired_processes()
|
||||
await ctx.send(f"Cleaned up {len(expired)} expired processes.")
|
||||
|
||||
elif action.lower() == "status":
|
||||
active_count = len(get_active_processes(status="active", guild_id=guild_id))
|
||||
completed_count = len(get_active_processes(status="completed", guild_id=guild_id))
|
||||
expired_count = len(get_active_processes(status="expired", guild_id=guild_id))
|
||||
|
||||
embed = discord.Embed(title="Process Status", color=0x3498db)
|
||||
embed.add_field(name="Active", value=str(active_count), inline=True)
|
||||
embed.add_field(name="Completed", value=str(completed_count), inline=True)
|
||||
embed.add_field(name="Expired", value=str(expired_count), inline=True)
|
||||
embed.add_field(name="Process Manager", value="Running" if process_manager.is_running() else "Stopped", inline=False)
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
else:
|
||||
await ctx.send("Invalid action. Use: list, cleanup, or status")
|
||||
|
||||
@client.hybrid_command()
|
||||
async def version(ctx):
|
||||
"""Displays the current version of the bot."""
|
||||
|
||||
Reference in New Issue
Block a user