Stash dead repository MiRCARTools.

This commit is contained in:
Lucio Andrés Illanes Albornoz 2018-10-25 03:06:28 +02:00
parent 54522ac329
commit 08e5856db9
2 changed files with 57 additions and 28 deletions

View File

@ -38,12 +38,15 @@ class IrcClient:
self.clientSocket.close()
self.clientSocket = self.clientSocketFile = None;
# }}}
# {{{ connect(self, preferFamily=socket.AF_INET, timeout=None): Connect to server and register w/ optional timeout
def connect(self, preferFamily=socket.AF_INET, timeout=None):
# {{{ connect(self, localAddr=None, preferFamily=socket.AF_INET, timeout=None): Connect to server and register w/ optional timeout
def connect(self, localAddr=None, preferFamily=socket.AF_INET, timeout=None):
gaiInfo = socket.getaddrinfo(self.serverHname, self.serverPort,
preferFamily, socket.SOCK_STREAM, socket.IPPROTO_TCP)
self.clientSocket = socket.socket(*gaiInfo[0][:3])
self.clientSocket.setblocking(0)
if localAddr != None:
gaiInfo_ = socket.getaddrinfo(localAddr, None, preferFamily, socket.SOCK_STREAM, socket.IPPROTO_TCP)
self.clientSocket.bind(gaiInfo_[0][4])
try:
self.clientSocket.connect(gaiInfo[0][4])
except BlockingIOError:
@ -60,16 +63,21 @@ class IrcClient:
self.queue("USER", self.clientIdent, "0", "0", self.clientGecos)
return True
# }}}
# {{{ readline(self): Read and parse single line from server into canonicalised list, honouring timers
def readline(self):
# {{{ readline(self, timeout=30): Read and parse single line from server into canonicalised list, honouring timers
def readline(self, timeout=30):
if self.clientNextTimeout:
timeNow = time.time()
if self.clientNextTimeout <= timeNow:
return ""
else:
readySet = select.select([self.clientSocket.fileno()], [], [], self.clientNextTimeout - timeNow)
if len(readySet[0]) == 0 \
and (time.time() - timeNow) >= timeout:
return ""
else:
readySet = select.select([self.clientSocket.fileno()], [], [])
readySet = select.select([self.clientSocket.fileno()], [], [], timeout)
if len(readySet[0]) == 0:
return ""
msg = self.clientSocketFile.readline()
if len(msg):
msg = msg.rstrip("\r\n")
@ -99,24 +107,31 @@ class IrcClient:
msg += args[argNum] + " "
self.clientQueue.append((msg + "\r\n").encode())
# }}}
# {{{ unqueue(self): Send all queued lines to server, honouring timers
def unqueue(self):
# {{{ unqueue(self, timeout=15): Send all queued lines to server, honouring timers
def unqueue(self, timeout=15):
while self.clientQueue:
msg = self.clientQueue[0]; msgLen = len(msg); msgBytesSent = 0;
while msgBytesSent < msgLen:
if self.clientNextTimeout:
timeNow = time.time()
if self.clientNextTimeout <= timeNow:
self.clientQueue[0] = msg; return;
self.clientQueue[0] = msg; return True;
else:
readySet = select.select([], [self.clientSocket.fileno()], [], self.clientNextTimeout - timeNow)
readySet = select.select([], [self.clientSocket.fileno()], [], min(self.clientNextTimeout - timeNow, timeout))
if len(readySet[1]) == 0:
self.clientQueue[0] = msg; return;
timeNow_ = time.time()
if (timeNow_ - timeNow) >= timeout:
return False
else:
self.clientQueue[0] = msg; return True;
else:
readySet = select.select([], [self.clientSocket.fileno()], [])
readySet = select.select([], [self.clientSocket.fileno()], [], timeout)
if len(readySet[1]) == 0:
return False
msgBytesSent = self.clientSocket.send(msg)
msg = msg[msgBytesSent:]; msgLen -= msgBytesSent;
del self.clientQueue[0]
return True
# }}}
#

View File

