· 6 years ago · Apr 02, 2020, 10:14 AM
1# -*- coding: utf-8 -*-
2""" Tinybot by Nortxort (https://github.com/nortxort/tinybot-rtc) """
3
4import logging
5import threading
6import random
7import pinylib
8import urllib, json
9import requests
10
11from util import tracklist
12from page import privacy
13from apis import youtube, lastfm, other, locals_
14import check_user
15import time
16
17
18
19__version__ = '2.0.3'
20log = logging.getLogger(__name__)
21
22
23class TinychatBot(pinylib.TinychatRTCClient):
24 privacy_ = None
25 timer_thread = None
26 playlist = tracklist.PlayList()
27 search_list = []
28 is_search_list_yt_playlist = False
29 bl_search_list = []
30
31 @property
32 def config_path(self):
33 """ Returns the path to the rooms configuration directory. """
34 return pinylib.CONFIG.CONFIG_PATH + self.room_name + '/'
35
36 def user_check(self, user, account=False, guest=False, nick=False, lurker=False):
37 """
38 A wrapper for the CheckUser class.
39
40 :return: True, if the user was banned.
41 :rtype: bool
42 """
43 if not self.is_client_mod:
44 return False
45
46 judge = check_user.CheckUser(self, user, pinylib.CONFIG)
47
48 if account and user.account != '':
49 log.debug('checking account: %s' % user.account)
50 if not user.is_mod and judge.check_account():
51 return True
52
53 api = pinylib.apis.tinychat.user_info(user.account)
54 if api is not None:
55 user.tinychat_id = api['tinychat_id']
56 user.last_login = api['last_active']
57
58 if guest:
59 log.debug('checking guest entrance: %s' % user.nick)
60 if judge.guest_entry():
61 return True
62
63 if nick and user.nick:
64 log.debug('checking nick: %s' % user.nick)
65 if not user.is_mod and judge.check_nick():
66 return True
67
68 if lurker and user.is_lurker:
69 log.debug('check lurker: %s' % user.nick)
70 if judge.check_lurker():
71 return True
72
73 return False
74#### 1l1l1l1l1l1l1l1l1l1l1l1l1l1l1l1l
75 def on_joined(self, client_info):
76 """
77 Received when the client have joined the room successfully.
78
79 :param client_info: This contains info about the client, such as user role and so on.
80 :type client_info: dict
81 """
82 log.info('client info: %s' % client_info)
83 self.client_id = client_info['handle']
84 self.is_client_mod = client_info['mod']
85 self.is_client_owner = client_info['owner']
86 client = self.users.add(client_info)
87 client.user_level = 0
88 self.console_write(pinylib.COLOR['bright_green'], 'Client joined the room: %s:%s' % (client.nick, client.id))
89
90 # do special operations.
91 threading.Thread(target=self.options).start()
92 #threading.Thread(target=self.clock).start()
93 self.send_chat_msg('Jura is Online! -- VIP Status: %s' % pinylib.CONFIG.B_vip)
94
95
96 test = None
97 def on_join(self, join_info):
98 """
99 Received when a user joins the room.
100
101 :param join_info: This contains user information such as role, account and so on.
102 :type join_info: dict
103 """
104 log.info('user join info: %s' % join_info)
105 _user = self.users.add(join_info)
106
107 adminlist = open(self.config_path + pinylib.CONFIG.B_Admins).read().splitlines()
108 #known =
109 knownlist = open(self.config_path + pinylib.CONFIG.B_known).read().splitlines()
110 #if self.active_user.account not in knownlist:
111 #self.do_ban(self.active_user.nick)
112 #self.send_chat_msg("Guest - %s not allowed." % self.active_user.account)
113 if not _user.account in knownlist:
114 #self.send_chat_msg('%s not known.' % _user.account )
115 print('========== %s not known.' % _user.account)
116
117 if pinylib.CONFIG.B_CheckUser:
118 self.send_chat_msg('%s not VIP - use !knownadd %s' % (_user.nick, _user.account))
119
120 if pinylib.CONFIG.B_vip:
121 #self.do_bad_nick(self.active_user.nick)
122 self.do_kick(_user.nick)
123 self.send_chat_msg('VIP to %s Denied - use !knownadd %s' % (_user.nick, _user.account))
124 print('========== VIP Denied - %s' % _user.account)
125
126 # If account is in known.txt print, sending to chat will get kicked for spam.
127 if _user.account in knownlist:
128 #self.send_chat_msg('%s is known.' % _user.account )
129 print('========== %s is known.' % _user.account)
130
131 # If a nickname starts with guest- such as guest-0001
132 if _user.nick.startswith('guest-'):
133 #self.send_chat_msg("guest")
134 self.do_ban(self.active_user.nick)
135 #self.send_chat_msg("Guest names not allowed.")
136
137
138 if _user.account:
139
140
141
142 if _user.is_owner or _user.account in adminlist:
143 _user.user_level = 1
144 self.console_write(pinylib.COLOR['red'], 'Room Owner %s:%d:%s' % (_user.nick, _user.id, _user.account))
145 if not _user.account in knownlist:
146
147 pinylib.file_handler.file_writer(self.config_path, pinylib.CONFIG.B_known, _user.account)
148 self.send_chat_msg('Admin saved to whitelist: %s' % _user.account)
149 #self.send_chat_msg('Room Owner %s has joined.' % _user.nick)
150
151 elif _user.is_mod:
152
153 _user.user_level = 3
154 self.console_write(pinylib.COLOR['bright_red'], 'Moderator %s:%d:%s' % (_user.nick, _user.id, _user.account))
155 if not _user.account in knownlist:
156
157 pinylib.file_handler.file_writer(self.config_path, pinylib.CONFIG.B_known, _user.account)
158 self.send_chat_msg('Mod saved to whitelist: %s' % _user.account)
159
160
161 else:
162 self.console_write(pinylib.COLOR['bright_yellow'], '%s:%d has account: %s' % (_user.nick, _user.id, _user.account))
163
164
165
166 if not self.user_check(_user, account=True, guest=True, nick=True, lurker=True):
167
168
169 if pinylib.CONFIG.B_GREET and self.is_client_mod:
170
171 if not _user.nick.startswith('guest-'):
172
173 if _user.account:
174
175 self.send_chat_msg('Welcome ' + _user.nick)
176 else:
177 #self.do_ban(_user.nick)
178 #self.send_chat_msg(heart + 'Welcome to the room %s:%s' % (_user.nick, _user.id))
179 self.send_chat_msg('Welcome ' + _user.nick)
180 self.console_write(pinylib.COLOR['cyan'], '%s:%d joined the room.' % (_user.nick, _user.id))
181
182 def on_nick(self, uid, nick):
183 """
184 Received when a user changes nick name.
185
186 :param uid: The ID (handle) of the user.
187 :type uid: int
188 :param nick: The new nick name.
189 :type nick: str
190 """
191 _user = self.users.search(uid)
192 old_nick = _user.nick
193 _user.nick = nick
194
195
196 if uid != self.client_id:
197 if not self.user_check(_user, nick=True):
198 if pinylib.CONFIG.B_GREET and self.is_client_mod:
199 if old_nick.startswith('guest-'):
200 if _user.account:
201 self.send_chat_msg('Welcome to the room %s:%s:%s' %
202 (_user.nick, _user.id, _user.account))
203 else:
204 self.send_chat_msg('Welcome to the room %s:%s' % (_user.nick, _user.id))
205
206 self.console_write(pinylib.COLOR['bright_cyan'], '%s:%s Changed nick to: %s' % (old_nick, uid, nick))
207
208 def on_yut_play(self, yt_data):
209 """
210 Received when a youtube gets started or time searched.
211
212 This also gets received when the client starts a youtube, the information is
213 however ignored in that case.
214
215 :param yt_data: The event information contains info such as the ID (handle) of the user
216 starting/searching the youtube, the youtube ID, youtube time and so on.
217 :type yt_data: dict
218 """
219 if self.playlist.has_active_track:
220 self.cancel_timer()
221
222 track = youtube.video_details(yt_data['item']['id'], False)
223
224 if 'handle' in yt_data:
225 if yt_data['handle'] != self.client_id:
226 _user = self.users.search(yt_data['handle'])
227
228 if yt_data['item']['offset'] == 0:
229 self.playlist.start(_user.nick, track)
230 self.timer(track.time)
231 self.console_write(pinylib.COLOR['bright_magenta'], '%s started youtube video (%s)' %
232 (_user.nick, track.title))
233
234 elif yt_data['item']['offset'] > 0:
235 offset = self.playlist.play(yt_data['item']['offset'])
236 self.timer(offset)
237 self.console_write(pinylib.COLOR['bright_magenta'], '%s searched the youtube video to: %s' %
238 (_user.nick, int(round(yt_data['item']['offset']))))
239 else:
240 if yt_data['item']['offset'] > 0:
241 self.playlist.start('started before joining.', track)
242 offset = self.playlist.play(yt_data['item']['offset'])
243 self.timer(offset)
244
245 def on_yut_pause(self, yt_data):
246 """
247 Received when a youtube gets paused or searched while paused.
248
249 This also gets received when the client pauses or searches while paused, the information is
250 however ignored in that case.
251
252 :param yt_data: The event information contains info such as the ID (handle) of the user
253 pausing/searching the youtube, the youtube ID, youtube time and so on.
254 :type yt_data: dict
255 """
256 if self.playlist.has_active_track:
257 self.cancel_timer()
258
259 self.playlist.pause()
260
261 if 'handle' in yt_data:
262 if yt_data['handle'] != self.client_id:
263 _user = self.users.search(yt_data['handle'])
264 self.console_write(pinylib.COLOR['bright_magenta'], '%s paused the video at %s' %
265 (_user.nick, int(round(yt_data['item']['offset']))))
266 else:
267 log.info('no handle for youtube pause: %s' % yt_data)
268
269
270 def message_handler(self, msg):
271 """
272 A basic handler for chat messages.
273
274 Overrides message_handler in pinylib
275 to allow commands.enied.')"""
276 #msg = (msg)
277 prefix = pinylib.CONFIG.B_PREFIX
278
279
280
281
282
283
284 #d3m = unicode('Ḑ̴̛̖͔͚̞̯̝͊͒̊̐̒͂̍͌̊̿̔3̴̡͎̲̣̪͕̰͖͍̻̦̥̝̭͆̐̀͑̈́̐̅́̔̅͜M̴̡̼̗̰͊̈͐̚͠ ? 卐 ̶̨̟̦̪̲͌̐̏̑͌́̽̿̍̔͊̕̕͜͜Ḋ̶̡̛̦͉̐͌̊̓̓̈́͂̋̈́̔͘͘͝3̶̧̡͕̮͔̦̀̍̐̑̿͝M̴̞̲͈͙̞̫̀̊̈̄̔̅̅̈́̒͝ͅ? 卐 ̴͇̟͖̓̋͑̌̇͑̿͗̕͝͝D̶̼̙̈́̎̇̊̒̚͝͝3̷̨̨̘̬̯̦̥̮̳̞́̐̌̌̋̊̍M̷̨̤̊̔̽͊͐̉̍̓̈́̋̄̓̑̈́͘͜? 卐 ̷̛̻͕̼̟͉̭̋̒͗͝D̶͈̟̣̼͔̟̤̏͗̚͠ͅ3̴̛̙̠͖̾̃̈́̏̊̅͠M̶͉͎͕͓̗̂͆̓̊͊͑̏̓͐͋̄͘͝? 卐 ̴̢̧̛͎͔͉͚͔̯̿̒D̵̜͉̖͖̹͊͌̈͊̍̂̽̈̿̔̄͂͂͝3̴̧̭̳̤̗̞̺͆͆̒͠M̷̛͖͇̹͙̰̬̟̬͗̑̀̿̄͒̓̕͠ ̵͙́̇̇̍̌̓́͐̃̋͠͠? 卐D̴͉̺͋̑͑̄͊͜3̸̨̞͔̻̞͑M̷̛̛̝͗͑̿̈̏̀͆̿̆́͗̋̈́? 卐 ̴̡̜̭̦̟̜̗͎̬̞̝̖͎̬̀͗̓͌͌̾̂̈͝Ḑ̶͎̦̖͙̠̩̎̀̓̒͛ͅ3̸̞͍̘̫̮͙͚̘̿̊̀̂͒̓̄̎͝ͅM̵̢̢̟̮͓̹̦̥̗̈́̌͊̑̈́̀̋̈́͗̑̐̓̕̚̚ ? 卐', 'utf-8')
285
286 # Only check chat msg for ban string if we are mod.
287 if self.is_client_mod and self.active_user.user_level > 4:
288 threading.Thread(target=self.check_msg, args=(msg,)).start()
289
290
291
292 #░
293
294 if "\n" in msg:
295 self.do_ban(self.active_user.nick)
296 #self.do_bad_nick(self.active_user.nick)
297 if len(msg) > 250:
298 self.do_ban(self.active_user.nick)
299 #self.do_bad_nick(self.active_user.nick)
300 self.send_chat_msg("Spam Detected (%s)!" % len(msg))
301
302
303 #if msg.startswith(unicode('⭕', 'utf-8')):
304 #self.do_ban(self.active_user.nick)
305 if msg.startswith(prefix):
306
307 parts = msg.split(' ')
308 cmd = parts[0].lower().strip()
309 cmd_arg = ' '.join(parts[1:]).strip()
310
311
312 #admin/botowner
313 if self.has_level(1):
314 if self.is_client_owner:
315
316
317
318 if cmd == prefix + 'mod':
319 threading.Thread(target=self.do_make_mod, args=(cmd_arg,)).start()
320
321
322
323 elif cmd == prefix + 'rmod':
324 threading.Thread(target=self.do_remove_mod, args=(cmd_arg,)).start()
325
326 elif cmd == prefix + 'dir':
327 threading.Thread(target=self.do_directory).start()
328
329 elif cmd == prefix + 'p2t':
330 threading.Thread(target=self.do_push2talk).start()
331
332 elif cmd == prefix + 'crb':
333 threading.Thread(target=self.do_clear_room_bans).start()
334
335 if cmd == prefix + 'kill':
336 self.do_kill()
337
338 elif cmd == prefix + 'reboot':
339 self.do_reboot()
340
341 #admin
342 if self.has_level(2):
343 if cmd == prefix + 'mi':
344 self.do_media_info()
345
346
347 elif cmd == prefix + 'spam':
348 #self.send_chat_msg(tt)
349 self.do_spam()
350
351 # elif cmd == prefix + "vip":
352
353 #self.do_vip()
354
355 elif cmd == prefix + 'crb':
356 threading.Thread(target=self.do_clear_room_bans).start()
357
358 elif cmd == prefix + 'noguest':
359 self.do_guests()
360
361 elif cmd == prefix + 'lurkers':
362 self.do_lurkers()
363
364 elif cmd == prefix + 'guestnick':
365 self.do_guest_nicks()
366
367 elif cmd == prefix + 'greet':
368 self.do_greet()
369
370 elif cmd == prefix + 'kab':
371 self.do_kick_as_ban()
372
373 elif cmd == prefix + 'rs':
374 self.do_room_settings()
375
376 elif cmd == prefix + 'v':
377 self.do_version()
378
379 elif cmd == prefix + 't':
380 self.do_uptime()
381
382 elif cmd == prefix + 'nick':
383 self.do_nick(cmd_arg)
384
385 #botmods
386 if self.has_level(3):
387
388 if cmd == prefix + 'op':
389 self.do_op_user(cmd_arg)
390
391 elif cmd == prefix + 'nick':
392 self.do_nick(cmd_arg)
393
394 elif cmd == prefix + 'knownadd':
395 pinylib.file_handler.file_writer(self.config_path, pinylib.CONFIG.B_known, cmd_arg)
396 self.send_chat_msg('Saved to whitelist: %s' % cmd_arg)
397
398 elif cmd == prefix + 'knownremove':
399
400 pinylib.file_handler.remove_from_file(self.config_path, pinylib.CONFIG.B_known, cmd_arg)
401 self.send_chat_msg('Removed from whitelist: %s' % cmd_arg)
402
403 elif cmd == prefix + "vip":
404
405 self.do_vip()
406
407 elif cmd == prefix + "checkuser":
408
409 self.do_vipcheck()
410 #elif cmd == prefix + 'd3m':
411
412 #self.send_chat_msg(d3m)
413
414 elif cmd == prefix + 'deop':
415 self.do_deop_user(cmd_arg)
416
417 elif cmd == prefix + 'pub':
418 self.do_public_cmds()
419
420 elif cmd == prefix + 'kick':
421 threading.Thread(target=self.do_kick, args=(cmd_arg,)).start()
422
423 elif cmd == prefix + 'ban':
424 threading.Thread(target=self.do_ban, args=(cmd_arg,)).start()
425
426 elif cmd == prefix + 'bn':
427 self.do_bad_nick(cmd_arg)
428
429 elif cmd == prefix + 'rmbn':
430 self.do_remove_bad_nick(cmd_arg)
431
432 elif cmd == prefix + 'bs':
433 self.do_bad_string(cmd_arg)
434
435 elif cmd == prefix + 'rmbs':
436 self.do_remove_bad_string(cmd_arg)
437
438 elif cmd == prefix + 'ba':
439 self.do_bad_account(cmd_arg)
440
441 elif cmd == prefix + 'rmba':
442 self.do_remove_bad_account(cmd_arg)
443
444 elif cmd == prefix + 't':
445 self.do_uptime()
446
447 elif cmd == prefix + 'list':
448 #self.do_list_info(cmd_arg)
449 self.send_chat_msg('Joke API Disabled.')
450
451 elif cmd == prefix + 'uinfo':
452 self.do_user_info(cmd_arg)
453
454 elif cmd == prefix + 'cam':
455 self.do_cam_approve(cmd_arg)
456
457 elif cmd == prefix + 'close':
458 self.do_close_broadcast(cmd_arg)
459
460 elif cmd == prefix + 'sbl':
461 self.do_banlist_search(cmd_arg)
462
463 elif cmd == prefix + 'fg':
464 self.do_forgive(cmd_arg)
465
466 elif cmd == prefix + 'unban':
467 self.do_unban(cmd_arg)
468
469 elif cmd == prefix + 'movie':
470 #self.do_Movie(cmd_arg)
471 threading.Thread(target=self.do_Movie, args=(cmd_arg,)).start()
472 elif cmd == prefix + 'clear':
473 self.do_clear()
474
475 elif cmd == prefix + "whiteknight":
476 self.send_chat_msg('White Knight has been awarded to %s' % cmd_arg)
477
478
479 #Moderators
480 if self.has_level(4):
481
482 if cmd == prefix + 'help':
483 self.do_help()
484
485 elif cmd == prefix + 'top':
486 threading.Thread(target=self.do_lastfm_chart, args=(cmd_arg,)).start()
487
488 elif cmd == prefix + 'ran':
489 threading.Thread(target=self.do_lastfm_random_tunes, args=(cmd_arg,)).start()
490
491 elif cmd == prefix + 'tag':
492 threading.Thread(target=self.do_search_lastfm_by_tag, args=(cmd_arg,)).start()
493
494 elif cmd == prefix + 'pls':
495 threading.Thread(target=self.do_youtube_playlist_search, args=(cmd_arg,)).start()
496
497 elif cmd == prefix + 'plp':
498 threading.Thread(target=self.do_play_youtube_playlist, args=(cmd_arg,)).start()
499
500 elif cmd == prefix + 'ssl':
501 self.do_show_search_list()
502
503 elif cmd == prefix + 'del':
504 self.do_delete_playlist_item(cmd_arg)
505
506 elif cmd == prefix + 'rpl':
507 self.do_media_replay()
508
509 elif cmd == prefix + 'mbpl':
510 self.do_play_media()
511
512 elif cmd == prefix + 'mbpa':
513 self.do_media_pause()
514
515 elif cmd == prefix + 'seek':
516 self.do_seek_media(cmd_arg)
517
518 elif cmd == prefix + 'cm':
519 self.do_close_media()
520
521 elif cmd == prefix + 'cpl':
522 self.do_clear_playlist()
523
524 elif cmd == prefix + 'spl':
525 self.do_playlist_info()
526
527 elif cmd == prefix + 'yts':
528 threading.Thread(target=self.do_youtube_search, args=(cmd_arg,)).start()
529
530 elif cmd == prefix + 'pyts':
531 self.do_play_youtube_search(cmd_arg)
532
533 elif cmd == prefix + 'jeopardy':
534 threading.Thread(target=self.jeo).start()
535
536 elif cmd == prefix + 'word':
537 threading.Thread(target=self.GetScramble).start()
538
539 elif cmd == prefix + 'pedo':
540 threading.Thread(target=self.GetPedo).start()
541
542 elif cmd == prefix + 'hyde':
543 self.do_Hyde()
544
545 elif cmd == prefix + 'commands':
546 threading.Thread(target=self.do_commands).start()
547
548 elif cmd == prefix + 'ytadd':
549
550 pinylib.file_handler.file_writer(self.config_path, pinylib.CONFIG.B_Youtube_Play_List, cmd_arg)
551 self.send_chat_msg('Saved to Youtube Log: %s' % cmd_arg)
552
553 elif cmd == prefix + 'ytban' :
554
555 pinylib.file_handler.file_writer(self.config_path, pinylib.CONFIG.B_Youtube_Ban_List, cmd_arg)
556 self.send_chat_msg('Saved to Youtube Filter: %s' % cmd_arg)
557
558
559 elif cmd == prefix + 'ytunban':
560
561 pinylib.file_handler.remove_from_file(self.config_path, pinylib.CONFIG.B_Youtube_Ban_List, cmd_arg)
562 self.send_chat_msg('Removed from Youtube Filter: %s' % cmd_arg)
563
564 elif cmd == prefix + 'ytremove':
565
566 pinylib.file_handler.remove_from_file(self.config_path, pinylib.CONFIG.B_Youtube_Play_List, cmd_arg)
567 self.send_chat_msg('Removed from Youtube Log: %s' % cmd_arg)
568
569 elif cmd == prefix + 'ytlog':
570 lines = open(self.config_path + pinylib.CONFIG.B_Youtube_Play_List).read().splitlines()
571 myline =random.choice(lines)
572 #self.send_chat_msg(myline)
573
574 results = myline
575 threading.Thread(target=self.do_play_youtube, args=(results,)).start()
576 self.send_chat_msg("Random Song: %s" % results)
577
578
579 ytbanlist = open(self.config_path + pinylib.CONFIG.B_Youtube_Ban_List).read().splitlines()
580 if (pinylib.CONFIG.B_PUBLIC_CMD and self.has_level(5)) or self.active_user.user_level < 5:
581
582 # Tinychat API commands.
583 if cmd == prefix + 'acspy':
584 threading.Thread(target=self.do_account_spy, args=(cmd_arg,)).start()
585
586 # Other API commands.
587 elif cmd == prefix + 'urb':
588 threading.Thread(target=self.do_search_urban_dictionary, args=(cmd_arg,)).start()
589
590 elif cmd == prefix + 'wea':
591 threading.Thread(target=self.do_weather_search, args=(cmd_arg,)).start()
592
593 elif cmd == prefix + 'ip':
594 threading.Thread(target=self.do_whois_ip, args=(cmd_arg,)).start()
595
596 # Just for fun.
597 elif cmd == prefix + 'cn':
598 threading.Thread(target=self.do_chuck_noris).start()
599
600 # Just for fun.
601 elif cmd == prefix + 'check':
602 threading.Thread(target=self.do_check).start()
603
604
605
606 elif cmd == prefix + '8ball':
607 self.do_8ball(cmd_arg)
608
609 elif cmd == prefix + 'scope':
610 self.do_scope(cmd_arg)
611
612 elif cmd == prefix + 'fact':
613 self.do_fact()
614
615 elif cmd == prefix + 'joke':
616 #self.do_joke()
617 self.send_chat_msg('Joke API Disabled.')
618
619 elif cmd == prefix + 'mood':
620 self.do_mood()
621
622 elif cmd == prefix + 'roll':
623 self.do_dice()
624
625 elif cmd == prefix + "cookie":
626 self.do_fortune()
627
628 elif cmd == prefix + "ltc":
629 self.do_ltc()
630
631 elif cmd == prefix + "btc":
632 self.do_bitcoin()
633
634 elif cmd == prefix + "xmr":
635 self.do_xmr()
636
637 elif cmd == prefix + "eth":
638 self.do_eth()
639
640 elif cmd == prefix + "sia":
641 self.do_sia()
642
643 elif cmd == prefix + "gank":
644 self.do_gank()
645
646 elif cmd == prefix + "pot":
647 self.do_pot()
648
649 elif cmd == prefix + "jokes":
650 self.do_joke()
651
652 elif cmd == prefix + "line":
653 self.do_line()
654
655 elif cmd == prefix + "advice":
656 self.do_Advice()
657
658 elif cmd == prefix + "mom":
659 self.do_mom()
660
661 elif cmd == prefix + "trump":
662 self.do_Trump()
663
664 elif cmd == prefix + "geek":
665 self.do_Geek()
666
667
668 elif cmd == prefix + "tokes":
669 threading.Thread(target=self.toketimer).start()
670
671 #Bender · Isolate
672 elif cmd == prefix + 'yt':
673
674 threading.Thread(target=self.do_play_youtube, args=(cmd_arg,)).start()
675
676 elif cmd == prefix + 'rules':
677
678 self.send_chat_msg("https://pastebin.com/UPFcaqck")
679
680 elif cmd == prefix + 'q':
681 self.do_playlist_status()
682
683 elif cmd == prefix + 'n':
684 self.do_next_tune_in_playlist()
685
686 elif cmd == prefix + 'np':
687 self.do_now_playing()
688
689 elif cmd == prefix + 'wp':
690 self.do_who_plays()
691
692 elif cmd == prefix + 'skip':
693 self.do_skip()
694
695 #if cmd == prefix + 'msgme':
696 #self.do_pmme()
697
698 # Print command to console.
699 self.console_write(pinylib.COLOR['yellow'], self.active_user.nick + ': ' + cmd + ' ' + cmd_arg)
700 else:
701 # Print chat message to console.
702 self.console_write(pinylib.COLOR['green'], self.active_user.nick + ': ' + msg)
703
704
705 self.active_user.last_msg = msg
706
707
708 def do_vip(self):
709 """ Toggles if public commands are public or not. """
710 pinylib.CONFIG.B_vip = not pinylib.CONFIG.B_vip
711 self.send_chat_msg('VIP Enabled: %s' % pinylib.CONFIG.B_vip)
712
713 def do_vipcheck(self):
714 """ Toggles if public commands are public or not. """
715 pinylib.CONFIG.B_CheckUser = not pinylib.CONFIG.B_CheckUser
716 self.send_chat_msg('VIP Check Enabled: %s' % pinylib.CONFIG.B_vip)
717
718 def toketimer(self):
719
720 self.send_chat_msg('Tokes for 3 mins.')
721 time.sleep(1 * 60)
722 self.send_chat_msg('Tokes for 2 mins.')
723 time.sleep(1 * 60)
724 self.send_chat_msg('Tokes for 1 mins.')
725 time.sleep(1 * 60)
726 self.send_chat_msg('Tokes completed.')
727
728
729 def jeo(self):
730 url = "http://jservice.io/api/random"
731 out = requests.get(url).text
732 resp_dict = json.loads(out)
733 question = resp_dict[0]['question']
734 answer = resp_dict[0]['answer']
735
736
737 self.send_chat_msg('Jeopoardy Question: \n"' + question + '."')
738
739 time.sleep(20)
740 self.send_chat_msg('Jeopardy Answer (what/who is/are):\n "' + answer + '."')
741
742 def GetScramble(self):
743
744 words = ["arugola",
745 "assenters",
746 "atlee",
747 "balatas",
748 "basophilic",
749 "bastinading",
750 "begotten",
751 "blameful",
752 "bloodthirstiest",
753 "bribeworthy",
754 "burnoose",
755 "calcaneonavicular",
756 "cautionry",
757 "cesure",
758 "chimed",
759 "classes",
760 "commemorating",
761 "cuchia",
762 "decemviral",
763 "decrepitness",
764 "deloul",
765 "doweled",
766 "emeute",
767 "excipule",
768 "fractionizing",
769 "galvanoplastically",
770 "ganglionated",
771 "gastrothecal",
772 "gestalter",
773 "gonidiferous",
774 "gusle",
775 "hairweaver",
776 "hajji",
777 "handmaid",
778 "helminthosporium",
779 "homecrofting",
780 "immeasurably",
781 "impregnant",
782 "impunible",
783 "infusedly",
784 "initialed",
785 "kahar",
786 "kokum",
787 "lactify",
788 "lifen",
789 "localistic",
790 "manchild",
791 "marrowed",
792 "mennuet",
793 "metachromatism",
794 "mezuzah",
795 "mishmi",
796 "mothball",
797 "nonaudibility",
798 "nonemendation",
799 "nonmilitarily",
800 "oecist",
801 "olfactories",
802 "oppugner",
803 "outpoll",
804 "overfertility",
805 "participatively",
806 "pastils",
807 "petrol",
808 "polydomous",
809 "polygalaceous",
810 "porocephalus",
811 "prissiest",
812 "prodigy",
813 "prussianization",
814 "quantitied",
815 "rancheros",
816 "reargues",
817 "reliability",
818 "renopulmonary",
819 "shakiest",
820 "showerier",
821 "sinuous",
822 "speckled",
823 "speedaway",
824 "strawflower",
825 "subcontraoctave",
826 "sula",
827 "swims",
828 "tenfoldness",
829 "tetraketone",
830 "thoracoacromial",
831 "tidecoach",
832 "toxicology",
833 "trespassory",
834 "trochoids",
835 "turkology",
836 "unalerted",
837 "unbarren",
838 "unbutchered",
839 "unexpiring",
840 "unmangled",
841 "unspiritedly",
842 "unteeming",
843 "vaccinee"]
844
845 word = random.choice(words)
846
847
848 self.send_chat_msg('Scrambled Word: \n"' + ''.join(random.sample(word, len(word))))
849 time.sleep(20)
850 self.send_chat_msg('Scrambled Word Answer:\n "' + word + '."')
851
852
853 def do_pedo(self, user_name):
854 """
855 Pedo alert and kick by MeKLiN
856
857 :param user_name: The username to kick.
858 :type user_name: str
859 """
860
861 words = ["arugola",
862 "Gᴀʏ Pᴇᴅᴏᴘʜɪʟᴇ Aʟᴇʀᴛ!",
863 "Gaͣy Рⷬeͤdͩoͦрⷬhͪiͥleͤ Aͣleͤrͬᴛⷮ!",
864 "ᴳᵃʸ ᴾᵉᵈᵒᵖʰⁱˡᵉ ᴬˡᵉʳᵗ!",
865 "??? ℙ???????? ?????❕",
866 "¡ʇɹǝʅ∀ ǝʅᴉɥdopǝԀ ʎɐ⅁",
867 "G̶a̶y̶ P̶e̶d̶o̶p̶h̶i̶l̶e̶ A̶l̶e̶r̶t̶!̶",
868 "G͓͚̦a̫̪y̻̼͓ P̻͚͔e̠̺͕d͓̻̝o͕̘p͍̼h͔̦͍i̙̼̦l̫̟͜e͔̫ A̡̼̦l̝͖̟e͕̘̪r̝̪t̠̫̺!̡͉͔",
869 "G̔͛̚a̓̽͌ỳ̈́͠ P̒͋̚e͋̒̈́d͒͝͠o͑͑͠p͛̾̓h͑̈́͝ḯ͐̕l̀͌̓e͆̐ A͑͑͑l͑͝e̔͑̐r̐͐̓t̀̾͠!͛̾̈́",
870 "G̴͕͓͖͒͒̈́a̴̢̻͍̐̒y̵̫͉͙͊̒͝ P̵͇͇͎̽̔́e̸͇̘̺̽͠͠d̴̢̠̼̓͊͌o̴͖̟̓̈́͠p̵̢͇͖͒̐͌h̸̡͖͔͘̚͠i̴̡͕͉͋̕l̵͙̺̈́̓̚e̵͎̙͆̓́ A̴̡͉͑̀̓l̴̢͖̠͋̔͑e̵̘̙̘̽̚͝r̵͚͙͚͆͝͠t̵̘͔͖͌̈́̓!̵͙͇̻͊͛̒",
871 "G̷a̷y̷ P̷e̷d̷o̷p̷h̷i̷l̷e̷ A̷l̷e̷r̷t̷!̷",
872 "??? ?????ℎ??? ?????!",
873 "??? ????????? ????�",
874 "??? ????????? ????�",
875 "??? ????????? ????�",
876 "??? ????????? ????�",
877 "??? ????????? ?????!",
878 "??? ????????? ?????!",
879 "??? ????????? ?????❗",
880 "??? ?ℯ?ℴ????ℯ ??ℯ??!",
881 "??? ????????? ?????❗",
882 "?ⲁⲩ Ⲣⲉⲇⲟⲣⲏⲓ?ⲉ Ⲁ?ⲉꞅⲧ!",
883 "Gay Pedophile Alert",
884 "Ꮆ闩丫 尸?ᗪㄖ尸卄讠㇄? 闩㇄?尺セ!",
885 "Gαყ ᑭҽԃσρԋιɬҽ ?ɬҽɾ?!",
886 "ᎶᎯႸ ᖘ∈ᖙ?ᕈᖺ⫯?∈ ᗩ?∈ᖇ?❗",
887 "Gₐy ₚₑdₒₚₕᵢₗₑ ₐₗₑᵣₜ!",
888 "??? ????????? ?????!",
889 "??? ????????? ?????!",
890 "G̲a̲y̲ P̲e̲d̲o̲p̲h̲i̲l̲e̲ A̲l̲e̲r̲t̲!̲+ l̲i̲n̲e̲",
891 "G̳a̳y̳ P̳e̳d̳o̳p̳h̳i̳l̳e̳ A̳l̳e̳r̳t̳!̳+",
892 "G⃨a⃨y⃨ P⃨e⃨d⃨o⃨p⃨h⃨i⃨l⃨e⃨ A⃨l⃨e⃨r⃨t⃨!⃨+",
893 "G̅a̅y̅ P̅e̅d̅o̅p̅h̅i̅l̅e̅ A̅l̅e̅r̅t̅!̅",]
894
895 word = random.choice(words)
896
897
898 self.send_chat_msg('??? ????????? ?????????: %s' % cmd_arg)
899 time.sleep(20)
900
901 if self.is_client_mod:
902 if len(user_name) is 0:
903 self.send_chat_msg('Missing pedos name.')
904 elif user_name == self.nickname:
905 self.send_chat_msg('Action not allowed.')
906 else:
907 if user_name.startswith('*'):
908 user_name = user_name.replace('*', '')
909 _users = self.users.search_containing(user_name)
910 if len(_users) > 0:
911 for i, user in enumerate(_users):
912 if user.nick != self.nickname and user.user_level > self.active_user.user_level:
913 if i <= pinylib.CONFIG.B_MAX_MATCH_BANS - 1:
914 self.send_kick_msg(user.id)
915 else:
916 _user = self.users.search_by_nick(user_name)
917 if _user is None:
918 self.send_chat_msg('No user named: %s' % user_name)
919 elif _user.user_level < self.active_user.user_level:
920 self.send_chat_msg('Not allowed.')
921 else:
922 self.send_kick_msg(_user.id)
923 self.send_chat_msg('???? ????? ?????????!')
924
925 # Level 1 Command methods.
926 def do_make_mod(self, account):
927 """
928 Make a tinychat account a room moderator.
929
930 :param account: The account to make a moderator.
931 :type account: str
932 """
933 if self.is_client_owner:
934 if len(account) is 0:
935 self.send_chat_msg('Missing account name.')
936 else:
937 tc_user = self.privacy_.make_moderator(account)
938 if tc_user is None:
939 self.send_chat_msg('The account is invalid.')
940 elif not tc_user:
941 self.send_chat_msg('%s is already a moderator.' % account)
942 elif tc_user:
943 self.send_chat_msg('%s was made a room moderator.' % account)
944
945 def do_remove_mod(self, account):
946 """
947 Removes a tinychat account from the moderator list.
948
949 :param account: The account to remove from the moderator list.
950 :type account: str
951 """
952 if self.is_client_owner:
953 if len(account) is 0:
954 self.send_chat_msg('Missing account name.')
955 else:
956 tc_user = self.privacy_.remove_moderator(account)
957 if tc_user:
958 self.send_chat_msg('%s is no longer a room moderator.' % account)
959 elif not tc_user:
960 self.send_chat_msg('%s is not a room moderator.' % account)
961
962 def do_directory(self):
963 """ Toggles if the room should be shown on the directory. """
964 if self.is_client_owner:
965 if self.privacy_.show_on_directory():
966 self.send_chat_msg('Room IS shown on the directory.')
967 else:
968 self.send_chat_msg('Room is NOT shown on the directory.')
969
970 def do_push2talk(self):
971 """ Toggles if the room should be in push2talk mode. """
972 if self.is_client_owner:
973 if self.privacy_.set_push2talk():
974 self.send_chat_msg('Push2Talk is enabled.')
975 else:
976 self.send_chat_msg('Push2Talk is disabled.')
977
978 def do_green_room(self):
979 """ Toggles if the room should be in greenroom mode. """
980 if self.is_client_owner:
981 if self.privacy_.set_greenroom():
982 self.send_chat_msg('Green room is enabled.')
983 else:
984 self.send_chat_msg('Green room is disabled.')
985
986 def do_clear_room_bans(self):
987 """ Clear all room bans. """
988 if self.is_client_owner:
989 if self.privacy_.clear_bans():
990 self.send_chat_msg('All room bans was cleared.')
991
992 def do_kill(self):
993 """ Kills the bot. """
994 self.disconnect()
995
996 def do_reboot(self):
997 """ Reboots the bot. """
998 self.reconnect()
999
1000 # Level 2 Command Methods.
1001 def do_media_info(self):
1002 """ Show information about the currently playing youtube. """
1003 if self.is_client_mod and self.playlist.has_active_track:
1004 self.send_chat_msg(
1005 'Playlist Tracks: ' + str(len(self.playlist.track_list)) + '\n' +
1006 'Track Title: ' + self.playlist.track.title + '\n' +
1007 'Track Index: ' + str(self.playlist.track_index) + '\n' +
1008 'Elapsed Track Time: ' + self.format_time(self.playlist.elapsed) + '\n' +
1009 'Remaining Track Time: ' + self.format_time(self.playlist.remaining)
1010 )
1011
1012 # Level 3 Command Methods.
1013 def do_op_user(self, user_name):
1014 """
1015 Lets the room owner, a mod or a bot controller make another user a bot controller.
1016
1017 :param user_name: The user to op.
1018 :type user_name: str
1019 """
1020 if self.is_client_mod:
1021 if len(user_name) is 0:
1022 self.send_chat_msg('Missing username.')
1023 else:
1024 _user = self.users.search_by_nick(user_name)
1025 if _user is not None:
1026 _user.user_level = 4
1027 self.send_chat_msg('%s is now a bot controller (L4)' % user_name)
1028 else:
1029 self.send_chat_msg('No user named: %s' % user_name)
1030
1031 def do_deop_user(self, user_name):
1032 """
1033 Lets the room owner, a mod or a bot controller remove a user from being a bot controller.
1034
1035 :param user_name: The user to deop.
1036 :type user_name: str
1037 """
1038 if self.is_client_mod:
1039 if len(user_name) is 0:
1040 self.send_chat_msg('Missing username.')
1041 else:
1042 _user = self.users.search_by_nick(user_name)
1043 if _user is not None:
1044 _user.user_level = 5
1045 self.send_chat_msg('%s is not a bot controller anymore (L5)' % user_name)
1046 else:
1047 self.send_chat_msg('No user named: %s' % user_name)
1048
1049 def do_guests(self):
1050 """ Toggles if guests are allowed to join the room or not. """
1051 pinylib.CONFIG.B_ALLOW_GUESTS = not pinylib.CONFIG.B_ALLOW_GUESTS
1052 self.send_chat_msg('Allow Guests: %s' % pinylib.CONFIG.B_ALLOW_GUESTS)
1053
1054
1055 def do_spam(self):
1056 """ Toggles if guests are allowed to join the room or not. """
1057 pinylib.config.B_AllowSpam = not pinylib.config.B_AllowSpam
1058 self.send_chat_msg('Allow Spam: %s' % pinylib.config.B_AllowSpam)
1059
1060 def do_lurkers(self):
1061 """ Toggles if lurkers are allowed or not. """
1062 pinylib.CONFIG.B_ALLOW_LURKERS = not pinylib.CONFIG.B_ALLOW_LURKERS
1063 self.send_chat_msg('Allowe Lurkers: %s' % pinylib.CONFIG.B_ALLOW_LURKERS)
1064
1065 def do_guest_nicks(self):
1066 """ Toggles if guest nicks are allowed or not. """
1067 pinylib.CONFIG.B_ALLOW_GUESTS_NICKS = not pinylib.CONFIG.B_ALLOW_GUESTS_NICKS
1068 self.send_chat_msg('Allow Guest Nicks: %s' % pinylib.CONFIG.B_ALLOW_GUESTS_NICKS)
1069
1070 def do_greet(self):
1071 """ Toggles if users should be greeted on entry. """
1072 pinylib.CONFIG.B_GREET = not pinylib.CONFIG.B_GREET
1073 self.send_chat_msg('Greet Users: %s' % pinylib.CONFIG.B_GREET)
1074
1075 def do_public_cmds(self):
1076 """ Toggles if public commands are public or not. """
1077 pinylib.CONFIG.B_PUBLIC_CMD = not pinylib.CONFIG.B_PUBLIC_CMD
1078 self.send_chat_msg('Public Commands Enabled: %s' % pinylib.CONFIG.B_PUBLIC_CMD)
1079
1080 def do_kick_as_ban(self):
1081 """ Toggles if kick should be used instead of ban for auto bans . """
1082 pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN = not pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN
1083 self.send_chat_msg('Use Kick As Auto Ban: %s' % pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN)
1084
1085 def do_room_settings(self):
1086 """ Shows current room settings. """
1087 if self.is_client_owner:
1088 settings = self.privacy_.current_settings()
1089 self.send_chat_msg(
1090 'Broadcast Password: ' + settings['broadcast_pass'] + '\n' +
1091 'Room Password: ' + settings['room_pass'] + '\n' +
1092 'Login Type: ' + settings['allow_guest'] + '\n' +
1093 'Directory: ' + settings['show_on_directory'] + '\n' +
1094 'Push2Talk: ' + settings['push2talk'] + '\n' +
1095 'Greenroom: ' + settings['greenroom']
1096 )
1097
1098 def do_lastfm_chart(self, chart_items):
1099 """
1100 Create a playlist from the most played tracks on last.fm.
1101
1102 :param chart_items: The maximum amount of chart items.
1103 :type chart_items: str | int
1104 """
1105 if self.is_client_mod:
1106 if len(chart_items) == 0 or chart_items is None:
1107 self.send_chat_msg('Please specify the max amount of tracks you want.')
1108 else:
1109 try:
1110 chart_items = int(chart_items)
1111 except ValueError:
1112 self.send_chat_msg('Only numbers allowed.')
1113 else:
1114 if 0 < chart_items < 30:
1115 self.send_chat_msg('Please wait while creating a playlist...')
1116 _items = lastfm.chart(chart_items)
1117 if _items is not None:
1118 self.playlist.add_list(self.active_user.nick, _items)
1119 self.send_chat_msg('Added ' + str(len(_items)) + ' tracks from last.fm chart.')
1120 if not self.playlist.has_active_track:
1121 track = self.playlist.next_track
1122 self.send_yut_play(track.id, track.time, track.title)
1123 self.timer(track.time)
1124 else:
1125 self.send_chat_msg('Failed to retrieve a result from last.fm.')
1126 else:
1127 self.send_chat_msg('No more than 30 tracks.')
1128
1129 def do_lastfm_random_tunes(self, max_tracks):
1130 """
1131 Creates a playlist from what other people are listening to on last.fm
1132
1133 :param max_tracks: The miximum amount of tracks.
1134 :type max_tracks: str | int
1135 """
1136 if self.is_client_mod:
1137 if len(max_tracks) == 0 or max_tracks is None:
1138 self.send_chat_msg('Please specify the max amount of tunes you want.')
1139 else:
1140 try:
1141 max_tracks = int(max_tracks)
1142 except ValueError:
1143 self.send_chat_msg('Only numbers allowed.')
1144 else:
1145 if 0 < max_tracks < 50:
1146 self.send_chat_msg('Please wait while creating playlist...')
1147 _items = lastfm.listening_now(max_tracks)
1148 if _items is not None:
1149 self.playlist.add_list(self.active_user.nick, _items)
1150 self.send_chat_msg('Added ' + str(len(_items)) + ' tracks from last.fm')
1151 if not self.playlist.has_active_track:
1152 track = self.playlist.next_track
1153 self.send_yut_play(track.id, track.time, track.title)
1154 self.timer(track.time)
1155 else:
1156 self.send_chat_msg('Failed to retrieve a result from last.fm.')
1157 else:
1158 self.send_chat_msg('No more than 50 tracks.')
1159
1160 def do_search_lastfm_by_tag(self, search_str):
1161 """
1162 Search last.fm for tunes matching a tag.
1163
1164 :param search_str: The search tag to search for.
1165 :type search_str: str
1166 """
1167 if self.is_client_mod:
1168 if len(search_str) == 0 or search_str is None:
1169 self.send_chat_msg('Missing search string.')
1170 else:
1171 self.send_chat_msg('Please wait while creating playlist..')
1172 _items = lastfm.tag_search(search_str)
1173 if _items is not None:
1174 self.playlist.add_list(self.active_user.nick, _items)
1175 self.send_chat_msg('Added ' + str(len(_items)) + ' tracks from last.fm')
1176 if not self.playlist.has_active_track:
1177 track = self.playlist.next_track
1178 self.send_yut_play(track.id, track.time, track.title)
1179 self.timer(track.time)
1180 else:
1181 self.send_chat_msg('Failed to retrieve a result from last.fm.')
1182
1183 def do_youtube_playlist_search(self, search_str):
1184 """
1185 Search youtube for a playlist.
1186
1187 :param search_str: The search term to search for.
1188 :type search_str: str
1189 """
1190 if self.is_client_mod:
1191 if len(search_str) == 0:
1192 self.send_chat_msg('Missing search string.')
1193 else:
1194 self.search_list = youtube.playlist_search(search_str)
1195 if len(self.search_list) > 0:
1196 self.is_search_list_yt_playlist = True
1197 _ = '\n'.join('(%s) %s' % (i, d['playlist_title']) for i, d in enumerate(self.search_list))
1198 self.send_chat_msg(_)
1199 else:
1200 self.send_chat_msg('Failed to find playlist matching search term: %s' % search_str)
1201
1202 def do_play_youtube_playlist(self, int_choice):
1203 """
1204 Play a previous searched playlist.
1205
1206 :param int_choice: The index of the playlist.
1207 :type int_choice: str | int
1208 """
1209 if self.is_client_mod:
1210 if self.is_search_list_yt_playlist:
1211 try:
1212 int_choice = int(int_choice)
1213 except ValueError:
1214 self.send_chat_msg('Only numbers allowed.')
1215 else:
1216 if 0 <= int_choice <= len(self.search_list) - 1:
1217 self.send_chat_msg('Please wait while creating playlist..')
1218 tracks = youtube.playlist_videos(self.search_list[int_choice])
1219 if len(tracks) > 0:
1220 self.playlist.add_list(self.active_user.nick, tracks)
1221 self.send_chat_msg('Added %s tracks from youtube playlist.' % len(tracks))
1222 if not self.playlist.has_active_track:
1223 track = self.playlist.next_track
1224 self.send_yut_play(track.id, track.time, track.title)
1225 self.timer(track.time)
1226 else:
1227 self.send_chat_msg('Failed to retrieve videos from youtube playlist.')
1228 else:
1229 self.send_chat_msg('Please make a choice between 0-%s' % str(len(self.search_list) - 1))
1230 else:
1231 self.send_chat_msg('The search list does not contain any youtube playlist id\'s.')
1232
1233 def do_show_search_list(self):
1234 """ Show what the search list contains. """
1235 if self.is_client_mod:
1236 if len(self.search_list) == 0:
1237 self.send_chat_msg('The search list is empty.')
1238 elif self.is_search_list_yt_playlist:
1239 _ = '\n'.join('(%s) - %s' % (i, d['playlist_title']) for i, d in enumerate(self.search_list))
1240 self.send_chat_msg('Youtube Playlist\'s\n' + _)
1241 else:
1242 _ = '\n'.join('(%s) %s %s' % (i, d['video_title'], self.format_time(d['video_time']))
1243 for i, d in enumerate(self.search_list))
1244 self.send_chat_msg('Youtube Tracks\n' + _)
1245
1246 # Level 4 Command Methods.
1247 def do_skip(self):
1248 """ Skip to the next item in the playlist. """
1249 if self.is_client_mod:
1250 if self.playlist.is_last_track is None:
1251 self.send_chat_msg('No tunes to skip. The playlist is empty.')
1252 elif self.playlist.is_last_track:
1253 self.send_chat_msg('This is the last track in the playlist.')
1254 else:
1255 self.cancel_timer()
1256 next_track = self.playlist.next_track
1257 self.send_yut_play(next_track.id, next_track.time, next_track.title)
1258 self.timer(next_track.time)
1259
1260 def do_delete_playlist_item(self, to_delete): # TODO: Make sure this is working.
1261 """
1262 Delete items from the playlist.
1263
1264 :param to_delete: Item indexes to delete.
1265 :type to_delete: str
1266 """
1267 if self.is_client_mod:
1268 if len(self.playlist.track_list) == 0:
1269 self.send_chat_msg('The playlist is empty.')
1270 elif len(to_delete) == 0:
1271 self.send_chat_msg('No indexes provided.')
1272 else:
1273 indexes = None
1274 by_range = False
1275
1276 try:
1277 if ':' in to_delete:
1278 range_indexes = map(int, to_delete.split(':'))
1279 temp_indexes = range(range_indexes[0], range_indexes[1] + 1)
1280 if len(temp_indexes) > 1:
1281 by_range = True
1282 else:
1283 temp_indexes = map(int, to_delete.split(','))
1284 except ValueError as ve:
1285 log.error('wrong format: %s' % ve)
1286 else:
1287 indexes = []
1288 for i in temp_indexes:
1289 if i < len(self.playlist.track_list) and i not in indexes:
1290 indexes.append(i)
1291
1292 if indexes is not None and len(indexes) > 0:
1293 result = self.playlist.delete(indexes, by_range)
1294 if result is not None:
1295 if by_range:
1296 self.send_chat_msg('Deleted from index: %s to index: %s' %
1297 (result['from'], result['to']))
1298 elif result['deleted_indexes_len'] is 1:
1299 self.send_chat_msg('Deleted %s' % result['track_title'])
1300 else:
1301 self.send_chat_msg('Deleted tracks at index: %s' %
1302 ', '.join(result['deleted_indexes']))
1303 else:
1304 self.send_chat_msg('Nothing was deleted.')
1305
1306 def do_media_replay(self):
1307 """ Replay the currently playing track. """
1308 if self.is_client_mod:
1309 if self.playlist.track is not None:
1310 self.cancel_timer()
1311 track = self.playlist.replay()
1312 self.send_yut_play(track.id, track.time, track.title)
1313 self.timer(track.time)
1314
1315 def do_play_media(self):
1316 """ Play a track on pause . """
1317 if self.is_client_mod:
1318 if self.playlist.track is not None:
1319 if self.playlist.has_active_track:
1320 self.cancel_timer()
1321 if self.playlist.is_paused:
1322 self.playlist.play(self.playlist.elapsed)
1323 self.send_yut_play(self.playlist.track.id, self.playlist.track.time,
1324 self.playlist.track.title, self.playlist.elapsed) #
1325 self.timer(self.playlist.remaining)
1326
1327 def do_media_pause(self):
1328 """ Pause a track. """
1329 if self.is_client_mod:
1330 track = self.playlist.track
1331 if track is not None:
1332 if self.playlist.has_active_track:
1333 self.cancel_timer()
1334 self.playlist.pause()
1335 self.send_yut_pause(track.id, track.time, self.playlist.elapsed)
1336
1337 def do_close_media(self):
1338 """ Close a track playing. """
1339 if self.is_client_mod:
1340 if self.playlist.has_active_track:
1341 self.cancel_timer()
1342 self.playlist.stop()
1343 self.send_yut_stop(self.playlist.track.id, self.playlist.track.time, self.playlist.elapsed)
1344
1345
1346 def do_seek_media(self, time_point):
1347 """
1348 Time search a track.
1349
1350 :param time_point: The time point in which to search to.
1351 :type time_point: str
1352 """
1353 if self.is_client_mod:
1354 if ('h' in time_point) or ('m' in time_point) or ('s' in time_point):
1355 offset = pinylib.string_util.convert_to_seconds(time_point)
1356 if offset == 0:
1357 self.send_chat_msg('Invalid seek time.')
1358 else:
1359 track = self.playlist.track
1360 if track is not None:
1361 if 0 < offset < track.time:
1362 if self.playlist.has_active_track:
1363 self.cancel_timer()
1364 if self.playlist.is_paused:
1365 self.playlist.pause(offset=offset) #
1366 self.send_yut_pause(track.id, track.time, offset)
1367 else:
1368 self.playlist.play(offset)
1369 self.send_yut_play(track.id, track.time, track.title, offset)
1370 self.timer(self.playlist.remaining)
1371
1372 def do_clear_playlist(self):
1373 """ Clear the playlist for items."""
1374 if self.is_client_mod:
1375 if len(self.playlist.track_list) > 0:
1376 pl_length = str(len(self.playlist.track_list))
1377 self.playlist.clear()
1378 self.send_chat_msg('Deleted %s items in the playlist.' % pl_length)
1379 else:
1380 self.send_chat_msg('The playlist is empty, nothing to delete.')
1381
1382 def do_playlist_info(self): # TODO: this needs more work !
1383 """ Shows the next tracks in the playlist. """
1384 if self.is_client_mod:
1385 if len(self.playlist.track_list) > 0:
1386 tracks = self.playlist.get_tracks()
1387 if len(tracks) > 0:
1388 # If i is 0 then mark that as the next track
1389 _ = '\n'.join('(%s) - %s %s' % (track[0], track[1].title, self.format_time(track[1].time))
1390 for i, track in enumerate(tracks))
1391 self.send_chat_msg(_)
1392
1393 def do_youtube_search(self, search_str):
1394 """
1395 Search youtube for a list of matching candidates.
1396
1397 :param search_str: The search term to search for.
1398 :type search_str: str
1399 """
1400 if self.is_client_mod:
1401 if len(search_str) == 0:
1402 self.send_chat_msg('Missing search string.')
1403 else:
1404 self.search_list = youtube.search_list(search_str, results=5)
1405 if len(self.search_list) > 0:
1406 self.is_search_list_yt_playlist = False
1407 _ = '\n'.join('(%s) %s %s' % (i, d['video_title'], self.format_time(d['video_time']))
1408 for i, d in enumerate(self.search_list)) #
1409 self.send_chat_msg(_)
1410 else:
1411 self.send_chat_msg('Could not find anything matching: %s' % search_str)
1412
1413 def do_play_youtube_search(self, int_choice):
1414 """
1415 Play a track from a previous youtube search list.
1416
1417 :param int_choice: The index of the track in the search.
1418 :type int_choice: str | int
1419 """
1420 if self.is_client_mod:
1421 if not self.is_search_list_yt_playlist:
1422 if len(self.search_list) > 0:
1423 try:
1424 int_choice = int(int_choice)
1425 except ValueError:
1426 self.send_chat_msg('Only numbers allowed.')
1427 else:
1428 if 0 <= int_choice <= len(self.search_list) - 1:
1429
1430 if self.playlist.has_active_track:
1431 track = self.playlist.add(self.active_user.nick, self.search_list[int_choice])
1432 self.send_chat_msg('Added (%s) %s %s' %
1433 (self.playlist.last_index,
1434 track.title, self.format_time(track.time)))
1435 else:
1436 track = self.playlist.start(self.active_user.nick, self.search_list[int_choice])
1437 self.send_yut_play(track.id, track.time, track.title)
1438 self.timer(track.time)
1439 else:
1440 self.send_chat_msg('Please make a choice between 0-%s' % str(len(self.search_list) - 1))
1441 else:
1442 self.send_chat_msg('No youtube track id\'s in the search list.')
1443 else:
1444 self.send_chat_msg('The search list only contains youtube playlist id\'s.')
1445
1446 def do_clear(self):
1447 """ Clears the chat box. """
1448 self.send_chat_msg('_\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'
1449 '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n_')
1450
1451
1452 def do_nick(self, new_nick):
1453 """
1454 Set a new nick for the bot.
1455
1456 :param new_nick: The new nick name.
1457 :type new_nick: str
1458 """
1459 if len(new_nick) is 0:
1460 self.nickname = pinylib.string_util.create_random_string(5, 25)
1461 self.set_nick()
1462 else:
1463 self.nickname = new_nick
1464 self.set_nick()
1465
1466 def do_kick(self, user_name):
1467 """
1468 Kick a user out of the room.
1469
1470 :param user_name: The username to kick.
1471 :type user_name: str
1472 """
1473 if self.is_client_mod:
1474 if len(user_name) is 0:
1475 self.send_chat_msg('Missing username.')
1476 elif user_name == self.nickname:
1477 self.send_chat_msg('Action not allowed.')
1478 else:
1479 if user_name.startswith('*'):
1480 user_name = user_name.replace('*', '')
1481 _users = self.users.search_containing(user_name)
1482 if len(_users) > 0:
1483 for i, user in enumerate(_users):
1484 if user.nick != self.nickname and user.user_level > self.active_user.user_level:
1485 if i <= pinylib.CONFIG.B_MAX_MATCH_BANS - 1:
1486 self.send_kick_msg(user.id)
1487 else:
1488 _user = self.users.search_by_nick(user_name)
1489 if _user is None:
1490 self.send_chat_msg('No user named: %s' % user_name)
1491 elif _user.user_level < self.active_user.user_level:
1492 self.send_chat_msg('Not allowed.')
1493 else:
1494 self.send_kick_msg(_user.id)
1495
1496 def do_ban(self, user_name):
1497 """
1498 Ban a user from the room.
1499
1500 :param user_name: The username to ban.
1501 :type user_name: str
1502 """
1503 if self.is_client_mod:
1504 if len(user_name) is 0:
1505 self.send_chat_msg('Missing username.')
1506 elif user_name == self.nickname:
1507 self.send_chat_msg('Action not allowed.')
1508 else:
1509 if user_name.startswith('*'):
1510 user_name = user_name.replace('*', '')
1511 _users = self.users.search_containing(user_name)
1512 if len(_users) > 0:
1513 for i, user in enumerate(_users):
1514 if user.nick != self.nickname and user.user_level > self.active_user.user_level:
1515 if i <= pinylib.CONFIG.B_MAX_MATCH_BANS - 1:
1516 self.send_ban_msg(user.id)
1517 else:
1518 _user = self.users.search_by_nick(user_name)
1519 if _user is None:
1520 self.send_chat_msg('No user named: %s' % user_name)
1521 elif _user.user_level < self.active_user.user_level:
1522 self.send_chat_msg('Not allowed.')
1523 else:
1524 self.send_ban_msg(_user.id)
1525
1526 def do_bad_nick(self, bad_nick):
1527 """
1528 Adds a username to the nick bans file.
1529
1530 :param bad_nick: The bad nick to write to the nick bans file.
1531 :type bad_nick: str
1532 """
1533 if self.is_client_mod:
1534 if len(bad_nick) is 0:
1535 self.send_chat_msg('Missing username.')
1536 elif bad_nick in pinylib.CONFIG.B_NICK_BANS:
1537 self.send_chat_msg('%s is already in list.' % bad_nick)
1538 else:
1539 pinylib.file_handler.file_writer(self.config_path,
1540 pinylib.CONFIG.B_NICK_BANS_FILE_NAME, bad_nick)
1541 self.send_chat_msg('%s was added to file.' % bad_nick)
1542 self.load_list(nicks=True)
1543
1544 def do_remove_ytlog(self, name):
1545 """
1546 Removes nick from the nick bans file.
1547
1548 :param bad_nick: The bad nick to remove from the nick bans file.
1549 :type bad_nick: str
1550 """
1551 if self.is_client_mod:
1552 if len(name) is 0:
1553 self.send_chat_msg('Missing link...')
1554 else:
1555 if name in pinylib.CONFIG.B_Youtube_Play_List:
1556 rem = pinylib.file_handler.remove_from_file(self.config_path,
1557 pinylib.CONFIG.B_Youtube_Play_List,
1558 name)
1559 if rem:
1560 self.send_chat_msg('%s was removed.' % bad_nick)
1561 self.load_list(links=True)
1562
1563 def do_remove_bad_nick(self, bad_nick):
1564 """
1565 Removes nick from the nick bans file.
1566
1567 :param bad_nick: The bad nick to remove from the nick bans file.
1568 :type bad_nick: str
1569 """
1570 if self.is_client_mod:
1571 if len(bad_nick) is 0:
1572 self.send_chat_msg('Missing username')
1573 else:
1574 if bad_nick in pinylib.CONFIG.B_NICK_BANS:
1575 rem = pinylib.file_handler.remove_from_file(self.config_path,
1576 pinylib.CONFIG.B_NICK_BANS_FILE_NAME,
1577 bad_nick)
1578 if rem:
1579 self.send_chat_msg('%s was removed.' % bad_nick)
1580 self.load_list(nicks=True)
1581
1582 def do_bad_string(self, bad_string):
1583 """
1584 Adds a string to the string bans file.
1585
1586 :param bad_string: The bad string to add to the string bans file.
1587 :type bad_string: str
1588 """
1589 if self.is_client_mod:
1590 if len(bad_string) is 0:
1591 self.send_chat_msg('Ban string can\'t be blank.')
1592 elif len(bad_string) < 1:
1593 self.send_chat_msg('Ban string to short: ' + str(len(bad_string)))
1594 elif bad_string in pinylib.CONFIG.B_STRING_BANS:
1595 self.send_chat_msg('%s is already in list.' % bad_string)
1596 else:
1597 pinylib.file_handler.file_writer(self.config_path,
1598 pinylib.CONFIG.B_STRING_BANS_FILE_NAME, bad_string)
1599 self.send_chat_msg('%s was added to file.' % bad_string)
1600 self.load_list(strings=True)
1601
1602 def do_remove_bad_string(self, bad_string):
1603 """
1604 Removes a string from the string bans file.
1605
1606 :param bad_string: The bad string to remove from the string bans file.
1607 :type bad_string: str
1608 """
1609 if self.is_client_mod:
1610 if len(bad_string) is 0:
1611 self.send_chat_msg('Missing word string.')
1612 else:
1613 if bad_string in pinylib.CONFIG.B_STRING_BANS:
1614 rem = pinylib.file_handler.remove_from_file(self.config_path,
1615 pinylib.CONFIG.B_STRING_BANS_FILE_NAME,
1616 bad_string)
1617 if rem:
1618 self.send_chat_msg('%s was removed.' % bad_string)
1619 self.load_list(strings=True)
1620
1621 def do_bad_account(self, bad_account_name):
1622 """
1623 Adds an account name to the account bans file.
1624
1625 :param bad_account_name: The bad account name to add to the account bans file.
1626 :type bad_account_name: str
1627 """
1628 if self.is_client_mod:
1629 if len(bad_account_name) is 0:
1630 self.send_chat_msg('Account can\'t be blank.')
1631 elif len(bad_account_name) < 1:
1632 self.send_chat_msg('Account to short: ' + str(len(bad_account_name)))
1633 elif bad_account_name in pinylib.CONFIG.B_ACCOUNT_BANS:
1634 self.send_chat_msg('%s is already in list.' % bad_account_name)
1635 else:
1636 pinylib.file_handler.file_writer(self.config_path,
1637 pinylib.CONFIG.B_ACCOUNT_BANS_FILE_NAME,
1638 bad_account_name)
1639 self.send_chat_msg('%s was added to file.' % bad_account_name)
1640 self.load_list(accounts=True)
1641
1642 def do_remove_bad_account(self, bad_account):
1643 """
1644 Removes an account from the account bans file.
1645
1646 :param bad_account: The badd account name to remove from account bans file.
1647 :type bad_account: str
1648 """
1649 if self.is_client_mod:
1650 if len(bad_account) is 0:
1651 self.send_chat_msg('Missing account.')
1652 else:
1653 if bad_account in pinylib.CONFIG.B_ACCOUNT_BANS:
1654 rem = pinylib.file_handler.remove_from_file(self.config_path,
1655 pinylib.CONFIG.B_ACCOUNT_BANS_FILE_NAME,
1656 bad_account)
1657 if rem:
1658 self.send_chat_msg('%s was removed.' % bad_account)
1659 self.load_list(accounts=True)
1660
1661 def do_list_info(self, list_type):
1662 """
1663 Shows info of different lists/files.
1664
1665 :param list_type: The type of list to find info for.
1666 :type list_type: str
1667 """
1668 if self.is_client_mod:
1669 if len(list_type) is 0:
1670 self.send_chat_msg('Missing list type.')
1671 else:
1672 if list_type.lower() == 'bn':
1673 if len(pinylib.CONFIG.B_NICK_BANS) is 0:
1674 self.send_chat_msg('No items in this list.')
1675 else:
1676 self.send_chat_msg('%s nicks bans in list.' % len(pinylib.CONFIG.B_NICK_BANS))
1677
1678 elif list_type.lower() == 'bs':
1679 if len(pinylib.CONFIG.B_STRING_BANS) is 0:
1680 self.send_chat_msg('No items in this list.')
1681 else:
1682 self.send_chat_msg('%s string bans in list.' % pinylib.CONFIG.B_STRING_BANS)
1683
1684 elif list_type.lower() == 'ba':
1685 if len(pinylib.CONFIG.B_ACCOUNT_BANS) is 0:
1686 self.send_chat_msg('No items in this list.')
1687 else:
1688 self.send_chat_msg('%s account bans in list.' % pinylib.CONFIG.B_ACCOUNT_BANS)
1689
1690 elif list_type.lower() == 'bl':
1691 if len(self.users.banned_users) == 0:
1692 self.send_chat_msg('The banlist is empty.')
1693 else:
1694 _ban_list = '\n'.join('(%s) %s:%s [%s]' %
1695 (i, banned_user.nick, banned_user.account, banned_user.ban_id)
1696 for i, banned_user in enumerate(self.users.banned_users))
1697 if len(_ban_list) > 150: # maybe have a B_MAX_MSG_LENGTH in config
1698 # use string_util.chunk_string
1699 pass
1700 else:
1701 self.send_chat_msg(_ban_list)
1702
1703 elif list_type.lower() == 'mods':
1704 if self.is_client_owner:
1705 if len(self.privacy_.room_moderators) is 0:
1706 self.send_chat_msg('There is currently no moderators for this room.')
1707 elif len(self.privacy_.room_moderators) is not 0:
1708 mods = ', '.join(self.privacy_.room_moderators)
1709 self.send_chat_msg('Moderators: ' + mods)
1710
1711 def do_user_info(self, user_name):
1712 """
1713 Shows user object info for a given user name.
1714
1715 :param user_name: The user name of the user to show the info for.
1716 :type user_name: str
1717 """
1718 if self.is_client_mod:
1719 if len(user_name) is 0:
1720 self.send_chat_msg('Missing username.')
1721 else:
1722 _user = self.users.search_by_nick(user_name)
1723 if _user is None:
1724 self.send_chat_msg('No user named: %s' % user_name)
1725 else:
1726 if _user.account and _user.tinychat_id is None:
1727 user_info = pinylib.apis.tinychat.user_info(_user.account)
1728 if user_info is not None:
1729 _user.tinychat_id = user_info['tinychat_id']
1730 _user.last_login = user_info['last_active']
1731 online_time = (pinylib.time.time() - _user.join_time)
1732
1733 info = [
1734 'User Level: ' + str(_user.user_level),
1735 'Online Time: ' + self.format_time(online_time),
1736 'Last Message: ' + str(_user.last_msg)
1737 ]
1738 if _user.tinychat_id is not None:
1739 info.append('Account: ' + str(_user.account))
1740 info.append('Tinychat ID: ' + str(_user.tinychat_id))
1741 info.append('Last Login: ' + _user.last_login)
1742
1743 self.send_chat_msg('\n'.join(info))
1744
1745 def do_cam_approve(self, user_name):
1746 """
1747 Allow a user to broadcast in a green room enabled room.
1748
1749 :param user_name: The name of the user allowed to broadcast.
1750 :type user_name: str
1751 """
1752 if self.is_green_room and self.is_client_mod:
1753 if len(user_name) == 0 and self.active_user.is_waiting:
1754 self.send_cam_approve_msg(self.active_user.id)
1755 elif len(user_name) > 0:
1756 _user = self.users.search_by_nick(user_name)
1757 if _user is not None and _user.is_waiting:
1758 self.send_cam_approve_msg(_user.id)
1759 else:
1760 self.send_chat_msg('No user named: %s' % user_name)
1761
1762 def do_close_broadcast(self, user_name):
1763 """
1764 Close a users broadcast.
1765
1766 :param user_name: The name of the user to close.
1767 :type user_name: str
1768 """
1769 if self.is_client_mod:
1770 if len(user_name) == 0:
1771 self.send_chat_msg('Missing user name.')
1772 else:
1773 _user = self.users.search_by_nick(user_name)
1774 if _user is not None and _user.is_broadcasting:
1775 self.send_close_user_msg(_user.id)
1776 else:
1777 self.send_chat_msg('No user named: %s' % user_name)
1778
1779 def do_banlist_search(self, user_name):
1780 """
1781 Search the banlist for matches.
1782
1783 NOTE: This method/command was meant to be a private message command,
1784 but it seems like the private messages is broken, so for now
1785 it will be a room command.
1786
1787 :param user_name: The user name or partial username to search for.
1788 :type user_name: str
1789 """
1790 if self.is_client_mod:
1791 if len(user_name) == 0:
1792 self.send_chat_msg('Missing user name to search for.')
1793 else:
1794 self.bl_search_list = self.users.search_banlist_containing(user_name)
1795 if len(self.bl_search_list) == 0:
1796 self.send_chat_msg('No banlist matches.')
1797 else:
1798 _ban_list_info = '\n'.join('(%s) %s:%s [%s]' % (i, user.nick, user.account, user.ban_id)
1799 for i, user in enumerate(self.bl_search_list))
1800 # maybe user string_util.chunk_string here
1801 self.send_chat_msg(_ban_list_info)
1802
1803 def do_forgive(self, user_index):
1804 """
1805 Forgive a user from the ban list search.
1806
1807 NOTE: This method/command was meant to be a private message command,
1808 but it seems like the private messages is broken, so for now
1809 it will be a room command.
1810
1811 :param user_index: The index in the ban list search.
1812 :type user_index: str | int
1813 """
1814 if self.is_client_mod:
1815 try:
1816 user_index = int(user_index)
1817 except ValueError:
1818 self.send_chat_msg('Only numbers allowed (%s)' % user_index)
1819 else:
1820 if len(self.bl_search_list) > 0:
1821 if user_index <= len(self.bl_search_list) - 1:
1822 self.send_unban_msg(self.bl_search_list[user_index].ban_id)
1823 else:
1824 if len(self.bl_search_list) > 1:
1825 self.send_chat_msg(
1826 'Please make a choice between 0-%s' % len(self.bl_search_list))
1827 else:
1828 self.send_chat_msg('The ban search is empty.')
1829
1830 # self.bl_search_list[:] = []
1831
1832 def do_unban(self, user_name):
1833 """
1834 Un-ban the last banned user or a user by user name.
1835
1836 NOTE: experimental. In case the user name match more than one
1837 user in the banlist, then the last banned user will be unbanned.
1838
1839 :param user_name: The exact user name to unban.
1840 :type user_name: str
1841 """
1842 if self.is_client_mod:
1843 if len(user_name.strip()) == 0:
1844 self.send_chat_msg('Missing user name.')
1845 elif user_name == '/': # shortcut to the last banned user.
1846 last_banned_user = self.users.last_banned
1847 if last_banned_user is not None:
1848 self.send_unban_msg(last_banned_user.ban_id)
1849 else:
1850 self.send_chat_msg('Failed to find the last banned user.')
1851 else:
1852 banned_user = self.users.search_banlist_by_nick(user_name)
1853 if banned_user is not None:
1854 self.send_unban_msg(banned_user.ban_id)
1855 else:
1856 self.send_chat_msg('No user named: %s in the banlist.' % user_name)
1857
1858 # Public (Level 5) Command Methods.
1859 def do_playlist_status(self):
1860 """ Shows the playlist queue. """
1861 if self.is_client_mod:
1862 if len(self.playlist.track_list) == 0:
1863 self.send_chat_msg('The playlist is empty.')
1864 else:
1865 queue = self.playlist.queue
1866 if queue is not None:
1867 self.send_chat_msg('%s items in the playlist, %s still in queue.' %
1868 (queue[0], queue[1]))
1869
1870 def do_next_tune_in_playlist(self):
1871 """ Shows the next track in the playlist. """
1872 if self.is_client_mod:
1873 if self.playlist.is_last_track is None:
1874 self.send_chat_msg('The playlist is empty.')
1875 elif self.playlist.is_last_track:
1876 self.send_chat_msg('This is the last track.')
1877 else:
1878 pos, next_track = self.playlist.next_track_info()
1879 if next_track is not None:
1880 self.send_chat_msg('(%s) %s %s' %
1881 (pos, next_track.title, self.format_time(next_track.time)))
1882
1883 def do_now_playing(self):
1884 """ Shows what track is currently playing. """
1885 if self.is_client_mod:
1886 if self.playlist.has_active_track:
1887 track = self.playlist.track
1888 if len(self.playlist.track_list) > 0:
1889 self.send_private_msg(self.active_user.id,
1890 '(%s) %s %s' % (self.playlist.current_index, track.title,
1891 self.format_time(track.time)))
1892 else:
1893 self.send_private_msg(self.active_user.id, '%s %s' %
1894 (track.title, self.format_time(track.time)))
1895 else:
1896 self.send_private_msg(self.active_user.id, 'No track playing.')
1897
1898 def do_who_plays(self):
1899 """ Show who requested the currently playing track. """
1900 if self.is_client_mod:
1901 if self.playlist.has_active_track:
1902 track = self.playlist.track
1903 ago = self.format_time(int(pinylib.time.time() - track.rq_time))
1904 self.send_chat_msg('%s requested this track %s ago.' % (track.owner, ago))
1905 else:
1906 self.send_chat_msg('No track playing.')
1907
1908 def do_version(self):
1909 """ Show version info. """
1910 self.send_private_msg(self.active_user.id, 'tinybot %s pinylib %s' %
1911 (__version__, pinylib.__version__))
1912
1913 def do_help(self):
1914 """ Posts a link to github readme/wiki or other page about the bot commands. """
1915 self.send_private_msg(self.active_user.id,
1916 'Help: https://github.com/nortxort/tinybot-rtc/wiki/commands')
1917 def join_message():
1918 self.send_private_msg(self.active_user.id,
1919 'This is an automatted message to fix a PM bug.')
1920 def do_uptime(self):
1921 """ Shows the bots uptime. """
1922 self.send_chat_msg('Bot-Uptime: ' + self.format_time(self.get_runtime()))
1923
1924 def do_pmme(self):
1925 """ Opens a PM session with the bot. """
1926 self.send_private_msg(self.active_user.id, 'How can i help you %s?' % self.active_user.nick)
1927
1928 def do_play_youtube(self, search_str):
1929 """
1930 Plays a youtube video matching the search term.
1931
1932 :param search_str: The search term.
1933 :type search_str: str
1934 """
1935
1936 log.info('user: %s:%s is searching youtube: %s' % (self.active_user.nick, self.active_user.id, search_str))
1937 if self.is_client_mod:
1938 if len(search_str) is 0:
1939 self.send_chat_msg('Please specify youtube title, id or link.')
1940
1941
1942 else:
1943 _youtube = youtube.search(search_str)
1944
1945
1946 if _youtube is None:
1947 log.warning('youtube request returned: %s' % _youtube)
1948 self.send_chat_msg('Could not find video: ' + search_str)
1949
1950 else:
1951 log.info('youtube found: %s' % _youtube)
1952 if self.playlist.has_active_track:
1953 track = self.playlist.add(self.active_user.nick, _youtube)
1954 self.send_chat_msg('(%s) %s %s' %
1955 (self.playlist.last_index, track.title, self.format_time(track.time)))
1956 else:
1957 track = self.playlist.start(self.active_user.nick, _youtube)
1958 self.send_yut_play(track.id, track.time, track.title)
1959 self.timer(track.time)
1960
1961 # == Tinychat API Command Methods. ==
1962 def do_account_spy(self, account):
1963 """
1964 Shows info about a tinychat account.
1965
1966 :param account: tinychat account.
1967 :type account: str
1968 """
1969 if self.is_client_mod:
1970 if len(account) is 0:
1971 self.send_chat_msg('Missing username to search for.')
1972 else:
1973 tc_usr = pinylib.apis.tinychat.user_info(account)
1974 if tc_usr is None:
1975 self.send_chat_msg('Could not find tinychat info for: %s' % account)
1976 else:
1977 self.send_chat_msg('ID: %s, \nLast Login: %s' %
1978 (tc_usr['tinychat_id'], tc_usr['last_active']))
1979
1980 # == Other API Command Methods. ==
1981 def do_search_urban_dictionary(self, search_str):
1982 """
1983 Shows urbandictionary definition of search string.
1984
1985 :param search_str: The search string to look up a definition for.
1986 :type search_str: str
1987 """
1988 if self.is_client_mod:
1989 if len(search_str) is 0:
1990 self.send_chat_msg('Please specify something to look up.')
1991 else:
1992 urban = other.urbandictionary_search(search_str)
1993 if urban is None:
1994 self.send_chat_msg('Could not find a definition for: %s' % search_str)
1995 else:
1996 if len(urban) > 70:
1997 chunks = pinylib.string_util.chunk_string(urban, 70)
1998 for i in range(0, 2):
1999 self.send_chat_msg(chunks[i])
2000 else:
2001 self.send_chat_msg(urban)
2002
2003 def do_weather_search(self, search_str):
2004 """
2005 Shows weather info for a given search string.
2006
2007 :param search_str: The search string to find weather data for.
2008 :type search_str: str
2009 """
2010 if len(search_str) is 0:
2011 self.send_chat_msg('Please specify a city to search for.')
2012 else:
2013 weather = other.weather_search(search_str)
2014 if weather is None:
2015 self.send_chat_msg('Could not find weather data for: %s' % search_str)
2016 else:
2017 self.send_chat_msg(weather)
2018
2019 def do_whois_ip(self, ip_str):
2020 """
2021 Shows whois info for a given ip address or domain.
2022
2023 :param ip_str: The ip address or domain to find info for.
2024 :type ip_str: str
2025 """
2026 if len(ip_str) is 0:
2027 self.send_chat_msg('Please provide an IP address or domain.')
2028 else:
2029 whois = other.whois(ip_str)
2030 if whois is None:
2031 self.send_chat_msg('No info found for: %s' % ip_str)
2032 else:
2033 self.send_chat_msg(whois)
2034
2035 # == Just For Fun Command Methods. ==
2036 def do_chuck_noris(self):
2037 """ Shows a chuck norris joke/quote. """
2038 chuck = other.chuck_norris()
2039 if chuck is not None:
2040 self.send_chat_msg(chuck)
2041
2042 # == Just For Fun Command Methods. ==
2043 def do_check(self):
2044 self.send_chat_msg('Status: Online! - Bot-Uptime: ' + self.format_time(self.get_runtime()))
2045
2046 def do_commands(self):
2047 self.send_chat_msg('Public commands are located @ https://pastebin.com/CyKfR27Z')
2048
2049 def do_mood(self):
2050
2051 self.send_chat_msg(locals_.get_mood())
2052
2053 def do_Movie(self, title):
2054
2055 self.send_chat_msg(locals_.getMovie(title))
2056
2057
2058 def do_Hyde(self):
2059
2060 self.send_chat_msg(locals_.getHyde())
2061
2062
2063
2064 def do_8ball(self, question):
2065 """
2066 Shows magic eight ball answer to a yes/no question.
2067
2068 :param question: The yes/no question.
2069 :type question: str
2070 """
2071 if len(question) is 0:
2072 self.send_chat_msg('Question.')
2073 else:
2074 self.send_chat_msg('8Ball says: %s' % locals_.eight_ball())
2075
2076 def do_scope(self, month):
2077 """
2078 Shows magic eight ball answer to a yes/no question.
2079
2080 :param question: The yes/no question.
2081 :type question: str
2082 """
2083 if len(month) is 0:
2084 self.send_chat_msg('Sign required..')
2085 else:
2086 self.send_chat_msg('Scope says: %s' % locals_.getScope(month))
2087
2088 def do_number(self, number):
2089 """
2090 Shows magic eight ball answer to a yes/no question.
2091
2092 :param question: The yes/no question.
2093 :type question: str
2094 """
2095 if len(number) is 0:
2096 self.send_chat_msg('Number required..')
2097 else:
2098 self.send_chat_msg('Number says: %s' % locals_.getNumber(number))
2099
2100 def do_fact(self):
2101
2102
2103 self.send_chat_msg('Fact is: %s' % locals_.get_Animal())
2104
2105 def do_joke(self):
2106
2107
2108 self.send_chat_msg('Fact is: %s' % locals_.getJokes())
2109
2110 def do_line(self):
2111
2112 self.send_chat_msg(locals_.getOneliner())
2113
2114 def do_mom(self):
2115
2116
2117 self.send_chat_msg('Api is down')
2118
2119 def do_Advice(self):
2120
2121
2122 self.send_chat_msg('Advice is: %s' % locals_.advice())
2123 #self.send_chat_msg('Disabled by x0r till further notice')
2124
2125 def do_Geek(self):
2126
2127
2128 self.send_chat_msg(locals_.getGeek())
2129 #self.send_chat_msg('Disabled by x0r till further notice')
2130
2131 def do_bitcoin(self):
2132
2133
2134 self.send_chat_msg('Cryptowatch says: %s' % locals_.getbitcoin())
2135
2136 def do_eth(self):
2137
2138 self.send_chat_msg('Cryptowatch says: %s' % locals_.geteth())
2139
2140 def do_xmr(self):
2141
2142 self.send_chat_msg('Cryptowatch says: %s' % locals_.getxmr())
2143
2144 def do_ltc(self):
2145
2146 self.send_chat_msg('Cryptowatch says: %s' % locals_.getlitecoins())
2147
2148 def do_pot(self):
2149
2150 self.send_chat_msg('Cryptowatch says: %s' % locals_.getpot())
2151
2152 def do_sia(self):
2153
2154 self.send_chat_msg('Cryptowatch says: %s' % locals_.getsia())
2155
2156 def do_gank(self):
2157
2158 self.send_chat_msg('Gods gift to women and mankind.')
2159
2160 def do_jokes(self):
2161
2162 self.send_chat_msg('Joker says: %s' % locals_.get_joke())
2163
2164 def do_dice(self):
2165 """ roll the dice. """
2166 self.send_chat_msg('The dice rolled: %s' % locals_.roll_dice())
2167
2168 def do_flip_coin(self):
2169 """ Flip a coin. """
2170 self.send_chat_msg('The coin was: %s' % locals_.flip_coin())
2171
2172 def do_fortune(self):
2173 """ Flip a coin. """
2174 self.send_chat_msg('The fortune was: %s' % locals_.fortune())
2175
2176 def do_Trump(self):
2177 """ Flip a coin. """
2178 self.send_chat_msg('Trump says: %s' % locals_.getTrump())
2179
2180 def private_message_handler(self, private_msg):
2181 """
2182 Private message handler.
2183
2184 Overrides private_message_handler in pinylib
2185 to enable private commands.
2186
2187 :param private_msg: The private message.
2188 :type private_msg: str
2189 """
2190
2191 prefix = pinylib.CONFIG.B_PREFIX
2192 # Split the message in to parts.
2193 pm_parts = private_msg.split(' ')
2194 # parts[0] is the command..
2195 pm_cmd = pm_parts[0].lower().strip()
2196 # The rest is a command argument.
2197 pm_arg = ' '.join(pm_parts[1:]).strip()
2198
2199 #Bots operating owner
2200 if self.has_level(1):
2201 if self.is_client_owner:
2202 pass
2203
2204 #if pm_cmd == prefix + 'key':
2205 # self.do_key(pm_arg)
2206
2207 elif pm_cmd == prefix + 'clrbn':
2208 self.do_clear_bad_nicks()
2209
2210 elif pm_cmd == prefix + 'clrbs':
2211 self.do_clear_bad_strings()
2212
2213 elif pm_cmd == prefix + 'clrban':
2214 self.do_clear_bad_accounts()
2215
2216
2217
2218 # Public commands.
2219 if self.has_level(5):
2220 if pm_cmd == prefix + 'opme1':
2221 self.do_opme(pm_arg)
2222
2223 # Print to console.
2224 #msg = str(private_msg).replace(pinylib.CONFIG.B_KEY, '***KEY***'). \
2225 # replace(pinylib.CONFIG.B_SUPER_KEY, '***SUPER KEY***')
2226
2227 #self.console_write(pinylib.COLOR['white'], 'Private message from %s: %s' % (self.active_user.nick, msg))
2228
2229 def do_key(self, new_key):
2230 """
2231 Shows or sets a new secret bot controller key.
2232
2233 :param new_key: The new secret key.
2234 :type new_key: str
2235 """
2236 if len(new_key) == 0:
2237 self.send_private_msg(self.active_user.id, 'The current secret key is: %s' % pinylib.CONFIG.B_KEY)
2238 elif len(new_key) < 6:
2239 self.send_private_msg(self.active_user.id, 'The key is to short, it must be atleast 6 characters long.'
2240 'It is %s long.' % len(new_key))
2241 elif len(new_key) >= 6:
2242 # reset current bot controllers.
2243 for user in self.users.all:
2244 if self.users.all[user].user_level is 2 or self.users.all[user].user_level is 4:
2245 self.users.all[user].user_level = 5
2246
2247 pinylib.CONFIG.B_KEY = new_key
2248 self.send_private_msg(self.active_user.id, 'The key was changed to: %s' % new_key)
2249
2250 def do_clear_bad_nicks(self):
2251 """ Clear the nick bans file. """
2252 pinylib.CONFIG.B_NICK_BANS[:] = []
2253 pinylib.file_handler.delete_file_content(self.config_path, pinylib.CONFIG.B_NICK_BANS_FILE_NAME)
2254
2255 def do_clear_bad_strings(self):
2256 """ Clear the string bans file. """
2257 pinylib.CONFIG.B_STRING_BANS[:] = []
2258 pinylib.file_handler.delete_file_content(self.config_path, pinylib.CONFIG.B_STRING_BANS_FILE_NAME)
2259
2260 def do_clear_bad_accounts(self):
2261 """ Clear the account bans file. """
2262 pinylib.CONFIG.B_ACCOUNT_BANS[:] = []
2263 pinylib.file_handler.delete_file_content(self.config_path, pinylib.CONFIG.B_ACCOUNT_BANS_FILE_NAME)
2264
2265 def do_opme(self, key):
2266 """
2267 Make a user a bot controller if the correct key is provided.
2268
2269 :param key: The secret bot controller key.
2270 :type key: str
2271 """
2272 if len(key) == 0:
2273 self.send_private_msg(self.active_user.id, 'Missing key.')
2274 elif key == pinylib.CONFIG.B_SUPER_KEY:
2275 if self.is_client_owner:
2276 self.active_user.user_level = 1
2277 self.send_private_msg(self.active_user.id, 'You are now a super mod.')
2278 else:
2279 self.send_private_msg(self.active_user.id, 'The client is not using the owner account.')
2280 elif key == pinylib.CONFIG.B_KEY:
2281 if self.is_client_mod:
2282 self.active_user.user_level = 2
2283 self.send_private_msg(self.active_user.id, 'You are now a bot controller.')
2284 else:
2285 self.send_private_msg(self.active_user.id, 'The client is not moderator.')
2286 else:
2287 self.send_private_msg(self.active_user.id, 'Wrong key.')
2288
2289 # Timer Related.
2290 def timer_event(self):
2291 """ This gets called when the timer has reached the time. """
2292 if len(self.playlist.track_list) > 0:
2293 if self.playlist.is_last_track:
2294 if self.is_connected:
2295 self.send_chat_msg('Resetting playlist.')
2296 self.playlist.clear()
2297 else:
2298 track = self.playlist.next_track
2299 if track is not None and self.is_connected:
2300 self.send_yut_play(track.id, track.time, track.title)
2301 self.timer(track.time)
2302
2303 def timer(self, event_time):
2304 """
2305 Track event timer.
2306
2307 This will cause an event to occur once the time is done.
2308
2309 :param event_time: The time in seconds for when an event should occur.
2310 :type event_time: int | float
2311 """
2312 self.timer_thread = threading.Timer(event_time, self.timer_event)
2313 self.timer_thread.start()
2314
2315 def cancel_timer(self):
2316 """ Cancel the track timer. """
2317 if self.timer_thread is not None:
2318 if self.timer_thread.is_alive():
2319 self.timer_thread.cancel()
2320 self.timer_thread = None
2321 return True
2322 return False
2323 return False
2324
2325 # Helper Methods.
2326 def options(self):
2327 """ Load/set special options. """
2328 log.info('options: is_client_owner: %s, is_client_mod: %s' % (self.is_client_owner, self.is_client_mod))
2329 if self.is_client_owner:
2330 self.get_privacy_settings()
2331 if self.is_client_mod:
2332 self.send_banlist_msg()
2333 self.load_list(nicks=True, accounts=True, strings=True, links=True)
2334
2335 def get_privacy_settings(self):
2336 """ Parse the privacy settings page. """
2337 log.info('Parsing %s\'s privacy page.' % self.account)
2338 self.privacy_ = privacy.Privacy(proxy=None)
2339 self.privacy_.parse_privacy_settings()
2340
2341 def load_list(self, nicks=False, accounts=False, strings=False, links=False):
2342 """
2343 Loads different list to memory.
2344
2345 :param nicks: bool, True load nick bans file.
2346 :param accounts: bool, True load account bans file.
2347 :param strings: bool, True load ban strings file.
2348 """
2349 if nicks:
2350 pinylib.CONFIG.B_NICK_BANS = pinylib.file_handler.file_reader(self.config_path,
2351 pinylib.CONFIG.B_NICK_BANS_FILE_NAME)
2352 if accounts:
2353 pinylib.CONFIG.B_ACCOUNT_BANS = pinylib.file_handler.file_reader(self.config_path,
2354 pinylib.CONFIG.B_ACCOUNT_BANS_FILE_NAME)
2355 if strings:
2356 pinylib.CONFIG.B_STRING_BANS = pinylib.file_handler.file_reader(self.config_path,
2357 pinylib.CONFIG.B_STRING_BANS_FILE_NAME)
2358 if links:
2359 pinylib.CONFIG.B_STRING_BANS = pinylib.file_handler.file_reader(self.config_path,
2360 pinylib.CONFIG.B_Youtube_Play_List)
2361 #pinylib.CONFIG.B_Youtube_Play_List
2362 def has_level(self, level):
2363 """
2364 Checks the active user for correct user level.
2365
2366 :param level: The level to check the active user against.
2367 :type level: int
2368 :return: True if the user has correct level, else False
2369 :rtype: bool
2370 """
2371 if self.active_user.user_level == 6:
2372 return False
2373 elif self.active_user.user_level <= level:
2374 return True
2375 return False
2376
2377 @staticmethod
2378 def format_time(time_stamp, is_milli=False):
2379 """
2380 Converts a time stamp as seconds or milliseconds to (day(s)) hours minutes seconds.
2381
2382 :param time_stamp: Seconds or milliseconds to convert.
2383 :param is_milli: The time stamp to format is in milliseconds.
2384 :return: A string in the format (days) hh:mm:ss
2385 :rtype: str
2386 """
2387 if is_milli:
2388 m, s = divmod(time_stamp / 1000, 60)
2389 else:
2390 m, s = divmod(time_stamp, 60)
2391 h, m = divmod(m, 60)
2392 d, h = divmod(h, 24)
2393
2394 if d == 0 and h == 0:
2395 human_time = '%02d:%02d' % (m, s)
2396 elif d == 0:
2397 human_time = '%d:%02d:%02d' % (h, m, s)
2398 else:
2399 human_time = '%d Day(s) %d:%02d:%02d' % (d, h, m, s)
2400 return human_time
2401
2402 def check_msg(self, msg):
2403 """
2404 Checks the chat message for ban string.
2405
2406 :param msg: The chat message.
2407 :type msg: str
2408 """
2409 should_be_banned = False
2410 chat_words = msg.split(' ')
2411 for bad in pinylib.CONFIG.B_STRING_BANS:
2412 if bad.startswith('*'):
2413 _ = bad.replace('*', '')
2414 if _ in msg:
2415 should_be_banned = True
2416 elif bad in chat_words:
2417 should_be_banned = True
2418 if should_be_banned:
2419 if pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN:
2420 self.send_kick_msg(self.active_user.id)
2421 else:
2422 self.send_ban_msg(self.active_user.id)