-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommands_helper.py
212 lines (197 loc) · 9.13 KB
/
commands_helper.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import time
class PrivmsgCommand:
"""
Util class to manage commands like !wr for messages sent in a channel,
has support for cooldown (individual user, global) and mod-only/broadcaster-only too
"""
def __init__(self, name, func, channel_cooldown=0, user_cooldown=0, mod_only=False, broadcaster_only=False, enabled=True):
"""
Init a new Command
Params:
name (str): Name of the command. Note that the name is automatically prefixed with '!',
if you want the Command to be executed when the user types in '!wr' in chat,
name ist 'wr'
func (function): Function to handle the command, params: (username, channel, message, tags)
channel_cooldown (int, optional): Number of seconds of cooldown, after the command was used in the channel
user_cooldown (int, optional): Number of seconds of cooldown, after a user can use this command again
mod_only(bool, default=False): IF only mods or the broadcaster can use this command
broadcaster_only(bool, default=False): If only broadcaster can use this command
enabled(bool, default=True): If the command can be used in chat, otherwise it's useless
"""
self._name=None
def assignname(nm):
self._name=nm.lower()
self.name=property(lambda:self._name,assignname)
self.name=name
self.func=func
self.channel_cooldown=channel_cooldown
self.user_cooldown=user_cooldown
self.mod_only=mod_only
self.broadcaster_only=broadcaster_only
self.enabled=enabled
class WhisperCommand:
"""
Util class to manage whisper commands like !uptime,
has support for cooldown (individual user)
"""
def __init__(self, name, func, user_cooldown=0):
"""
Init a new Command
Params:
name (str): Name of the command. Note that the name is automatically prefixed with '!',
if you want the Command to be executed when the user types in '!wr' in chat,
name ist 'wr'
func (function): Function to handle the command, params: (username, channel, message, tags)
user_cooldown (int, optional): Number of seconds of cooldown, after a user can use this command again
"""
self._name=None
def assignname(nm):
self._name=nm.lower()
self.name=property(lambda:self._name,assignname)
self.name=name
self.func=func
self.user_cooldown=user_cooldown
def check_mod(tags):
"""
Check if a person with these tags is mod
"""
return 'mod' in tags['badges']
def check_broadcaster(tags):
"""
Check if a person with these tags is the broadcaster
"""
return 'broadcaster' in tags['badges']
class CommandsHelper:
def __init__(self):
#(channel, commandname):last used time
self.channel_cooldowns={}
#(channel, username, commandname):last used time
self.channel_user_cooldowns={}
#(username, commandname):last used time
self.user_cooldowns={}
#commandname:PrivmsgCommand
self.privmsg_commands={}
#commandname:WhisperCommand
self.whisper_commands={}
def add_privmsg_command(self, name, func, channel_cooldown=0, user_cooldown=0, mod_only=False, broadcaster_only=False, enabled=True):
"""
Add a new privmsg-command
Params:
name (str): Name of the command. Note that the name is automatically prefixed with '!',
if you want the Command to be executed when the user types in '!wr' in chat,
name ist 'wr'
func (function): Function to handle the command, params: (username, channel, message, tags)
channel_cooldown (int, optional): Number of seconds of cooldown, after the command was used in the channel
user_cooldown (int, optional): Number of seconds of cooldown, after a user can use this command again
mod_only(bool, default=False): IF only mods or the broadcaster can use this command
broadcaster_only(bool, default=False): If only broadcaster can use this command
enabled(bool, default=True): If the command can be used
"""
self._add_privmsg_command(PrivmsgCommand(name, func, channel_cooldown, user_cooldown, mod_only, broadcaster_only))
def _add_privmsg_command(self, command):
self.privmsg_commands[command.name]=command
def add_whisper_command(self, name, func, user_cooldown=0):
"""
Add a new whisper-command
Params:
name (str): Name of the command. Note that the name is automatically prefixed with '!',
if you want the Command to be executed when the user types in '!wr' in chat,
name ist 'wr'
func (function): Function to handle the command, params: (username, channel, message, tags)
user_cooldown (int, optional): Number of seconds of cooldown, after a user can use this command again
"""
self.whisper_commands[name]=WhisperCommand(name, func, user_cooldown)
def remove_privmsg_command(self, name):
"""
Remove a command by name
"""
if name in self.privmsg_commands:
del self.privmsg_commands[name]
def remove_whisper_command(self, name):
"""
Remove a command by name
"""
if name in self.whisper_commands:
del self.whisper_commands[name]
def check_privmsgcommand_exists(self, name):
"""
Check if the privmsgcommand given by name exists
"""
return name in self.privmsg_commands
def check_whispercommand_exists(self, name):
"""
Check if the whispercommand given by name exists
"""
return name in self.whisper_commands
def get_privmsgcommand(self, name):
"""
Returns the privmsgcommand by name or None if it doesn't exist
"""
return self.privmsg_commands[name] if self.check_privmsgcommand_exists(name) else None
def get_whispercommand(self, name):
"""
Returns the whispercommand by name or None if it doesn't exist
"""
return self.whisper_commands[name] if self.check_whispercommand_exists(name) else None
def privmsg_listener(self, username, channel, message, tags):
if message.startswith('!'):
split=message[1:].split(' ',1)
commandname=split[0].lower()
if len(split)==1:
rest=''
else:
rest=split[1]
#Search Command
if not commandname in self.privmsg_commands:
return
command=self.privmsg_commands[commandname]
#Check enabled
if not command.enabled:
return
#Check mod/broadcaster only
if command.mod_only and not (check_mod(tags) or check_broadcaster(tags)):
return
if command.broadcaster_only and not check_broadcaster(tags):
return
#Check cooldowns
if command.channel_cooldown!=0:
if (channel, commandname) in self.channel_cooldowns:
last=self.channel_cooldowns[(channel,commandname)]
#Check if enough time elapsed since last usage
if last!=None and (time.time()-last)<command.channel_cooldown:
return
#Update last use
self.channel_cooldowns[(channel,commandname)]=time.time()
if command.user_cooldown!=0:
if (channel, username, commandname) in self.channel_user_cooldowns:
last=self.channel_user_cooldowns[(channel,username,commandname)]
#Check if enough time elapsed since last usage
if last!=None and (time.time()-last)<command.user_cooldown:
return
#Update last use
self.channel_user_cooldowns[(channel,username,commandname)]=time.time()
#Call command
command.func(username=username,channel=channel,message=rest,tags=tags)
def whisper_listener(self, username, message, tags):
if message.startswith('!'):
split=message[1:].split(' ',1)
commandname=split[0].lower()
if len(split)==1:
rest=''
else:
rest=split[1]
#Search Command
if not commandname in self.whisper_commands:
return
command=self.whisper_commands[commandname]
#Check cooldown
if command.user_cooldown!=0:
if (username, commandname) in self.user_cooldowns:
last=self.user_cooldowns[(username,commandname)]
#Check if enough time elapsed since last usage
if last!=None and (time.time()-last)<command.user_cooldown:
return
#Update last use
self.user_cooldowns[(username,commandname)]=time.time()
#Call command
command.func(username=username,message=rest,tags=tags)