You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
5.9 KiB
Python

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.network.keys():
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.network.keys():
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.network.keys():
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.network.keys():
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