Implement Ctrl-C handling and fix a large number of small bugs

This commit is contained in:
Mark Veidemanis 2019-09-28 19:46:10 +01:00
parent 006f8db6f6
commit 15ca45e5df
12 changed files with 88 additions and 61 deletions

View File

@ -14,11 +14,11 @@ class AutoCommand:
if not spl[2].isdigit():
failure("Must be integer, not %s" % spl[2])
return
id, alias = main.network[spl[1]].add_relay(int(spl[2]))
relayNum = int(spl[2])
id, alias = main.network[spl[1]].add_relay(relayNum)
success("Successfully created relay %s on network %s with alias %s" % (str(id), spl[1], alias))
main.saveConf("network")
rtrn = provision.provisionRelay(int(spl[2]), spl[1])
rtrn = provision.provisionRelay(relayNum, spl[1])
success("Started provisioning network %s on relay %s for alias %s" % (spl[1], spl[2], rtrn))
return

View File

@ -10,19 +10,23 @@ class DelCommand:
if not spl[1] in main.network.keys():
failure("No such network: %s" % spl[1])
return
if not spl[2].isdigit():
failure("Must be integer, not %s" % spl[2])
return
if not int(spl[2]) in main.network[spl[1]].relays.keys():
failure("No such relay: %s in network %s" % (spl[2], spl[1]))
return
main.network[spl[1]].delete_relay(int(spl[2]))
if spl[1]+spl[2] in main.ReactorPool.keys():
if spl[1]+spl[2] in main.FactoryPool.keys():
main.FactoryPool[spl[1]+spl[2]].stopTrying()
main.ReactorPool[spl[1]+spl[2]].disconnect()
if spl[1]+spl[2] in main.IRCPool.keys():
del main.IRCPool[spl[1]+spl[2]]
del main.ReactorPool[spl[1]+spl[2]]
del main.FactoryPool[spl[1]+spl[2]]
name = spl[1]+spl[2]
if name in main.ReactorPool.keys():
if name in main.FactoryPool.keys():
main.FactoryPool[name].stopTrying()
main.ReactorPool[name].disconnect()
if name in main.IRCPool.keys():
del main.IRCPool[name]
del main.ReactorPool[name]
del main.FactoryPool[name]
success("Successfully removed bot: %s" % spl[1])
main.saveConf("network")
return

View File

@ -11,25 +11,31 @@ class DisableCommand:
if not spl[1] in main.network.keys():
failure("No such network: %s" % spl[1])
return
if not int(spl[2]) in main.network[spl[1]].relays.keys():
if not spl[2].isdigit():
failure("Must be integer, not %s" % spl[2])
return
relayNum = int(spl[2])
name = spl[1]+spl[2]
if not spl[1] in main.IRCPool.keys():
info("Note - instance not running, proceeding anyway")
if not relayNum in main.network[spl[1]].relays.keys():
failure("No such relay: %s in network %s" % (spl[2], spl[1]))
return
main.network[spl[1]].relays[int(spl[2])]["enabled"] = False
user = main.network[spl[1]].aliases[int(spl[2])]
main.network[spl[1]].relays[relayNum]["enabled"] = False
user = main.network[spl[1]].aliases[relayNum]["nick"]
network = spl[1]
relay = main.network[spl[1]].relays[int(spl[2])]
relay = main.network[spl[1]].relays[relayNum]
commands = {"status": ["Disconnect"]}
deliverRelayCommands(relay, commands, user=user+"/"+network)
deliverRelayCommands(relayNum, commands, user=user+"/"+network)
main.saveConf("network")
if spl[1]+spl[2] in main.ReactorPool.keys():
if spl[1]+spl[2] in main.FactoryPool.keys():
main.FactoryPool[spl[1]+spl[2]].stopTrying()
main.ReactorPool[spl[1]+spl[2]].disconnect()
if name in main.ReactorPool.keys():
if name in main.FactoryPool.keys():
main.FactoryPool[name].stopTrying()
main.ReactorPool[name].disconnect()
if spl[1] in main.IRCPool.keys():
del main.IRCPool[spl[1]+spl[2]]
del main.ReactorPool[spl[1]+spl[2]]
del main.FactoryPool[spl[1]+spl[2]]
del main.IRCPool[name]
del main.ReactorPool[name]
del main.FactoryPool[name]
success("Successfully disabled bot %s on network %s" % (spl[2], spl[1]))
return
else:

