forked from Murgeye/teamspeak3-python-bot
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcommand_handler.py
148 lines (131 loc) · 5.05 KB
/
command_handler.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
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
138
139
140
141
142
143
144
145
146
147
148
# standard imports
import logging
# third-party imports
from ts3API.Events import TextMessageEvent
# local imports
import teamspeak_bot
import client_info
logger = logging.getLogger("bot")
class CommandHandler:
"""
Command handler class that listens for PrivateMessages and informs registered handlers of possible commands.
"""
# configure logger
class_name = __qualname__
logger = logging.getLogger(class_name)
logger.propagate = 0
logger.setLevel(logging.INFO)
file_handler = logging.FileHandler(f"logs/{class_name.lower()}.log", mode="a+")
formatter = logging.Formatter("%(asctime)s: %(levelname)s: %(message)s")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.info("Configured %s logger", str(class_name))
logger.propagate = 0
def __init__(self, ts3conn):
"""
Create new CommandHandler.
:param ts3conn: TS3Connection to use
"""
self.handlers = {}
self.ts3conn = ts3conn
# Default group if group not specified.
self.accept_from_groups = ["Server Admin"]
def add_handler(self, handler, command):
"""
Add a handler for a command.
:param handler: Handler function to add.
:type handler: function
:param command: Command to handle.
:type command: str
"""
if self.handlers.get(command) is None:
self.handlers[command] = [handler]
else:
self.handlers[command].append(handler)
def check_permission(self, handler, clientinfo):
"""
Check if the client is allowed to call this command for this handler.
:param handler: Handler function to check permissions for.
:param clientinfo: Client info of the client that tries to use the command.
:return:
"""
if hasattr(handler, "allowed_groups"):
for group in handler.allowed_groups:
if clientinfo.is_in_servergroups(group):
return True
else:
for group in self.accept_from_groups:
if clientinfo.is_in_servergroups(group):
return True
return False
def handle_command(self, msg, sender=0):
"""
Handle a new command by informing the corresponding handlers.
:param msg: Command message.
:param sender: Client id of the sender.
"""
if not msg.startswith("!") and len(msg) > 2:
teamspeak_bot.send_msg_to_client(
self.ts3conn, sender, "Sorry, I only understand defined commands."
)
teamspeak_bot.send_msg_to_client(
self.ts3conn, sender, "Use `!help` to get a list of available commands."
)
logger.info(
"`clid=%s` sent a textmessage without any command: %s",
int(sender),
str(msg),
)
return
logger.info("`clid=%s` sent a command: %s", int(sender), str(msg))
command = msg.split(None, 1)[0][1:]
handlers = self.handlers.get(command)
if handlers is None:
try:
command = f"{msg.split(None, 2)[0][1:]} {msg.split(None, 2)[1]}"
handlers = self.handlers.get(command)
except IndexError:
handlers = None
if handlers is None:
teamspeak_bot.send_msg_to_client(
self.ts3conn,
sender,
f"Sorry, but I could not find your command `{command}`.",
)
teamspeak_bot.send_msg_to_client(
self.ts3conn,
sender,
"Use `!help` to get a list of available commands.",
)
logger.info(
"`clid=%s` sent an unknown command: %s", int(sender), str(msg)
)
return
has_permissions = False
for handler in handlers:
if self.check_permission(
handler, client_info.ClientInfo(sender, self.ts3conn)
):
has_permissions = True
handler(sender, msg)
if not has_permissions:
teamspeak_bot.send_msg_to_client(
self.ts3conn, sender, "You are not allowed to use this command!"
)
def inform(self, event):
"""
Inform the EventHandler of a new event.
:param event: New event.
"""
if isinstance(event, TextMessageEvent):
if event.targetmode == "Private":
if event.invoker_id != int(
self.ts3conn.whoami()["client_id"]
): # Don't talk to yourself ...
cl_info = client_info.ClientInfo(event.invoker_id, self.ts3conn)
self.logger.info(
"`%s` wrote the following message: %s",
str(cl_info.name),
str(event.message),
)
self.handle_command(event.message, sender=event.invoker_id)