Add purge embeds feature
All checks were successful
Docker Build and Push (Multi-architecture) / build-and-push (push) Successful in 31s
All checks were successful
Docker Build and Push (Multi-architecture) / build-and-push (push) Successful in 31s
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
.gitea
|
||||
.gitignore
|
||||
.env
|
||||
__pycache__
|
||||
.venv
|
||||
__pycache__/
|
||||
md_images/
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -175,10 +175,10 @@ cython_debug/
|
||||
.pypirc
|
||||
|
||||
# Logs
|
||||
/logs
|
||||
logs/
|
||||
|
||||
# Embeds
|
||||
/embed
|
||||
embed/
|
||||
|
||||
# Config file
|
||||
config.ini
|
149
pterodisbot.py
149
pterodisbot.py
@@ -1062,6 +1062,155 @@ async def refresh_embeds(interaction: discord.Interaction):
|
||||
ephemeral=True
|
||||
)
|
||||
|
||||
@bot.tree.command(name="purge_embeds", description="Permanently delete all server status embeds (admin only)")
|
||||
async def purge_embeds(interaction: discord.Interaction):
|
||||
"""
|
||||
Slash command to permanently purge all server status embeds from Discord channels.
|
||||
|
||||
This command performs a complete cleanup of all tracked server status embeds by:
|
||||
1. Iterating through all tracked embed locations in embed_locations.json
|
||||
2. Attempting to delete each embed message from its respective Discord channel
|
||||
3. Clearing the embed tracking file and internal state tracking
|
||||
4. Providing real-time progress updates during the operation
|
||||
|
||||
Args:
|
||||
interaction: Discord interaction object representing the command invocation
|
||||
|
||||
Workflow:
|
||||
- Validates administrator permissions
|
||||
- Checks if any embeds are currently tracked
|
||||
- Sends initial progress embed
|
||||
- Processes each embed sequentially with error handling
|
||||
- Updates progress embed in real-time
|
||||
- Saves cleared tracking data to disk
|
||||
- Sends final results with comprehensive statistics
|
||||
|
||||
Safety:
|
||||
- Only affects tracked embeds (won't delete arbitrary messages)
|
||||
- Maintains logs for audit purposes
|
||||
- Provides rollback protection through immediate tracking removal
|
||||
- Includes rate limiting to avoid Discord API limits
|
||||
|
||||
Returns:
|
||||
None: Sends follow-up messages with operation results
|
||||
"""
|
||||
if not await check_allowed_guild(interaction):
|
||||
return
|
||||
|
||||
logger.info(f"Purge embeds command invoked by {interaction.user.name}")
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
|
||||
# Require administrator permissions
|
||||
if not interaction.user.guild_permissions.administrator:
|
||||
logger.warning(f"Unauthorized purge attempt by {interaction.user.name}")
|
||||
await interaction.followup.send(
|
||||
"You need administrator permissions to purge all embeds.",
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
logger.info("Starting embed purge per admin request")
|
||||
|
||||
# Variables to track purge statistics
|
||||
deleted_count = 0
|
||||
not_found_count = 0
|
||||
error_count = 0
|
||||
total_embeds = len(bot.embed_locations)
|
||||
|
||||
if total_embeds == 0:
|
||||
await interaction.followup.send(
|
||||
"No embeds are currently being tracked. Nothing to purge.",
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
# Create progress embed
|
||||
progress_embed = discord.Embed(
|
||||
title="🔄 Purging Server Embeds",
|
||||
description=f"Processing {total_embeds} embeds...",
|
||||
color=discord.Color.orange()
|
||||
)
|
||||
progress_embed.add_field(name="Deleted", value="0", inline=True)
|
||||
progress_embed.add_field(name="Not Found", value="0", inline=True)
|
||||
progress_embed.add_field(name="Errors", value="0", inline=True)
|
||||
progress_embed.set_footer(text="This may take a while...")
|
||||
|
||||
progress_message = await interaction.followup.send(embed=progress_embed, ephemeral=True)
|
||||
|
||||
# Process each tracked embed
|
||||
for server_id, location in list(bot.embed_locations.items()):
|
||||
try:
|
||||
channel = bot.get_channel(int(location['channel_id']))
|
||||
if channel:
|
||||
try:
|
||||
message = await channel.fetch_message(int(location['message_id']))
|
||||
await message.delete()
|
||||
deleted_count += 1
|
||||
logger.debug(f"Successfully purged embed for server {server_id}")
|
||||
except discord.NotFound:
|
||||
not_found_count += 1
|
||||
logger.debug(f"Embed for server {server_id} already deleted")
|
||||
except discord.Forbidden:
|
||||
error_count += 1
|
||||
logger.error(f"Permission denied when deleting embed for server {server_id}")
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
logger.error(f"Error deleting embed for server {server_id}: {str(e)}")
|
||||
else:
|
||||
not_found_count += 1
|
||||
logger.warning(f"Channel not found for server {server_id}")
|
||||
|
||||
# Remove from tracking immediately
|
||||
bot.embed_locations.pop(server_id, None)
|
||||
bot.previous_states.pop(server_id, None) # Also clean up state tracking
|
||||
|
||||
# Update progress every 5 embeds or for the last one
|
||||
if (deleted_count + not_found_count + error_count) % 5 == 0 or \
|
||||
(deleted_count + not_found_count + error_count) == total_embeds:
|
||||
|
||||
progress_embed.description = f"Processed {deleted_count + not_found_count + error_count}/{total_embeds} embeds"
|
||||
progress_embed.set_field_at(0, name="Deleted", value=str(deleted_count), inline=True)
|
||||
progress_embed.set_field_at(1, name="Not Found", value=str(not_found_count), inline=True)
|
||||
progress_embed.set_field_at(2, name="Errors", value=str(error_count), inline=True)
|
||||
|
||||
await progress_message.edit(embed=progress_embed)
|
||||
|
||||
# Small delay to avoid rate limits
|
||||
await asyncio.sleep(0.3)
|
||||
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
logger.error(f"Unexpected error processing server {server_id}: {str(e)}")
|
||||
|
||||
# Save the cleared embed locations
|
||||
await bot.save_embed_locations()
|
||||
|
||||
# Create results embed
|
||||
result_embed = discord.Embed(
|
||||
title="✅ Embed Purge Complete",
|
||||
color=discord.Color.green(),
|
||||
timestamp=datetime.now()
|
||||
)
|
||||
result_embed.add_field(name="Total Tracked", value=str(total_embeds), inline=True)
|
||||
result_embed.add_field(name="✅ Successfully Deleted", value=str(deleted_count), inline=True)
|
||||
result_embed.add_field(name="❌ Already Missing", value=str(not_found_count), inline=True)
|
||||
result_embed.add_field(name="⚠️ Errors", value=str(error_count), inline=True)
|
||||
result_embed.add_field(name="📊 Success Rate",
|
||||
value=f"{((deleted_count + not_found_count) / total_embeds * 100):.1f}%",
|
||||
inline=True)
|
||||
result_embed.set_footer(text="Embed tracking file has been cleared")
|
||||
|
||||
await progress_message.edit(embed=result_embed)
|
||||
logger.info(f"Embed purge completed: {deleted_count} deleted, {not_found_count} not found, {error_count} errors")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Embed purge failed: {str(e)}")
|
||||
await interaction.followup.send(
|
||||
f"❌ Failed to purge embeds: {str(e)}",
|
||||
ephemeral=True
|
||||
)
|
||||
|
||||
# ==============================================
|
||||
# BOT EVENTS
|
||||
# ==============================================
|
||||
|
Reference in New Issue
Block a user