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
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
|
from functools import wraps
from irctokens import build
import importlib
import sys
import random
class Command:
def __init__(self, config):
self.config = config
self.commands = []
def mesg(self, msg, t=None):
self.util.mesg(msg, t)
def notice(self, msg):
self.util.notice(msg)
def action(self, msg):
self.util.action(msg)
def send(self, msg):
self.util.send(msg)
def err_perm(self, level="admin"):
self.mesg(f"Error: insufficient privileges, you lack {level} access")
def adm(func, *args, **kwargs):
"""decorator for admin commands"""
global adm_cmds
try:
if func.__name__ not in adm_cmds and func.__name__ != "_":
adm_cmds.append(func.__name__)
except NameError:
adm_cmds = []
if func.__name__ not in adm_cmds and func.__name__ != "_":
adm_cmds.append(func.__name__)
@wraps(func)
def _(self, *args, **kwargs):
if func.__name__ == "help":
self.admin_commands = adm_cmds
if not self.admin:
self.err_perm()
else:
return func(
self,
self.prefix,
self.line,
self.pm,
self._line,
self.admin,
self.mesg,
)
return _
def cmd(func, *args, **kwargs):
"""decorator for user commands"""
global cmds
try:
if func.__name__ not in cmds and func.__name__ != "_":
cmds.append(func.__name__)
except NameError:
cmds = []
if func.__name__ not in cmds and func.__name__ != "_":
cmds.append(func.__name__)
@wraps(func)
def _(self, *args, **kwargs):
if func.__name__ == "help":
self.commands = cmds
if func.__name__ not in self.config.cmd.disabled:
return func(
self,
self.prefix,
self.line,
self.pm,
self._line,
self.admin,
self.mesg,
)
return _
def internal(func, *args, **kwargs):
"""decorator for commands like ctcp which are for internal use, but use normal args template"""
global cmds
if func.__name__ in cmds:
cmds.remove(func.__name__)
return func
def preq_cmd(self): # command prequisites / triggers
cmd = self.line
needs_prefix = True
# self.mesg(f"attempting command: {cmd}")
if cmd == "help" or cmd.startswith("help "):
command = "help"
elif cmd.startswith("quit"):
command = "quit"
elif cmd.startswith("echo "):
command = "echo"
elif cmd.startswith("roll ") or cmd == "roll":
command = "dice"
elif cmd.startswith("pick ") or cmd.startswith("choose "):
command = "choose"
elif cmd.startswith("yt ") or self.YouTube.match_urls(self.YouTube, cmd) != []:
command = "yt"
needs_prefix = False
elif cmd.startswith("w ") or cmd.startswith("weather "):
command = "weather"
elif cmd.startswith("me "):
command = "me"
elif cmd == "crapdate" or cmd.startswith("crapdate "):
command = "crapdate"
elif cmd == "dbg" or cmd.startswith("dbg "):
command = "dbg"
elif cmd == "dbg2" or cmd.startswith("dbg2 "):
command = "dbg2"
elif cmd == "version" or cmd == "ver":
command = "version"
elif cmd.startswith("\x01") or self.is_ctcp:
command = "ctcp"
else:
# self.mesg(cmd)
return
if command not in self.config.cmd.disabled:
if needs_prefix == False:
eval(f"self.{command}()")
elif not (self.prefix == None and self.pm == False):
eval(f"self.{command}()")
# else:
# self.mesg("this ain't a valid commanderoonie, you twat")
def getversion(self):
with open(self.config.self.gitdir + ".git/logs/HEAD") as f:
for l in f:
pass
return l.split()[1]
@internal
@cmd
def ctcp(self, prefix, cmd, pm, line, admin, mesg):
"""CTCP responses"""
notice = self.notice
ctcp = cmd[1:]
ctcp_upper = ctcp.upper()
if not ctcp.endswith("\x01"):
ctcp = ctcp + "\x01"
if ctcp_upper.startswith("PING"):
ctcp = (
"\x01PING"
+ ("" if 1 == len(ctcp.split(" ")) else " ")
+ " ".join(ctcp.split(" ")[1:])
)
print(ctcp)
self.notice(ctcp)
if ctcp_upper.startswith("SOURCE"):
self.notice("\x01SOURCE " + self.config.self.source + "\x01")
elif ctcp_upper.startswith("VERSION"):
self.notice(f"\x01VERSION {self.getversion()}\x01")
elif ctcp_upper.startswith("FINGER"):
self.notice(
f"\x01FINGER {self.config.self.nick} version {self.getversion()} ({self.config.self.source})\x01"
)
elif ctcp_upper.startswith("USERINFO"):
self.notice("\x01USERINFO pawky's crude IRC bot\x01")
elif ctcp_upper.startswith("CLIENTINFO"):
self.notice("\x01CLIENTINFO USERINFO PING SOURCE FINGER VERSION\x01")
@adm
def quit(self, prefix, cmd, pm, line, admin, mesg):
if admin and (cmd == "q" or cmd == "quit"):
self.util.quit()
elif admin and (cmd.startswith("q ") or cmd.startswith("quit ")):
self.util.quit(cmd.split(" ", 1)[1])
@adm
def crapdate(self, prefix, cmd, pm, line, admin, mesg):
"""hacky and crappy update command, don't use it, lol"""
args = cmd.split()[1:]
if not args:
args = [""]
popen = __import__("os").popen
# mesg(args)
if args[0] in ["log", "list"]:
if len(args) == 1:
args = args + ["", 3]
elif len(args) < 3:
args = args + ["3"]
for i in (
popen(f"git log --pretty=oneline --abbrev-commit {args[1]}")
.read()
.split("\n", int(args[2]))
):
mesg(i)
else:
mesg(popen("git pull").read())
mesg(popen("git status|tr '\\n' ' '").read())
@adm
def dbg(self, prefix, cmd, pm, line, admin, mesg):
"""temporary debug command, subject to change A LOT"""
mesg(dir())
@cmd
def yt(self, prefix, cmd, pm, line, admin, mesg):
"""youtube"""
YouTube = self.YouTube
if cmd.startswith("yt "):
cmd = cmd[3:]
try:
YouTube.premature_optimization = self.config.cmd.yt_premature_opt
except AttributeError:
pass
print(f" YT premature_optimization={YouTube.premature_optimization}")
urls = YouTube.match_urls(YouTube, cmd)
yt_failed = False
for video in urls:
if yt_failed == True:
yt_failed = False
break
try:
a, yt_failed = YouTube.yt(YouTube, video)
except Exception as e:
a = e
yt_failed = True
mesg(a)
@cmd
def echo(self, prefix, cmd, pm, line, admin, mesg):
"""simple echo command | "echo ABC..." """
mesg("\x7f" + cmd.split(" ", 1)[1])
@cmd
def choose(self, prefix, cmd, pm, line, admin, mesg):
"""simple random choice command | "choose A B C..." """
mesg("I choose: " + str(random.choice(cmd.split(" ", 1)[1].split(" "))))
@cmd
def dice(self, prefix, cmd, pm, line, admin, mesg):
"""simple dice command | "roll [N[d[M]]]" where N is number of dice, and M is number of faces"""
cmd = cmd.split(" ", 1)[1]
amount, faces = 1, 6
try:
amount = 0 + int(cmd.split("d", 1)[0])
faces = 0 + int(cmd.split("d", 1)[1])
except:
pass
if not str(amount).isnumeric() or amount > 100:
amount = 1
if not str(faces).isnumeric() or faces > 100:
faces = 6
mesg(
f"rolling {amount}d{faces}: "
+ str([random.choice([i for i in range(faces)]) for n in range(amount)])
)
@cmd
def version(self, prefix, cmd, pm, line, admin, mesg):
"""version"""
mesg(
f"{self.config.self.nick} version {self.getversion()} ({self.config.self.source})"
)
@adm
def dbg2(self, prefix, cmd, pm, line, admin, mesg):
"""version"""
with open(self.config.self.gitdir + ".git/logs/HEAD") as f:
for l in f:
pass
mesg("version " + l.split()[1])
@cmd
def me(self, prefix, cmd, pm, line, admin, mesg):
"""simple /me command"""
self.action(cmd.split(" ", 1)[1])
@cmd
def help(self, prefix, cmd, pm, line, admin, mesg):
global adm_cmds
global cmds
disabled_commands = self.config.cmd.disabled
admin_commands, commands = [], []
for i in ["exec", "eval", "reload"]:
if i not in adm_cmds:
adm_cmds.append(i)
for i in adm_cmds:
if i not in disabled_commands:
admin_commands.append(i)
for i in cmds:
if i not in admin_commands and i not in disabled_commands:
commands.append(i)
prefixes = '"' + '", "'.join(self.config.cmd.prefixes) + '"'
admin_commands = ", ".join(admin_commands)
try:
topic = cmd.split(" ", 1)[1]
except IndexError:
topic = None
try:
self_nick = self.self_nick
except IndexError:
self_nick = None
abs_topics = {"prefixes": f'available prefixes are {prefixes} or "{self_nick}"'}
if topic == None:
mesg(f"available topics: " + ", ".join(list(abs_topics.keys())))
mesg(f"available commands: " + ", ".join(commands))
if admin:
mesg(f"admin commands: {admin_commands}")
else:
try:
mesg(f"{topic}: " + eval(f"self.{topic}.__doc__"))
except (TypeError, AttributeError) as e:
# mesg(str( e.__class__.__name__ ))
if topic in abs_topics:
mesg(f"{topic}: " + abs_topics[topic])
else:
mesg(f'no help available for "{topic}"...')
except Exception as e:
mesg(str(e.__class__) + " " + str(e))
|