Advertisement
Guest User

Untitled

a guest
Aug 5th, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 82.05 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. """ Tinybot by Nortxort (https://github.com/nortxort/tinybot-rtc) """
  3.  
  4. import logging
  5. import threading
  6. import time
  7.  
  8.  
  9. import pinylib
  10. from util import tracklist
  11. from page import privacy
  12. from apis import youtube, lastfm, other, locals_
  13.  
  14.  
  15. __version__ = '1.0.6 (RTC)'
  16. log = logging.getLogger(__name__)
  17.  
  18.  
  19. class Cheers():
  20. def __init__(self):
  21. self.room = None
  22. self.mode = False
  23. self.paused = False
  24. self.CHEERS = 'TOKES'
  25. self.CHUGS = 'CHUGS'
  26. self.type = self.CHEERS
  27. self.announce = 0 # Interval in seconds, announcing tokes incoming. Reusable.
  28. self.announceCheck = 0
  29.  
  30. self.joined = [] # Nicks who joined in tokes.
  31. self.start = 0 # time() started.
  32. self.end = 0 # seconds from start() to end. Reusable.
  33.  
  34. self.thread = threading.Thread(target=self.count, args=())
  35. self.thread.daemon = True
  36. self.thread.start()
  37.  
  38. self.message_1 = False
  39. self.type = self.CHEERS
  40. def pluralize(self, s="", n=0, pluralForm=None):
  41. if n != 1:
  42. if pluralForm is None:
  43. s += "s"
  44. else:
  45. s = pluralForm
  46.  
  47. return s
  48.  
  49. # Returns the time in minutes, until tokes.
  50. # Part of minute is a minute.
  51. def until(self):
  52. t = int(time.time())
  53. # Gets best minute approximation.
  54. d = int(round(float(self.start + self.end - t) / 60))
  55. # Left time minimum 1 minute rounding.
  56. if d == 0:
  57. d = 1
  58. return d
  59.  
  60. # Start a new count!
  61. # end is in minutes -> seconds.
  62. # announce is in minutes -> seconds. Falsy value is no announcements.
  63. def startCount(self, room, end, announce=0, **kwargs):
  64. if 'type' in kwargs:
  65. self.type = kwargs['type']
  66.  
  67. self.room = room
  68. self.mode = True
  69.  
  70. t = int(time.time())
  71.  
  72. self.announce = int(announce) * 60
  73. self.announceCheck = t + self.announce
  74.  
  75. self.joined = []
  76.  
  77. self.start = t
  78. self.end = int(end) * 60
  79.  
  80. # Clears out current count.
  81. def clearOut(self):
  82. self.room = None
  83. self.mode = False
  84. self.announceCheck = 0
  85. self.joined = []
  86. self.start = 0
  87.  
  88. self.message_1 = False
  89. self.message_2 = False
  90. self.message_3 = False
  91. self.message_4 = False
  92. self.message_5 = False
  93.  
  94. # At end, announces it's time for tokes!
  95. def count(self):
  96. while True:
  97. time.sleep(1)
  98.  
  99. if not self.mode:
  100. time.sleep(5)
  101. continue
  102.  
  103. t = time.time()
  104. if self.until() <= 1:
  105. if not self.message_1:
  106. self.room.send_bot_msg('*' + str(self.until()) + ' ' + str(
  107. self.pluralize(s="minute", n=self.until())) + "* for " + self.type + " left to go. *Type *" +
  108. '.' + "JOIN* in chat to toke together. (Do *" + '.' + "" + self.type + " " + '.' + "* to clear it out.)")
  109. self.message_1 = True
  110.  
  111. # Count finished!
  112. if t > self.start + self.end:
  113. start = int((t - self.start) / 60)
  114.  
  115. if len(self.joined) > 1:
  116. if len(self.joined) == 2:
  117. # Just one other person joined.
  118. joined = self.joined[1]
  119. else:
  120. # Many joined.
  121. joined = ""
  122. j = 0
  123. for name in self.joined[1:]:
  124. if j == len(self.joined) - 2:
  125. joined += "and " + name
  126. else:
  127. joined += name + ", "
  128. j += 1
  129.  
  130. self.room.send_bot_msg(str(self.joined[0]) + " called " + self.type + " " + str(start) +
  131. " " + str(self.pluralize(s="minute", n=start)) +
  132. " ago, and *" + str(joined) + "* joined in. *" + self.type + " NOW!*")
  133. else:
  134. # Lonely toke.
  135. self.room.send_bot_msg(str(self.joined[0]) + ", you called " + self.type + " " + str(start) +
  136. " " + str(self.pluralize(s="minute", n=start)) +
  137. " ago, and nobody joined in. Who cares... *" + self.type + " NOW!*")
  138.  
  139. # Clear out counter.
  140. self.clearOut()
  141. continue
  142.  
  143. # Optional periodical announcements.
  144. if self.announce and t > self.announceCheck:
  145. self.announceCheck = t + self.announce
  146.  
  147. start = int((t - self.start) / 60)
  148. self.room.send_bot_msg(self.joined[0] + " called " + self.type + " " + str(start) +
  149. " " + str(self.pluralize("minute", start)) + " ago. Y'all better *!JOIN* in.")
  150.  
  151. class TinychatBot(pinylib.TinychatRTCClient):
  152. privacy_ = None
  153. timer_thread = None
  154. playlist = tracklist.PlayList()
  155. search_list = []
  156. is_search_list_yt_playlist = False
  157. is_broadcasting = False
  158. CHEERS = Cheers()
  159. CHUGS = Cheers()
  160.  
  161. @property
  162. def config_path(self):
  163. """ Returns the path to the rooms configuration directory. """
  164. return pinylib.CONFIG.CONFIG_PATH + self.room_name + '/'
  165.  
  166. def on_joined(self, client_info):
  167. """
  168. Received when the client have joined the room successfully.
  169.  
  170. :param client_info: This contains info about the client, such as user role and so on.
  171. :type client_info: dict
  172. """
  173. log.info('client info: %s' % client_info)
  174. self.client_id = client_info['handle']
  175. self.is_client_mod = client_info['mod']
  176. self.is_client_owner = client_info['owner']
  177. client = self.users.add(client_info)
  178. client.user_level = 0
  179. self.console_write(pinylib.COLOR['bright_green'], 'Client joined the room: %s:%s' % (client.nick, client.id))
  180.  
  181. # do special operations.
  182. threading.Thread(target=self.options).start()
  183.  
  184. def on_join(self, join_info):
  185. """
  186. Received when a user joins the room.
  187.  
  188. :param join_info: This contains user information such as role, account and so on.
  189. :type join_info: dict
  190. """
  191. log.info('user join info: %s' % join_info)
  192. _user = self.users.add(join_info)
  193.  
  194. if _user.account:
  195. if _user.is_owner:
  196. _user.user_level = 1
  197. self.console_write(pinylib.COLOR['red'], 'Room Owner %s:%d:%s' %
  198. (_user.nick, _user.id, _user.account))
  199.  
  200. if _user.account in ["710dabbot"]:
  201. _user.user_level = 1
  202. _user.is_mod == True
  203.  
  204. elif _user.is_mod:
  205. _user.user_level = 3
  206. self.console_write(pinylib.COLOR['bright_red'], 'Moderator %s:%d:%s' %
  207. (_user.nick, _user.id, _user.account))
  208. else:
  209. self.console_write(pinylib.COLOR['bright_yellow'], '%s:%d has account: %s' %
  210. (_user.nick, _user.id, _user.account))
  211.  
  212. if _user.account in pinylib.CONFIG.B_ACCOUNT_BANS and self.is_client_mod:
  213. if pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN:
  214. self.send_kick_msg(_user.id)
  215. else:
  216. self.send_ban_msg(_user.id)
  217. self.send_chat_msg('Auto-Banned: (bad account)')
  218. else:
  219. tc_info = pinylib.apis.tinychat.user_info(_user.account)
  220. if tc_info is not None:
  221. _user.tinychat_id = tc_info['tinychat_id']
  222. _user.last_login = tc_info['last_active']
  223.  
  224. else:
  225. if _user.is_lurker and not pinylib.CONFIG.B_ALLOW_LURKERS and self.is_client_mod:
  226. if pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN:
  227. self.send_kick_msg(_user.id)
  228. else:
  229. self.send_ban_msg(_user.id)
  230. self.send_chat_msg('Auto-Banned: (lurkers not allowed)')
  231.  
  232. elif not pinylib.CONFIG.B_ALLOW_GUESTS and self.is_client_mod:
  233. if pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN:
  234. self.send_kick_msg(_user.id)
  235. else:
  236. self.send_ban_msg(_user.id)
  237. self.send_chat_msg('Auto-Banned: (guests not allowed)')
  238.  
  239. if pinylib.CONFIG.B_GREET and self.is_client_mod:
  240. if not _user.nick.startswith('guest-'):
  241. if _user.account:
  242. self.send_chat_msg('Welcome to the room %s' % (_user.nick))
  243. else:
  244. self.send_chat_msg('Welcome to the room %s' % (_user.nick))
  245.  
  246. self.console_write(pinylib.COLOR['cyan'], '%s joined the room.' % (_user.nick,))
  247.  
  248.  
  249. def on_nick(self, old, new, uid):
  250. """ Application message received when a user changes nick name.
  251. :param old: The old nick name of the user.
  252. :type old: str
  253. :param new: The new nick name of the user
  254. :type new: str
  255. :param uid: The Id of the user.
  256. :type uid: int
  257. """
  258. if uid == self._client_id:
  259. self.nickname = new
  260. old_info = self.users.search(old)
  261. old_info.nick = new
  262. if not self.users.change(old, new, old_info):
  263. log.error('failed to change nick for user: %s' % new)
  264. if self.check_nick(old, old_info):
  265. if pinylib.CONFIG.B_FORGIVE_AUTO_BANS:
  266. self.send_forgive_msg(uid)
  267. elif uid != self._client_id:
  268. if self.is_client_mod and pinylib.CONFIG.B_GREET:
  269. if old_info.account:
  270. self.send_bot_msg('*Welcome* %s:%s:%s' % (new, uid, old_info.account))
  271. else:
  272. self.send_bot_msg('*Welcome* %s:%s' % (new, uid))
  273. if self.media.has_active_track():
  274. if not self.media.is_mod_playing:
  275. self.send_media_broadcast_start(self.media.track().type,
  276. self.media.track().id,
  277. time_point=self.media.elapsed_track_time(),
  278. private_nick=new)
  279.  
  280. self.console_write(pinylib.COLOR['bright_cyan'], '%s:%s changed nick to: %s' % (old, uid, new))
  281.  
  282.  
  283. def on_yut_play(self, yt_data):
  284. """
  285. Received when a youtube gets started or time searched.
  286.  
  287. This also gets received when the client starts a youtube, the information is
  288. however ignored in that case.
  289.  
  290. :param yt_data: The event information contains info such as the ID (handle) of the user
  291. starting/searching the youtube, the youtube ID, youtube time and so on.
  292. :type yt_data: dict
  293. """
  294. user_nick = 'n/a'
  295. if 'handle' in yt_data:
  296. if yt_data['handle'] != self.client_id:
  297. _user = self.users.search(yt_data['handle'])
  298. user_nick = _user.nick
  299.  
  300. if self.playlist.has_active_track:
  301. self.cancel_timer()
  302.  
  303. if yt_data['item']['offset'] == 0:
  304. # the video was started from the start. (start)
  305. _youtube = youtube.video_details(yt_data['item']['id'], False)
  306. self.playlist.start(user_nick, _youtube)
  307. self.timer(self.playlist.track.time)
  308. self.console_write(pinylib.COLOR['bright_magenta'], '%s started youtube video (%s)' %
  309. (user_nick, yt_data['item']['id']))
  310. elif yt_data['item']['offset'] > 0:
  311. if user_nick == 'n/a':
  312. _youtube = youtube.video_details(yt_data['item']['id'], False)
  313. self.playlist.start(user_nick, _youtube)
  314. offset = self.playlist.play(yt_data['item']['offset'])
  315. self.timer(offset)
  316. else:
  317. offset = self.playlist.play(yt_data['item']['offset'])
  318. self.timer(offset)
  319. self.console_write(pinylib.COLOR['bright_magenta'], '%s searched the youtube video to: %s' %
  320. (user_nick, int(round(yt_data['item']['offset']))))
  321.  
  322. def on_yut_pause(self, yt_data):
  323. """
  324. Received when a youtube gets paused or searched while paused.
  325.  
  326. This also gets received when the client pauses or searches while paused, the information is
  327. however ignored in that case.
  328.  
  329. :param yt_data: The event information contains info such as the ID (handle) of the user
  330. pausing/searching the youtube, the youtube ID, youtube time and so on.
  331. :type yt_data: dict
  332. """
  333. if 'handle' in yt_data:
  334. if yt_data['handle'] != self.client_id:
  335. _user = self.users.search(yt_data['handle'])
  336. if self.playlist.has_active_track:
  337. self.cancel_timer()
  338. self.playlist.pause()
  339. self.console_write(pinylib.COLOR['bright_magenta'], '%s paused the video at %s' %
  340. (_user.nick, int(round(yt_data['item']['offset']))))
  341.  
  342. def message_handler(self, msg):
  343. """
  344. A basic handler for chat messages.
  345.  
  346. Overrides message_handler in pinylib
  347. to allow commands.
  348.  
  349. :param msg: The chat message.
  350. :type msg: str
  351. """
  352. prefix = pinylib.CONFIG.B_PREFIX
  353.  
  354. if msg.startswith(prefix):
  355. # Split the message in to parts.
  356. parts = msg.split(' ')
  357. # parts[0] is the command..
  358. cmd = parts[0].lower().strip()
  359. # The rest is a command argument.
  360. cmd_arg = ' '.join(parts[1:]).strip()
  361.  
  362. if self.has_level(1):
  363. if self.is_client_owner:
  364. if cmd == prefix + 'mod':
  365. threading.Thread(target=self.do_make_mod, args=(cmd_arg,)).start()
  366.  
  367. elif cmd == prefix + 'rmod':
  368. threading.Thread(target=self.do_remove_mod, args=(cmd_arg,)).start()
  369.  
  370. elif cmd == prefix + 'dir':
  371. threading.Thread(target=self.do_directory).start()
  372.  
  373. elif cmd == prefix + 'p2t':
  374. threading.Thread(target=self.do_push2talk).start()
  375.  
  376. elif cmd == prefix + 'crb':
  377. threading.Thread(target=self.do_clear_room_bans).start()
  378.  
  379. if cmd == prefix + 'kill':
  380. self.do_kill()
  381.  
  382. elif cmd == prefix + 'reboot':
  383. self.do_reboot()
  384.  
  385. if self.has_level(2):
  386. if cmd == prefix + 'mi':
  387. self.do_media_info()
  388.  
  389. if self.has_level(3):
  390. if cmd == prefix + 'op':
  391. self.do_op_user(cmd_arg)
  392.  
  393. elif cmd == prefix + 'deop':
  394. self.do_deop_user(cmd_arg)
  395.  
  396. elif cmd == prefix + 'noguest':
  397. self.do_guests()
  398.  
  399. elif cmd == prefix + 'lurkers':
  400. self.do_lurkers()
  401.  
  402. elif cmd == prefix + 'guestnick':
  403. self.do_guest_nicks()
  404.  
  405. elif cmd == prefix + 'greet':
  406. self.do_greet()
  407.  
  408. elif cmd == prefix + 'pub':
  409. self.do_public_cmds()
  410.  
  411. elif cmd == prefix == 'kab':
  412. self.do_kick_as_ban()
  413.  
  414. elif cmd == prefix + 'rs':
  415. self.do_room_settings()
  416.  
  417. elif cmd == prefix + 'top':
  418. threading.Thread(target=self.do_lastfm_chart, args=(cmd_arg,)).start()
  419.  
  420. elif cmd == prefix + 'ran':
  421. threading.Thread(target=self.do_lastfm_random_tunes, args=(cmd_arg,)).start()
  422.  
  423. elif cmd == prefix + 'tag':
  424. threading.Thread(target=self.do_search_lastfm_by_tag, args=(cmd_arg,)).start()
  425.  
  426. elif cmd == prefix + 'pls':
  427. threading.Thread(target=self.do_youtube_playlist_search, args=(cmd_arg,)).start()
  428.  
  429. elif cmd == prefix + 'plp':
  430. threading.Thread(target=self.do_play_youtube_playlist, args=(cmd_arg,)).start()
  431.  
  432. elif cmd == prefix + 'ssl':
  433. self.do_show_search_list()
  434.  
  435. if self.has_level(4):
  436. if cmd == prefix + 'skip':
  437. self.do_skip()
  438.  
  439. elif cmd == prefix + 'del':
  440. self.do_delete_playlist_item(cmd_arg)
  441.  
  442. elif cmd == prefix + 'rpl':
  443. self.do_media_replay()
  444.  
  445. elif cmd == prefix + 'mbpl':
  446. self.do_play_media()
  447.  
  448. elif cmd == prefix + 'mbpa':
  449. self.do_media_pause()
  450.  
  451. elif cmd == prefix + 'seek':
  452. self.do_seek_media(cmd_arg)
  453.  
  454. elif cmd == prefix + 'cm':
  455. self.do_close_media()
  456.  
  457. elif cmd == prefix + 'cpl':
  458. self.do_clear_playlist()
  459.  
  460. elif cmd == prefix + 'spl':
  461. self.do_playlist_info()
  462.  
  463. elif cmd == prefix + 'yts':
  464. threading.Thread(target=self.do_youtube_search, args=(cmd_arg,)).start()
  465.  
  466. elif cmd == prefix + 'pyts':
  467. self.do_play_youtube_search(cmd_arg)
  468.  
  469. elif cmd == prefix + 'clr':
  470. self.do_clear()
  471.  
  472. elif cmd == prefix + 'nick':
  473. self.do_nick(cmd_arg)
  474.  
  475. elif cmd == prefix + 'kick':
  476. threading.Thread(target=self.do_kick, args=(cmd_arg,)).start()
  477.  
  478. elif cmd == prefix + 'ban':
  479. threading.Thread(target=self.do_ban, args=(cmd_arg,)).start()
  480.  
  481. elif cmd == prefix + 'bn':
  482. self.do_bad_nick(cmd_arg)
  483.  
  484. elif cmd == prefix + 'rmbn':
  485. self.do_remove_bad_nick(cmd_arg)
  486.  
  487. elif cmd == prefix + 'tokes':
  488. threading.Thread(target=self.do_tokes, args=(cmd_arg,)).start()
  489.  
  490. elif cmd == prefix + 'bs':
  491. self.do_bad_string(cmd_arg)
  492.  
  493. elif cmd == prefix + 'rmbs':
  494. self.do_remove_bad_string(cmd_arg)
  495.  
  496. elif cmd == prefix + 'ba':
  497. self.do_bad_account(cmd_arg)
  498.  
  499. elif cmd == prefix + 'rmba':
  500. self.do_remove_bad_account(cmd_arg)
  501.  
  502. elif cmd == prefix + 'list':
  503. self.do_list_info(cmd_arg)
  504.  
  505. elif cmd == prefix + 'uinfo':
  506. self.do_user_info(cmd_arg)
  507.  
  508. elif cmd == prefix + 'cam':
  509. self.do_cam_approve(cmd_arg)
  510.  
  511. elif cmd == prefix + 'close':
  512. self.do_close_broadcast(cmd_arg)
  513.  
  514. if (pinylib.CONFIG.B_PUBLIC_CMD and self.has_level(5)) or self.active_user.user_level < 5:
  515. if cmd == prefix + 'v':
  516. self.do_version()
  517.  
  518. elif cmd == prefix + 'help':
  519. self.do_help()
  520.  
  521. elif cmd == prefix + 't':
  522. self.do_uptime()
  523.  
  524. elif cmd == prefix + 'yt':
  525. threading.Thread(target=self.do_play_youtube, args=(cmd_arg,)).start()
  526.  
  527. elif cmd == prefix + 'q':
  528. self.do_playlist_status()
  529.  
  530. elif cmd == prefix + 'n':
  531. self.do_next_tune_in_playlist()
  532.  
  533. elif cmd == prefix + 'np':
  534. self.do_now_playing()
  535.  
  536. elif cmd == prefix + 'wp':
  537. self.do_who_plays()
  538.  
  539. # Tinychat API commands.
  540. elif cmd == prefix + 'spy':
  541. threading.Thread(target=self.do_spy, args=(cmd_arg,)).start()
  542.  
  543. elif cmd == prefix + 'acspy':
  544. threading.Thread(target=self.do_account_spy, args=(cmd_arg,)).start()
  545.  
  546. # Other API commands.
  547. elif cmd == prefix + 'urb':
  548. threading.Thread(target=self.do_search_urban_dictionary, args=(cmd_arg,)).start()
  549.  
  550. elif cmd == prefix + 'wea':
  551. threading.Thread(target=self.do_weather_search, args=(cmd_arg,)).start()
  552.  
  553. elif cmd == prefix + 'ip':
  554. threading.Thread(target=self.do_whois_ip, args=(cmd_arg,)).start()
  555.  
  556. # Just for fun.
  557. elif cmd == prefix + 'cn':
  558. threading.Thread(target=self.do_chuck_noris).start()
  559.  
  560. elif cmd == prefix + '8ball':
  561. self.do_8ball(cmd_arg)
  562.  
  563. elif cmd == prefix + 'roll':
  564. self.do_dice()
  565.  
  566. elif cmd == prefix + 'flip':
  567. self.do_flip_coin()
  568.  
  569. if cmd == prefix + 'pmme':
  570. self.do_pmme()
  571.  
  572. # Print command to console.
  573. self.console_write(pinylib.COLOR['yellow'], self.active_user.nick + ': ' + cmd + ' ' + cmd_arg)
  574. else:
  575. # Print chat message to console.
  576. self.console_write(pinylib.COLOR['green'], self.active_user.nick + ': ' + msg)
  577. # Only check chat msg for ban string if we are mod.
  578. if self.is_client_mod and self.active_user.user_level > 4:
  579. threading.Thread(target=self.check_msg, args=(msg,)).start()
  580.  
  581. self.active_user.last_msg = msg
  582.  
  583. # Level 1 Command methods.
  584. def do_make_mod(self, account):
  585. """
  586. Make a tinychat account a room moderator.
  587.  
  588. :param account: The account to make a moderator.
  589. :type account: str
  590. """
  591. if self.is_client_owner:
  592. if len(account) is 0:
  593. self.send_chat_msg('Missing account name.')
  594. else:
  595. tc_user = self.privacy_.make_moderator(account)
  596. if tc_user is None:
  597. self.send_chat_msg('The account is invalid.')
  598. elif not tc_user:
  599. self.send_chat_msg('%s is already a moderator.' % account)
  600. elif tc_user:
  601. self.send_chat_msg('%s was made a room moderator.' % account)
  602.  
  603. def do_remove_mod(self, account):
  604. """
  605. Removes a tinychat account from the moderator list.
  606.  
  607. :param account: The account to remove from the moderator list.
  608. :type account: str
  609. """
  610. if self.is_client_owner:
  611. if len(account) is 0:
  612. self.send_chat_msg('Missing account name.')
  613. else:
  614. tc_user = self.privacy_.remove_moderator(account)
  615. if tc_user:
  616. self.send_chat_msg('%s is no longer a room moderator.' % account)
  617. elif not tc_user:
  618. self.send_chat_msg('%s is not a room moderator.' % account)
  619.  
  620. def do_directory(self):
  621. """ Toggles if the room should be shown on the directory. """
  622. if self.is_client_owner:
  623. if self.privacy_.show_on_directory():
  624. self.send_chat_msg('Room IS shown on the directory.')
  625. else:
  626. self.send_chat_msg('Room is NOT shown on the directory.')
  627.  
  628. def do_push2talk(self):
  629. """ Toggles if the room should be in push2talk mode. """
  630. if self.is_client_owner:
  631. if self.privacy_.set_push2talk():
  632. self.send_chat_msg('Push2Talk is enabled.')
  633. else:
  634. self.send_chat_msg('Push2Talk is disabled.')
  635.  
  636. def do_green_room(self):
  637. """ Toggles if the room should be in greenroom mode. """
  638. if self.is_client_owner:
  639. if self.privacy_.set_greenroom():
  640. self.send_chat_msg('Green room is enabled.')
  641. else:
  642. self.send_chat_msg('Green room is disabled.')
  643.  
  644. def do_clear_room_bans(self):
  645. """ Clear all room bans. """
  646. # NOTE: This might not be needed in this version
  647. if self.is_client_owner:
  648. if self.privacy_.clear_bans():
  649. self.send_chat_msg('All room bans was cleared.')
  650.  
  651. def do_kill(self):
  652. """ Kills the bot. """
  653. self.disconnect()
  654.  
  655. def do_reboot(self):
  656. """ Reboots the bot. """
  657. self.reconnect()
  658.  
  659. # Level 2 Command Methods.
  660. def do_media_info(self):
  661. """ Show information about the currently playing youtube. """
  662. if self.is_client_mod and self.playlist.has_active_track:
  663. self.send_chat_msg(
  664. 'Playlist Tracks: ' + str(len(self.playlist.track_list)) + '\n' +
  665. 'Track Title: ' + self.playlist.track.title + '\n' +
  666. 'Track Index: ' + str(self.playlist.track_index) + '\n' +
  667. 'Elapsed Track Time: ' + self.format_time(self.playlist.elapsed) + '\n' +
  668. 'Remaining Track Time: ' + self.format_time(self.playlist.remaining)
  669. )
  670.  
  671. # Level 3 Command Methods.
  672. def do_op_user(self, user_name):
  673. """
  674. Lets the room owner, a mod or a bot controller make another user a bot controller.
  675.  
  676. :param user_name: The user to op.
  677. :type user_name: str
  678. """
  679. if self.is_client_mod:
  680. if len(user_name) is 0:
  681. self.send_chat_msg('Missing username.')
  682. else:
  683. _user = self.users.search_by_nick(user_name)
  684. if _user is not None:
  685. _user.user_level = 4
  686. self.send_chat_msg('%s is now a bot controller (L4)' % user_name)
  687. else:
  688. self.send_chat_msg('No user named: %s' % user_name)
  689.  
  690. def do_deop_user(self, user_name):
  691. """
  692. Lets the room owner, a mod or a bot controller remove a user from being a bot controller.
  693.  
  694. :param user_name: The user to deop.
  695. :type user_name: str
  696. """
  697. if self.is_client_mod:
  698. if len(user_name) is 0:
  699. self.send_chat_msg('Missing username.')
  700. else:
  701. _user = self.users.search_by_nick(user_name)
  702. if _user is not None:
  703. _user.user_level = 5
  704. self.send_chat_msg('%s is not a bot controller anymore (L5)' % user_name)
  705. else:
  706. self.send_chat_msg('No user named: %s' % user_name)
  707.  
  708. def do_guests(self):
  709. """ Toggles if guests are allowed to join the room or not. """
  710. pinylib.CONFIG.B_ALLOW_GUESTS = not pinylib.CONFIG.B_ALLOW_GUESTS
  711. self.send_chat_msg('Allow Guests: %s' % pinylib.CONFIG.B_ALLOW_GUESTS)
  712.  
  713. def do_lurkers(self):
  714. """ Toggles if lurkers are allowed or not. """
  715. pinylib.CONFIG.B_ALLOW_LURKERS = not pinylib.CONFIG.B_ALLOW_LURKERS
  716. self.send_chat_msg('Allowe Lurkers: %s' % pinylib.CONFIG.B_ALLOW_LURKERS)
  717.  
  718. def do_guest_nicks(self):
  719. """ Toggles if guest nicks are allowed or not. """
  720. pinylib.CONFIG.B_ALLOW_GUESTS_NICKS = not pinylib.CONFIG.B_ALLOW_GUESTS_NICKS
  721. self.send_chat_msg('Allow Guest Nicks: %s' % pinylib.CONFIG.B_ALLOW_GUESTS_NICKS)
  722.  
  723. def do_greet(self):
  724. """ Toggles if users should be greeted on entry. """
  725. pinylib.CONFIG.B_GREET = not pinylib.CONFIG.B_GREET
  726. self.send_chat_msg('Greet Users: %s' % pinylib.CONFIG.B_GREET)
  727.  
  728. def do_public_cmds(self):
  729. """ Toggles if public commands are public or not. """
  730. pinylib.CONFIG.B_PUBLIC_CMD = not pinylib.CONFIG.B_PUBLIC_CMD
  731. self.send_chat_msg('Public Commands Enabled: %s' % pinylib.CONFIG.B_PUBLIC_CMD)
  732.  
  733. def do_kick_as_ban(self):
  734. """ Toggles if kick should be used instead of ban for auto bans . """
  735. pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN = not pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN
  736. self.send_chat_msg('Use Kick As Auto Ban: %s' % pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN)
  737.  
  738. def do_room_settings(self):
  739. """ Shows current room settings. """
  740. if self.is_client_owner:
  741. settings = self.privacy_.current_settings()
  742. self.send_chat_msg(
  743. 'Broadcast Password: ' + settings['broadcast_pass'] + '\n' +
  744. 'Room Password: ' + settings['room_pass'] + '\n' +
  745. 'Login Type: ' + settings['allow_guest'] + '\n' +
  746. 'Directory: ' + settings['show_on_directory'] + '\n' +
  747. 'Push2Talk: ' + settings['push2talk'] + '\n' +
  748. 'Greenroom: ' + settings['greenroom']
  749. )
  750.  
  751. def do_lastfm_chart(self, chart_items):
  752. """
  753. Create a playlist from the most played tracks on last.fm.
  754.  
  755. :param chart_items: The maximum amount of chart items.
  756. :type chart_items: str | int
  757. """
  758. if self.is_client_mod:
  759. if len(chart_items) == 0 or chart_items is None:
  760. self.send_chat_msg('Please specify the max amount of tracks you want.')
  761. else:
  762. try:
  763. chart_items = int(chart_items)
  764. except ValueError:
  765. self.send_chat_msg('Only numbers allowed.')
  766. else:
  767. if 0 < chart_items < 30:
  768. self.send_chat_msg('Please wait while creating a playlist...')
  769. _items = lastfm.chart(chart_items)
  770. if _items is not None:
  771. self.playlist.add_list(self.active_user.nick, _items)
  772. self.send_chat_msg('Added ' + str(len(_items)) + 'tracks from last.fm chart.')
  773. if not self.playlist.has_active_track:
  774. track = self.playlist.next_track
  775. self.send_yut_play(track.id, track.time, track.title)
  776. self.timer(track.time)
  777. else:
  778. self.send_chat_msg('Failed to retrieve a result from last.fm.')
  779. else:
  780. self.send_chat_msg('No more than 30 tracks.')
  781.  
  782. def do_lastfm_random_tunes(self, max_tracks):
  783. """
  784. Creates a playlist from what other people are listening to on last.fm
  785.  
  786. :param max_tracks: The miximum amount of tracks.
  787. :type max_tracks: str | int
  788. """
  789. if self.is_client_mod:
  790. if len(max_tracks) == 0 or max_tracks is None:
  791. self.send_chat_msg('Please specify the max amount of tunes you want.')
  792. else:
  793. try:
  794. max_tracks = int(max_tracks)
  795. except ValueError:
  796. self.send_chat_msg('Only numbers allowed.')
  797. else:
  798. if 0 < max_tracks < 50:
  799. self.send_chat_msg('Please wait while creating playlist...')
  800. _items = lastfm.listening_now(max_tracks)
  801. if _items is not None:
  802. self.playlist.add_list(self.active_user.nick, _items)
  803. self.send_chat_msg('Added ' + str(len(_items)) + 'tracks from last.fm')
  804. if not self.playlist.has_active_track:
  805. track = self.playlist.next_track
  806. self.send_yut_play(track.id, track.time, track.title)
  807. self.timer(track.time)
  808. else:
  809. self.send_chat_msg('Failed to retrieve a result from last.fm.')
  810. else:
  811. self.send_chat_msg('No more than 50 tracks.')
  812.  
  813. def do_search_lastfm_by_tag(self, search_str):
  814. """
  815. Search last.fm for tunes matching a tag.
  816.  
  817. :param search_str: The search tag to search for.
  818. :type search_str: str
  819. """
  820. if self.is_client_mod:
  821. if len(search_str) == 0 or search_str is None:
  822. self.send_chat_msg('Missing search string.')
  823. else:
  824. self.send_chat_msg('Please wait while creating playlist..')
  825. _items = lastfm.tag_search(search_str)
  826. if _items is not None:
  827. self.playlist.add_list(self.active_user.nick, _items)
  828. self.send_chat_msg('Added ' + str(len(_items)) + 'tracks from last.fm')
  829. if not self.playlist.has_active_track:
  830. track = self.playlist.next_track
  831. self.send_yut_play(track.id, track.time, track.title)
  832. self.timer(track.time)
  833. else:
  834. self.send_chat_msg('Failed to retrieve a result from last.fm.')
  835.  
  836. def do_youtube_playlist_search(self, search_str):
  837. """
  838. Search youtube for a playlist.
  839.  
  840. :param search_str: The search term to search for.
  841. :type search_str: str
  842. """
  843. if self.is_client_mod:
  844. if len(search_str) == 0:
  845. self.send_chat_msg('Missing search string.')
  846. else:
  847. self.search_list = youtube.playlist_search(search_str)
  848. if len(self.search_list) > 0:
  849. self.is_search_list_yt_playlist = True
  850. _ = '\n'.join('(%s) %s' % (i, d['playlist_title']) for i, d in enumerate(self.search_list))
  851. self.send_chat_msg(_)
  852. else:
  853. self.send_chat_msg('Failed to find playlist matching search term: %s' % search_str)
  854.  
  855. def do_play_youtube_playlist(self, int_choice):
  856. """
  857. Play a previous searched playlist.
  858.  
  859. :param int_choice: The index of the playlist.
  860. :type int_choice: str | int
  861. """
  862. if self.is_client_mod:
  863. if self.is_search_list_yt_playlist:
  864. try:
  865. int_choice = int(int_choice)
  866. except ValueError:
  867. self.send_chat_msg('Only numbers allowed.')
  868. else:
  869. if 0 <= int_choice <= len(self.search_list) - 1:
  870. self.send_chat_msg('Please wait while creating playlist..')
  871. tracks = youtube.playlist_videos(self.search_list[int_choice])
  872. if len(tracks) > 0:
  873. self.playlist.add_list(self.active_user.nick, tracks)
  874. self.send_chat_msg('Added %s tracks from youtube playlist.' % len(tracks))
  875. if not self.playlist.has_active_track:
  876. track = self.playlist.next_track
  877. self.send_yut_play(track.id, track.time, track.title)
  878. self.timer(track.time)
  879. else:
  880. self.send_chat_msg('Failed to retrieve videos from youtube playlist.')
  881. else:
  882. self.send_chat_msg('Please make a choice between 0-%s' % str(len(self.search_list) - 1))
  883. else:
  884. self.send_chat_msg('The search list does not contain any youtube playlist id\'s.')
  885.  
  886. def do_show_search_list(self):
  887. """ Show what the search list contains. """
  888. if self.is_client_mod:
  889. if len(self.search_list) == 0:
  890. self.send_chat_msg('The search list is empty.')
  891. elif self.is_search_list_yt_playlist:
  892. _ = '\n'.join('(%s) - %s' % (i, d['playlist_title']) for i, d in enumerate(self.search_list))
  893. self.send_chat_msg('Youtube Playlist\'s\n' + _)
  894. else:
  895. _ = '\n'.join('(%s) %s %s' % (i, d['video_title'], self.format_time(d['video_time']))
  896. for i, d in enumerate(self.search_list))
  897. self.send_chat_msg('Youtube Tracks\n' + _)
  898.  
  899. # Level 4 Command Methods.
  900. def do_skip(self):
  901. """ Skip to the next item in the playlist. """
  902. if self.is_client_mod:
  903. if self.playlist.is_last_track is None:
  904. self.send_chat_msg('No tunes to skip. The playlist is empty.')
  905. elif self.playlist.is_last_track:
  906. self.send_chat_msg('This is the last track in the playlist.')
  907. else:
  908. self.cancel_timer()
  909. next_track = self.playlist.next_track
  910. self.send_yut_play(next_track.id, next_track.time, next_track.title)
  911. self.timer(next_track.time)
  912.  
  913. def do_delete_playlist_item(self, to_delete): # TODO: Make sure this is working.
  914. """
  915. Delete items from the playlist.
  916.  
  917. :param to_delete: Item indexes to delete.
  918. :type to_delete: str
  919. """
  920. if self.is_client_mod:
  921. if len(self.playlist.track_list) == 0:
  922. self.send_chat_msg('The playlist is empty.')
  923. elif len(to_delete) == 0:
  924. self.send_chat_msg('No indexes provided.')
  925. else:
  926. indexes = None
  927. by_range = False
  928.  
  929. try:
  930. if ':' in to_delete:
  931. range_indexes = map(int, to_delete.split(':'))
  932. temp_indexes = range(range_indexes[0], range_indexes[1] + 1)
  933. if len(temp_indexes) > 1:
  934. by_range = True
  935. else:
  936. temp_indexes = map(int, to_delete.split(','))
  937. except ValueError as ve:
  938. log.error('wrong format: %s' % ve)
  939. else:
  940. indexes = []
  941. for i in temp_indexes:
  942. if i < len(self.playlist.track_list) and i not in indexes:
  943. indexes.append(i)
  944.  
  945. if indexes is not None and len(indexes) > 0:
  946. result = self.playlist.delete(indexes, by_range)
  947. if result is not None:
  948. if by_range:
  949. self.send_chat_msg('Deleted from index: %s to index: %s' %
  950. (result['from'], result['to']))
  951. elif result['deleted_indexes_len'] is 1:
  952. self.send_chat_msg('Deleted %s' % result['track_title'])
  953. else:
  954. self.send_chat_msg('Deleted tracks at index: %s' %
  955. ', '.join(result['deleted_indexes']))
  956. else:
  957. self.send_chat_msg('Nothing was deleted.')
  958.  
  959. def do_media_replay(self):
  960. """ Replay the currently playing track. """
  961. if self.is_client_mod:
  962. if self.playlist.track is not None:
  963. self.cancel_timer()
  964. track = self.playlist.replay()
  965. self.send_yut_play(track.id, track.time, track.title)
  966. self.timer(track.time)
  967.  
  968. def do_play_media(self):
  969. """ Play a track on pause . """
  970. if self.is_client_mod:
  971. if self.playlist.track is not None:
  972. if self.playlist.has_active_track:
  973. self.cancel_timer()
  974. if self.playlist.is_paused:
  975. self.playlist.play(self.playlist.elapsed)
  976. self.send_yut_play(self.playlist.track.id, self.playlist.track.time,
  977. self.playlist.track.title, self.playlist.elapsed) #
  978. self.timer(self.playlist.remaining)
  979.  
  980. def do_media_pause(self):
  981. """ Pause a track. """
  982. if self.is_client_mod:
  983. track = self.playlist.track
  984. if track is not None:
  985. if self.playlist.has_active_track:
  986. self.cancel_timer()
  987. self.playlist.pause()
  988. self.send_yut_pause(track.id, track.time, self.playlist.elapsed)
  989.  
  990. def do_close_media(self):
  991. """ Close a track playing. """
  992. if self.is_client_mod:
  993. if self.playlist.has_active_track:
  994. self.cancel_timer()
  995. self.playlist.stop()
  996. self.send_yut_stop(self.playlist.track.id, self.playlist.track.time, self.playlist.elapsed)
  997.  
  998. def do_seek_media(self, time_point):
  999. """
  1000. Time search a track.
  1001.  
  1002. :param time_point: The time point in which to search to.
  1003. :type time_point: str
  1004. """
  1005. if self.is_client_mod:
  1006. if ('h' in time_point) or ('m' in time_point) or ('s' in time_point):
  1007. offset = pinylib.string_util.convert_to_seconds(time_point)
  1008. if offset == 0:
  1009. self.send_chat_msg('Invalid seek time.')
  1010. else:
  1011. track = self.playlist.track
  1012. if track is not None:
  1013. if 0 < offset < track.time:
  1014. if self.playlist.has_active_track:
  1015. self.cancel_timer()
  1016. if self.playlist.is_paused:
  1017. self.playlist.pause(offset=offset) #
  1018. self.send_yut_pause(track.id, track.time, offset)
  1019. else:
  1020. self.playlist.play(offset)
  1021. self.send_yut_play(track.id, track.time, track.title, offset)
  1022. self.timer(self.playlist.remaining)
  1023.  
  1024. def do_clear_playlist(self):
  1025. """ Clear the playlist for items."""
  1026. if self.is_client_mod:
  1027. if len(self.playlist.track_list) > 0:
  1028. pl_length = str(len(self.playlist.track_list))
  1029. self.playlist.clear()
  1030. self.send_chat_msg('Deleted %s items in the playlist.' % pl_length)
  1031. else:
  1032. self.send_chat_msg('The playlist is empty, nothing to delete.')
  1033.  
  1034. def do_playlist_info(self): # TODO: this needs more work !
  1035. """ Shows the next tracks in the playlist. """
  1036. if self.is_client_mod:
  1037. if len(self.playlist.track_list) > 0:
  1038. tracks = self.playlist.get_tracks()
  1039. if len(tracks) > 0:
  1040. # If i is 0 then mark that as the next track
  1041. _ = '\n'.join('(%s) - %s %s' % (track[0], track[1].title, self.format_time(track[1].time))
  1042. for i, track in enumerate(tracks))
  1043. self.send_chat_msg(_)
  1044.  
  1045. def do_youtube_search(self, search_str):
  1046. """
  1047. Search youtube for a list of matching candidates.
  1048.  
  1049. :param search_str: The search term to search for.
  1050. :type search_str: str
  1051. """
  1052. if self.is_client_mod:
  1053. if len(search_str) == 0:
  1054. self.send_chat_msg('Missing search string.')
  1055. else:
  1056. self.search_list = youtube.search_list(search_str, results=5)
  1057. if len(self.search_list) > 0:
  1058. self.is_search_list_yt_playlist = False
  1059. _ = '\n'.join('(%s) %s %s' % (i, d['video_title'], self.format_time(d['video_time']))
  1060. for i, d in enumerate(self.search_list)) #
  1061. self.send_chat_msg(_)
  1062. else:
  1063. self.send_chat_msg('Could not find anything matching: %s' % search_str)
  1064.  
  1065. def do_play_youtube_search(self, int_choice):
  1066. """
  1067. Play a track from a previous youtube search list.
  1068.  
  1069. :param int_choice: The index of the track in the search.
  1070. :type int_choice: str | int
  1071. """
  1072. if self.is_client_mod:
  1073. if not self.is_search_list_yt_playlist:
  1074. if len(self.search_list) > 0:
  1075. try:
  1076. int_choice = int(int_choice)
  1077. except ValueError:
  1078. self.send_chat_msg('Only numbers allowed.')
  1079. else:
  1080. if 0 <= int_choice <= len(self.search_list) - 1:
  1081.  
  1082. if self.playlist.has_active_track:
  1083. track = self.playlist.add(self.active_user.nick, self.search_list[int_choice])
  1084. self.send_chat_msg('Added (%s) %s %s' %
  1085. (self.playlist.last_index,
  1086. track.title, self.format_time(track.time)))
  1087. else:
  1088. track = self.playlist.start(self.active_user.nick, self.search_list[int_choice])
  1089. self.send_yut_play(track.id, track.time, track.title)
  1090. self.timer(track.time)
  1091. else:
  1092. self.send_chat_msg('Please make a choice between 0-%s' % str(len(self.search_list) - 1))
  1093. else:
  1094. self.send_chat_msg('No youtube track id\'s in the search list.')
  1095. else:
  1096. self.send_chat_msg('The search list only contains youtube playlist id\'s.')
  1097.  
  1098. def do_clear(self):
  1099. """ Clears the chat box. """
  1100. self.send_chat_msg('_\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'
  1101. '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n_')
  1102.  
  1103. def do_nick(self, new_nick):
  1104. """
  1105. Set a new nick for the bot.
  1106.  
  1107. :param new_nick: The new nick name.
  1108. :type new_nick: str
  1109. """
  1110. if len(new_nick) is 0:
  1111. self.nickname = pinylib.string_util.create_random_string(5, 25)
  1112. self.set_nick()
  1113. else:
  1114. self.nickname = new_nick
  1115. self.set_nick()
  1116.  
  1117. def do_kick(self, user_name):
  1118. """
  1119. Kick a user out of the room.
  1120.  
  1121. :param user_name: The username to kick.
  1122. :type user_name: str
  1123. """
  1124. if self.is_client_mod:
  1125. if len(user_name) is 0:
  1126. self.send_chat_msg('Missing username.')
  1127. elif user_name == self.nickname:
  1128. self.send_chat_msg('Action not allowed.')
  1129. else:
  1130. if user_name.startswith('*'):
  1131. user_name = user_name.replace('*', '')
  1132. _users = self.users.search_containing(user_name)
  1133. if len(_users) > 0:
  1134. for i, user in enumerate(_users):
  1135. if user.nick != self.nickname and user.user_level > self.active_user.user_level:
  1136. if i <= pinylib.CONFIG.B_MAX_MATCH_BANS - 1:
  1137. self.send_kick_msg(user.id)
  1138. else:
  1139. _user = self.users.search_by_nick(user_name)
  1140. if _user is None:
  1141. self.send_chat_msg('No user named: %s' % user_name)
  1142. elif _user.user_level < self.active_user.user_level:
  1143. self.send_chat_msg('Not allowed.')
  1144. else:
  1145. self.send_kick_msg(_user.id)
  1146.  
  1147. def do_ban(self, user_name):
  1148. """
  1149. Ban a user from the room.
  1150.  
  1151. :param user_name: The username to ban.
  1152. :type user_name: str
  1153. """
  1154. if self.is_client_mod:
  1155. if len(user_name) is 0:
  1156. self.send_chat_msg('Missing username.')
  1157. elif user_name == self.nickname:
  1158. self.send_chat_msg('Action not allowed.')
  1159. else:
  1160. if user_name.startswith('*'):
  1161. user_name = user_name.replace('*', '')
  1162. _users = self.users.search_containing(user_name)
  1163. if len(_users) > 0:
  1164. for i, user in enumerate(_users):
  1165. if user.nick != self.nickname and user.user_level > self.active_user.user_level:
  1166. if i <= pinylib.CONFIG.B_MAX_MATCH_BANS - 1:
  1167. self.send_ban_msg(user.id)
  1168. else:
  1169. _user = self.users.search_by_nick(user_name)
  1170. if _user is None:
  1171. self.send_chat_msg('No user named: %s' % user_name)
  1172. elif _user.user_level < self.active_user.user_level:
  1173. self.send_chat_msg('Not allowed.')
  1174. else:
  1175. self.send_ban_msg(_user.id)
  1176.  
  1177. def do_bad_nick(self, bad_nick):
  1178. """
  1179. Adds a username to the nick bans file.
  1180.  
  1181. :param bad_nick: The bad nick to write to the nick bans file.
  1182. :type bad_nick: str
  1183. """
  1184. if self.is_client_mod:
  1185. if len(bad_nick) is 0:
  1186. self.send_chat_msg('Missing username.')
  1187. elif bad_nick in pinylib.CONFIG.B_NICK_BANS:
  1188. self.send_chat_msg('%s is already in list.' % bad_nick)
  1189. else:
  1190. pinylib.file_handler.file_writer(self.config_path,
  1191. pinylib.CONFIG.B_NICK_BANS_FILE_NAME, bad_nick)
  1192. self.send_chat_msg('%s was added to file.' % bad_nick)
  1193. self.load_list(nicks=True)
  1194.  
  1195. def do_remove_bad_nick(self, bad_nick):
  1196. """
  1197. Removes nick from the nick bans file.
  1198.  
  1199. :param bad_nick: The bad nick to remove from the nick bans file.
  1200. :type bad_nick: str
  1201. """
  1202. if self.is_client_mod:
  1203. if len(bad_nick) is 0:
  1204. self.send_chat_msg('Missing username')
  1205. else:
  1206. if bad_nick in pinylib.CONFIG.B_NICK_BANS:
  1207. rem = pinylib.file_handler.remove_from_file(self.config_path,
  1208. pinylib.CONFIG.B_NICK_BANS_FILE_NAME,
  1209. bad_nick)
  1210. if rem:
  1211. self.send_chat_msg('%s was removed.' % bad_nick)
  1212. self.load_list(nicks=True)
  1213.  
  1214. def do_bad_string(self, bad_string):
  1215. """
  1216. Adds a string to the string bans file.
  1217.  
  1218. :param bad_string: The bad string to add to the string bans file.
  1219. :type bad_string: str
  1220. """
  1221. if self.is_client_mod:
  1222. if len(bad_string) is 0:
  1223. self.send_chat_msg('Ban string can\'t be blank.')
  1224. elif len(bad_string) < 3:
  1225. self.send_chat_msg('Ban string to short: ' + str(len(bad_string)))
  1226. elif bad_string in pinylib.CONFIG.B_STRING_BANS:
  1227. self.send_chat_msg('%s is already in list.' % bad_string)
  1228. else:
  1229. pinylib.file_handler.file_writer(self.config_path,
  1230. pinylib.CONFIG.B_STRING_BANS_FILE_NAME, bad_string)
  1231. self.send_chat_msg('%s was added to file.' % bad_string)
  1232. self.load_list(strings=True)
  1233.  
  1234. def do_remove_bad_string(self, bad_string):
  1235. """
  1236. Removes a string from the string bans file.
  1237.  
  1238. :param bad_string: The bad string to remove from the string bans file.
  1239. :type bad_string: str
  1240. """
  1241. if self.is_client_mod:
  1242. if len(bad_string) is 0:
  1243. self.send_chat_msg('Missing word string.')
  1244. else:
  1245. if bad_string in pinylib.CONFIG.B_STRING_BANS:
  1246. rem = pinylib.file_handler.remove_from_file(self.config_path,
  1247. pinylib.CONFIG.B_STRING_BANS_FILE_NAME,
  1248. bad_string)
  1249. if rem:
  1250. self.send_chat_msg('%s was removed.' % bad_string)
  1251. self.load_list(strings=True)
  1252.  
  1253. def do_bad_account(self, bad_account_name):
  1254. """
  1255. Adds an account name to the account bans file.
  1256.  
  1257. :param bad_account_name: The bad account name to add to the account bans file.
  1258. :type bad_account_name: str
  1259. """
  1260. if self.is_client_mod:
  1261. if len(bad_account_name) is 0:
  1262. self.send_chat_msg('Account can\'t be blank.')
  1263. elif len(bad_account_name) < 3:
  1264. self.send_chat_msg('Account to short: ' + str(len(bad_account_name)))
  1265. elif bad_account_name in pinylib.CONFIG.B_ACCOUNT_BANS:
  1266. self.send_chat_msg('%s is already in list.' % bad_account_name)
  1267. else:
  1268. pinylib.file_handler.file_writer(self.config_path,
  1269. pinylib.CONFIG.B_ACCOUNT_BANS_FILE_NAME,
  1270. bad_account_name)
  1271. self.send_chat_msg('%s was added to file.' % bad_account_name)
  1272. self.load_list(accounts=True)
  1273.  
  1274. def do_remove_bad_account(self, bad_account):
  1275. """
  1276. Removes an account from the account bans file.
  1277.  
  1278. :param bad_account: The badd account name to remove from account bans file.
  1279. :type bad_account: str
  1280. """
  1281. if self.is_client_mod:
  1282. if len(bad_account) is 0:
  1283. self.send_chat_msg('Missing account.')
  1284. else:
  1285. if bad_account in pinylib.CONFIG.B_ACCOUNT_BANS:
  1286. rem = pinylib.file_handler.remove_from_file(self.config_path,
  1287. pinylib.CONFIG.B_ACCOUNT_BANS_FILE_NAME,
  1288. bad_account)
  1289. if rem:
  1290. self.send_chat_msg('%s was removed.' % bad_account)
  1291. self.load_list(accounts=True)
  1292.  
  1293. def do_list_info(self, list_type):
  1294. """
  1295. Shows info of different lists/files.
  1296.  
  1297. :param list_type: The type of list to find info for.
  1298. :type list_type: str
  1299. """
  1300. if self.is_client_mod:
  1301. if len(list_type) is 0:
  1302. self.send_chat_msg('Missing list type.')
  1303. else:
  1304. if list_type.lower() == 'bn':
  1305. if len(pinylib.CONFIG.B_NICK_BANS) is 0:
  1306. self.send_chat_msg('No items in this list.')
  1307. else:
  1308. self.send_chat_msg('%s nicks bans in list.' % len(pinylib.CONFIG.B_NICK_BANS))
  1309.  
  1310. elif list_type.lower() == 'bs':
  1311. if len(pinylib.CONFIG.B_STRING_BANS) is 0:
  1312. self.send_chat_msg('No items in this list.')
  1313. else:
  1314. self.send_chat_msg('%s string bans in list.' % pinylib.CONFIG.B_STRING_BANS)
  1315.  
  1316. elif list_type.lower() == 'ba':
  1317. if len(pinylib.CONFIG.B_ACCOUNT_BANS) is 0:
  1318. self.send_chat_msg('No items in this list.')
  1319. else:
  1320. self.send_chat_msg('%s account bans in list.' % pinylib.CONFIG.B_ACCOUNT_BANS)
  1321.  
  1322. elif list_type.lower() == 'mods':
  1323. if self.is_client_owner:
  1324. if len(self.privacy_.room_moderators) is 0:
  1325. self.send_chat_msg('There is currently no moderators for this room.')
  1326. elif len(self.privacy_.room_moderators) is not 0:
  1327. mods = ', '.join(self.privacy_.room_moderators)
  1328. self.send_chat_msg('Moderators: ' + mods)
  1329.  
  1330. def do_user_info(self, user_name):
  1331. """
  1332. Shows user object info for a given user name.
  1333.  
  1334. :param user_name: The user name of the user to show the info for.
  1335. :type user_name: str
  1336. """
  1337. if self.is_client_mod:
  1338. if len(user_name) is 0:
  1339. self.send_chat_msg('Missing username.')
  1340. else:
  1341. _user = self.users.search_by_nick(user_name)
  1342. if _user is None:
  1343. self.send_chat_msg('No user named: %s' % user_name)
  1344. else:
  1345. if _user.account and _user.tinychat_id is None:
  1346. user_info = pinylib.apis.tinychat.user_info(_user.account)
  1347. if user_info is not None:
  1348. _user.tinychat_id = user_info['tinychat_id']
  1349. _user.last_login = user_info['last_active']
  1350. online_time = (pinylib.time.time() - _user.join_time)
  1351.  
  1352. info = [
  1353. 'User Level: ' + str(_user.user_level),
  1354. 'Online Time: ' + self.format_time(online_time),
  1355. 'Last Message: ' + str(_user.last_msg)
  1356. ]
  1357. if _user.tinychat_id is not None:
  1358. info.append('Account: ' + str(_user.account))
  1359. info.append('Tinychat ID: ' + str(_user.tinychat_id))
  1360. info.append('Last Login: ' + _user.last_login)
  1361.  
  1362. self.send_chat_msg('\n'.join(info))
  1363.  
  1364. def do_cam_approve(self, user_name):
  1365. """
  1366. Allow a user to broadcast in a green room enabled room.
  1367.  
  1368. :param user_name: The name of the user allowed to broadcast.
  1369. :type user_name: str
  1370. """
  1371. if self.is_green_room and self.is_client_mod:
  1372. if len(user_name) == 0 and self.active_user.is_waiting:
  1373. self.send_cam_approve_msg(self.active_user.id)
  1374. elif len(user_name) > 0:
  1375. _user = self.users.search_by_nick(user_name)
  1376. if _user is not None and _user.is_waiting:
  1377. self.send_cam_approve_msg(_user.id)
  1378. else:
  1379. self.send_chat_msg('No user named: %s' % user_name)
  1380.  
  1381. def do_close_broadcast(self, user_name):
  1382. """
  1383. Close a users broadcast.
  1384.  
  1385. :param user_name: The name of the user to close.
  1386. :type user_name: str
  1387. """
  1388. if self.is_client_mod:
  1389. if len(user_name) == 0:
  1390. self.send_chat_msg('Mising user name.')
  1391. else:
  1392. _user = self.users.search_by_nick(user_name)
  1393. if _user is not None and _user.is_broadcasting:
  1394. self.send_close_user_msg(_user.id)
  1395. else:
  1396. self.send_chat_msg('No user named: %s' % user_name)
  1397.  
  1398. # Public (Level 5) Command Methods.
  1399. def do_playlist_status(self):
  1400. """ Shows the playlist queue. """
  1401. if self.is_client_mod:
  1402. if len(self.playlist.track_list) == 0:
  1403. self.send_chat_msg('The playlist is empty.')
  1404. else:
  1405. queue = self.playlist.queue
  1406. if queue is not None:
  1407. self.send_chat_msg('%s items in the playlist, %s still in queue.' %
  1408. (queue[0], queue[1]))
  1409.  
  1410. def do_next_tune_in_playlist(self):
  1411. """ Shows the next track in the playlist. """
  1412. if self.is_client_mod:
  1413. if self.playlist.is_last_track is None:
  1414. self.send_chat_msg('The playlist is empty.')
  1415. elif self.playlist.is_last_track:
  1416. self.send_chat_msg('This is the last track.')
  1417. else:
  1418. pos, next_track = self.playlist.next_track_info()
  1419. if next_track is not None:
  1420. self.send_chat_msg('(%s) %s %s' %
  1421. (pos, next_track.title, self.format_time(next_track.time)))
  1422.  
  1423. def do_now_playing(self):
  1424. """ Shows what track is currently playing. """
  1425. if self.is_client_mod:
  1426. if self.playlist.has_active_track:
  1427. track = self.playlist.track
  1428. if len(self.playlist.track_list) > 0:
  1429. self.send_private_msg(self.active_user.id,
  1430. '(%s) %s %s' % (self.playlist.current_index, track.title,
  1431. self.format_time(track.time)))
  1432. else:
  1433. self.send_private_msg(self.active_user.id, '%s %s' %
  1434. (track.title, self.format_time(track.time)))
  1435. else:
  1436. self.send_private_msg(self.active_user.nick, 'No track playing.')
  1437.  
  1438. def do_who_plays(self):
  1439. """ Show who requested the currently playing track. """
  1440. if self.is_client_mod:
  1441. if self.playlist.has_active_track:
  1442. track = self.playlist.track
  1443. ago = self.format_time(int(pinylib.time.time() - track.rq_time))
  1444. self.send_chat_msg('%s requested this track %s ago.' % (track.owner, ago))
  1445. else:
  1446. self.send_chat_msg('No track playing.')
  1447.  
  1448. def do_version(self):
  1449. """ Show version info. """
  1450. self.send_private_msg(self.active_user.id, 'tinybot %s pinylib %s' %
  1451. (__version__, pinylib.__version__))
  1452.  
  1453. def do_help(self):
  1454. """ Posts a link to github readme/wiki or other page about the bot commands. """
  1455. self.send_private_msg(self.active_user.id,
  1456. 'Help: https://github.com/nortxort/tinybot-rtc/wiki/commands')
  1457.  
  1458. def do_uptime(self):
  1459. """ Shows the bots uptime. """
  1460. self.send_chat_msg('Bot-Uptime: ' + self.format_time(self.get_runtime()))
  1461.  
  1462. def do_pmme(self):
  1463. """ Opens a PM session with the bot. """
  1464. self.send_private_msg(self.active_user.id, 'How can i help you %s?' % self.active_user.nick)
  1465.  
  1466. def do_play_youtube(self, search_str):
  1467. """
  1468. Plays a youtube video matching the search term.
  1469.  
  1470. :param search_str: The search term.
  1471. :type search_str: str
  1472. """
  1473. log.info('user: %s:%s is searching youtube: %s' % (self.active_user.nick, self.active_user.id, search_str))
  1474. if self.is_client_mod:
  1475. if len(search_str) is 0:
  1476. self.send_chat_msg('Please specify youtube title, id or link.')
  1477. else:
  1478. _youtube = youtube.search(search_str)
  1479. if _youtube is None:
  1480. log.warning('youtube request returned: %s' % _youtube)
  1481. self.send_chat_msg('Could not find video: ' + search_str)
  1482. else:
  1483. log.info('youtube found: %s' % _youtube)
  1484. if self.playlist.has_active_track:
  1485. track = self.playlist.add(self.active_user.nick, _youtube)
  1486. self.send_chat_msg('(%s) %s %s' %
  1487. (self.playlist.last_index, track.title, self.format_time(track.time)))
  1488. else:
  1489. track = self.playlist.start(self.active_user.nick, _youtube)
  1490. self.send_yut_play(track.id, track.time, track.title)
  1491. self.timer(track.time)
  1492.  
  1493. # == Tinychat API Command Methods. ==
  1494. def do_spy(self, roomname):
  1495. """
  1496. Shows info for a given room.
  1497.  
  1498. :param roomname: The room name to find spy info for.
  1499. :type roomname: str
  1500. """
  1501. if self.is_client_mod:
  1502. if len(roomname) is 0:
  1503. self.send_chat_msg('Missing room name.')
  1504. else:
  1505. spy_info = pinylib.apis.tinychat.spy_info(roomname)
  1506. if spy_info is None:
  1507. self.send_chat_msg('Failed to retrieve information.')
  1508. elif 'error' in spy_info:
  1509. self.send_chat_msg(spy_info['error'])
  1510. else:
  1511. self.send_chat_msg('Mods: %s, \nBroadcasters: %s, \nUsers: %s' %
  1512. (spy_info['mod_count'], spy_info['broadcaster_count'],
  1513. spy_info['total_count']))
  1514. if self.has_level(3):
  1515. users = ', '.join(spy_info['users'])
  1516. self.send_chat_msg(users)
  1517.  
  1518. def do_account_spy(self, account):
  1519. """
  1520. Shows info about a tinychat account.
  1521.  
  1522. :param account: tinychat account.
  1523. :type account: str
  1524. """
  1525. if self.is_client_mod:
  1526. if len(account) is 0:
  1527. self.send_chat_msg('Missing username to search for.')
  1528. else:
  1529. tc_usr = pinylib.apis.tinychat.user_info(account)
  1530. if tc_usr is None:
  1531. self.send_chat_msg('Could not find tinychat info for: %s' % account)
  1532. else:
  1533. self.send_chat_msg('ID: %s, \nLast Login: %s' %
  1534. (tc_usr['tinychat_id'], tc_usr['last_active']))
  1535.  
  1536. # == Other API Command Methods. ==
  1537. def do_search_urban_dictionary(self, search_str):
  1538. """
  1539. Shows urbandictionary definition of search string.
  1540.  
  1541. :param search_str: The search string to look up a definition for.
  1542. :type search_str: str
  1543. """
  1544. if self.is_client_mod:
  1545. if len(search_str) is 0:
  1546. self.send_chat_msg('Please specify something to look up.')
  1547. else:
  1548. urban = other.urbandictionary_search(search_str)
  1549. if urban is None:
  1550. self.send_chat_msg('Could not find a definition for: %s' % search_str)
  1551. else:
  1552. if len(urban) > 70:
  1553. chunks = pinylib.string_util.chunk_string(urban, 70)
  1554. for i in range(0, 2):
  1555. self.send_chat_msg(chunks[i])
  1556. else:
  1557. self.send_chat_msg(urban)
  1558.  
  1559. def do_weather_search(self, search_str):
  1560. """
  1561. Shows weather info for a given search string.
  1562.  
  1563. :param search_str: The search string to find weather data for.
  1564. :type search_str: str
  1565. """
  1566. if len(search_str) is 0:
  1567. self.send_chat_msg('Please specify a city to search for.')
  1568. else:
  1569. weather = other.weather_search(search_str)
  1570. if weather is None:
  1571. self.send_chat_msg('Could not find weather data for: %s' % search_str)
  1572. else:
  1573. self.send_chat_msg(weather)
  1574.  
  1575. def do_whois_ip(self, ip_str):
  1576. """
  1577. Shows whois info for a given ip address or domain.
  1578.  
  1579. :param ip_str: The ip address or domain to find info for.
  1580. :type ip_str: str
  1581. """
  1582. if len(ip_str) is 0:
  1583. self.send_chat_msg('Please provide an IP address or domain.')
  1584. else:
  1585. whois = other.whois(ip_str)
  1586. if whois is None:
  1587. self.send_chat_msg('No info found for: %s' % ip_str)
  1588. else:
  1589. self.send_chat_msg(whois)
  1590.  
  1591. # == Just For Fun Command Methods. ==
  1592. def do_chuck_noris(self):
  1593. """ Shows a chuck norris joke/quote. """
  1594. chuck = other.chuck_norris()
  1595. if chuck is not None:
  1596. self.send_chat_msg(chuck)
  1597.  
  1598. def do_8ball(self, question):
  1599. """
  1600. Shows magic eight ball answer to a yes/no question.
  1601.  
  1602. :param question: The yes/no question.
  1603. :type question: str
  1604. """
  1605. if len(question) is 0:
  1606. self.send_chat_msg('Question.')
  1607. else:
  1608. self.send_chat_msg('MAGIC 8BALL: %s' % locals_.eight_ball())
  1609.  
  1610. def do_dice(self):
  1611. """ roll the dice. """
  1612. self.send_chat_msg('The dice rolled: %s' % locals_.roll_dice())
  1613.  
  1614. def do_flip_coin(self):
  1615. """ Flip a coin. """
  1616. self.send_chat_msg('The coin was: %s' % locals_.flip_coin())
  1617.  
  1618.  
  1619. def do_join(self):
  1620. if not self.CHEERS.mode:
  1621. self.send_bot_msg("No one started a countdown... Do *.tokes #MINUTES* to start one.")
  1622. return
  1623.  
  1624. # No multiples. No removes.
  1625. if self.active_user in self.CHEERS.joined:
  1626. return
  1627.  
  1628. self.CHEERS.joined.append(self.active_user.nick)
  1629. mins = self.CHEERS.until()
  1630. self.send_bot_msg(self.active_user.nick + " joined tokes! " + str(mins) + " " + str(
  1631. self.CHEERS.pluralize("minute", mins)) + " left for rips...")
  1632. return
  1633.  
  1634. def do_join_chugs(self):
  1635. if not self.CHUGS.mode:
  1636. self.send_bot_msg("No one started a countdown... Do *.chugs #MINUTES* to start one.")
  1637. return
  1638.  
  1639. # No multiples. No removes.
  1640. if self.active_user in self.CHUGS.joed:
  1641. return
  1642.  
  1643. self.CHUGS.joined.append(self.active_user.nick)
  1644. mins = self.CHUGS.until()
  1645. self.send_bot_msg(self.active_user.nick + " joined for CHUGS! " + str(mins) + " " + str(
  1646. self.CHUGS.pluralize("minute", mins)) + " left for CHUGS...")
  1647. return
  1648.  
  1649. def do_tokes(self, target):
  1650. self.add_exp(self.active_user.account, 10)
  1651.  
  1652. # Tokes now, if not active.
  1653. # If active, it will fall in further check.
  1654.  
  1655. if not target:
  1656. if not self.CHEERS.mode:
  1657. self.send_bot_msg("Pack up! *TOKES NOW.*")
  1658. return
  1659.  
  1660. # Stop and remove tokes count.
  1661. if self.CHEERS.mode and target == '.':
  1662. self.CHEERS.clearOut()
  1663. self.send_bot_msg("*Tokes counter stopped and cleared.*)")
  1664. return
  1665.  
  1666. # Ignore more requests, if counter already running.
  1667. if self.CHEERS.mode:
  1668. mins = self.CHEERS.until()
  1669. self.send_bot_msg("Tokes counter is already up and will finish in " + str(mins) + " " +
  1670. self.CHEERS.pluralize("minute", mins) + (", and is paused" if self.CHEERS.paused else "")
  1671. + ". Do *" + '.' + "JOIN* to toke together.")
  1672. return
  1673.  
  1674. # Start new counter.
  1675. try:
  1676. end = int(target)
  1677. if not 1 <= end <= 20:
  1678. raise Exception()
  1679. except:
  1680. self.send_bot_msg("Give me a time in minutes, between 1 and 20, until tokes...")
  1681. return
  1682.  
  1683. # Optional periodical announcements.
  1684. announce = 0
  1685. if len(target) > 1:
  1686. try:
  1687. announce = int(target[1])
  1688. except:
  1689. self.send_bot_msg("Give me a time in minutes, to announce until tokes, periodically...")
  1690. return
  1691.  
  1692. self.CHEERS.startCount(self, end, announce)
  1693.  
  1694. self.CHEERS.joined.append(self.active_user.nick)
  1695.  
  1696. # Verbose.
  1697. mins = self.CHEERS.until()
  1698. self.send_bot_msg(str(mins) + " " + str(self.CHEERS.pluralize("minute", mins)) + " until tokes! Type *" +
  1699. '.' + "JOIN* in chat to toke together. (Do *" + '.' + "tokes " + '.' + "* to clear it out.)")
  1700. return
  1701.  
  1702. def do_chugs(self, target):
  1703. # Tokes now, if not active.
  1704. # If active, it will fall in further check.
  1705.  
  1706. if not target:
  1707. if not self.CHUGS.mode:
  1708. self.send_bot_msg("Pour up! *CHUGS NOW.*")
  1709. return
  1710.  
  1711. # Stop and remove tokes count.
  1712. if self.CHUGS.mode and target == '.':
  1713. self.CHUGS.clearOut()
  1714. self.send_bot_msg("*CHUGS counter stopped and cleared.*)")
  1715. return
  1716.  
  1717. # Ignore more requests, if counter already running.
  1718. if self.CHUGS.mode:
  1719. mins = self.CHUGS.until()
  1720. self.send_bot_msg("CHUGS counter is already up and will finish in " + str(mins) + " " +
  1721. self.CHUGS.pluralize("minute", mins) + (", and is paused" if self.CHUGS.paused else "")
  1722. + ". Do *" + '.' + "CHUG* to chug together.")
  1723. return
  1724.  
  1725. # Start new counter.
  1726. try:
  1727. end = int(target)
  1728. if not 1 <= end <= 20:
  1729. raise Exception()
  1730. except:
  1731. self.send_bot_msg("Give me a time in minutes, between 1 and 20, until CHUGS...")
  1732. return
  1733.  
  1734. # Optional periodical announcements.
  1735. announce = 0
  1736. if len(target) > 1:
  1737. try:
  1738. announce = int(target[1])
  1739. except:
  1740. self.send_bot_msg("Give me a time in minutes, to announce until CHUGS, periodically...")
  1741. return
  1742.  
  1743. self.CHUGS.startCount(self, end, announce,type=self.CHUGS.CHUGS)
  1744.  
  1745. self.CHUGS.joined.append(self.active_user.nick)
  1746.  
  1747. # Verbose.
  1748. mins = self.CHUGS.until()
  1749. self.send_bot_msg(str(mins) + " " + str(self.CHUGS.pluralize("minute", mins)) + " until CHUGS! Type *" +
  1750. '.' + "CHUG* in chat to toke together. (Do *" + '.' + "chugs " + '.' + "* to clear it out.)")
  1751. return
  1752.  
  1753.  
  1754. def private_message_handler(self, private_msg):
  1755. """
  1756. Private message handler.
  1757.  
  1758. Overrides private_message_handler in pinylib
  1759. to enable private commands.
  1760.  
  1761. :param private_msg: The private message.
  1762. :type private_msg: str
  1763. """
  1764. prefix = pinylib.CONFIG.B_PREFIX
  1765. # Split the message in to parts.
  1766. pm_parts = private_msg.split(' ')
  1767. # parts[0] is the command..
  1768. pm_cmd = pm_parts[0].lower().strip()
  1769. # The rest is a command argument.
  1770. pm_arg = ' '.join(pm_parts[1:]).strip()
  1771.  
  1772. if self.has_level(1):
  1773. if self.is_client_owner:
  1774. pass
  1775.  
  1776. if pm_cmd == prefix + 'key':
  1777. self.do_key(pm_arg)
  1778.  
  1779. elif pm_cmd == prefix + 'clrbn':
  1780. self.do_clear_bad_nicks()
  1781.  
  1782. elif pm_cmd == prefix + 'clrbs':
  1783. self.do_clear_bad_strings()
  1784.  
  1785. elif pm_cmd == prefix + 'clrba':
  1786. self.do_clear_bad_accounts()
  1787.  
  1788. # Public commands.
  1789. if self.has_level(5):
  1790. if pm_cmd == prefix + 'opme':
  1791. self.do_opme(pm_arg)
  1792.  
  1793. # Print to console.
  1794. msg = str(private_msg).replace(pinylib.CONFIG.B_KEY, '***KEY***'). \
  1795. replace(pinylib.CONFIG.B_SUPER_KEY, '***SUPER KEY***')
  1796.  
  1797. self.console_write(pinylib.COLOR['white'], 'Private message from %s: %s' % (self.active_user.nick, msg))
  1798.  
  1799. def do_key(self, new_key):
  1800. """
  1801. Shows or sets a new secret bot controller key.
  1802.  
  1803. :param new_key: The new secret key.
  1804. :type new_key: str
  1805. """
  1806. if len(new_key) == 0:
  1807. self.send_private_msg(self.active_user.id, 'The current secret key is: %s' % pinylib.CONFIG.B_KEY)
  1808. elif len(new_key) < 6:
  1809. self.send_private_msg(self.active_user.id, 'The key is to short, it must be atleast 6 characters long.'
  1810. 'It is %s long.' % len(new_key))
  1811. elif len(new_key) >= 6:
  1812. # reset current bot controllers.
  1813. for user in self.users.all:
  1814. if self.users.all[user].user_level is 2 or self.users.all[user].user_level is 4:
  1815. self.users.all[user].user_level = 5
  1816.  
  1817. pinylib.CONFIG.B_KEY = new_key
  1818. self.send_private_msg(self.active_user.id, 'The key was changed to: %s' % new_key)
  1819.  
  1820. def do_clear_bad_nicks(self):
  1821. """ Clear the nick bans file. """
  1822. pinylib.CONFIG.B_NICK_BANS[:] = []
  1823. pinylib.file_handler.delete_file_content(self.config_path, pinylib.CONFIG.B_NICK_BANS_FILE_NAME)
  1824.  
  1825. def do_clear_bad_strings(self):
  1826. """ Clear the string bans file. """
  1827. pinylib.CONFIG.B_STRING_BANS[:] = []
  1828. pinylib.file_handler.delete_file_content(self.config_path, pinylib.CONFIG.B_STRING_BANS_FILE_NAME)
  1829.  
  1830. def do_clear_bad_accounts(self):
  1831. """ Clear the account bans file. """
  1832. pinylib.CONFIG.B_ACCOUNT_BANS[:] = []
  1833. pinylib.file_handler.delete_file_content(self.config_path, pinylib.CONFIG.B_ACCOUNT_BANS_FILE_NAME)
  1834.  
  1835. def do_opme(self, key):
  1836. """
  1837. Make a user a bot controller if the correct key is provided.
  1838.  
  1839. :param key: The secret bot controller key.
  1840. :type key: str
  1841. """
  1842. if len(key) == 0:
  1843. self.send_private_msg(self.active_user.id, 'Missing key.')
  1844. elif key == pinylib.CONFIG.B_SUPER_KEY:
  1845. if self.is_client_owner:
  1846. self.active_user.user_level = 1
  1847. self.send_private_msg(self.active_user.id, 'You are now a super mod.')
  1848. else:
  1849. self.send_private_msg(self.active_user.id, 'The client is not using the owner account.')
  1850. elif key == pinylib.CONFIG.B_KEY:
  1851. if self.is_client_mod:
  1852. self.active_user.user_level = 2
  1853. self.send_private_msg(self.active_user.id, 'You are now a bot controller.')
  1854. else:
  1855. self.send_private_msg(self.active_user.id, 'The client is not moderator.')
  1856. else:
  1857. self.send_private_msg(self.active_user.id, 'Wrong key.')
  1858.  
  1859. # Timer Related.
  1860. def timer_event(self):
  1861. """ This gets called when the timer has reached the time. """
  1862. if len(self.playlist.track_list) > 0:
  1863. if self.playlist.is_last_track:
  1864. if self.is_connected:
  1865. self.send_chat_msg('Resetting playlist.')
  1866. self.playlist.clear()
  1867. else:
  1868. track = self.playlist.next_track
  1869. if track is not None and self.is_connected:
  1870. self.send_yut_play(track.id, track.time, track.title)
  1871. self.timer(track.time)
  1872.  
  1873. def timer(self, event_time):
  1874. """
  1875. Track event timer.
  1876.  
  1877. This will cause an event to occur once the time is done.
  1878.  
  1879. :param event_time: The time in seconds for when an event should occur.
  1880. :type event_time: int | float
  1881. """
  1882. self.timer_thread = threading.Timer(event_time, self.timer_event)
  1883. self.timer_thread.start()
  1884.  
  1885. def cancel_timer(self):
  1886. """ Cancel the track timer. """
  1887. if self.timer_thread is not None:
  1888. if self.timer_thread.is_alive():
  1889. self.timer_thread.cancel()
  1890. self.timer_thread = None
  1891. return True
  1892. return False
  1893. return False
  1894.  
  1895. # Helper Methods.
  1896. def options(self):
  1897. """ Load/set special options. """
  1898. log.info('options: is_client_owner: %s, is_client_mod: %s' % (self.is_client_owner, self.is_client_mod))
  1899. if self.is_client_owner:
  1900. self.get_privacy_settings()
  1901. if self.is_client_mod:
  1902. self.send_banlist_msg()
  1903. self.load_list(nicks=True, accounts=True, strings=True)
  1904.  
  1905. def get_privacy_settings(self):
  1906. """ Parse the privacy settings page. """
  1907. log.info('Parsing %s\'s privacy page.' % self.account)
  1908. self.privacy_ = privacy.Privacy(proxy=None)
  1909. self.privacy_.parse_privacy_settings()
  1910.  
  1911. def load_list(self, nicks=False, accounts=False, strings=False):
  1912. """
  1913. Loads different list to memory.
  1914.  
  1915. :param nicks: bool, True load nick bans file.
  1916. :param accounts: bool, True load account bans file.
  1917. :param strings: bool, True load ban strings file.
  1918. """
  1919. if nicks:
  1920. pinylib.CONFIG.B_NICK_BANS = pinylib.file_handler.file_reader(self.config_path,
  1921. pinylib.CONFIG.B_NICK_BANS_FILE_NAME)
  1922. if accounts:
  1923. pinylib.CONFIG.B_ACCOUNT_BANS = pinylib.file_handler.file_reader(self.config_path,
  1924. pinylib.CONFIG.B_ACCOUNT_BANS_FILE_NAME)
  1925. if strings:
  1926. pinylib.CONFIG.B_STRING_BANS = pinylib.file_handler.file_reader(self.config_path,
  1927. pinylib.CONFIG.B_STRING_BANS_FILE_NAME)
  1928.  
  1929. def has_level(self, level):
  1930. """
  1931. Checks the active user for correct user level.
  1932.  
  1933. :param level: The level to check the active user against.
  1934. :type level: int
  1935. :return: True if the user has correct level, else False
  1936. :rtype: bool
  1937. """
  1938. if self.active_user.user_level == 6:
  1939. return False
  1940. elif self.active_user.user_level <= level:
  1941. return True
  1942. return False
  1943.  
  1944. @staticmethod
  1945. def format_time(time_stamp, is_milli=False):
  1946. """
  1947. Converts a time stamp as seconds or milliseconds to (day(s)) hours minutes seconds.
  1948.  
  1949. :param time_stamp: Seconds or milliseconds to convert.
  1950. :param is_milli: The time stamp to format is in milliseconds.
  1951. :return: A string in the format (days) hh:mm:ss
  1952. :rtype: str
  1953. """
  1954. if is_milli:
  1955. m, s = divmod(time_stamp / 1000, 60)
  1956. else:
  1957. m, s = divmod(time_stamp, 60)
  1958. h, m = divmod(m, 60)
  1959. d, h = divmod(h, 24)
  1960.  
  1961. if d == 0 and h == 0:
  1962. human_time = '%02d:%02d' % (m, s)
  1963. elif d == 0:
  1964. human_time = '%d:%02d:%02d' % (h, m, s)
  1965. else:
  1966. human_time = '%d Day(s) %d:%02d:%02d' % (d, h, m, s)
  1967. return human_time
  1968.  
  1969. def check_msg(self, msg):
  1970. """
  1971. Checks the chat message for ban string.
  1972.  
  1973. :param msg: The chat message.
  1974. :type msg: str
  1975. """
  1976. should_be_banned = False
  1977. chat_words = msg.split(' ')
  1978. for bad in pinylib.CONFIG.B_STRING_BANS:
  1979. if bad.startswith('*'):
  1980. _ = bad.replace('*', '')
  1981. if _ in msg:
  1982. should_be_banned = True
  1983. elif bad in chat_words:
  1984. should_be_banned = True
  1985. if should_be_banned:
  1986. if pinylib.CONFIG.B_USE_KICK_AS_AUTOBAN:
  1987. self.send_kick_msg(self.active_user.id)
  1988. else:
  1989. self.send_ban_msg(self.active_user.id)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement