Example #1
0
class VitaminBot:
   def __init__(self, config):
      self.config = config

      self._current_users = []
      self._dj_queue = []
      self._djs = []
      self._mods = []

      self._waitingDj = False
      self._waiting_down = False
      self._waiting_user = None

      self._bot = Bot(self.config.authInfo.auth, self.config.authInfo.userid, self.config.authInfo.roomid)

      self._bot.on('speak', self._speak)
      self._bot.on('registered', self._user_in)
      self._bot.on('deregistered', self._user_out)
      self._bot.on('add_dj', self._dj_added)
      self._bot.on('rem_dj', self._dj_removed)
      self._bot.on('roomChanged', self._room_changed)
      self._bot.on('endsong', self._end_song)

      #This prefix can be used by anyone in the room, and it specifies local utility commands for bot management
      #under certain circumstances
      self.LOCAL_COMMAND_PREFIX = ":%:"

#Local helper functions
   def _getUserById(self, l, userid):
      for user in l:
         if user.uid == userid:
            return user
   
   def _getUserByName(self, l, name):
      for user in l:
         if user.name == name:
            return user

   def _removeUser(self, l, userid):
      for user in l:
         if user.uid == userid:
            l.remove(user)
            return user

      return None

   def _queueTimeout(self, user):
      self._bot.speak("Well fine then @%s! You're out of line!" % user.name)
      self._removeUser(self._dj_queue, user.uid)
      self._waitingDj = False
      if len(self._dj_queue) > 0:
         self._notifyQueueUp(self._dj_queue[0])


   def _halfTimeout(self, user):
      self._bot.speak("@%s, 15 seconds and you're out breh..." % user.name)
      self._up_timer = Timer(15,self._queueTimeout, [user])
      self._up_timer.start()

   def _stepDownTimeout(self, user):
      self._bot.speak("Okay @%s, time's up!" % user.name)
      self._waiting_down = False
      self._waiting_user = None

      self._bot.remDj(user.uid)

   def _notifyQueueUp(self, user):
      if not self._waitingDj:
         self._bot.speak("Alright @%s, you're up!" % user.name)
         self._up_timer = Timer(15, self._halfTimeout, [user])
         self._up_timer.start()
         self._waitingDj = True

#Public API functions
#NOTE: These are the only functions that should be called from an
#      implementing module
   def start(self):
      self._bot.start()

   def stop(self):
      self._bot.stop()

   def startDaemon(self, pidfile):
      _daemon = VitaminDaemon(pidfile, self._bot)
      _daemon.start()

   def stopDaemon(self, pidfile):
      _daemon = VitaminDaemon(pidfile, self._bot)
      _daemon.stop()

   def speak(self, s):
      self._bot.speak(str(s))

   def printQueue(self):
      if not self.config.q_enabled:
         self._bot.speak("We are not currently using a queue")
         return

      l = ""

      for i in range(len(self._dj_queue)):
         l += self._dj_queue[i].name + ", "

      self._bot.speak(l)

   def printCommands(self):
      l = ""

      for cmd in self.config.commandList:
         l += cmd + ", "

      self._bot.speak(l)

   def addQueue(self, name, userid):
      user = self._getUserById(self._current_users, userid)

      if not user:
         return

      if not self.config.q_enabled:
         self._bot.speak("We are not currently using a queue")
         return

      if self._dj_queue.count(user) == 0:
         self._dj_queue.append(user)
         self._bot.speak("You have been added to the queue @%s" % name)

         #Now make sure we don't have room for them already
         if len(self._djs) < self.config.MAX_DJS:
            self._notifyQueueUp(user)

      else:
         self._bot.speak("You are already added to the queue... dumb shit.")

   def removeQueue(self, name, userid):
      user = self._getUserById(self._current_users, userid)

      if not user: 
         return

      if not self.config.q_enabled:
         self._bot.speak("We are not currently using a queue")
         return

      if self._dj_queue.count(user) > 0:
         try:
            index = self._dj_queue.index(user)
         except ValueError:
            index = -1

         self._dj_queue.remove(user)
         self._bot.speak("You have been removed from the queue @%s" % name)

         #If this is the user we are waiting on to get up, cancel his timer
         if(index == 0):
            self._up_timer.cancel()
            self._waitingDj = False
            if len(self._dj_queue) > 0:
               self._notifyQueueUp(self._dj_queue[0])

      else:
         self._bot.speak("You aren't in the queue. Get you shit together @%s!" % name)

   def _roomInfoclb(self, data):
      new_users = []
      new_mods = []
      for u in data['users']:
         new_users.append(UserInfo(u['name'], u['userid']))

      for m in data['room']['metadata']['moderator_id']:
         new_mods.append(m)

      self._mods = new_mods

      self._current_users = new_users


   def roomUpdate(self):
      self._bot.roomInfo(False, self._roomInfoclb)


   def enableQueue(self):
      self.config.q_enabled = True

   def disableQueue(self):
      self.config.q_enabled = False

   def vote(self, val):
      if val == 'up' or val == 'down':
         self._bot.vote(val)

   def bop(self):
      self.vote('up')
