-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
137 lines (116 loc) · 3.61 KB
/
main.py
File metadata and controls
137 lines (116 loc) · 3.61 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# A/main.py
"""
File: main.py
Path: A/main.py
Author: Benoit Desrosiers
Date: 06-04-23
Description: Main entry point for the Discord bot application.
"""
import logging
import sys
import asyncio
import threading
import time
from bot.bot import Bot
from config.settings import BOT_TOKEN
from pynput import keyboard
# Event to signal when Ctrl-Q is pressed
shutdown_event = threading.Event()
# Variable to keep track of the last displayed message time
last_display_time = 0
def setup_logging():
"""
Set up logging for the application.
"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s:%(levelname)s:%(name)s: %(message)s'
)
def display_quit_message():
"""
Display "Press ctrl-q to quit" message if not displayed in the last 20 seconds.
"""
global last_display_time
current_time = time.time()
if current_time - last_display_time >= 20:
print("Press ctrl-q to quit")
last_display_time = current_time
def keyboard_listener():
"""
Listen for Ctrl-Q keypress and set the shutdown_event when detected.
"""
def on_press(key):
"""
Handle key press events.
"""
pass # We only need to handle key releases
def on_release(key):
"""
Handle key release events.
"""
if key == keyboard.Key.ctrl_l or key == keyboard.Key.ctrl_r:
# Control key released; nothing to do
pass
elif key == keyboard.KeyCode.from_char('q'):
# 'q' key released; check if control is pressed
if any([keyboard.Controller().pressed(keyboard.Key.ctrl_l),
keyboard.Controller().pressed(keyboard.Key.ctrl_r)]):
# Ctrl-Q detected
shutdown_event.set()
return False # Stop listener
# Start the keyboard listener
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
async def shutdown_bot(bot):
"""
Gracefully shut down the bot.
Args:
bot (Bot): The bot instance.
"""
# Disconnect from voice channels
for vc in bot.voice_clients:
if vc.is_connected():
await vc.disconnect()
# Close the bot
await bot.close()
async def periodic_task(bot):
"""
Periodic task to display the quit message and check for shutdown event.
Args:
bot (Bot): The bot instance.
"""
while not shutdown_event.is_set():
display_quit_message()
await asyncio.sleep(1) # Check every second for responsiveness
# Shutdown event is set; proceed to shut down the bot
await shutdown_bot(bot)
async def main():
"""
Main function to run the Discord bot.
"""
setup_logging()
if not BOT_TOKEN:
logging.error("BOT_TOKEN is not set. Please set it as an environment variable.")
sys.exit(1)
# Create the bot instance
bot = Bot()
# Start the keyboard listener in a separate thread
keyboard_thread = threading.Thread(target=keyboard_listener, daemon=True)
keyboard_thread.start()
# Run the periodic task in the event loop
asyncio.create_task(periodic_task(bot))
# Run the bot
try:
await bot.start(BOT_TOKEN)
except KeyboardInterrupt:
# Handle Ctrl-C gracefully
logging.info("Bot is shutting down due to keyboard interrupt.")
await shutdown_bot(bot)
except Exception as e:
logging.error(f"An error occurred: {e}")
finally:
# Ensure the bot is closed properly
if not bot.is_closed():
await shutdown_bot(bot)
if __name__ == "__main__":
asyncio.run(main())