from twisted.internet.threads import deferToThread from string import digits import main from utils.logging.log import * from utils.logging.debug import debug def getWhoSingle(name, query): result = main.r.sscan("live.who."+name, 0, query, count=9999999) if result[1] == []: return None return [i.decode() for i in result[1]] def getWho(query): result = {} for i in main.nets(): f = getWhoSingle(i, query) if f: result[i] = f return result def getChansSingle(name, nick): nick = ["live.chan."+name+"."+i for i in nick] result = main.r.sinter(*nick) if len(result) == 0: return None return [i.decode() for i in result] def getChanList(name, nick): chanspace = "live.chan."+name+"."+nick result = main.r.smembers(chanspace) if len(result) == 0: return None return [i.decode() for i in result] def getChans(nick): result = {} for i in main.nets(): f = getChansSingle(i, nick) if f: result[i] = f return result def getUsersSingle(name, nick): nick = ["live.who."+name+"."+i for i in nick] result = main.r.sinter(*nick) if len(result) == 0: return None return [i.decode() for i in result] def getUsers(nick): result = {} for i in main.nets(): f = getUsersSingle(i, nick) if f: result[i] = f return result def getNumWhoEntries(name): return main.r.scard("live.who."+name) def getNumTotalWhoEntries(): total = 0 for i in main.nets(): total += getNumWhoEntries(i) return total def getNamespace(name, channel, nick): gnamespace = "live.who.%s" % name namespace = "live.who.%s.%s" % (name, channel) chanspace = "live.chan.%s.%s" % (name, nick) return [gnamespace, namespace, chanspace] def _initialUsers(name, channel, users): gnamespace = "live.who.%s" % name p = main.r.pipeline() for i in users: p.sadd(gnamespace, i[0]+"!"+i[1]+"@"+i[2]) p.execute() def initialUsers(name, channel, users): debug("Initialising WHO records for %s on %s" % (channel, name)) d = deferToThread(_initialUsers, name, channel, users) #d.addCallback(testCallback) def _initialNames(name, channel, names): namespace = "live.who.%s.%s" % (name, channel) p = main.r.pipeline() for i in names: p.sadd(namespace, i) p.sadd("live.chan."+name+"."+i, channel) p.execute() def initialNames(name, channel, names): debug("Initialising NAMES records for %s on %s" % (channel, name)) d = deferToThread(_initialNames, name, channel, names) #d.addCallback(testCallback) def editUser(name, user): gnamespace = "live.who.%s" % name main.r.sadd(gnamespace, user) def addUser(name, channel, nick, user): gnamespace, namespace, chanspace = getNamespace(name, channel, nick) p = main.r.pipeline() p.sadd(gnamespace, user) p.sadd(namespace, nick) p.sadd(chanspace, channel) p.execute() def delUser(name, channel, nick, user): gnamespace, namespace, chanspace = getNamespace(name, channel, nick) p = main.r.pipeline() channels = main.r.smembers(chanspace) p.srem(namespace, nick) if channels == {channel.encode()}: p.delete(chanspace) p.srem(gnamespace, user) else: p.srem(chanspace, channel) p.execute() def escape(text): chars = ["[", "]", "^", "-", "*", "?"] text = text.replace("\\", "\\\\") for i in chars: text = text.replace(i, "\\"+i) return text def getUserByNick(name, nick): gnamespace = "live.who.%s" % name usermatch = main.r.sscan(gnamespace, match=escape(nick)+"!*", count=9999999) if usermatch[1] == []: return False else: if len(usermatch[1]) == 1: user = usermatch[1][0] return user else: warn("Entry doesn't exist: %s on %s" % (nick, gnamespace)) return False def renameUser(name, oldnick, olduser, newnick, newuser): gnamespace = "live.who.%s" % name chanspace = "live.chan.%s.%s" % (name, oldnick) newchanspace = "live.chan.%s.%s" % (name, newnick) p = main.r.pipeline() p.srem(gnamespace, olduser) p.sadd(gnamespace, newuser) for i in main.r.smembers(chanspace): i = i.decode() p.srem("live.who."+name+"."+i, oldnick) p.sadd("live.who."+name+"."+i, newnick) if main.r.exists(chanspace): p.rename(chanspace, newchanspace) else: warn("Key doesn't exist: %s" % chanspace) p.execute() def delUserByNick(name, channel, nick): user = getUserByNick(name, nick) delUser(name, channel, nick, user) def delUserByNetwork(name, nick, user): gnamespace = "live.who.%s" % name chanspace = "live.chan.%s.%s" % (name, nick) p = main.r.pipeline() p.srem(gnamespace, user) for i in main.r.smembers(chanspace): p.srem("live.who."+name+"."+i.decode(), nick) p.delete(chanspace) p.execute() def _delChannel(name, channel): # This function is extremely expensive, look to replace gnamespace = "live.who.%s" % name namespace = "live.who.%s.%s" % (name, channel) p = main.r.pipeline() for i in main.r.smembers(namespace): user = getUserByNick(name, i.decode()) if main.r.smembers("live.chan."+name+"."+i.decode()) == {channel.encode()}: if user: p.srem(gnamespace, user) p.delete("live.chan."+name+"."+i.decode()) else: p.srem("live.chan."+name+"."+i.decode(), channel) p.delete(namespace) p.execute() return [name, channel] def delChannel(name, channel): debug("Purging channel %s for %s" % (channel, name)) d = deferToThread(_delChannel, name, channel) #d.addCallback(testCallback) def delNetwork(name, channels): debug("Purging channels for %s" % name) for i in channels: delChannel(name, i) #log("Finished purging channels for %s" % name) return