import json import os from typing import Dict, Optional, Tuple, Union, Any DATA_FILE_PATH = "data/custom_emojis_stickers.json" class EmojiManager: def __init__(self, data_file: str = DATA_FILE_PATH): self.data_file = data_file # Adjusted type hint for self.data to accommodate guild_id, url, and description self.data: Dict[str, Dict[str, Dict[str, Any]]] = {"emojis": {}, "stickers": {}} self._load_data() def _load_data(self): """Loads emoji and sticker data from the JSON file.""" try: if os.path.exists(self.data_file): with open(self.data_file, "r", encoding="utf-8") as f: loaded_json = json.load(f) if isinstance(loaded_json, dict): # Ensure guild_id is present, defaulting to None if missing for backward compatibility during load self.data["emojis"] = { name: { "id": data.get("id"), "animated": data.get("animated", False), "guild_id": data.get("guild_id"), "url": data.get("url"), # Load new field "description": data.get( "description" ), # Load new field } for name, data in loaded_json.get("emojis", {}).items() if isinstance(data, dict) } self.data["stickers"] = { name: { "id": data.get("id"), "guild_id": data.get("guild_id"), "url": data.get("url"), # Load new field "description": data.get( "description" ), # Load new field } for name, data in loaded_json.get("stickers", {}).items() if isinstance(data, dict) } print( f"Loaded {len(self.data['emojis'])} emojis and {len(self.data['stickers'])} stickers from {self.data_file}" ) else: print( f"Warning: Data in {self.data_file} is not a dictionary. Initializing with empty data." ) self._save_data() # Initialize with empty structure if format is wrong else: print(f"{self.data_file} not found. Initializing with empty data.") self._save_data() # Create the file if it doesn't exist except json.JSONDecodeError: print( f"Error decoding JSON from {self.data_file}. Initializing with empty data." ) self._save_data() except Exception as e: print(f"Error loading emoji/sticker data: {e}") # Ensure data is initialized even on other errors if "emojis" not in self.data: self.data["emojis"] = {} if "stickers" not in self.data: self.data["stickers"] = {} def _save_data(self): """Saves the current emoji and sticker data to the JSON file.""" try: os.makedirs(os.path.dirname(self.data_file), exist_ok=True) with open(self.data_file, "w", encoding="utf-8") as f: json.dump(self.data, f, indent=4) print(f"Saved emoji and sticker data to {self.data_file}") return True except Exception as e: print(f"Error saving emoji/sticker data: {e}") return False async def add_emoji( self, name: str, emoji_id: str, is_animated: bool, guild_id: Optional[int], url: Optional[str] = None, description: Optional[str] = None, ) -> bool: """Adds a custom emoji with its guild ID, URL, and description.""" if name in self.data["emojis"]: existing_data = self.data["emojis"][name] if ( existing_data.get("id") == emoji_id and existing_data.get("guild_id") == guild_id and existing_data.get("animated") == is_animated and existing_data.get("url") == url and existing_data.get("description") == description ): return False # No change self.data["emojis"][name] = { "id": emoji_id, "animated": is_animated, "guild_id": guild_id, "url": url, "description": description, } return self._save_data() async def remove_emoji(self, name: str) -> bool: """Removes a custom emoji.""" if name not in self.data["emojis"]: return False # Emoji not found del self.data["emojis"][name] return self._save_data() async def list_emojis(self) -> Dict[str, Dict[str, Any]]: """Lists all custom emojis.""" return self.data["emojis"] async def get_emoji(self, name: str) -> Optional[Dict[str, Any]]: """Gets a specific custom emoji by name.""" return self.data["emojis"].get(name) async def add_sticker( self, name: str, sticker_id: str, guild_id: Optional[int], url: Optional[str] = None, description: Optional[str] = None, ) -> bool: """Adds a custom sticker with its guild ID, URL, and description.""" if name in self.data["stickers"]: existing_data = self.data["stickers"][name] if ( existing_data.get("id") == sticker_id and existing_data.get("guild_id") == guild_id and existing_data.get("url") == url and existing_data.get("description") == description ): return False # No change self.data["stickers"][name] = { "id": sticker_id, "guild_id": guild_id, "url": url, "description": description, } return self._save_data() async def remove_sticker(self, name: str) -> bool: """Removes a custom sticker.""" if name not in self.data["stickers"]: return False # Sticker not found del self.data["stickers"][name] return self._save_data() async def list_stickers(self) -> Dict[str, Dict[str, Any]]: """Lists all custom stickers.""" return self.data["stickers"] async def get_sticker(self, name: str) -> Optional[Dict[str, Any]]: """Gets a specific custom sticker by name.""" return self.data["stickers"].get(name)