Spaces:
Configuration error
Configuration error
| import discord | |
| from discord.ext import commands | |
| from discord import app_commands | |
| import json | |
| import os | |
| MISC_DIR = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "misc")) | |
| ROLES_JSON_PATH = os.path.join(MISC_DIR, "roles.json") | |
| AUTHORIZED_USER_ID = 966338171958886420 | |
| # List of available roles | |
| AVAILABLE_ROLES = [ | |
| "Management", | |
| "Owner", | |
| "Overseer", | |
| "Manager", | |
| "Staff Manager", | |
| "Tester Manager", | |
| "Senior Moderator", | |
| "Moderator", | |
| "Senior Tester", | |
| "Verified Tester", | |
| "Helper", | |
| "Staff Team", | |
| "Administrator" | |
| ] | |
| def load_roles(): | |
| """Load roles from roles.json""" | |
| try: | |
| os.makedirs(MISC_DIR, exist_ok=True) | |
| if os.path.isfile(ROLES_JSON_PATH): | |
| with open(ROLES_JSON_PATH, "r", encoding="utf-8") as f: | |
| return json.load(f) | |
| except Exception as e: | |
| print(f"Error loading roles.json: {e}") | |
| return {} | |
| def save_roles(roles_data): | |
| """Save roles to roles.json""" | |
| try: | |
| os.makedirs(MISC_DIR, exist_ok=True) | |
| with open(ROLES_JSON_PATH, "w", encoding="utf-8") as f: | |
| json.dump(roles_data, f, ensure_ascii=False, indent=2) | |
| except Exception as e: | |
| print(f"Error saving roles.json: {e}") | |
| class Miscellaneous(commands.Cog): | |
| def __init__(self, bot): | |
| self.bot = bot | |
| self.backup_service = None | |
| self._initialize_backup() | |
| def _initialize_backup(self): | |
| """Initialize backup service""" | |
| try: | |
| import config | |
| from google_drive_backup import GoogleDriveBackup | |
| oauth_credentials = os.path.join( | |
| os.path.dirname(os.path.dirname(__file__)), | |
| "oauth_credentials.json" | |
| ) | |
| if os.path.exists(oauth_credentials) and hasattr(config, 'GOOGLE_DRIVE_BACKUP_FOLDER_ID'): | |
| self.backup_service = GoogleDriveBackup( | |
| oauth_credentials, | |
| config.GOOGLE_DRIVE_BACKUP_FOLDER_ID | |
| ) | |
| print("[MISC] [OK] Backup service initialized") | |
| else: | |
| if not os.path.exists(oauth_credentials): | |
| print("[MISC] [!] oauth_credentials.json not found - Google Drive backup disabled") | |
| elif not hasattr(config, 'GOOGLE_DRIVE_BACKUP_FOLDER_ID'): | |
| print("[MISC] [!] GOOGLE_DRIVE_BACKUP_FOLDER_ID not in config.py") | |
| else: | |
| print("[MISC] [!] Backup service not configured") | |
| except Exception as e: | |
| print(f"[MISC] [ERROR] Error initializing backup: {str(e)}") | |
| async def save_backup(self, interaction: discord.Interaction): | |
| """ | |
| Create a forced backup of all bot data and code to Google Drive | |
| Only authorized users can execute this | |
| """ | |
| print(f"[SAVE] Command started by {interaction.user.name} ({interaction.user.id})") | |
| # Check if user is authorized | |
| if interaction.user.id != AUTHORIZED_USER_ID: | |
| print(f"[SAVE] [!] Permission denied - {interaction.user.name} is not authorized") | |
| await interaction.response.send_message( | |
| "β You don't have permission to use this command.", | |
| ephemeral=True | |
| ) | |
| return | |
| # Check if backup service is available | |
| if not self.backup_service: | |
| print(f"[SAVE] [ERROR] Backup service not initialized") | |
| await interaction.response.send_message( | |
| "β Backup service is not properly configured. Contact admin.", | |
| ephemeral=True | |
| ) | |
| return | |
| try: | |
| # Defer response as backup may take time | |
| await interaction.response.defer() | |
| # Get or create backup-logs channel | |
| backup_logs_channel = await self._get_or_create_backup_logs_channel(interaction.guild) | |
| print(f"[SAVE] [BACKUP] Starting forced backup by {interaction.user.name}") | |
| # Perform backup | |
| result = self.backup_service.backup_bot_data(backup_type="forced") | |
| if result.get("success"): | |
| success_msg = f"β **FORCED BACKUP COMPLETED**\n\nπ Folder: `{result['folder_name']}`\nβ° Time: {result['timestamp']}\nπ€ User: {interaction.user.mention}" | |
| print(f"[SAVE] [OK] Backup successful: {result['folder_name']}") | |
| # Send confirmation in Discord | |
| await interaction.followup.send( | |
| success_msg, | |
| ephemeral=True | |
| ) | |
| # Log in backup-logs channel | |
| if backup_logs_channel: | |
| embed = discord.Embed( | |
| title="β Forced Backup Created", | |
| description=f"**Folder:** `{result['folder_name']}`", | |
| color=discord.Color.green(), | |
| timestamp=discord.utils.utcnow() | |
| ) | |
| embed.add_field(name="Triggered By", value=interaction.user.mention, inline=True) | |
| embed.add_field(name="Type", value="Forced Backup", inline=True) | |
| embed.set_footer(text="Backup System") | |
| await backup_logs_channel.send(embed=embed) | |
| else: | |
| error_msg = f"β **BACKUP FAILED**\n\nError: {result.get('error', 'Unknown error')}" | |
| print(f"[SAVE] [ERROR] Backup failed: {result.get('error')}") | |
| await interaction.followup.send( | |
| error_msg, | |
| ephemeral=True | |
| ) | |
| # Log error in backup-logs channel | |
| if backup_logs_channel: | |
| embed = discord.Embed( | |
| title="β Backup Failed", | |
| description=f"**Error:** {result.get('error', 'Unknown error')}", | |
| color=discord.Color.red(), | |
| timestamp=discord.utils.utcnow() | |
| ) | |
| embed.add_field(name="Triggered By", value=interaction.user.mention, inline=True) | |
| embed.set_footer(text="Backup System") | |
| await backup_logs_channel.send(embed=embed) | |
| except Exception as e: | |
| error_msg = f"[SAVE] β Unexpected error: {str(e)}" | |
| print(error_msg) | |
| await interaction.followup.send( | |
| f"β Error: {str(e)}", | |
| ephemeral=True | |
| ) | |
| async def _get_or_create_backup_logs_channel(self, guild: discord.Guild) -> discord.TextChannel: | |
| """Get or create backup-logs channel""" | |
| try: | |
| channel = discord.utils.get(guild.text_channels, name="backup-logs") | |
| if not channel: | |
| print("[SAVE] [DIR] Creating backup-logs channel...") | |
| channel = await guild.create_text_channel( | |
| "backup-logs", | |
| topic="π Automated backup logs - View all backup operations here" | |
| ) | |
| print("[SAVE] [OK] Created backup-logs channel") | |
| return channel | |
| except Exception as e: | |
| print(f"[SAVE] [ERROR] Error with backup-logs channel: {str(e)}") | |
| return None | |
| # Deprecated: Use /setuproles command instead (from queue_system.py) | |
| async def stop_bot(self, interaction: discord.Interaction): | |
| """ | |
| Safely turns off the bot. | |
| Only accessible by authorized user ID. | |
| """ | |
| # Check if user is authorized | |
| if interaction.user.id != AUTHORIZED_USER_ID: | |
| await interaction.response.send_message( | |
| "β You don't have permission to use this command.", | |
| ephemeral=True | |
| ) | |
| return | |
| await interaction.response.send_message( | |
| "π Bot is shutting down safely...", | |
| ephemeral=True | |
| ) | |
| print(f"Bot shutdown initiated by {interaction.user} ({interaction.user.id})") | |
| await self.bot.close() | |
| async def setup(bot: commands.Bot): | |
| await bot.add_cog(Miscellaneous(bot)) | |