Move things into factories and implement reconnecting

pull/1/head
Mark Veidemanis 7 years ago
parent cd8c61cdc6
commit 88426be62a

@ -21,6 +21,10 @@
"protocol": null,
"bind": null,
"timeout": 30,
"maxdelay": 5,
"initialdelay": 1,
"factor": 2,
"jitter": 5,
"nickname": null,
"username": null,
"realname": null,
@ -33,8 +37,7 @@
"password": null,
"authentity": "NickServ",
"key": "key.pem",
"certificate": "cert.pem",
"enabled": true
"certificate": "cert.pem"
},
"Master": [null, null]
}

@ -2,8 +2,7 @@
from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.internet.ssl import DefaultOpenSSLContextFactory
from twisted.internet.protocol import Protocol, Factory
from twisted.internet.endpoints import SSL4ClientEndpoint, TCP4ClientEndpoint, connectProtocol
from twisted.internet.protocol import Protocol, Factory, ClientFactory, ReconnectingClientFactory
from twisted.words.protocols.irc import IRCClient
#from twisted.python import log
@ -19,6 +18,8 @@ numbers = "0123456789"
listener = None
connections = {}
IRCPool = {}
ReactorPool = {}
FactoryPool = {}
MonitorPool = []
@ -246,19 +247,39 @@ class IRCBot(IRCClient):
nick, ident, host = self.parsen(user)
helper.setWhoSingle(self.name, nick, ident, host)
def connectionLost(self, reason):
self.connected = False
self.channels = []
class IRCBotFactory(ReconnectingClientFactory):
def __init__(self, name):
self.instance = pool[name]
self.name = name
self.maxDelay = self.instance["maxdelay"]
self.initialDelay = self.instance["initialdelay"]
self.factor = self.instance["factor"]
self.jitter = self.instance["jitter"]
def buildProtocol(self, addr):
global IRCPool
entry = IRCBot(self.name)
IRCPool[self.name] = entry
self.client = entry
return entry
def clientConnectionLost(self, connector, reason):
self.client.connected = False
self.client.channels = []
error = reason.getErrorMessage()
log("%s: connection lost: %s" % (self.name, error))
helper.sendAll("%s: connection lost: %s" % (self.name, error))
self.retry(connector)
#ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
def connectionFailed(self, reason):
self.connected = False
self.channels = []
def clientConnectionFailed(self, connector, reason):
self.client.connected = False
self.client.channels = []
error = reason.getErrorMessage()
log("%s: connection failed: %s" % (self.name, error))
helper.sendAll("%s: connection failed: %s" % (self.name, error))
self.retry(connector)
#ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
class Base(Protocol):
def __init__(self, addr):
@ -431,32 +452,37 @@ class Helper(object):
log("Started bot %s to %s:%s protocol %s nickname %s" % (name, instance["host"], instance["port"], instance["protocol"], instance["nickname"]))
if instance["protocol"] == "plain":
if instance["bind"] == None:
point = TCP4ClientEndpoint(reactor, instance["host"], int(instance["port"]), timeout=int(instance["timeout"]))
bot = IRCBot(name)
IRCPool[name] = bot
d = connectProtocol(point, bot)
bot = IRCBotFactory(name)
rct = reactor.connectTCP(instance["host"], instance["port"], bot, timeout=int(instance["timeout"]))
ReactorPool[name] = rct
FactoryPool[name] = bot
return
else:
point = TCP4ClientEndpoint(reactor, instance["host"], int(instance["port"]), timeout=int(instance["timeout"]), bindAddress=instance["bind"])
bot = IRCBot(name)
IRCPool[name] = bot
d = connectProtocol(point, bot)
bot = IRCBotFactory(name)
rct = reactor.connectTCP(instance["host"], instance["port"], bot, timeout=int(instance["timeout"]), bindAddress=instance["bind"])
ReactorPool[name] = rct
FactoryPool[name] = bot
return
elif instance["protocol"] == "ssl":
keyFN = certPath+instance["key"]
certFN = certPath+instance["certificate"]
contextFactory = DefaultOpenSSLContextFactory(keyFN.encode("utf-8", "replace"), certFN.encode("utf-8", "replace"))
if instance["bind"] == None:
point = SSL4ClientEndpoint(reactor, instance["host"], int(instance["port"]), contextFactory, timeout=int(instance["timeout"]))
bot = IRCBot(name)
IRCPool[name] = bot
d = connectProtocol(point, bot)
bot = IRCBotFactory(name)
rct = reactor.connectSSL(instance["host"], int(instance["port"]), bot, contextFactory)
ReactorPool[name] = rct
FactoryPool[name] = bot
return
else:
point = SSL4ClientEndpoint(reactor, instance["host"], int(instance["port"]), contextFactory, timeout=int(instance["timeout"]), bindAddress=instance["bind"])
bot = IRCBot(name)
IRCPool[name] = bot
d = connectProtocol(point, bot)
bot = IRCBotFactory(name)
rct = reactor.connectSSL(instance["host"], int(instance["port"]), bot, contextFactory, bindAddress=instance["bind"])
ReactorPool[name] = rct
FactoryPool[name] = bot
return
def addKeyword(self, keyword):
@ -637,10 +663,13 @@ class Helper(object):
return
pool[spl[1]]["enabled"] = False
self.save("pool")
if spl[1] in IRCPool.keys():
if IRCPool[spl[1]].connected == True:
IRCPool[spl[1]].transport.loseConnection()
del IRCPool[spl[1]]
if spl[1] in ReactorPool.keys():
if spl[1] in FactoryPool.keys():
FactoryPool[spl[1]].stopTrying()
ReactorPool[spl[1]].disconnect()
del IRCPool[spl[1]]
del ReactorPool[spl[1]]
del FactoryPool[spl[1]]
success("Successfully disabled bot %s" % spl[1])
return
else:
@ -995,9 +1024,9 @@ class Helper(object):
spl[2] = None
toUnset = True
if spl[1] in ["port", "timeout"]:
if spl[1] in ["port", "timeout", "maxdelay", "initialdelay", "factor", "jitter"]:
try:
int(spl[2])
spl[2] = int(spl[2])
except:
failure("Value must be an integer, not %s" % spl[2])
return
@ -1066,12 +1095,7 @@ class Helper(object):
if not spl[2] in pool[spl[1]].keys():
failure("No such key: %s" % spl[2])
return
if spl[2] in ["port", "timeout"]:
try:
int(spl[3])
except:
failure("Value must be an integer, not %s" % spl[3])
return
if spl[2] == "protocol":
if not spl[3] in ["ssl", "plain"]:
failure("Protocol must be ssl or plain, not %s" % spl[3])
@ -1084,6 +1108,13 @@ class Helper(object):
spl[3] = None
toUnset = True
if spl[2] in ["port", "timeout", "maxdelay", "initialdelay", "factor", "jitter"]:
try:
spl[3] = int(spl[3])
except:
failure("Value must be an integer, not %s" % spl[3])
return
if spl[2] == "authtype":
if not toUnset:
if not spl[3] in ["sp", "ns"]:

Loading…
Cancel
Save