pngbot.py:IrcBot.readline(): add optional timeout parameter.

pngbot.py:IrcMiRCARTBot.clientChannelRejoin{,TimerNext}: added to support delayed rejoin-on-kick logic.
pngbot.py:IrcMiRCARTBot.dispatchJoin(): reset clientChannelRejoin{,TimerNext} on successful (re)join to clientChannel.
pngbot.py:IrcMiRCARTBot.dispatchKick(): set clientChannelRejoin{,TimerNext} on kick from clientChannel to time.time() + 15 (seconds.)
pngbot.py:IrcMiRCARTBot.dispatchTimer(): (re)join clientChannel and set clientChannelRejoin{,TimerNext} to time.time() + 15 (seconds.)
pngbot.py:IrcMiRCARTBot.dispatch(): call readline() w/ timeout delta given clientChannelRejoinTimerNext.
This commit is contained in:
Lucio Andrés Illanes Albornoz 2018-01-03 00:40:37 +01:00
parent 936bfb6c86
commit a0db56a530

View File

@ -50,9 +50,14 @@ class IrcBot:
self.clientSocket.close() self.clientSocket.close()
self.clientSocket = self.clientSocketFile = None; self.clientSocket = self.clientSocketFile = None;
# }}} # }}}
# {{{ readline(): Read and parse single line from server into canonicalised list # {{{ readline(): Read and parse single line from server into canonicalised list w/ optional timeout
def readline(self): def readline(self, timeout=0):
if timeout:
self.clientSocket.settimeout(timeout)
try:
msg = self.clientSocketFile.readline() msg = self.clientSocketFile.readline()
except TimeoutException:
return "TIMEOUT"
if len(msg): if len(msg):
msg = msg.rstrip("\r\n") msg = msg.rstrip("\r\n")
else: else:
@ -87,6 +92,7 @@ class IrcBot:
class IrcMiRCARTBot(IrcBot): class IrcMiRCARTBot(IrcBot):
"""IRC<->MiRCART bot""" """IRC<->MiRCART bot"""
clientChannelLastMessage = clientChannelOps = clientChannel = None clientChannelLastMessage = clientChannelOps = clientChannel = None
clientChannelRejoinTimerNext = clientChannelRejoin = None
# {{{ connect(): Connect to server and (re)initialise # {{{ connect(): Connect to server and (re)initialise
def connect(self): def connect(self):
@ -95,6 +101,7 @@ class IrcMiRCARTBot(IrcBot):
print("Connected to {}:{}.".format(self.serverHname, self.serverPort)) print("Connected to {}:{}.".format(self.serverHname, self.serverPort))
print("Registering on {}:{} as {}, {}, {}...".format(self.serverHname, self.serverPort, self.clientNick, self.clientIdent, self.clientGecos)) print("Registering on {}:{} as {}, {}, {}...".format(self.serverHname, self.serverPort, self.clientNick, self.clientIdent, self.clientGecos))
self.clientLastMessage = 0; self.clientChannelOps = []; self.clientLastMessage = 0; self.clientChannelOps = [];
clientChannelRejoinTimerNext = 0; self.clientChannelRejoin = False;
# }}} # }}}
# {{{ dispatchNone(): Dispatch None message from server # {{{ dispatchNone(): Dispatch None message from server
def dispatchNone(self): def dispatchNone(self):
@ -104,7 +111,7 @@ class IrcMiRCARTBot(IrcBot):
# {{{ dispatch001(): Dispatch single 001 (RPL_WELCOME) # {{{ dispatch001(): Dispatch single 001 (RPL_WELCOME)
def dispatch001(self, message): def dispatch001(self, message):
print("Registered on {}:{} as {}, {}, {}.".format(self.serverHname, self.serverPort, self.clientNick, self.clientIdent, self.clientGecos)) print("Registered on {}:{} as {}, {}, {}.".format(self.serverHname, self.serverPort, self.clientNick, self.clientIdent, self.clientGecos))
print("Joining {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort)) print("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort))
self.sendline("JOIN", self.clientChannel) self.sendline("JOIN", self.clientChannel)
# }}} # }}}
# {{{ dispatch353(): Dispatch single 353 (RPL_NAMREPLY) # {{{ dispatch353(): Dispatch single 353 (RPL_NAMREPLY)
@ -116,12 +123,17 @@ class IrcMiRCARTBot(IrcBot):
self.clientChannelOps.append(channelNickSpec[1:].lower()) self.clientChannelOps.append(channelNickSpec[1:].lower())
print("Authorising {} on {}".format(channelNickSpec[1:].lower(), message[4].lower())) print("Authorising {} on {}".format(channelNickSpec[1:].lower(), message[4].lower()))
# }}} # }}}
# {{{ dispatchJoin(): Dispatch single JOIN message from server
def dispatchJoin(self, message):
print("Joined {} on {}:{}.".format(message[2].lower(), self.serverHname, self.serverPort))
self.clientChannelRejoinTimerNext = 0; self.clientChannelRejoin = False;
# }}}
# {{{ dispatchKick(): Dispatch single KICK message from server # {{{ dispatchKick(): Dispatch single KICK message from server
def dispatchKick(self, message): def dispatchKick(self, message):
if message[2].lower() == self.clientChannel.lower() \ if message[2].lower() == self.clientChannel.lower() \
and message[3].lower() == self.clientNick.lower(): and message[3].lower() == self.clientNick.lower():
print("Kicked from {} by {}, rejoining".format(message[2].lower(), message[0])) print("Kicked from {} by {}, rejoining in 15 seconds".format(message[2].lower(), message[0]))
self.sendline("JOIN", message[2]) self.clientChannelRejoinTimerNext = time.time() + 15; self.clientChannelRejoin = True;
# }}} # }}}
# {{{ dispatchMode(): Dispatch single MODE message from server # {{{ dispatchMode(): Dispatch single MODE message from server
def dispatchMode(self, message): def dispatchMode(self, message):
@ -188,16 +200,32 @@ class IrcMiRCARTBot(IrcBot):
if os.path.isfile(imgTmpFilePath): if os.path.isfile(imgTmpFilePath):
os.remove(imgTmpFilePath) os.remove(imgTmpFilePath)
# }}} # }}}
# {{{ dispatchTimer(): Dispatch single client timer expiration
def dispatchTimer(self):
if self.clientChannelRejoin:
print("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort))
self.sendline("JOIN", self.clientChannel)
self.clientChannelRejoinTimerNext = time.time() + 15; self.clientChannelRejoin = True;
# }}}
# {{{ dispatch(): Read, parse, and dispatch single line from server # {{{ dispatch(): Read, parse, and dispatch single line from server
def dispatch(self): def dispatch(self):
while True: while True:
serverMessage = self.readline() clientTimerNextDelta = 0
if self.clientChannelRejoinTimerNext:
timeNow = time.time()
if self.clientChannelRejoinTimerNext > timeNow:
clientTimerNextDelta = self.clientChannelRejoinTimerNext - timeNow
serverMessage = self.readline(clientTimerNextDelta)
if serverMessage == None: if serverMessage == None:
self.dispatchNone(); break; self.dispatchNone(); break;
elif serverMessage == "TIMEOUT":
self.dispatchTimer()
elif serverMessage[1] == "001": elif serverMessage[1] == "001":
self.dispatch001(serverMessage) self.dispatch001(serverMessage)
elif serverMessage[1] == "353": elif serverMessage[1] == "353":
self.dispatch353(serverMessage) self.dispatch353(serverMessage)
elif serverMessage[1] == "JOIN":
self.dispatchJoin(serverMessage)
elif serverMessage[1] == "KICK": elif serverMessage[1] == "KICK":
self.dispatchKick(serverMessage) self.dispatchKick(serverMessage)
elif serverMessage[1] == "MODE": elif serverMessage[1] == "MODE":