Reformat code with pre-commit

This commit is contained in:
2022-07-21 13:39:41 +01:00
parent 0777a55264
commit ff1ee63900
60 changed files with 547 additions and 278 deletions

View File

@@ -2,9 +2,11 @@ import main
import random
import re
def generate_password():
return "".join([chr(random.randint(0, 74) + 48) for i in range(32)])
def generate_alias():
nick = random.choice(main.aliasdata["stubs"])
rand = random.randint(1, 2)
@@ -12,8 +14,8 @@ def generate_alias():
nick = nick.capitalize()
rand = random.randint(1, 4)
while rand == 1:
split = random.randint(0, len(nick)-1)
nick = nick[:split] + nick[split+1:]
split = random.randint(0, len(nick) - 1)
nick = nick[:split] + nick[split + 1 :]
rand = random.randint(1, 4)
rand = random.randint(1, 3)
if rand == 1 or rand == 4:
@@ -63,4 +65,10 @@ def generate_alias():
if rand == 3 or rand == 4:
realname = realname.capitalize()
return {"nick": nick, "altnick": altnick, "ident": ident, "realname": realname, "emails": []}
return {
"nick": nick,
"altnick": altnick,
"ident": ident,
"realname": realname,
"emails": [],
}

View File

@@ -6,11 +6,12 @@ from math import ceil
import modules.provision
from twisted.internet.threads import deferToThread
def allRelaysActive(net):
relayNum = len(main.network[net].relays.keys())
existNum = 0
for i in main.network[net].relays.keys():
name = net+str(i)
name = net + str(i)
if name in main.IRCPool.keys():
if main.IRCPool[name].authenticated:
existNum += 1
@@ -18,20 +19,22 @@ def allRelaysActive(net):
return True
return False
def getChanFree(net, new):
chanfree = {}
chanlimits = set()
for i in main.network[net].relays.keys():
if i in new:
continue
name = net+str(i)
chanfree[i] = main.IRCPool[name].chanlimit-len(main.IRCPool[name].channels)
name = net + str(i)
chanfree[i] = main.IRCPool[name].chanlimit - len(main.IRCPool[name].channels)
chanlimits.add(main.IRCPool[name].chanlimit)
if not len(chanlimits) == 1:
error("Network %s has servers with different CHANLIMIT values" % net)
return False
return (chanfree, chanlimits.pop())
def emptyChanAllocate(net, flist, relay, new):
chanfree = getChanFree(net, new)
if not chanfree:
@@ -41,10 +44,10 @@ def emptyChanAllocate(net, flist, relay, new):
allocated = {}
toalloc = len(flist)
if toalloc > sum(chanfree[0].values()):
correction = round(toalloc-sum(chanfree[0].values()) / chanfree[1])
#print("correction", correction)
correction = round(toalloc - sum(chanfree[0].values()) / chanfree[1])
# print("correction", correction)
warn("Ran out of channel spaces, provisioning additional %i relays for %s" % (correction, net))
#newNums = modules.provision.provisionMultipleRelays(net, correction)
# newNums = modules.provision.provisionMultipleRelays(net, correction)
return False
for i in chanfree[0].keys():
for x in range(chanfree[0][i]):
@@ -56,8 +59,9 @@ def emptyChanAllocate(net, flist, relay, new):
allocated[i] = [flist.pop()]
return allocated
def populateChans(net, clist, relay, new):
#divided = array_split(clist, relay)
# divided = array_split(clist, relay)
allocated = emptyChanAllocate(net, clist, relay, new)
if not allocated:
return
@@ -67,18 +71,20 @@ def populateChans(net, clist, relay, new):
else:
main.TempChan[net] = {i: allocated[i]}
def notifyJoin(net):
for i in main.network[net].relays.keys():
name = net+str(i)
name = net + str(i)
if name in main.IRCPool.keys():
main.IRCPool[name].checkChannels()
def minifyChans(net, listinfo):
if not allRelaysActive(net):
error("All relays for %s are not active, cannot minify list" % net)
return False
for i in main.network[net].relays.keys():
name = net+str(i)
name = net + str(i)
for x in main.IRCPool[name].channels:
for y in listinfo:
if y[0] == x:
@@ -88,29 +94,31 @@ def minifyChans(net, listinfo):
return False
return listinfo
def keepChannels(net, listinfo, mean, sigrelay, relay):
listinfo = minifyChans(net, listinfo)
if not listinfo:
return
if relay <= main.config["ChanKeep"]["SigSwitch"]: # we can cover all of the channels
if relay <= main.config["ChanKeep"]["SigSwitch"]: # we can cover all of the channels
coverAll = True
elif relay > main.config["ChanKeep"]["SigSwitch"]: # we cannot cover all of the channels
elif relay > main.config["ChanKeep"]["SigSwitch"]: # we cannot cover all of the channels
coverAll = False
if not sigrelay <= main.config["ChanKeep"]["MaxRelay"]:
error("Network %s is too big to cover: %i relays required" % (net, sigrelay))
return
if coverAll:
needed = relay-len(main.network[net].relays.keys())
needed = relay - len(main.network[net].relays.keys())
newNums = modules.provision.provisionMultipleRelays(net, needed)
flist = [i[0] for i in listinfo]
populateChans(net, flist, relay, newNums)
else:
needed = sigrelay-len(main.network[net].relays.keys())
needed = sigrelay - len(main.network[net].relays.keys())
newNums = modules.provision.provisionMultipleRelays(net, needed)
siglist = [i[0] for i in listinfo if int(i[1]) > mean]
populateChans(net, siglist, sigrelay, newNums)
notifyJoin(net)
def joinSingle(net, channel):
if allRelaysActive(net):
chanfree = getChanFree(net, [])
@@ -122,14 +130,16 @@ def joinSingle(net, channel):
error("All relays for %s are not active" % net)
return False
def nukeNetwork(net):
#purgeRecords(net)
#p = main.g.pipeline()
main.g.delete("analytics.list."+net)
#p.delete("list."+net)
#p.execute()
#def nukeNetwork(net):
def nukeNetwork(net):
# purgeRecords(net)
# p = main.g.pipeline()
main.g.delete("analytics.list." + net)
# p.delete("list."+net)
# p.execute()
# def nukeNetwork(net):
# deferToThread(_nukeNetwork, net)
@@ -141,7 +151,7 @@ def _initialList(net, num, listinfo, chanlimit):
except TypeError:
warn("Bad LIST data received from %s - %i" % (net, num))
return
mean = round(cumul/listlength, 2)
mean = round(cumul / listlength, 2)
siglength = 0
insiglength = 0
sigcumul = 0
@@ -154,8 +164,8 @@ def _initialList(net, num, listinfo, chanlimit):
insiglength += 1
insigcumul += int(i[1])
sigrelay = ceil(siglength/chanlimit)
relay = ceil(listlength/chanlimit)
sigrelay = ceil(siglength / chanlimit)
relay = ceil(listlength / chanlimit)
netbase = "list.%s" % net
abase = "analytics.list.%s" % net
p = main.g.pipeline()
@@ -163,18 +173,18 @@ def _initialList(net, num, listinfo, chanlimit):
p.hset(abase, "total", listlength)
p.hset(abase, "sigtotal", siglength)
p.hset(abase, "insigtotal", insiglength)
p.hset(abase, "sigperc", round(siglength/listlength*100, 2))
p.hset(abase, "insigperc", round(insiglength/listlength*100, 2))
p.hset(abase, "sigperc", round(siglength / listlength * 100, 2))
p.hset(abase, "insigperc", round(insiglength / listlength * 100, 2))
p.hset(abase, "cumul", cumul)
p.hset(abase, "sigcumul", sigcumul)
p.hset(abase, "insigcumul", insigcumul)
p.hset(abase, "relay", relay)
p.hset(abase, "sigrelay", sigrelay)
p.hset(abase, "insigrelay", ceil(insiglength/chanlimit))
p.hset(abase, "insigrelay", ceil(insiglength / chanlimit))
# Purge existing records before writing
#purgeRecords(net)
#for i in listinfo:
# purgeRecords(net)
# for i in listinfo:
# p.rpush(netbase+"."+i[0], i[1])
# p.rpush(netbase+"."+i[0], i[2])
# p.sadd(netbase, i[0])
@@ -183,6 +193,6 @@ def _initialList(net, num, listinfo, chanlimit):
debug("List parsing completed on %s" % net)
keepChannels(net, listinfo, mean, sigrelay, relay)
def initialList(net, num, listinfo, chanlimit):
deferToThread(_initialList, net, num, deepcopy(listinfo), chanlimit)