View File

@ -17,7 +17,7 @@ class StatsCommand:
numChannels += len(main.IRCPool[i].channels)
numWhoEntries += userinfo.getNumTotalWhoEntries()
stats.append("Registered servers:")
stats.append(" Total: %s" % len(main.network.keys()))
stats.append(" Unique: %s" % len(main.network.keys()))
stats.append("Online servers:")
stats.append(" Total: %s" % len(main.IRCPool.keys()))
stats.append(" Unique: %s" % len(main.liveNets()))

View File

@ -11,18 +11,21 @@ class SwhoCommand:
failure("Network does not exist: %s" % spl[1])
return
for i in main.IRCPool.keys():
if spl[1] in i:
if spl[1] == main.IRCPool[i].net:
for x in main.IRCPool[i].channels:
main.IRCPool[i].who(x)
success("Sent WHO to all channels on all networks on %s" % spl[1])
success("Sent WHO to all channels on all networks for %s" % spl[1])
return
elif length == 3:
if not spl[1] in main.network.keys():
failure("Network does not exist: %s" % spl[1])
return
matches = []
# This loop gets all networks where the core network matches spl[1]
# where there is also a currently joined channel matching spl[2]
for i in main.IRCPool.keys():
if spl[1] in i:
if spl[1] == main.IRCPool[i].net:
for x in main.IRCPool[i].channels:
if x == spl[2]:
main.IRCPool[i].who(x)

View File

@ -1,7 +1,7 @@
{
"pass": "pass <password>",
"logout": "logout",
"del": "del <name>",
"del": "del <name> <num>",
"mod": "mod <name> [<key>] [<value>]",
"who": "who <query>",
"join": "join <name> <num> <channel> [<key>]",
@ -24,5 +24,6 @@
"cmd": "cmd <relay> <user> <entity> <text ...>",
"token": "token <add|del|list> [<key>] [<relay>]",
"all": "all <entity> <text ...>",
"allc": "allc <network|alias> <(network)|(alias)> <entity> <text ...>"
"allc": "allc <network|alias> <(network)|(alias)> <entity> <text ...>",
"swho": "swho <network> [<channel>]"
}

View File

@ -72,7 +72,6 @@ class IRCRelay(IRCClient):
sendAll("[%s] %s -> %s" % (self.num, nick, msg))
def irc_ERR_PASSWDMISMATCH(self, prefix, params):
print(', '.join("%s: %s" % item for item in vars(self).items()))
log("%s: relay password mismatch" % self.num)
sendAll("%s: relay password mismatch" % self.num)
@ -113,7 +112,7 @@ class IRCBot(IRCClient):
self.versionEnv = None
self.sourceURL = None
self._who = {}
self._tempWho = {}
self._getWho = {}
self._names = {}
@ -227,14 +226,17 @@ class IRCBot(IRCClient):
log("%s: password mismatch" % self.name)
sendAll("%s: password mismatch" % self.name)
def who(self, channel):
def _who(self, channel):
d = Deferred()
if channel not in self._who:
self._who[channel] = ([], [])
self._who[channel][0].append(d)
if channel not in self._tempWho:
self._tempWho[channel] = ([], [])
self._tempWho[channel][0].append(d)
self.sendLine("WHO %s" % channel)
return d
def who(self, channel):
self._who(channel).addCallback(self.got_who)
def irc_RPL_WHOREPLY(self, prefix, params):
channel = params[1]
ident = params[2]
@ -243,20 +245,20 @@ class IRCBot(IRCClient):
nick = params[5]
status = params[6]
realname = params[7]
if channel not in self._who:
if channel not in self._tempWho:
return
n = self._who[channel][1]
n = self._tempWho[channel][1]
n.append([nick, nick, host, server, status, realname])
self.event(type="who", nick=nick, ident=ident, host=host, realname=realname, target=channel, server=server, status=status)
def irc_RPL_ENDOFWHO(self, prefix, params):
channel = params[1]
if channel not in self._who:
if channel not in self._tempWho:
return
callbacks, info = self._who[channel]
callbacks, info = self._tempWho[channel]
for cb in callbacks:
cb.callback((channel, info))
del self._who[channel]
del self._tempWho[channel]
def got_who(self, whoinfo):
userinfo.initialUsers(self.net, whoinfo[0], whoinfo[1])
@ -382,7 +384,8 @@ class IRCBot(IRCClient):
self.channels.append(channel)
self.names(channel).addCallback(self.got_names)
if main.config["Toggles"]["Who"]:
self.who(channel).addCallback(self.got_who)
#self.who(channel).addCallback(self.got_who)
#self.who(channel)
lc = LoopingCall(self.who, channel)
self._getWho[channel] = lc
intrange = main.config["Tweaks"]["Delays"]["WhoRange"]
@ -466,7 +469,7 @@ class IRCBotFactory(ReconnectingClientFactory):
self.relayCommands, self.user, self.stage2 = relayCommands, user, stage2
def buildProtocol(self, addr):
if self.net == None:
if self.relay == None:
entry = IRCRelay(self.num, self.relayCommands, self.user, self.stage2)
else:
entry = IRCBot(self.net, self.num)

