-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcommands.py
596 lines (483 loc) · 16.2 KB
/
commands.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
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
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# GCI bot. Commands module
#
# Copyright (C) Ignacio Rodríguez <[email protected]>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
import re
import datetime
import data
import geonames_api
import subprocess
public_commands = [
"ping",
"about",
"rules",
"guide",
"faq",
"timeline",
"!floss",
"!license",
"thanks",
"!musicblocks",
"help",
"pending memos",
"memo",
"hi",
"ignore me",
".time",
".city"]
commands = [
"runpi",
"run",
"sayplz",
"i rock",
"you rock",
"ignacio rocks",
"all memos",
"pending memos",
"memo",
"you can stand",
"allcommands",
"commands",
"ping",
"about",
"rules",
"guide",
"faq",
"timeline",
"leave this channel",
"join",
"no longer ignore",
"ignore me",
"ignore",
"!license",
"ignoring",
"add admin",
"remove admin",
"admins",
"bored",
"!floss",
"!sugar",
"i love you",
"!tea",
"!coffee",
"help",
"!thanks",
"!musicblocks",
"!high5",
"!hi5",
"thanks",
"!nick",
"!register",
"!svineet",
".time",
"hi",
"!hi",
".city",
"dfpi",
"uptimepi",
"uptime",
"df"]
no_interaction_required = [
"!license",
"!floss",
"!sugar",
"!musicblocks",
"!coffee",
"!tea",
"!thanks",
"!high5",
"!hi5",
"!nick",
"!register",
"!svineet",
".time",
".hny",
".city"]
about_data = "I'm a bot written by Ignacio, paste GCI link task and \
I will tell data about it.\nSource code available in: https://github.com/i5o/gcibot"
music_blocks = """Music Blocks code is here: https://github.com/walterbender/musicblocks You can try Music Blocks at https://play.musicblocks.net. Also, WE CURRENTLY RECOMMEND FIREFOX, because of a bug with Chrome/ium (currently versions 53+ plays wrong notes)."""
links = {
"rules": "https://developers.google.com/open-source/gci/resources/contest-rules",
"guide": "https://developers.google.com/open-source/gci/resources/getting-started",
"faq": "https://developers.google.com/open-source/gci/faq",
"timeline": "https://developers.google.com/open-source/gci/timeline",
"floss": "https://www.gnu.org/philosophy/free-sw.html"}
full_admins = ["@fedora/sugar/ignacio", "@wikimedia/Tymon-r"]
admins = ["@fedora/sugar/ignacio", "@wikimedia/Tymon-r", "@unaffiliated/ohnx"]
licensing_info = "please read: http://people.sugarlabs.org/ignacio/about_licensing.txt"
class Commands():
def __init__(self, client):
self.client = client
self.msg = None
self.channel = None
self.user = None
self.human_user = None
self.ignored_users = ["meeting", "soakbot", "bannon3001", "zcz"]
self.pending_msgs = []
def process_msg(self, msg, channel, user):
self.msg = msg
self.channel = channel
self.user = user
self.human_user = user.split('!', 1)[0]
if self.human_user in self.ignored_users and "ignore me" not in self.msg or self.human_user == self.client.nickname:
return False
talking_to_me = msg.startswith(self.client.nickname + ":") \
or msg.startswith(self.client.nickname + ",") \
or msg.startswith(self.client.nickname + " ")
if not talking_to_me:
no_interaction = False
for command in no_interaction_required:
if command in msg.lower():
no_interaction = True
if not no_interaction:
return True
done = False
output = None
for c in commands:
if c in msg.lower() and not done:
command = c.replace(
" ",
"_").replace(
"!",
"").replace(
".",
"_")
output = eval("self.%s()" % command)
done = True
if output is not None:
self.client.msg(channel, output.encode("utf-8"))
return False
return True
def hi(self):
return "Hi %s :)" % self.human_user
def hi5(self):
self.high5()
def high5(self):
self.client.describe(self.channel, "HIGH FIVES ALL AROUND!!!")
def help(self):
return self.about() + "\nTry 'gcibot, commands' for more commands."
def i_love_you(self):
return "%s, I love you too 💕" % self.human_user
def ping(self):
return "%s, pong" % self.human_user
def about(self):
return "%s, %s" % (self.human_user, about_data)
def rules(self):
return "%s, %s" % (self.human_user, links["rules"])
def guide(self):
return "%s, %s" % (self.human_user, links["guide"])
def faq(self):
return "%s, %s" % (self.human_user, links["faq"])
def timeline(self):
return "%s, %s" % (self.human_user, links["timeline"])
def leave_this_channel(self):
if not self.is_admin():
return
self.client.leave(self.channel)
def join(self):
if not self.is_admin():
return
finder = re.compile(ur'(#[a-z]+)')
channels = finder.findall(self.msg)
for channel in channels:
self.client.join(channel)
def is_admin(self):
is_admin = False
for admin in admins:
if admin in self.user:
is_admin = True
for admin in full_admins:
if admin in self.user:
is_admin = True
return is_admin
def ignore(self):
if not self.is_admin():
return
finder = re.compile(ur'([\S*]+)')
users = finder.findall(self.msg)
users[0] = None
users[1] = None
for user in users:
if user is None or user in self.ignored_users or user in admins:
continue
self.ignored_users.append(user)
self.client.describe(self.channel, "is now ignoring %s" % user)
def ignore_me(self):
if self.human_user in self.ignored_users:
self.ignored_users.remove(self.human_user)
self.client.describe(
self.channel,
"is no longer ignoring %s :)" %
self.human_user)
else:
self.ignored_users.append(self.human_user)
self.client.describe(
self.channel,
"is now ignoring %s :(" %
self.human_user)
def no_longer_ignore(self):
if not self.is_admin():
return
finder = re.compile(ur'([\S*]+)')
users = finder.findall(self.msg)
users[0] = None
users[1] = None
for user in users:
if user is None or user not in self.ignored_users:
continue
self.ignored_users.remove(user)
self.client.describe(self.channel, "is no longer ignoring %s" %
user)
def license(self):
finder = re.compile(ur'!license ([\S*]+)')
users = finder.findall(self.msg)
done = False
for user in users:
self.client.msg(self.channel, "%s, %s" % (user, licensing_info))
done = True
if not done:
self.client.msg(
self.channel, "%s, %s" %
(self.human_user, licensing_info))
def floss(self):
finder = re.compile(ur'!floss ([\S*]+)')
users = finder.findall(self.msg)
done = False
for user in users:
self.client.msg(
self.channel, "%s, please read: %s" %
(user, links["floss"]))
done = True
if not done:
self.client.msg(
self.channel, "%s, please read: %s" %
(self.human_user, links["floss"]))
def sugar(self):
self.client.msg(
self.channel,
"Chemical compounds of sugar | glucose (C_6 H_12 O_6) and sucrose (C_12 H_22 O_11) | See: https://en.wikipedia.org/wiki/Sugar")
def coffee(self, is_tea=False):
word = 'coffee'
if is_tea:
word = 'tea'
finder = re.compile(ur'!%s ([\S*]+)' % word)
users = finder.findall(self.msg)
done = False
for user in users:
self.client.msg(
self.channel, "%s, here is your %s ☕" % (user, word))
done = True
if not done:
self.client.msg(
self.channel, "%s, here is your %s ☕" %
(self.human_user, word))
def tea(self):
self.coffee(True)
def thanks(self):
self.client.msg(
self.channel,
"%s, you are quite welcome. :)" %
self.human_user)
def musicblocks(self):
finder = re.compile(ur'!musicblocks ([\S*]+)')
users = finder.findall(self.msg)
done = False
for user in users:
self.client.msg(
self.channel, "%s, %s" %
(user, music_blocks))
done = True
if not done:
self.client.msg(
self.channel, "%s, %s" %
(self.human_user, music_blocks))
def commands(self):
self.client.msg(
self.channel, "%s, %s" %
(self.human_user, ", ".join(public_commands)))
def allcommands(self):
if not self.is_admin():
return
self.client.msg(
self.channel, "%s, %s" %
(self.human_user, ", ".join(commands)))
def ignoring(self):
if not self.is_admin():
return
str_ignored = str(self.ignored_users)
self.client.describe(self.channel, "is ignoring %s" % str_ignored)
def bored(self):
if not self.is_admin():
return
for channel in self.client.channels:
self.client.describe(channel, "is bored :(")
def remove_admin(self):
if not self.is_admin():
return
finder = re.compile(ur'([\S*]+)')
users = finder.findall(self.msg)
users[0] = None
users[1] = None
users[2] = None
for user in users:
if user is None or user not in admins in user.lower():
continue
admins.remove(user)
self.client.describe(self.channel, "no longer loves %s" %
user)
def add_admin(self):
if not self.is_admin():
return
finder = re.compile(ur'([\S*]+)')
users = finder.findall(self.msg)
users[0] = None
users[1] = None
users[2] = None
for user in users:
if user is None or user in admins:
continue
admins.append(user)
self.client.describe(self.channel, "loves %s" %
user)
def admins(self):
if not self.is_admin():
self.client.describe(
self.channel,
"has %s mysterious admins" % str(
len(admins)))
return
str_admins = str(admins)
self.client.describe(self.channel, "loves %s" % str_admins)
def memo(self):
finder = re.compile(ur'([\S*]+)')
users = finder.findall(self.msg)
users[0] = None
users[1] = None
to = users[2]
message = " ".join(users[3:len(users)])
chan = self.channel
if chan == "gcibot":
chan = self.human_user
self.pending_msgs.append([self.channel,
to,
self.human_user,
message,
datetime.datetime.now().strftime("%H:%M %D")])
self.client.msg(chan, "I'll wait for the user.")
def pending_memos(self):
pending = []
for memo in self.pending_msgs:
if memo[2] == self.human_user:
pending.append(
"'%s' to %s at %s" %
(memo[3], memo[1], memo[4]))
self.client.msg(self.human_user, str(pending))
def all_memos(self):
if not self.is_admin():
return
pending = []
for memo in self.pending_msgs:
pending.append(
"'%s' to %s at %s" %
(memo[3], memo[1], memo[4]))
self.client.msg(self.human_user, str(pending))
self.client.describe(
self.channel,
"has %s pending memos (to deliver)" % len(
self.pending_msgs))
def nick(self):
if not self.is_admin():
return
finder = re.compile(ur'!nick ([\S*]+)')
nicknames = finder.findall(self.msg)
for nick in nicknames:
self.client.setNick(nick)
def you_can_stand(self):
return "under my umbrella (ella, ella, eh, eh)"
def i_rock(self):
return "%s, sure.." % self.human_user
def you_rock(self):
return "%s, I know :)" % self.human_user
def ignacio_rocks(self):
if not self.is_admin():
return False
return "%s, eh. plz... are you ok?" % self.human_user
def register(self, ignore_admin=False):
if not ignore_admin:
if not self.is_admin():
return
for blah in range(0, 2):
self.client.msg(
"NickServ",
"identify " +
data.username +
" " +
data.password)
self.client.msg("NickServ", "release " + data.nickname)
self.client.setNick(data.nickname)
def svineet(self):
if not self.is_admin():
return
for x in range(0, 5):
self.client.msg("#poxip", "@svineet, hi m8, how's your gf??")
self.client.msg(
"svineet",
"hi m8, how's your gf?? are you even alive?????")
def sayplz(self):
if not self.is_admin():
return False
finder = re.compile(ur'([\S*]+)')
xxxy = finder.findall(self.msg)
xxxy[0] = None
xxxy[1] = None
channel = xxxy[2]
message = " ".join(xxxy[3:])
self.client.msg(channel, message)
def _time(self):
finder = re.compile(ur'([\S*]+)')
addresses = finder.findall(self.msg)
if not self.msg.startswith(".time"):
return None
if not addresses[0] == ".time":
return None
addresses[0] = ""
cmd = " ".join(addresses)[1:]
return geonames_api.get_date_time(cmd)
def _city(self):
finder = re.compile(ur'([\S*]+)')
addresses = finder.findall(self.msg)
if not self.msg.startswith(".city"):
return None
if not addresses[0] == ".city":
return None
addresses[0] = ""
cmd = " ".join(addresses)[1:]
return geonames_api.city(cmd)
def uptime(self):
host = subprocess.check_output("hostname").replace("\n", " ")
up = subprocess.check_output("uptime").replace("\n", " ")
self.client.msg(self.channel, "%s %s" % (host, up))
def df(self):
df = subprocess.check_output(["df", "-h", "-x", "tmpfs"])
self.client.msg(self.channel, df)
def run(self):
if "@fedora/sugar/ignacio" in self.user or self.client.nickname not in self.human_user:
return
command = self.msg[len(self.client.nickname) +
len(", run "):].split(" ")
try:
xx = subprocess.check_output(command)
self.client.msg(self.channel, xx.replace("\n", "⏎ "))
except Exception as error:
self.client.msg(self.channel, str(error))