#Event Handlers

   def _user_id_clb(self, data):
      if data['success']:
         self._current_users.append(UserInfo(self.pendingUserName, data['userid']))

   def _speak(self, data):
      name = data['name']
      text = data['text']

      if text.startswith(self.LOCAL_COMMAND_PREFIX):
         print "Local Command Captured"
         newText = text[len(self.LOCAL_COMMAND_PREFIX):]
         tokenList = newText.split()
         commandToken = tokenList[0]
         print("Token: %s" % commandToken)
         if commandToken == "adduser":
            self.pendingUserName = tokenList[1]
            self._bot.getUserId(tokenList[1], self._user_id_clb)
            return
         if commandToken == "update":
            self.roomUpdate()
            return
         
      #Check if this is a bot command
      if text.startswith(self.config.COMMAND_PREFIX):
         newText = text[len(self.config.COMMAND_PREFIX):]
         tokenList = newText.split()
         commandToken = tokenList[0]
         tokenList.pop(0)
         lCommandToken = commandToken.lower()

         if lCommandToken in self.config.commandList:
            (self.config.commandList[lCommandToken])(data['name'], data['userid'], tokenList)
         else:
            if lCommandToken in self.config.modCommandList:
               if data['userid'] in self.config.modList or data['userid'] in self._mods:
                  (self.config.modCommandList[lCommandToken])(data['name'], data['userid'], tokenList)
               else:
                  self._bot.speak("I don't take those kind of orders from bitches like you, @%s" % data['name'])
            else:
               self._bot.speak("Sorry, I don't recognize %s as a command" % commandToken)

   def _user_in(self, data):
      self._current_users.append(UserInfo(data['user'][0]['name'], data['user'][0]['userid']))
      self._bot.speak("Hello @%s, welcome to SS1!" % data['user'][0]['name'])

   def _user_out(self, data):
      self._removeUser(self._current_users, data['user'][0]['userid'])

   def _dj_added(self, data):
      if self.config.q_enabled:
         if len(self._dj_queue) > 0 and data['user'][0]['userid'] == self._dj_queue[0].uid:
            self._djs.append(self._dj_queue.pop(0))
            self._up_timer.cancel()
            self._waitingDj = False
            if len(self._djs) < self.config.MAX_DJS and len(self._dj_queue) > 0:
               self._notifyQueueUp(self._dj_queue[0])
         else:
            self._bot.remDj(data['user'][0]['userid'])
            self._bot.speak("Get your ass in back in line @%s!" % data['user'][0]['name'])

      else:
         user = self._getUserById(self._current_users, data['user'][0]['userid'])
         self._djs.append(user)

   def _dj_removed(self, data):
      user = self._removeUser(self._djs, data['user'][0]['userid'])
      
      #The user must've been kicked for getting up out of turn
      if not user or not self.config.q_enabled:
         return

      if self._waiting_down and user == self._waiting_user:
         self._waiting_down = False
         self._down_timer.cancel()

      user.playcount = 0
      self._dj_queue.append(user)

      self._bot.speak("You have been added back into the queue @%s" % user.name)

      if len(self._dj_queue):
         self._notifyQueueUp(self._dj_queue[0])

   def _room_changed(self, data):
      self.roomUpdate()

   def _end_song(self, data):
      if not self.config.q_enabled:
         return

      user = self._getUserById(self._djs, data['room']['metadata']['current_dj'])

      if not user:
         return

      user.playcount += 1

      if user.playcount >= self.config.playcount and not self._waiting_down:
         self._bot.speak("Alright @%s. Your plays are up! GTFO" % user.name)
         self._down_timer = Timer(15, self._stepDownTimeout, [user])
         self._waiting_down = True
         self._waiting_user = user
         self._down_timer.start()