-
Notifications
You must be signed in to change notification settings - Fork 0
/
flipcom.py
263 lines (215 loc) · 9.84 KB
/
flipcom.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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
from discord.ext import commands
from .utils.dataIO import dataIO
from .utils import checks
from .utils.chat_formatting import pagify, box
import os
import re
import shlex
class FlipCommands:
"""Custom commands
Creates commands used to display text"""
def __init__(self, bot):
self.bot = bot
self.file_path = "data/flipcom/commands.json"
self.c_commands = dataIO.load_json(self.file_path)
@commands.group(aliases=["flipc"], pass_context=True, no_pm=True)
async def flipcom(self, ctx):
"""Custom commands management"""
if ctx.invoked_subcommand is None:
await self.bot.send_cmd_help(ctx)
@flipcom.command(name="add", pass_context=True)
@checks.mod_or_permissions(administrator=True)
async def flipc_add(self, ctx, command : str, *, text):
"""Adds a custom command
Example:
[p]flipcom add yourcommand Text you want
CCs can be enhanced with arguments:
https://twentysix26.github.io/Red-Docs/red_guide_command_args/
"""
server = ctx.message.server
command = command.lower()
if command in self.bot.commands:
await self.bot.say("That command is already a standard command.")
return
if server.id not in self.c_commands:
self.c_commands[server.id] = {}
cmdlist = self.c_commands[server.id]
if command not in cmdlist:
cmdlist[command] = text
self.c_commands[server.id] = cmdlist
dataIO.save_json(self.file_path, self.c_commands)
await self.bot.say("Custom command successfully added.")
else:
await self.bot.say("This command already exists. Use "
"`{}flipcom edit` to edit it."
"".format(ctx.prefix))
@flipcom.command(name="edit", pass_context=True)
@checks.mod_or_permissions(administrator=True)
async def flipc_edit(self, ctx, command : str, *, text):
"""Edits a custom command
Example:
[p]flipcom edit yourcommand Text you want
"""
server = ctx.message.server
command = command.lower()
if server.id in self.c_commands:
cmdlist = self.c_commands[server.id]
if command in cmdlist:
cmdlist[command] = text
self.c_commands[server.id] = cmdlist
dataIO.save_json(self.file_path, self.c_commands)
await self.bot.say("Custom command successfully edited.")
else:
await self.bot.say("That command doesn't exist. Use "
"`{}flipcom add` to add it."
"".format(ctx.prefix))
else:
await self.bot.say("There are no custom commands in this server."
" Use `{}flipcom add` to start adding some."
"".format(ctx.prefix))
@flipcom.command(name="delete", pass_context=True)
@checks.mod_or_permissions(administrator=True)
async def flipc_delete(self, ctx, command : str):
"""Deletes a custom command
Example:
[p]flipcom delete yourcommand"""
server = ctx.message.server
command = command.lower()
if server.id in self.c_commands:
cmdlist = self.c_commands[server.id]
if command in cmdlist:
cmdlist.pop(command, None)
self.c_commands[server.id] = cmdlist
dataIO.save_json(self.file_path, self.c_commands)
await self.bot.say("Custom command successfully deleted.")
else:
await self.bot.say("That command doesn't exist.")
else:
await self.bot.say("There are no custom commands in this server."
" Use `{}flipcom add` to start adding some."
"".format(ctx.prefix))
@flipcom.command(name="list", pass_context=True)
async def flipc_list(self, ctx):
"""Shows custom commands list"""
server = ctx.message.server
commands = self.c_commands.get(server.id, {})
if not commands:
await self.bot.say("There are no custom commands in this server."
" Use `{}flipcom add` to start adding some."
"".format(ctx.prefix))
return
commands = ", ".join([ctx.prefix + c for c in sorted(commands)])
commands = "Custom commands:\n\n" + commands
if len(commands) < 1500:
await self.bot.say(box(commands))
else:
for page in pagify(commands, delims=[" ", "\n"]):
await self.bot.whisper(box(page))
async def on_message(self, message):
if len(message.content) < 2 or message.channel.is_private:
return
server = message.server
prefix = self.get_prefix(message)
if not prefix:
return
if server.id in self.c_commands and self.bot.user_allowed(message):
cmdlist = self.c_commands[server.id]
cmd = self.get_command(message)
if cmd in cmdlist:
cmd = cmdlist[cmd]
cmd = self.format_cc(cmd, message)
await self.bot.send_message(message.channel, cmd)
elif cmd.lower() in cmdlist:
cmd = self.format_cc(cmd, message)
await self.bot.send_message(message.channel, cmd)
cmd = cmdlist[cmd.lower()]
def get_prefix(self, message):
for p in self.bot.settings.get_prefixes(message.server):
if message.content.startswith(p):
return p
return False
def get_command(self, message):
prefix = self.get_prefix(message)
return message.content.split(" ")[prefix.count(' ')][len(prefix):]
def format_cc(self, command, message):
results = re.findall("\{([^}]+)\}", command)
for result in results:
param = self.transform_parameter(result, message)
command = command.replace("{" + result + "}", param)
return command
def is_int(self, s):
try:
int(s)
return True
except ValueError:
return False
def transform_parameter(self, result, message):
"""
For security reasons only specific objects are allowed
Internals are ignored
"""
raw_result = "{" + result + "}"
if self.is_int(result):
command = self.get_prefix(message) + self.get_command(message)
message_content = message.content[len(command)+1:]
message_mentions_re = re.findall("<@!?&?[0-9]*>", message_content)
message_mentioned = message.mentions
message_mentioned_str = [mentioned.mention for mentioned in message_mentioned]
message_content_split = shlex.split(message_content)
for mentioned in message_mentions_re:
if mentioned in message_mentioned_str:
user = message_mentioned[message_mentioned_str.index(mentioned)]
user_name = user.nick
if user_name == None:
user_name = user.name
message_content_split = [message.replace(mentioned, user_name) for message in message_content_split]
message_content_split = [message.replace("@", "") for message in message_content_split]
try:
return message_content_split[int(result)]
except IndexError:
return ""
if result == "content":
command = self.get_prefix(message) + self.get_command(message)
message_content = message.content[len(command)+1:]
message_mentions_re = re.findall("<@!?&?[0-9]*>", message_content)
message_mentioned = message.mentions
message_mentioned_str = [mentioned.mention for mentioned in message_mentioned]
for mentioned in message_mentions_re:
if mentioned in message_mentioned_str:
user = message_mentioned[message_mentioned_str.index(mentioned)]
user_name = user.nick
if user_name == None:
user_name = user.name
message_content = message_content.replace(mentioned, user_name)
message_content = message_content.replace("@", "")
return message_content
objects = {
"message" : message,
"author" : message.author,
"channel" : message.channel,
"server" : message.server,
}
if result in objects:
return str(objects[result])
try:
first, second = result.split(".")
except ValueError:
return raw_result
if first in objects and not second.startswith("_"):
first = objects[first]
else:
return raw_result
return str(getattr(first, second, raw_result))
def check_folders():
if not os.path.exists("data/flipcom"):
print("Creating data/flipcom folder...")
os.makedirs("data/flipcom")
def check_files():
f = "data/flipcom/commands.json"
if not dataIO.is_valid_json(f):
print("Creating empty commands.json...")
dataIO.save_json(f, {})
def setup(bot):
check_folders()
check_files()
bot.add_cog(FlipCommands(bot))