View File

@ -39,14 +39,6 @@ lastMinuteSample = 0
hashKey = urandom(16)
lastEvents = {}
def nets():
if not "pool" in globals():
return
networks = set()
for i in pool.keys():
networks.add("".join([x for x in i if not x in digits]))
return networks
def liveNets():
networks = set()
for i in IRCPool.keys():

View File

@ -13,7 +13,7 @@ def getWhoSingle(name, query):
def getWho(query):
result = {}
for i in main.nets():
for i in main.network.keys():
f = getWhoSingle(i, query)
if f:
result[i] = f
@ -35,7 +35,7 @@ def getChanList(name, nick):
def getChans(nick):
result = {}
for i in main.nets():
for i in main.network.keys():
f = getChansSingle(i, nick)
if f:
result[i] = f
@ -50,7 +50,7 @@ def getUsersSingle(name, nick):
def getUsers(nick):
result = {}
for i in main.nets():
for i in main.network.keys():
f = getUsersSingle(i, nick)
if f:
result[i] = f
@ -61,7 +61,7 @@ def getNumWhoEntries(name):
def getNumTotalWhoEntries():
total = 0
for i in main.nets():
for i in main.network.keys():
total += getNumWhoEntries(i)
return total

View File

@ -1,18 +1,21 @@
#!/usr/bin/env python
from twisted.internet import reactor
from twisted.internet.ssl import DefaultOpenSSLContextFactory
from sys import argv, stdout, stderr
import sys
from signal import signal, SIGINT
#from twisted.python import log
#from sys import stdout
#log.startLogging(stdout)
from sys import stdout, stderr # Import again because we want to override
from codecs import getwriter # fix printing odd shit to the terminal
stdout = getwriter("utf8")(stdout) # this is a generic fix but we all know
stderr = getwriter("utf8")(stderr) # it's just for the retards on Rizon using
# unicode quit messages for no reason
import main
main.initMain()
if "--debug" in argv: # yes really
from utils.cleanup import handler
signal(SIGINT, handler) # Handle Ctrl-C and run the cleanup routine
if "--debug" in sys.argv: # yes really
main.config["Debug"] = True
from utils.logging.log import *
from utils.loaders.command_loader import loadCommands

15
utils/cleanup.py Normal file
View File

@ -0,0 +1,15 @@
import main
from twisted.internet import reactor
from utils.logging.debug import debug
from utils.logging.log import *
import sys
def handler(sig, frame):
log("Received SIGINT, cleaning up")
cleanup()
def cleanup():
debug("Flushing Redis database")
main.r.flushdb()
reactor.stop()
#sys.exit(1)

View File

@ -1,6 +1,6 @@
from os import listdir
from importlib import reload
from sys import modules
import sys
from utils.logging.debug import debug
from utils.logging.log import *
@ -13,8 +13,8 @@ def loadSingle(commandName):
className = commandName.capitalize()+"Command"
try:
if commandName in CommandMap.keys():
reload(modules["commands."+commandName])
CommandMap[commandName] = getattr(modules["commands."+commandName], className)
reload(sys.modules["commands."+commandName])
CommandMap[commandName] = getattr(sys.modules["commands."+commandName], className)
debug("Reloaded command: %s" % commandName)
return "RELOAD"
module = __import__('commands.%s' % commandName)