def cacheKey(self, res, nickname): #clog.error('the key is %s:' % res[0], sys) assert res, 'no res at cacheKey' if res: clog.info("(cacheKey) cached %s's key %s" % (nickname, res[0])) self.nickdict[nickname]['keyId'] = res[0] return defer.succeed(res[0])
def onOpen(self): clog.info('(onOpen) Connected to Cytube!', sys) self.connectedTime = time.time() self.lastUserlistTime = 0 self.factory.prot = self self.factory.handle.cy = True self.initialize()
def bulkCheckVocaDb(self, songlessMedia): timeNow = round(time.time(), 4) clog.info('(bulkCheckVocaDb)', sys) for i, (mType, mId) in enumerate(songlessMedia): # 0.5s delay between each call reactor.callLater(i * 0.5, vdbapi.requestSongByPv, None, mType, mId, 1, timeNow, 4)
def userJoined(self, user, channel): clog.info('%s has joined %s' % (user, channel), sys) if channel == self.channelName: self.factory.handle.ircUserCount += 1 self.nicklist.append(user) elif channel == self.channelStatus: self.sendCyNames()
def cacheKey(self, res, nickname): clog.error('the key is %s:' % res[0], sys) assert res, 'no res at cacheKey' if res: clog.info("(cacheKey) cached %s's key %s" % (nickname, res[0])) self.nickdict[nickname]['keyId'] = res[0] return defer.succeed(res[0])
def _cyCall_delete(self, fdict): uid = fdict['args'][0]['uid'] index = self.getIndexFromUid(uid) deletedMedia = self.playlist.pop(index) clog.info('(_cyCall_delete) Removed uid %s, index %s from my playlist' % (uid, index), sys) assert uid == deletedMedia['uid'], 'Deleted media not correct!'
def deferredChatRes(self, res, key): if not res: clog.info('(deferredChatRes): wrote chat to database!', sys) return defer.succeed(key) else: clog.err('(deferredChatRes): error writing to database!', sys) return defer.fail(key)
def _com_tweet(self, yuka, user, args, source): if source != 'chat' or not self.allowed: #only cytube clog.info('tweet called from invalid source', syst) return if not args: return if args == 'reload' and self.allowed: # only the first person on the list can reload if self.allowed[0] == user: self._load_allowed() yuka.reply('[tweet] Reloaded allowed list.', source, user) else: yuka.reply("[tweet] You can't do that.", source, user) return if user not in self.allowed: yuka.reply('[tweet] You are not allowed to do that..', source, user) return if not self._count_tweet(user, args): yuka.reply('Tweet too long.', source, user) return try: status = self._create_status(user, args) headers = self._create_header(status) except Exception as e: clog.error(e, syst) self.last_error = e yuka.reply('Something went wrong!', source, user) return d = self.tweet(status, headers) d.addCallback(self.cbAnagramRequest) d.addCallback(self.parseTwitterResponse, yuka, source, user) d.addCallback(self.sendAnagram, yuka, args, source, user)
def clockUser(self, res, leftUser, timeNow): """ Clock out a user, by updating their accessTime """ username = leftUser['name'] clog.info('(clockUser) Clocking out %s!' % username, sys) timeJoined = leftUser['timeJoined'] timeStayed = timeNow - timeJoined userId = leftUser['keyId'] return database.updateCyUser(timeNow, timeStayed, userId)
def left(self, channel): clog.info('Left IRC channel: %s' % channel, sys) if channel == config['irc']['channel']: self.factory.handle.inIrcChan = False elif channel == config['irc']['np']: self.factory.handle.inIrcNp = False elif channel == config['irc']['status']: self.factory.handle.inIrcStatus = False
def userLeft(self, user, channel): clog.info('%s has left %s' % (user, channel), sys) if channel == self.channelName: self.factory.handle.ircUserCount -= 1 try: self.nicklist.remove(user) except (ValueError): clog.error('(userLeft) User %s not in nicklist' % user)
def userLeft(self, user, channel): clog.info('%s has left %s' % (user, channel), sys) if channel == self.channelName: self.factory.handle.ircUserCount -= 1 try: self.nicklist.remove(user) except(ValueError): clog.error('(userLeft) User %s not in nicklist' % user)
def cleanup(self): """ Prepares for shutdown """ clog.info('(cleanup) Cleaning up for shutdown!', sys) self.done = Deferred() if self.irc: self.ircFactory.prot.partLeave('Shutting down.') if self.cy: self.wsFactory.prot.cleanUp() return self.done
def userKicked(self, kickee, channel, kicker, message): clog.info('%s was kicked by %s from %s: %s' % (kickee, kicker, channel, message)) if channel == self.channelName: self.factory.handle.ircUserCount -= 1 try: self.nicklist.remove(kickee) except(ValueError): clog.error('(userKiced) User %s not in nicklist' % kickee)
def userKicked(self, kickee, channel, kicker, message): clog.info('%s was kicked by %s from %s: %s' % (kickee, kicker, channel, message)) if channel == self.channelName: self.factory.handle.ircUserCount -= 1 try: self.nicklist.remove(kickee) except (ValueError): clog.error('(userKiced) User %s not in nicklist' % kickee)
def _cyCall_changeMedia(self, fdict): # set self.nowPlaying mType = fdict['args'][0]['type'] mId = fdict['args'][0]['id'] mTitle = fdict['args'][0]['title'] self.nowPlaying = (mType, mId, mTitle) # these are unicode # everything has to be encoded to utf-8 or it errors s = mTitle.encode('utf-8') + ' (%s, %s)' % (mType.encode('utf-8'), mId.encode('utf-8')) clog.info('(_cyCall_changeMedia) %s' % s, sys)
def mediaSongResult(res, mType, mId, userId, timeNow): clog.info('(mediaSongResult) %s' % res, syst) if res: return defer.succeed(res[0]) else: dd = requestApiByPv(mType, mId, timeNow) dd.addErrback(apiError) dd.addCallback(youtubeDesc, mType, mId, timeNow) dd.addCallback(database.insertMediaSongPv, mType, mId, userId, timeNow) return dd
def mediaSongResult(res, mType, mId, userId, timeNow): clog.info("(mediaSongResult) %s" % res, syst) if res: return defer.succeed(res[0]) else: dd = requestApiByPv(mType, mId, timeNow) method = 0 dd.addErrback(apiError) dd.addCallback(database.insertMediaSongPv, mType, mId, userId, timeNow, method) return dd
def joined(self, channel): clog.info('Joined IRC channel: %s' % channel, sys) self.factory.handle.irc = True if channel == self.channelName: self.factory.handle.inIrcChan = True elif channel == self.channelNp: self.factory.handle.inIrcNp = True elif channel == self.channelStatus: self.factory.handle.inIrcStatus = True self.sendCyNames() self.getNicks(channel).addCallback(self.updateNicks, channel)
def flagOrDelete(self, res, cy, mType, mId, title, uid): if res == 'EmbedOk': clog.info('%s EmbedOk' % title, syst) database.unflagMedia(0b1, mType, mId) elif res in ('Status503', 'Status403', 'Status404', 'NoEmbed','NoVid'): clog.warning('%s: %s' % (title, res), syst) cy.doDeleteMedia(uid) cy.uncache(mId) msg = 'Removing non-playable media %s' % title database.flagMedia(0b1, mType, mId) cy.sendCyWhisper(msg)
def _omit(self, cy, username, args, dir, source): if cy._getRank(username) < 2: return clog.info('(_com_omit) %s' % args) mType, mId = self._omit_args(cy, args) if not mType: cy.doSendChat('Invalid parameters.') else: # check existence and retrieve title d = database.getMediaByTypeId(mType, mId) d.addCallback(self.cbOmit, cy, mType, mId, username, dir, source)
def _importPlugins(self): modules = importPlugins('plugins/') self.triggers = {'commands':{}} for module in modules: instance = module.setup() for method in dir(instance): # commands in cytube chat if method.startswith('_com_'): trigger = '%s' % method[5:] self.triggers['commands'][trigger] = getattr(instance, method) clog.info('Imported %s!' % trigger, syst)
def processVocadb(self, res, mType, mId, nameLower, isReg, isCommand): if not res: d = vdbapi3.obtainSong(mType, mId, nameLower, isReg) if isCommand: clog.info('(processVocadb) we got $vocadb command', syst) else: clog.info('(processVocadb) Vocadb db query returned [] ', syst) d.addCallback(self.displayResults, mType, mId, nameLower, isReg) return d else: return self.displayResults(res, mType, mId, nameLower, isReg)
def movePlaylistItems(self, beforeUid, afterUid): # 'before' is just the uid of the video that is going to move clog.info('(movePlaylistItems) move uid:%s, after uid%s' % (beforeUid, afterUid), sys) if afterUid == 'prepend': indexAfter = 0 else: indexAfter = self.getIndexFromUid(afterUid) indexBefore = self.getIndexFromUid(beforeUid) if indexBefore > indexAfter and afterUid != 'prepend': indexAfter += 1 self.playlist.insert(indexAfter, self.playlist.pop(indexBefore))
def flagOrDelete(self, res, cy, mType, mId, title, uid): if res == 'EmbedOk': clog.info('%s EmbedOk' % title, syst) database.unflagMedia(0b1, mType, mId) elif res in ('Status503', 'Status403', 'Status404', 'NoEmbed', 'NoVid'): clog.warning('%s: %s' % (title, res), syst) cy.doDeleteMedia(uid) cy.uncache(mId) msg = 'Removing non-playable media %s' % title database.flagMedia(0b1, mType, mId) cy.sendCyWhisper(msg)
def doneCleanup(self, protocol): """ Fires the done deferred, which unpauses the shutdown sequence """ # If the application is stuck after Ctrl+C due to a bug, # use telnet(manhole) to manually fire the 'done' deferred. if protocol == 'irc': self.irc = None clog.info('(doneCleanup) Done shutting down IRC.', sys) elif protocol == 'cy': self.cy = None clog.info('(doneCleanup) Done shutting down Cy.', sys) if self.irc is not True and self.cy is not True: self.done.callback(None)
def getVdbBySongId(songId): """Return a deferred of the json response of vocadb song result""" args = { 'fields': 'Artists,Names', 'lang': 'romaji', } url = 'https://vocadb.net/api/songs/{}?{}'.format(songId, urllib.urlencode(args)) clog.info('requesting vocadb API by song id : {}'.format(url), syst) d = treq.get(url, headers=HEADERS) d.addCallback(cbResponse) return d
def _bulkQueryMediaSong(txn, playlist): clog.debug('(_queryBulkMediaSong)', sys) songlessMedia = [] for media in playlist: sql = ('SELECT songId FROM MediaSong WHERE mediaId IS' ' (SELECT mediaId FROM Media WHERE type=? AND id=?)') txn.execute(sql, media) row = txn.fetchone() if not row: songlessMedia.append(media) clog.info(songlessMedia, sys) return songlessMedia
def requestApiBySongId(res, songId, timeNow): """ Request video information from VocaDb API v2 and save to the Song table """ agent = Agent(reactor) url = "http://vocadb.net/api/songs/%s?" % songId url += "&fields=artists,names&lang=romaji" clog.info("(requestApiBySongId) %s" % url, syst) d = agent.request("GET", url, Headers({"User-Agent": [UserAgentVdb]})) d.addCallback(readBody) d.addCallbacks(processVdbJson, apiError) d.addCallback(database.insertSong, timeNow) return d
def _com_add(self, username, msg): rank = self._getRank(username) clog.info('rank is %s' % rank, 'RANK') if not rank: return elif rank < 2: maxAdd = 5 else: maxAdd = 20 clog.info(msg, sys) arg = list(msg.split()[1:]) # shortcut in case people want to $add # # of course this can't be combined with other args try: num = int(arg[0]) arg = ['-n', str(num)] except(ValueError, IndexError): pass parser = argparse.ArgumentParser() parser.add_argument('-s', '--sample', default='queue', choices=('queue', 'q', 'add', 'a')) parser.add_argument('-u', '--user', default='Anyone') parser.add_argument('-g', '--guest', default=False, type=bool) parser.add_argument('-n', '--number', default=3, type=int) parser.add_argument('-t', '--title', default='') #TODO parser.add_argument('-a', '--artist', default='') #TODO parser.add_argument('-T', '--temporary', default=False, type=bool) parser.add_argument('-N', '--next', default=False, type=bool) try: args = parser.parse_args(arg) except(SystemExit): self.doSendChat('Invalid arguments.') return args.number = min(args.number, maxAdd) reply = ('Quantity:%s, sample:%s, user:%s, guest:%s, temp:%s, ' 'pos:%s' % (args.number, args.sample, args.user, args.guest, args.temporary, args.next)) self.doSendChat(reply) isRegistered = not args.guest if args.next: args.next = 'next' else: args.next = 'end' if args.user == 'Anyone': args.user = None self.getRandMedia(args.sample, args.number, args.user, args.temporary, args.next)
def _cyCall_pm(self, fdict): return # TODO clog.info(fdict, sys) username = fdict['args'][0]['username'] msg = fdict['args'][0]['msg'] if msg == '$down': self.votes -= 1 elif msg == '$up': self.votes += 1 else: return self.sendCss()
def _importPlugins(self): modules = importPlugins('plugins/') self.triggers = {'commands': {}} for module in modules: instance = module.setup() for method in dir(instance): # commands in cytube chat if method.startswith('_com_'): trigger = '%s' % method[5:] self.triggers['commands'][trigger] = getattr( instance, method) clog.info('Imported %s!' % trigger, sys)
def _bulkQueryMediaSong(txn, playlist): clog.debug('(_queryBulkMediaSong)', sys) songlessMedia = [] for media in playlist: sql = ('SELECT songId FROM MediaSong WHERE mediaId IS' ' (SELECT mediaId FROM Media WHERE type=? AND id=?)') binds = (media[1], media[2]) txn.execute(sql, binds) row = txn.fetchone() if not row: songlessMedia.append(binds) clog.info(songlessMedia, '[database] bulkquerymedia') return songlessMedia
def doneCleanup(self, protocol): """ Fires the done deferred, which unpauses the shutdown sequence """ # If the application is stuck after Ctrl+C due to a bug, # use telnet(manhole) to manually fire the 'done' deferred. clog.warning('(doneCleanup) CLEANUP FROM %s' % protocol, sys) if protocol == 'irc': self.irc = None clog.info('(doneCleanup) Done shutting down IRC.', sys) elif protocol == 'cy': self.cy = None clog.info('(doneCleanup) Done shutting down Cy.', sys) if not self.irc and not self.cy: self.done.callback(None)
def createShellServer(obj): """ Creates an interactive shell interface to send and receive output while the program is running. Connection's instance yukari is named y. e.g. dir(y), will list all of yukari's names""" clog.info('Creating shell server instance...', sys) factory = telnet.ShellFactory() port = reactor.listenTCP(int(config['telnet']['port']), factory) factory.namespace['y'] = obj factory.username = config['telnet']['username'] factory.password = config['telnet']['password'] #log.msg('starting shell server...', Loglevel=logging.ERROR, system='Shell') return port
def _addQueue(self, msg, action): if not self.underSpam and self.bucketToken != 0: self.chatQueue.append((msg, action)) self.popQueue() elif self.underSpam: clog.info('(_addQueue) chat is throttled', sys) return elif self.bucketToken == 0: clog.warning('(_addQueue) blocking messages from CyTube', sys) msg = '[Hit throttle: Dropping messages %s.]' self.say(self.channelName, msg % 'from Cytube') self.factory.handle.sendToCy(msg % 'to IRC', modflair=True) self.underSpam = True
def cleanup(self): """ Prepares for shutdown """ # Starts pre-shutdown cleanup clog.info('(cleanup) Cleaning up for shutdown!', sys) self.done = Deferred() # if nothing has started, shutdown immediately. if not self.irc and not self.cy: clog.info('(cleanup) Nothing to clean!', sys) self.done.callback(None) if self.irc: self.ircFactory.prot.partLeave('Shutting down.') if self.cy: self.cyRestart = False self.wsFactory.prot.sendClose() return self.done
def _cyCall_userlist(self, fdict): if time.time() - self.lastUserlistTime < 3: # most likely the same userlist # with ip/aliases if mod+ clog.info('(_cy_userlist) Duplicate userlist detected', sys) return self.lastUserlistTime = time.time() userlist = fdict['args'][0] timeNow = int(time.time()) # make a dictonary of users self.userdict = {} for user in userlist: user['timeJoined'] = timeNow self.userdict[user['name']] = user self.userJoin(user, timeNow)
def returnPoints(self, stats, cy, querier, username, source): # e.g. [(True, 1401.87244), (True, [(True, [(19,)]), (True, [(96,)]), # (True, [(22,)]), (True, [(3,)]), (True, [(23,)]), (True, [(2,)])])] points = stats[0][1] adds = stats[1][1][0][1][0][0] queues = stats[1][1][1][1][0][0] likes = stats[1][1][2][1][0][0] dislikes = stats[1][1][3][1][0][0] liked = stats[1][1][4][1][0][0] disliked = stats[1][1][5][1][0][0] clog.info('(returnPoints) %s has %d points.' %(username, points), syst) cy.doSendChat('[%s] points:%d (a%d / q%d / l%d / d%d / L%d / D%d)' % (username, points, adds, queues, likes, dislikes, liked, disliked), source=source, username=querier)
def packageVocadb(self, vdbjson): if not vdbjson: vdbjson = {} vocadbId = vdbjson.get('id') if not vocadbId: vocapack = {'res': False} clog.info('Pacakge Vocadb - None', syst) else: vocadbInfo = self.parseVocadb(vdbjson) vocapack = { 'vocadbId': vocadbId, 'vocadbInfo': vocadbInfo, 'res': True, } return vocapack
def addMedia(sample, nameLower, registered, words, limit, isRecent): """selects up to n (limit) random non-flagged media that was ever queued by registered user (nameLower)""" limit = max(0, limit) binds, sql = [], [] # only Youtube providers = '("yt")' if nameLower and sample == 'q': name = ('AND Queue.userId = %s' % _USERIDSQL) binds.extend((nameLower, int(registered))) elif nameLower and sample == 'a': name = ('AND by = %s' % _USERIDSQL) binds.extend((nameLower, int(registered))) elif nameLower and sample == 'l': name = ('AND Like.userId = %s' % _USERIDSQL) binds.extend((nameLower, int(registered))) else: name = '' if words: title = 'AND Media.title LIKE ? ' binds.append('%%%s%%' % words) # %% is escaped % else: title = '' if not isRecent: # by default exclude last 200 queued media from pool recent = ('AND Media.mediaId NOT IN (SELECT mediaId FROM Queue ' 'ORDER BY queueId DESC LIMIT 200)') else: recent = '' if sample == 'q': sql = ('SELECT type, id FROM Media WHERE type IN %s AND mediaId IN ' '(SELECT DISTINCT Media.mediaId FROM Media, Queue WHERE ' 'Media.mediaId = Queue.mediaId AND Media.flag=0 %s %s %s ' 'ORDER BY RANDOM() LIMIT ?)' % (providers, name, title, recent)) elif sample == 'a': sql = ( 'SELECT type, id FROM Media WHERE type IN %s AND flag=0 %s %s %s' 'ORDER BY RANDOM() LIMIT ?' % (providers, name, title, recent)) elif sample == 'l': sql = ('SELECT type, id FROM Media CROSS JOIN Like ON Media.mediaId ' '=Like.mediaId GROUP BY Media.mediaId HAVING type IN %s AND ' 'value=1 %s %s %s ORDER BY RANDOM() LIMIT ?' % (providers, name, title, recent)) binds.append(limit) binds = tuple(binds) clog.info(sql, 'sql') clog.info(binds, 'sql') return query(sql, binds)
def processVdbJson(body): clog.info('(processVdbJson) Received reply from VocaDB', syst) # clog.debug('(processVdbJson) %s' % body, syst) body = body.decode('UTF-8') try: pbody = json.loads(body) except (ValueError): return defer.fail(None) try: if 'message' in pbody: clog.error(pbody['message'], syst) except (TypeError): # body is null (pbody is None) clog.warning('(processVdbJson) null from Vocadb', syst) return defer.succeed(0) return defer.succeed((pbody))
def lineReceived(self, line): clog.info(line, sys) d = checkLine(line) if not d: self.sendBadArgs('Unknown', 'Invalid JSON') return request = self.parseDict(d) if request: callType, args = request thunk = getattr(self, '_rin_%s' % (callType, ), None) if thunk is not None: thunk(args) elif thunk is None: response = {'callType': None, 'result': 'badname'} self.sendLineAndLog(json.dumps(response)) else: clog.error('improper request', sys)
def createShellServer(namespace): """ Creates an interactive shell interface to send and receive output while the program is running. Connection's instance yukari is named y. e.g. dir(y), will list all of yukari's names""" # These are taken from manhole_tap module checker = checkers.FilePasswordDB('telnet.pw') telnetRealm = manhole_tap._StupidRealm(telnet.TelnetBootstrapProtocol, insults.ServerProtocol, manhole.ColoredManhole, {"y": namespace}) telnetPortal = portal.Portal(telnetRealm, [checker]) telnetFactory = protocol.ServerFactory() telnetFactory.protocol = manhole_tap.makeTelnetProtocol(telnetPortal) clog.info('Creating shell server instance...', sys) port = reactor.listenTCP(int(config['telnet']['port']), telnetFactory) return port
def returnGreeting(self, points, cy, username, source): clog.info('(returnGreeting) %s: %d points' % (username, points), syst) modflair = False if not points or points < 0: reply = 'Hello %s.' % username elif points < 999: reply = 'Hi %s.' % username elif points < 2000: reply = 'Hi %s!' % username elif points < 10000: reply = 'Hi %s! <3' % username elif points < 50000: reply = 'Hi %s!! <3' % username modflair = 3 else: reply = '>v< Hi %s!! <3' % username modflair = 3 cy.doSendChat(reply, source, username, modflair)
def returnPoints(self, stats, cy, querier, username, source): # e.g. [(True, 1401.87244), (True, [(True, [(19,)]), (True, [(96,)]), # (True, [(22,)]), (True, [(3,)]), (True, [(23,)]), (True, [(2,)])])] points = stats[0][1] adds = stats[1][1][0][1][0][0] queues = stats[1][1][1][1][0][0] likes = stats[1][1][2][1][0][0] dislikes = stats[1][1][3][1][0][0] liked = stats[1][1][4][1][0][0] disliked = stats[1][1][5][1][0][0] clog.info('(returnPoints) %s has %d points.' % (username, points), syst) cy.doSendChat( '[%s] points:%d (a%d / q%d / l%d / d%d / L%d / D%d)' % (username, points, adds, queues, likes, dislikes, liked, disliked), source=source, username=querier)
def processCommand(self, source, user, msg, prot): if msg.startswith('$'): msg = tools.returnUnicode(msg) #msg = msg.encode('utf-8') command = msg.split()[0][1:] argsList = msg.split(' ', 1) if len(argsList) == 2: args = argsList[1] else: args = None if command in self.triggers['commands']: clog.info( 'triggered command: [%s] args: [%s]' % (command, args), sys) self.triggers['commands'][command](self, user, args, source, prot=prot)
def _likeMedia(self, cy, username, args, source, value): if not cy.nowPlayingMedia: return if args is not None: mType, mId = args.split(', ') else: mType = cy.nowPlayingMedia['type'] mId = cy.nowPlayingMedia['id'] clog.info('(_com_like):type:%s, id:%s' % (mType, mId), syst) uid = cy.getUidFromTypeId(mType, mId) if uid is None: clog.error('Got None for UID _likeMedia', syst) i = cy.getIndexFromUid(uid) userId = cy.userdict[username]['keyId'] qid = cy.playlist[i]['qid'] d = database.queryMediaId(mType, mId) d.addCallback(self.processResult) d.addCallback(database.insertReplaceLike, qid, userId, getTime(), value) d.addCallback(self.updateCurrentLikes, cy, username, value)
def requestYtApi(ytId, content): """ Request video information from Youtube API. ytId : string of Youtube video ID content: check - embed and playback ability desc - video description """ # ytId is unicode, so needs to be changed to str/bytes ytId = str(ytId) agent = Agent(reactor, WebClientContextFactory()) if content == 'check': part = 'status' elif content == 'desc': part = 'snippet' url = ('https://www.googleapis.com/youtube/v3/videos?' 'part=%s&id=%s&key=%s' % (part, ytId, KEY)) clog.info(url, syst) d = agent.request('GET', url, Headers({'Content-type': ['application/json']})) d.addCallbacks(checkStatus, networkError, (ytId, )) return d
def sendManyMedia(self, res, quantity, args): if res: mediaList = [] for media in res: mediaList.append(self.jsonifyMedia(media)) clog.info('sendManyMedia %s' % mediaList, sys) fulfilled = True if len(mediaList) == quantity else False response = { 'callType': 'mediaByIdRange', 'result': 'ok', 'resource': mediaList, 'meta': { 'fulfilled': fulfilled } } else: response = { 'callType': 'mediaByIdRange', 'result': 'nomatch', 'args': args } self.sendLineAndLog(json.dumps(response))
def processVdbJsonForSongId(body): clog.info('(processVdbJsonForSongId) Received reply from VocaDB', syst) # clog.debug('(processVdbJsonForSongId) %s' % body, syst) body = body.decode('UTF-8') try: pbody = json.loads(body) except (ValueError): return defer.fail(None) try: if 'message' in pbody: clog.error(pbody['message'], syst) except (TypeError): # body is null (pbody is None) clog.warning('(processVdbJsonForSongId) null from Vocadb', syst) return defer.succeed(0) songId = pbody.get('id') # Couldn't find songId, this might be a list of songs...so pick the first ;) if not songId: items = pbody.get('items') if items and items[0]: songId = items[0]['id'] return defer.succeed((body, songId))
def processVocadb(self, res, mType, mId): if not res: clog.info('(processVocadb) Vocadb db query returned []') self.currentVocadb = 'vocapack =' + json.dumps({'res': False}) else: setby = res[0][0] mediaId = res[0][1] vocadbId = res[0][2] method = res[0][3] vocadbData = res[0][4] if vocadbId == 0: self.currentVocadb = 'vocapack =' + json.dumps({'res': False}) else: vocadbInfo = self.parseVocadb(vocadbData) vocapack = { 'setby': setby, 'vocadbId': vocadbId, 'method': method, 'vocadbInfo': vocadbInfo, 'res': True } vocapackjs = json.dumps(vocapack) self.currentVocadb = 'vocapack =' + vocapackjs return defer.succeed((self.jsName, self.currentVocadb))
def sendOneMedia(self, res, args): clog.info('sendonemedia %s' % res, sys) if res[0][0] and res[1][0] and res[0][1]: # not res[0][1] means no row mRow = res[0][1][0] mLastRowId = res[1][1][0][0] # 2deep4me mediaDict = self.jsonifyMedia(mRow) response = { 'callType': 'mediaById', 'result': 'ok', 'resource': mediaDict, 'meta': { 'isLastRow': False } } clog.info('lastrow %s %s' % (mRow[0], mLastRowId), sys) if mRow[0] == mLastRowId: response['meta']['isLastRow'] = True else: response = { 'callType': 'mediaById', 'result': 'nomatch', 'args': args } self.sendLineAndLog(json.dumps(response))
def pong(self, user, secs): """ Called with the results of a CTCP PING query. """ clog.info('PONG %s: %s secs' % (user, secs), sys)
def kickedFrom(self, channel, kicker, message): clog.info('kickedFrom %s by %s: %s' % (channel, kicker, message), sys) self.join(self.channelName)