View File

@@ -1,6 +1,7 @@
import main
from twisted.internet.task import LoopingCall
def event(name, eventType):
if not "local" in main.counters.keys():
main.counters["local"] = {}
@@ -18,6 +19,7 @@ def event(name, eventType):
main.counters["global"][eventType] += 1
main.runningSample += 1
def getEvents(name=None):
if name == None:
if "global" in main.counters.keys():
@@ -30,10 +32,12 @@ def getEvents(name=None):
else:
return None
def takeSample():
main.lastMinuteSample = main.runningSample
main.runningSample = 0
def setupCounterLoop():
lc = LoopingCall(takeSample)
lc.start(60)

View File

@@ -8,9 +8,25 @@ from modules import userinfo
from modules import regproc
from utils.dedup import dedup
order = ["type", "net", "num", "channel", "msg", "nick",
"ident", "host", "mtype", "user", "mode", "modearg",
"realname", "server", "status", "time"]
order = [
"type",
"net",
"num",
"channel",
"msg",
"nick",
"ident",
"host",
"mtype",
"user",
"mode",
"modearg",
"realname",
"server",
"status",
"time",
]
def parsemeta(numName, c):
if not "channel" in c.keys():
@@ -21,10 +37,16 @@ def parsemeta(numName, c):
if c["type"] in ["msg", "notice", "action", "topic", "mode"]:
if "muser" in c.keys():
userinfo.editUser(c["net"], c["muser"])
#if c["type"] == "mode":
# if c["type"] == "mode":
# userinfo.updateMode(c)
elif c["type"] == "nick":
userinfo.renameUser(c["net"], c["nick"], c["muser"], c["user"], c["user"]+"!"+c["ident"]+"@"+c["host"])
userinfo.renameUser(
c["net"],
c["nick"],
c["muser"],
c["user"],
c["user"] + "!" + c["ident"] + "@" + c["host"],
)
elif c["type"] == "kick":
userinfo.editUser(c["net"], c["muser"])
userinfo.delUserByNick(c["net"], c["channel"], c["user"])
@@ -37,9 +59,16 @@ def parsemeta(numName, c):
if "mtype" in c.keys():
if c["mtype"] == "nick":
userinfo.renameUser(c["net"], c["nick"], c["muser"], c["user"], c["user"]+"!"+c["ident"]+"@"+c["host"])
userinfo.renameUser(
c["net"],
c["nick"],
c["muser"],
c["user"],
c["user"] + "!" + c["ident"] + "@" + c["host"],
)
def event(numName, c): # yes I'm using a short variable because otherwise it goes off the screen
def event(numName, c): # yes I'm using a short variable because otherwise it goes off the screen
if dedup(numName, c):
return
@@ -48,7 +77,7 @@ def event(numName, c): # yes I'm using a short variable because otherwise it goe
if "muser" in c.keys():
del c["muser"]
sortedKeys = {k: c[k] for k in order if k in c} # Sort dict keys according to order
sortedKeys = {k: c[k] for k in order if k in c} # Sort dict keys according to order
sortedKeys["src"] = "irc"
sendLogstashNotification(sortedKeys)
sendRelayNotification(sortedKeys)

