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()