@ -34,8 +34,6 @@ from MiRCARTToPngFile import MiRCARTToPngFile
class IrcMiRCARTBot(IrcClient.IrcClient):
"""IRC<->MiRC2png bot"""
clientChannelLastMessage = clientChannelOps = clientChannel = None
clientChannelRejoin = None
imgurApiKey = MiRCARTImgurApiKey.imgurApiKey
# {{{ ContentTooLargeException(Exception): Raised by _urlretrieveReportHook() given download size > 1 MB
@ -111,7 +109,7 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
def _dispatchPrivmsg(self, message):
if message[2].lower() == self.clientChannel.lower() \
and message[3].startswith("!pngbot "):
if (int(time.time()) - self.clientLastMessage) < 5:
if (int(time.time()) - self.clientChannelLastMessage) < 5:
self._log("Ignoring request on {} from {} due to rate limit: {}".format(message[2].lower(), message[0], message[3]))
return
elif message[0].split("!")[0].lower() not in self.clientChannelOps:
@ -161,7 +159,7 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
if imgurResponse[0] == 200:
self._log("Uploaded as: {}".format(imgurResponse[1]))
self.queue("PRIVMSG", message[2], "8/!\\ Uploaded as: {}".format(imgurResponse[1]))
self.clientLastMessage = int(time.time())
self.clientChannelLastMessage = int(time.time())
else:
self._log("Upload failed with HTTP status code {}".format(imgurResponse[0]))
self._log("Message from website: {}".format(imgurResponse[1]))
@ -207,14 +205,15 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
if (totalSize > pow(2,20)):
raise IrcMiRCARTBot.ContentTooLargeException
# }}}
# {{{ connect(self, preferFamily=0, timeout=None): Connect to server and (re)initialise w/ optional timeout
def connect(self, preferFamily=0, timeout=None):
# {{{ connect(self, localAddr=None, preferFamily=0, timeout=None): Connect to server and (re)initialise w/ optional timeout
def connect(self, localAddr=None, preferFamily=0, timeout=None):
self._log("Connecting to {}:{}...".format(self.serverHname, self.serverPort))
if super().connect(preferFamily=preferFamily, timeout=timeout):
if super().connect(localAddr=localAddr, preferFamily=preferFamily, timeout=timeout):
self._log("Connected to {}:{}.".format(self.serverHname, self.serverPort))
self._log("Registering on {}:{} as {}, {}, {}...".format(self.serverHname, self.serverPort, self.clientNick, self.clientIdent, self.clientGecos))
self.clientLastMessage = 0; self.clientChannelOps = [];
self.clientChannelLastMessage = 0; self.clientChannelOps = [];
self.clientChannelRejoin = False
self.clientHasPing = False
return True
else:
return False
@ -226,13 +225,21 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
timeNow = time.time()
if self.clientNextTimeout <= timeNow:
self._dispatchTimer()
self.unqueue()
serverMessage = self.readline()
if serverMessage == None:
if self.unqueue() == False:
self._dispatchNone(); break;
elif serverMessage == "":
continue
elif serverMessage[1] == "001":
else:
serverMessage = self.readline()
if serverMessage == None:
self._dispatchNone(); break;
elif serverMessage == "":
if self.clientHasPing:
self._dispatchNone(); break;
else:
self.clientHasPing = True
self.queue("PING", str(time.time()))
self._log("Ping...")
continue
if serverMessage[1] == "001":
self._dispatch001(serverMessage)
elif serverMessage[1] == "353":
self._dispatch353(serverMessage)
@ -244,6 +251,9 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
self._dispatchMode(serverMessage)
elif serverMessage[1] == "PING":
self._dispatchPing(serverMessage)
elif serverMessage[1] == "PONG":
self._log("Pong.")
self.clientHasPing = False
elif serverMessage[1] == "PRIVMSG":
self._dispatchPrivmsg(serverMessage)
# }}}
@ -259,22 +269,26 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
def main(optdict, *argv):
_IrcMiRCARTBot = IrcMiRCARTBot(*argv)
while True:
if "-l" in optdict:
localAddr = optdict["-l"]
else:
localAddr = None
if "-4" in optdict:
preferFamily = socket.AF_INET
elif "-6" in optdict:
preferFamily = socket.AF_INET6
else:
preferFamily = 0
if _IrcMiRCARTBot.connect(preferFamily=preferFamily, timeout=15):
if _IrcMiRCARTBot.connect(localAddr=localAddr, preferFamily=preferFamily, timeout=15):
_IrcMiRCARTBot.dispatch()
_IrcMiRCARTBot.close()
time.sleep(15)
if __name__ == "__main__":
optlist, argv = getopt(sys.argv[1:], "46")
optlist, argv = getopt(sys.argv[1:], "46l:")
optdict = dict(optlist)
if len(argv) < 1 or len(argv) > 4:
print("usage: {} [-4|-6] " \
print("usage: {} [-4|-6] [-l <local hostname>]" \
"<IRC server hostname> " \
"[<IRC server port; defaults to 6667>] " \
"[<IRC bot nick name; defaults to pngbot>] " \