discordbot/gurt/emojis.py

114 lines
5.5 KiB
Python

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
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), # Default animated to False
"guild_id": data.get("guild_id") # Will be None if not present
}
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") # Will be None if not present
}
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]) -> bool:
"""Adds a custom emoji with its guild ID."""
if name in self.data["emojis"]:
# Allow update if guild_id was None and is now being set, or if ID changes
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:
return False # No change
self.data["emojis"][name] = {"id": emoji_id, "animated": is_animated, "guild_id": guild_id}
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]) -> bool:
"""Adds a custom sticker with its guild ID."""
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:
return False # No change
self.data["stickers"][name] = {"id": sticker_id, "guild_id": guild_id}
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)