IrcClient.py:IrcClient.{queue,unqueue}(): split.

IrcMiRCARTBot.py:IrcMiRCARTBot._dispatch{001,Ping,Privmsg,Timer}(): replace readline() calls w/ queue() calls.
IrcMiRCARTBot.py:IrcMiRCARTBot.dispatch(): call unqueue() after processing timers and prior to calling readline().
This commit is contained in:
Lucio Andrés Illanes Albornoz 2018-01-03 04:15:43 +01:00
parent 523d91ff89
commit 6fcf0e0a4f
2 changed files with 30 additions and 15 deletions

View File

@ -30,7 +30,7 @@ class IrcClient:
serverHname = serverPort = None; serverHname = serverPort = None;
clientNick = clientIdent = clientGecos = None; clientNick = clientIdent = clientGecos = None;
clientSocket = clientSocketFile = None; clientSocket = clientSocketFile = None;
clientNextTimeout = None clientNextTimeout = None; clientQueue = None;
# {{{ close(): Close connection to server # {{{ close(): Close connection to server
def close(self): def close(self):
@ -53,8 +53,9 @@ class IrcClient:
else: else:
select.select([], [self.clientSocket.fileno()], []) select.select([], [self.clientSocket.fileno()], [])
self.clientSocketFile = self.clientSocket.makefile() self.clientSocketFile = self.clientSocket.makefile()
self.sendline("NICK", self.clientNick) self.clientQueue = []
self.sendline("USER", self.clientIdent, "0", "0", self.clientGecos) self.queue("NICK", self.clientNick)
self.queue("USER", self.clientIdent, "0", "0", self.clientGecos)
return True return True
# }}} # }}}
# {{{ readline(): Read and parse single line from server into canonicalised list, honouring timers # {{{ readline(): Read and parse single line from server into canonicalised list, honouring timers
@ -86,20 +87,33 @@ class IrcClient:
msg = [""] + msg[0:] msg = [""] + msg[0:]
return msg return msg
# }}} # }}}
# {{{ sendline(): Parse and send single line to server from list, ignoring timers # {{{ queue(): Parse and queue single line to server from list
def sendline(self, *args): def queue(self, *args):
msg = ""; argNumMax = len(args); msg = ""; argNumMax = len(args);
for argNum in range(0, argNumMax): for argNum in range(0, argNumMax):
if argNum == (argNumMax - 1): if argNum == (argNumMax - 1):
msg += ":" + args[argNum] msg += ":" + args[argNum]
else: else:
msg += args[argNum] + " " msg += args[argNum] + " "
self.clientQueue.append(msg)
# }}}
# {{{ unqueue(): Send all queued lines to server, honouring timers
def unqueue(self):
while self.clientQueue:
msg = self.clientQueue[0]
msg = (msg + "\r\n").encode(); msgLen = len(msg); msgBytesSent = 0; msg = (msg + "\r\n").encode(); msgLen = len(msg); msgBytesSent = 0;
while msgBytesSent < msgLen: while msgBytesSent < msgLen:
if self.clientNextTimeout:
timeNow = time.time()
if self.clientNextTimeout <= timeNow:
self.clientQueue[0] = msg; return;
else:
readySet = select.select([], [self.clientSocket.fileno()], [], self.clientNextTimeout - timeNow)
else:
readySet = select.select([], [self.clientSocket.fileno()], []) readySet = select.select([], [self.clientSocket.fileno()], [])
msgBytesSent = self.clientSocket.send(msg) msgBytesSent = self.clientSocket.send(msg)
msg = msg[msgBytesSent:]; msgLen -= msgBytesSent; msg = msg[msgBytesSent:]; msgLen -= msgBytesSent;
# }}} del self.clientQueue[0]
# #
# Initialisation method # Initialisation method

View File

@ -37,7 +37,7 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
def _dispatch001(self, message): def _dispatch001(self, message):
self._log("Registered on {}:{} as {}, {}, {}.".format(self.serverHname, self.serverPort, self.clientNick, self.clientIdent, self.clientGecos)) self._log("Registered on {}:{} as {}, {}, {}.".format(self.serverHname, self.serverPort, self.clientNick, self.clientIdent, self.clientGecos))
self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort)) self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort))
self.sendline("JOIN", self.clientChannel) self.queue("JOIN", self.clientChannel)
# }}} # }}}
# {{{ _dispatch353(): Dispatch single 353 (RPL_NAMREPLY) # {{{ _dispatch353(): Dispatch single 353 (RPL_NAMREPLY)
def _dispatch353(self, message): def _dispatch353(self, message):
@ -96,7 +96,7 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
# }}} # }}}
# {{{ _dispatchPing(): Dispatch single PING message from server # {{{ _dispatchPing(): Dispatch single PING message from server
def _dispatchPing(self, message): def _dispatchPing(self, message):
self.sendline("PONG", message[2]) self.queue("PONG", message[2])
# }}} # }}}
# {{{ _dispatchPrivmsg(): Dispatch single PRIVMSG message from server # {{{ _dispatchPrivmsg(): Dispatch single PRIVMSG message from server
def _dispatchPrivmsg(self, message): def _dispatchPrivmsg(self, message):
@ -122,10 +122,10 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
imgurResponse = self._uploadToImgur(imgTmpFilePath, "MiRCART image", "MiRCART image", "c9a6efb3d7932fd") imgurResponse = self._uploadToImgur(imgTmpFilePath, "MiRCART image", "MiRCART image", "c9a6efb3d7932fd")
if imgurResponse[0] == 200: if imgurResponse[0] == 200:
self._log("Uploaded as: {}".format(imgurResponse[1])) self._log("Uploaded as: {}".format(imgurResponse[1]))
self.sendline("PRIVMSG", message[2], "8/!\\ Uploaded as: {}".format(imgurResponse[1])) self.queue("PRIVMSG", message[2], "8/!\\ Uploaded as: {}".format(imgurResponse[1]))
else: else:
self._log("Upload failed with HTTP status code {}".format(imgurResponse[0])) self._log("Upload failed with HTTP status code {}".format(imgurResponse[0]))
self.sendline("PRIVMSG", message[2], "4/!\\ Uploaded failed with HTTP status code {}!".format(imgurResponse[0])) self.queue("PRIVMSG", message[2], "4/!\\ Uploaded failed with HTTP status code {}!".format(imgurResponse[0]))
if os.path.isfile(asciiTmpFilePath): if os.path.isfile(asciiTmpFilePath):
os.remove(asciiTmpFilePath) os.remove(asciiTmpFilePath)
if os.path.isfile(imgTmpFilePath): if os.path.isfile(imgTmpFilePath):
@ -135,7 +135,7 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
def _dispatchTimer(self): def _dispatchTimer(self):
if self.clientChannelRejoin: if self.clientChannelRejoin:
self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort)) self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort))
self.sendline("JOIN", self.clientChannel) self.queue("JOIN", self.clientChannel)
self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True; self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True;
# }}} # }}}
# {{{ _log(): Log single message to stdout w/ timestamp # {{{ _log(): Log single message to stdout w/ timestamp
@ -179,6 +179,7 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
timeNow = time.time() timeNow = time.time()
if self.clientNextTimeout <= timeNow: if self.clientNextTimeout <= timeNow:
self._dispatchTimer() self._dispatchTimer()
self.unqueue()
serverMessage = self.readline() serverMessage = self.readline()
if serverMessage == None: if serverMessage == None:
self._dispatchNone(); break; self._dispatchNone(); break;