View File

@@ -10,6 +10,7 @@ import main
from utils.logging.log import *
from utils.get import getRelay
class Network:
def __init__(self, net, host, port, security, auth):
self.net = net
@@ -37,20 +38,20 @@ class Network:
"enabled": main.config["ConnectOnCreate"],
"net": self.net,
"id": num,
"registered": registered
"registered": registered,
}
password = alias.generate_password()
if not num in main.alias.keys():
main.alias[num] = alias.generate_alias()
main.saveConf("alias")
self.aliases[num] = {"password": password}
#if main.config["ConnectOnCreate"]: -- Done in provision
# if main.config["ConnectOnCreate"]: -- Done in provision
# self.start_bot(num)
return num, main.alias[num]["nick"]
def killAliases(self, aliasList):
for i in aliasList:
name = self.net+str(i)
name = self.net + str(i)
if name in main.ReactorPool.keys():
if name in main.FactoryPool.keys():
main.FactoryPool[name].stopTrying()
@@ -63,7 +64,7 @@ class Network:
def delete_relay(self, id):
del self.relays[id]
del self.aliases[id]
#del main.alias[id] - Aliases are global per num, so don't delete them!
# del main.alias[id] - Aliases are global per num, so don't delete them!
self.killAliases([id])
def seppuku(self):
@@ -74,11 +75,11 @@ class Network:
def start_bot(self, num):
# a single name is given to relays in the backend
# e.g. freenode1 for the first relay on freenode network
keyFN = main.certPath+main.config["Key"]
certFN = main.certPath+main.config["Certificate"]
keyFN = main.certPath + main.config["Key"]
certFN = main.certPath + main.config["Certificate"]
contextFactory = DefaultOpenSSLContextFactory(keyFN.encode("utf-8", "replace"), certFN.encode("utf-8", "replace"))
bot = IRCBotFactory(self.net, num)
#host, port = self.relays[num]["host"], self.relays[num]["port"]
# host, port = self.relays[num]["host"], self.relays[num]["port"]
host, port = getRelay(num)
rct = reactor.connectSSL(host, port, bot, contextFactory)
name = self.net + str(num)

