monolith/modules/monitor.py

112 lines
4.1 KiB
Python

from copy import deepcopy
from json import dumps
from datetime import datetime
import main
from core.relay import sendRelayNotification
from modules import userinfo
from modules import regproc
from utils.dedup import dedup
order = ["type", "net", "num", "channel", "msg", "nick",
"ident", "host", "mtype", "user", "modes", "modeargs"
"realname", "server", "status"]
def testNetTarget(name, target):
called = False
for i in main.monitor.keys():
if "sources" in main.monitor[i].keys():
if name in main.monitor[i]["sources"]:
if main.monitor[i]["sources"][name] == True:
yield i
called = True
elif target in main.monitor[i]["sources"][name]:
yield i
called = True
else:
yield i
called = True
if not called:
return False
def contained_in(x, y):
if x is None or y is None:
return False
elif x == y:
return True
else:
return y in x
def is_in(k, vs, A):
return any(contained_in(A.get(k), vp) for vp in vs)
def matches(A, B):
return all(is_in(k, vs, A) for (k, vs) in B.items())
def magicFunction(A, B):
isInside = False
if "send" in B.keys():
del B["send"]
if "sources" in B.keys():
del B["sources"]
if "inside" in B.keys():
if B["inside"] == True:
isInside = True
del B["inside"]
if isInside:
return matches(A, B)
else:
return all(A[k] in B[k] for k in set(A) & set(B)) and set(B) <= set(A)
def event(numName, c): # yes I'm using a short variable because otherwise it goes off the screen
if not "channel" in c.keys():
c["channel"] = None
if dedup(numName, c):
return
regproc.registerTest(c)
# metadata scraping
# need to check if this was received from a relay
# in which case, do not do this
if c["type"] in ["msg", "notice", "action", "topic", "mode"]:
userinfo.editUser(c["net"], c["muser"])
elif c["type"] == "nick":
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"])
elif c["type"] == "quit":
userinfo.delUserByNetwork(c["net"], c["nick"], c["muser"])
elif c["type"] == "join":
userinfo.addUser(c["net"], c["channel"], c["nick"], c["muser"])
elif c["type"] == "part":
userinfo.delUser(c["net"], c["channel"], c["nick"], c["muser"])
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"])
if "muser" in c.keys():
del c["muser"]
sendRelayNotification({k: c[k] for k in order if k in c}) # Sort dict keys according to order
# only monitors below
monitorGroups = testNetTarget(c["net"], c["channel"])
if monitorGroups == False:
return
for monitorGroup in monitorGroups:
matcher = magicFunction(deepcopy(c), deepcopy(main.monitor[monitorGroup]))
if matcher == True:
c["monitor"] = True
if "send" in main.monitor[monitorGroup].keys():
for i in main.monitor[monitorGroup]["send"].keys():
if isinstance(main.monitor[monitorGroup]["send"][i], bool):
sendRelayNotification({"type": "err", "net": net, "channel": channel, "message": c, "reason": "errdeliv"})
continue
if not i in main.pool.keys():
sendRelayNotification({"type": "err", "net": net, "channel": channel, "message": c, "reason": "noname"})
if not i in main.IRCPool.keys():
sendRelayNotification({"type": "err", "net": net, "channel": channel, "message": c, "reason": "noinstance"})
for x in main.monitor[monitorGroup]["send"][i]:
main.IRCPool[i].msg(x, "monitor [%s] (%s) %s" % (monitorGroup, c["net"], c))