-
Notifications
You must be signed in to change notification settings - Fork 0
/
bot.py
110 lines (91 loc) · 3.91 KB
/
bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import discord
import logging
import torch
from TTS.api import TTS
from queue_handler import QueueHandler
from config import Config
from logger import setup_logging
class MyClient(discord.Client):
def __init__(self, handler: QueueHandler, processing_limit: int = 100, **kwargs):
intents = kwargs.pop('intents', discord.Intents.default())
intents.messages = True
intents.message_content = True
super().__init__(intents=intents, **kwargs)
self.handler = handler
self.processing = set()
self.processing_limit = processing_limit
logging.info("Discord client initialized.")
async def on_ready(self):
"""
Event handler called when the bot is ready.
"""
logging.info(f'Logged in as {self.user} (ID: {self.user.id})')
self.loop.create_task(self.handler.handle_queue())
async def on_message(self, message: discord.Message):
"""
Event handler for incoming messages.
Args:
message (discord.Message): The message object.
"""
if message.author == self.user:
return # Avoid responding to own messages
if message.id in self.processing:
logging.debug(f"Message {message.id} is already being processed.")
return
# Limit the number of tracked messages to prevent memory leaks
if len(self.processing) >= self.processing_limit:
logging.warning("Processing limit reached. Ignoring new messages.")
return
self.processing.add(message.id)
try:
await self._handle_message(message)
except Exception as e:
logging.error(f"Error handling message {message.id}: {e}", exc_info=True)
await message.reply("An unexpected error occurred while processing your message.", mention_author=True)
finally:
self.processing.remove(message.id)
async def _handle_message(self, message: discord.Message):
"""
Handles the logic for processing incoming messages.
Args:
message (discord.Message): The message object.
"""
async with self.handler.lock:
if message.author.id in self.handler.users_in_queue:
await message.reply('You already have a message in the queue!', mention_author=True)
logging.info(f"User {message.author} attempted to queue multiple messages.")
return
elif self.handler.queue.full():
await message.reply('Queue is full! Please try again later.', mention_author=True)
logging.info("Queue is full. Message rejected.")
return
else:
await self.handler.queue.put(message)
self.handler.users_in_queue.add(message.author.id)
position = self.handler.queue.qsize()
await message.reply(f'Your position in the queue: {position}', mention_author=True)
logging.info(f"Message {message.id} from {message.author} added to queue at position {position}.")
def main():
"""
Main function to set up and run the Discord bot.
"""
setup_logging()
# Initialize TTS
device = "cuda" if torch.cuda.is_available() else "cpu"
try:
tts = TTS(model_name='tts_models/en/vctk/vits', progress_bar=False).to(device)
logging.info(f"TTS initialized on device: {device}")
except Exception as e:
logging.error(f"Failed to initialize TTS: {e}", exc_info=True)
return
# Initialize QueueHandler
handler = QueueHandler(max_queue_size=Config.MAX_QUEUE_SIZE, tts=tts)
logging.info("QueueHandler initialized.")
# Initialize and run the client
client = MyClient(handler=handler)
try:
client.run(Config.DISCORD_TOKEN)
except Exception as e:
logging.error(f"Failed to run Discord client: {e}", exc_info=True)
if __name__ == "__main__":
main()