View File

@@ -4,6 +4,7 @@ from utils.logging.log import *
from twisted.internet import reactor
import modules.regproc
def provisionUserNetworkData(num, nick, altnick, ident, realname, network, host, port, security, auth, password):
commands = {}
stage2commands = {}
@@ -17,7 +18,7 @@ def provisionUserNetworkData(num, nick, altnick, ident, realname, network, host,
commands["controlpanel"].append("Set Ident %s %s" % (user, ident))
commands["controlpanel"].append("Set RealName %s %s" % (user, realname))
if security == "ssl":
commands["controlpanel"].append("SetNetwork TrustAllCerts %s %s true" % (user, network)) # Don't judge me
commands["controlpanel"].append("SetNetwork TrustAllCerts %s %s true" % (user, network)) # Don't judge me
commands["controlpanel"].append("AddServer %s %s %s +%s" % (user, network, host, port))
elif security == "plain":
commands["controlpanel"].append("AddServer %s %s %s %s" % (user, network, host, port))
@@ -29,9 +30,9 @@ def provisionUserNetworkData(num, nick, altnick, ident, realname, network, host,
inst = modules.regproc.selectInst(network)
if "setmode" in inst.keys():
stage2commands["status"].append("LoadMod perform")
#stage2commands["perform"].append("add mode %nick% +"+inst["setmode"])
deliverRelayCommands(num, commands,
stage2=[[user+"/"+network, stage2commands]])
# stage2commands["perform"].append("add mode %nick% +"+inst["setmode"])
deliverRelayCommands(num, commands, stage2=[[user + "/" + network, stage2commands]])
def provisionAuthenticationData(num, nick, network, security, auth, password):
commands = {}
@@ -48,23 +49,28 @@ def provisionAuthenticationData(num, nick, network, security, auth, password):
commands["nickserv"].append("Set %s" % password)
inst = modules.regproc.selectInst(network)
if "setmode" in inst.keys():
#commands["status"].append("LoadMod perform")
commands["perform"] = ["add mode %nick% +"+inst["setmode"]]
deliverRelayCommands(num, commands, user=user+"/"+network)
# commands["status"].append("LoadMod perform")
commands["perform"] = ["add mode %nick% +" + inst["setmode"]]
deliverRelayCommands(num, commands, user=user + "/" + network)
def provisionRelay(num, network): # provision user and network data
def provisionRelay(num, network): # provision user and network data
aliasObj = main.alias[num]
alias = aliasObj["nick"]
provisionUserNetworkData(num, *aliasObj.values(), network,
main.network[network].host,
main.network[network].port,
main.network[network].security,
main.network[network].auth,
main.network[network].aliases[num]["password"])
provisionUserNetworkData(
num,
*aliasObj.values(),
network,
main.network[network].host,
main.network[network].port,
main.network[network].security,
main.network[network].auth,
main.network[network].aliases[num]["password"]
)
if main.config["ConnectOnCreate"]:
reactor.callLater(10, main.network[network].start_bot, num)
def provisionMultipleRelays(net, relaysNeeded):
numsProvisioned = []
for i in range(relaysNeeded):
@@ -73,4 +79,3 @@ def provisionMultipleRelays(net, relaysNeeded):
provisionRelay(num, net)
main.saveConf("network")
return numsProvisioned

View File

@@ -4,6 +4,7 @@ from utils.logging.log import *
from utils.logging.debug import *
from copy import deepcopy
def needToRegister(net):
inst = selectInst(net)
if "register" in inst.keys():
@@ -12,6 +13,7 @@ def needToRegister(net):
else:
return False
def selectInst(net):
if net in main.irc.keys():
inst = deepcopy(main.irc[net])
@@ -22,11 +24,12 @@ def selectInst(net):
inst = main.irc["_"]
return inst
def substitute(net, num, token=None):
inst = selectInst(net)
alias = main.alias[num]
nickname = alias["nick"]
username = nickname+"/"+net
username = nickname + "/" + net
password = main.network[net].aliases[num]["password"]
inst["email"] = inst["email"].replace("{nickname}", nickname)
for i in inst.keys():
@@ -39,29 +42,32 @@ def substitute(net, num, token=None):
inst[i] = inst[i].replace("{token}", token)
return inst
def registerAccount(net, num):
debug("Attempting to register: %s - %i" % (net, num))
sinst = substitute(net, num)
if not sinst["register"]:
error("Cannot register for %s: function disabled" % (net))
return False
name = net+str(num)
name = net + str(num)
main.IRCPool[name].msg(sinst["entity"], sinst["registermsg"])
def confirmAccount(net, num, token):
sinst = substitute(net, num, token=token)
name = net+str(num)
name = net + str(num)
main.IRCPool[name].msg(sinst["entity"], sinst["confirm"])
enableAuthentication(net, num)
def confirmRegistration(net, num, negativepass=None):
obj = main.network[net]
name = net+str(num)
name = net + str(num)
if name in main.IRCPool.keys():
if not negativepass == None:
main.IRCPool[name].regPing(negativepass=negativepass)
return
debug("Relay authenticated: %s - %i" %(net, num))
debug("Relay authenticated: %s - %i" % (net, num))
main.IRCPool[name].authenticated = True
main.IRCPool[name].recheckList()
if obj.relays[num]["registered"]:
@@ -75,21 +81,23 @@ def confirmRegistration(net, num, negativepass=None):
obj.relays[num]["registered"] = True
main.saveConf("network")
def enableAuthentication(net, num):
obj = main.network[net]
nick = main.alias[num]["nick"]
security = obj.security
auth = obj.auth
password = obj.aliases[num]["password"]
uname = main.alias[num]["nick"]+"/"+net
provision.provisionAuthenticationData(num, nick, net, security, auth, password) # Set up for auth
main.IRCPool[net+str(num)].msg(main.config["Tweaks"]["ZNC"]["Prefix"]+"status", "Jump")
uname = main.alias[num]["nick"] + "/" + net
provision.provisionAuthenticationData(num, nick, net, security, auth, password) # Set up for auth
main.IRCPool[net + str(num)].msg(main.config["Tweaks"]["ZNC"]["Prefix"] + "status", "Jump")
if selectInst(net)["check"] == False:
confirmRegistration(net, num)
def registerTest(c):
sinst = substitute(c["net"], c["num"])
name = c["net"]+str(c["num"])
name = c["net"] + str(c["num"])
if sinst["check"] == False:
return
if "msg" in c.keys() and not c["msg"] == None:
@@ -98,19 +106,19 @@ def registerTest(c):
if not main.IRCPool[name]._negativePass == True:
if c["type"] == "query" and c["nick"] == sinst["entity"]:
if sinst["checknegativemsg"] in c["msg"]:
confirmRegistration(c["net"], c["num"], negativepass=False) # Not passed negative check, report back
confirmRegistration(c["net"], c["num"], negativepass=False) # Not passed negative check, report back
return
if sinst["checkendnegative"] in c["msg"]:
confirmRegistration(c["net"], c["num"], negativepass=True) # Passed the negative check, report back
confirmRegistration(c["net"], c["num"], negativepass=True) # Passed the negative check, report back
return
if sinst["ping"]:
if sinst["checkmsg2"] in c["msg"] and c["nick"] == sinst["entity"]:
confirmRegistration(c["net"], c["num"])
return
if sinst["checktype"] == "msg":
if sinst["checkmsg"] in c["msg"]:
confirmRegistration(c["net"], c["num"])
return
if sinst["checkmsg"] in c["msg"]:
confirmRegistration(c["net"], c["num"])
return
elif sinst["checktype"] == "mode":
if c["type"] == "self":
if c["mtype"] == "mode":

View File

@@ -6,12 +6,14 @@ from utils.logging.log import *
from utils.logging.debug import debug, trace
from utils.parsing import parsen
def getWhoSingle(name, query):
result = main.r.sscan("live.who."+name, 0, query, count=999999)
result = main.r.sscan("live.who." + name, 0, query, count=999999)
if result[1] == []:
return None
return (i.decode() for i in result[1])
def getWho(query):
result = {}
for i in main.network.keys():
@@ -20,20 +22,23 @@ def getWho(query):
result[i] = f
return result
def getChansSingle(name, nick):
nick = ["live.chan."+name+"."+i for i in 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
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():
@@ -42,13 +47,15 @@ def getChans(nick):
result[i] = f
return result
def getUsersSingle(name, nick):
nick = ("live.who."+name+"."+i for i in 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():
@@ -57,8 +64,10 @@ def getUsers(nick):
result[i] = f
return result
def getNumWhoEntries(name):
return main.r.scard("live.who."+name)
return main.r.scard("live.who." + name)
def getNumTotalWhoEntries():
total = 0
@@ -66,6 +75,7 @@ def getNumTotalWhoEntries():
total += getNumWhoEntries(i)
return total
def getNamespace(name, channel, nick):
gnamespace = "live.who.%s" % name
namespace = "live.who.%s.%s" % (name, channel)
@@ -73,35 +83,40 @@ def getNamespace(name, channel, nick):
mapspace = "live.map.%s" % name
return (gnamespace, namespace, chanspace, mapspace)
def _initialUsers(name, channel, users):
gnamespace = "live.who.%s" % name
mapspace = "live.map.%s" % name
p = main.r.pipeline()
for i in users:
user = i[0]+"!"+i[1]+"@"+i[2]
user = i[0] + "!" + i[1] + "@" + i[2]
p.hset(mapspace, i[0], user)
p.sadd(gnamespace, user)
p.execute()
def initialUsers(name, channel, users):
trace("Initialising WHO records for %s on %s" % (channel, name))
d = deferToThread(_initialUsers, name, channel, users)
#d.addCallback(testCallback)
# d.addCallback(testCallback)
def _initialNames(name, channel, names):
namespace = "live.who.%s.%s" % (name, channel)
p = main.r.pipeline()
for mode, nick in names:
p.sadd(namespace, nick)
p.sadd("live.chan."+name+"."+nick, channel)
p.sadd("live.chan." + name + "." + nick, channel)
if mode:
p.hset("live.prefix."+name+"."+channel, nick, mode)
p.hset("live.prefix." + name + "." + channel, nick, mode)
p.execute()
def initialNames(name, channel, names):
trace("Initialising NAMES records for %s on %s" % (channel, name))
d = deferToThread(_initialNames, name, channel, names)
#d.addCallback(testCallback)
# d.addCallback(testCallback)
def editUser(name, user):
gnamespace = "live.who.%s" % name
@@ -109,9 +124,10 @@ def editUser(name, user):
parsed = parsen(user)
p = main.r.pipeline()
p.sadd(gnamespace, user)
p.hset(mapspace, parsed[0], user) # add nick -> user mapping
p.hset(mapspace, parsed[0], user) # add nick -> user mapping
p.execute()
def addUser(name, channel, nick, user):
gnamespace, namespace, chanspace, mapspace = getNamespace(name, channel, nick)
p = main.r.pipeline()
@@ -121,40 +137,43 @@ def addUser(name, channel, nick, user):
p.hset(mapspace, nick, user)
p.execute()
def delUser(name, channel, nick, user):
gnamespace, namespace, chanspace, mapspace = getNamespace(name, channel, nick)
p = main.r.pipeline()
channels = main.r.smembers(chanspace)
p.srem(namespace, nick)
if channels == {channel.encode()}: # can we only see them on this channel?
p.delete(chanspace) # remove channel tracking entry
p.hdel("live.prefix."+name+"."+channel, nick) # remove prefix tracking entry
p.hdel(mapspace, nick) # remove nick mapping entry
if channels == {channel.encode()}: # can we only see them on this channel?
p.delete(chanspace) # remove channel tracking entry
p.hdel("live.prefix." + name + "." + channel, nick) # remove prefix tracking entry
p.hdel(mapspace, nick) # remove nick mapping entry
if user:
p.srem(gnamespace, user) # remove global userinfo entry
p.srem(gnamespace, user) # remove global userinfo entry
else:
warn("Attempt to delete nonexistent user: %s" % user)
else:
p.srem(chanspace, channel) # keep up - remove the channel from their list
p.srem(chanspace, channel) # keep up - remove the channel from their list
p.execute()
def escape(text):
chars = ["[", "]", "^", "-", "*", "?"]
text = text.replace("\\", "\\\\")
for i in chars:
text = text.replace(i, "\\"+i)
text = text.replace(i, "\\" + i)
return text
def getUserByNick(name, nick):
gnamespace = "live.who.%s" % name # "nick": "nick!ident@host"
gnamespace = "live.who.%s" % name # "nick": "nick!ident@host"
mapspace = "live.map.%s" % name
if main.r.hexists(mapspace, nick):
return main.r.hget(mapspace, nick)
else:
warn("Entry doesn't exist: %s on %s - attempting auxiliary lookup" % (nick, mapspace))
#return False
# return False
# legacy code below - remove when map is reliable
usermatch = main.r.sscan(gnamespace, match=escape(nick)+"!*", count=999999999)
usermatch = main.r.sscan(gnamespace, match=escape(nick) + "!*", count=999999999)
if usermatch[1] == []:
warn("No matches found for user query: %s on %s" % (nick, name))
return False
@@ -166,6 +185,7 @@ def getUserByNick(name, nick):
warn("Auxiliary lookup failed: %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)
@@ -176,40 +196,43 @@ def renameUser(name, oldnick, olduser, newnick, newuser):
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)
p.srem("live.who." + name + "." + i, oldnick)
p.sadd("live.who." + name + "." + i, newnick)
p.hdel(mapspace, oldnick)
p.hset(mapspace, newnick, newuser)
if main.r.exists("live.prefix."+name+"."+i): # if there's a prefix entry for the channel
if main.r.hexists("live.prefix."+name+"."+i, oldnick): # if the old nick is in it
mode = main.r.hget("live.prefix."+name+"."+i, oldnick) # retrieve old modes
p.hset("live.prefix."+name+"."+i, newnick, mode) # set old modes to new nickname
if main.r.exists("live.prefix." + name + "." + i): # if there's a prefix entry for the channel
if main.r.hexists("live.prefix." + name + "." + i, oldnick): # if the old nick is in it
mode = main.r.hget("live.prefix." + name + "." + i, oldnick) # retrieve old modes
p.hset("live.prefix." + name + "." + i, newnick, mode) # set old modes to new nickname
if main.r.exists(chanspace):
p.rename(chanspace, newchanspace)
else:
warn("Key doesn't exist: %s" % chanspace)
p.execute()
def delUserByNick(name, channel, nick): # kick
def delUserByNick(name, channel, nick): # kick
user = getUserByNick(name, nick)
if not user:
return
delUser(name, channel, nick, user)
def delUserByNetwork(name, nick, user): # quit
def delUserByNetwork(name, nick, user): # quit
gnamespace = "live.who.%s" % name
chanspace = "live.chan.%s.%s" % (name, nick)
mapspace = "live.chan.%s" % name
p = main.r.pipeline()
p.srem(gnamespace, user)
for i in main.r.smembers(chanspace):
p.srem("live.who."+name+"."+i.decode(), nick)
p.hdel("live.prefix."+name+"."+i.decode(), nick)
p.srem("live.who." + name + "." + i.decode(), nick)
p.hdel("live.prefix." + name + "." + i.decode(), nick)
p.delete(chanspace)
p.hdel(mapspace, nick)
p.execute()
def _delChannels(net, channels):
gnamespace = "live.who.%s" % net
mapspace = "live.map.%s" % net
@@ -218,23 +241,24 @@ def _delChannels(net, channels):
namespace = "live.who.%s.%s" % (net, channel)
for i in main.r.smembers(namespace):
nick = i.decode()
#user = getUserByNick(net, nick) -- far too many function calls
# user = getUserByNick(net, nick) -- far too many function calls
user = main.r.hget(mapspace, nick)
if not user:
warn("User lookup failed: %s on %s" % (nick, net))
if main.r.smembers("live.chan."+net+"."+nick) == {channel.encode()}:
if main.r.smembers("live.chan." + net + "." + nick) == {channel.encode()}:
if user:
p.srem(gnamespace, user)
p.delete("live.chan."+net+"."+nick)
p.hdel(mapspace, nick) # remove map entry
p.delete("live.chan." + net + "." + nick)
p.hdel(mapspace, nick) # remove map entry
else:
p.srem("live.chan."+net+"."+nick, channel)
p.srem("live.chan." + net + "." + nick, channel)
p.delete(namespace)
p.delete("live.prefix."+net+"."+channel)
p.delete("live.prefix." + net + "." + channel)
p.execute()
def delChannels(net, channels): # we have left a channel
def delChannels(net, channels): # we have left a channel
trace("Purging channel %s for %s" % (", ".join(channels), net))
d = deferToThread(_delChannels, net, channels)
#d.addCallback(testCallback)
# d.addCallback(testCallback)