{IrcMiRCARTBot,MiRCART}.py: differentiate private class member functions.

This commit is contained in:
Lucio Andrés Illanes Albornoz 2018-01-03 03:33:57 +01:00
parent 9896108028
commit e182f0ffa9
3 changed files with 102 additions and 102 deletions

View File

@ -32,6 +32,12 @@ class IrcClient:
clientSocket = clientSocketFile = None;
clientNextTimeout = None
# {{{ close(): Close connection to server
def close(self):
if self.clientSocket != None:
self.clientSocket.close()
self.clientSocket = self.clientSocketFile = None;
# }}}
# {{{ connect(): Connect to server and register w/ optional timeout
def connect(self, timeout=None):
self.clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@ -51,12 +57,6 @@ class IrcClient:
self.sendline("USER", self.clientIdent, "0", "0", self.clientGecos)
return True
# }}}
# {{{ close(): Close connection to server
def close(self):
if self.clientSocket != None:
self.clientSocket.close()
self.clientSocket = self.clientSocketFile = None;
# }}}
# {{{ readline(): Read and parse single line from server into canonicalised list, honouring timers
def readline(self):
if self.clientNextTimeout:

View File

@ -33,31 +33,14 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
clientChannelLastMessage = clientChannelOps = clientChannel = None
clientChannelRejoin = None
# {{{ connect(): Connect to server and (re)initialise w/ optional timeout
def connect(self, timeout=None):
self._log("Connecting to {}:{}...".format(self.serverHname, self.serverPort))
if super().connect(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.clientChannelRejoin = False
return True
else:
return False
# }}}
# {{{ dispatchNone(): Dispatch None message from server
def dispatchNone(self):
self._log("Disconnected from {}:{}.".format(self.serverHname, self.serverPort))
self.close()
# }}}
# {{{ dispatch001(): Dispatch single 001 (RPL_WELCOME)
def dispatch001(self, message):
# {{{ _dispatch001(): Dispatch single 001 (RPL_WELCOME)
def _dispatch001(self, message):
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.sendline("JOIN", self.clientChannel)
# }}}
# {{{ dispatch353(): Dispatch single 353 (RPL_NAMREPLY)
def dispatch353(self, message):
# {{{ _dispatch353(): Dispatch single 353 (RPL_NAMREPLY)
def _dispatch353(self, message):
if message[4].lower() == self.clientChannel.lower():
for channelNickSpec in message[5].split(" "):
if len(channelNickSpec) \
@ -66,20 +49,20 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
self.clientChannelOps.append(channelNickSpec[1:].lower())
self._log("Authorising {} on {}".format(channelNickSpec[1:].lower(), message[4].lower()))
# }}}
# {{{ dispatchJoin(): Dispatch single JOIN message from server
def dispatchJoin(self, message):
# {{{ _dispatchJoin(): Dispatch single JOIN message from server
def _dispatchJoin(self, message):
self._log("Joined {} on {}:{}.".format(message[2].lower(), self.serverHname, self.serverPort))
self.clientNextTimeout = None; self.clientChannelRejoin = False;
# }}}
# {{{ dispatchKick(): Dispatch single KICK message from server
def dispatchKick(self, message):
# {{{ _dispatchKick(): Dispatch single KICK message from server
def _dispatchKick(self, message):
if message[2].lower() == self.clientChannel.lower() \
and message[3].lower() == self.clientNick.lower():
self._log("Kicked from {} by {}, rejoining in 15 seconds".format(message[2].lower(), message[0]))
self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True;
# }}}
# {{{ dispatchMode(): Dispatch single MODE message from server
def dispatchMode(self, message):
# {{{ _dispatchMode(): Dispatch single MODE message from server
def _dispatchMode(self, message):
if message[2].lower() == self.clientChannel.lower():
channelModeType = "+"; channelModeArg = 4;
channelAuthAdd = ""; channelAuthDel = "";
@ -106,12 +89,17 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
self._log("Deauthorising {} on {}".format(channelAuthDel, message[2].lower()))
self.clientChannelOps.remove(channelAuthDel)
# }}}
# {{{ dispatchPing(): Dispatch single PING message from server
def dispatchPing(self, message):
# {{{ _dispatchNone(): Dispatch None message from server
def _dispatchNone(self):
self._log("Disconnected from {}:{}.".format(self.serverHname, self.serverPort))
self.close()
# }}}
# {{{ _dispatchPing(): Dispatch single PING message from server
def _dispatchPing(self, message):
self.sendline("PONG", message[2])
# }}}
# {{{ dispatchPrivmsg(): Dispatch single PRIVMSG message from server
def dispatchPrivmsg(self, message):
# {{{ _dispatchPrivmsg(): Dispatch single PRIVMSG message from server
def _dispatchPrivmsg(self, message):
if message[2].lower() == self.clientChannel.lower() \
and message[3].startswith("!pngbot "):
if (int(time.time()) - self.clientLastMessage) < 45:
@ -131,7 +119,7 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
os.remove(imgTmpFilePath)
urllib.request.urlretrieve(asciiUrl, asciiTmpFilePath)
_MiRCART = mirc2png.MiRCART(asciiTmpFilePath, imgTmpFilePath, "DejaVuSansMono.ttf", 11)
imgurResponse = self.uploadToImgur(imgTmpFilePath, "MiRCART image", "MiRCART image", "c9a6efb3d7932fd")
imgurResponse = self._uploadToImgur(imgTmpFilePath, "MiRCART image", "MiRCART image", "c9a6efb3d7932fd")
if imgurResponse[0] == 200:
self._log("Uploaded as: {}".format(imgurResponse[1]))
self.sendline("PRIVMSG", message[2], "8/!\\ Uploaded as: {}".format(imgurResponse[1]))
@ -143,46 +131,19 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
if os.path.isfile(imgTmpFilePath):
os.remove(imgTmpFilePath)
# }}}
# {{{ dispatchTimer(): Dispatch single client timer expiration
def dispatchTimer(self):
# {{{ _dispatchTimer(): Dispatch single client timer expiration
def _dispatchTimer(self):
if self.clientChannelRejoin:
self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort))
self.sendline("JOIN", self.clientChannel)
self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True;
# }}}
# {{{ dispatch(): Read, parse, and dispatch single line from server
def dispatch(self):
while True:
if self.clientNextTimeout:
timeNow = time.time()
if self.clientNextTimeout <= timeNow:
self.dispatchTimer()
serverMessage = self.readline()
if serverMessage == None:
self.dispatchNone(); break;
elif serverMessage == "":
continue
elif serverMessage[1] == "001":
self.dispatch001(serverMessage)
elif serverMessage[1] == "353":
self.dispatch353(serverMessage)
elif serverMessage[1] == "JOIN":
self.dispatchJoin(serverMessage)
elif serverMessage[1] == "KICK":
self.dispatchKick(serverMessage)
elif serverMessage[1] == "MODE":
self.dispatchMode(serverMessage)
elif serverMessage[1] == "PING":
self.dispatchPing(serverMessage)
elif serverMessage[1] == "PRIVMSG":
self.dispatchPrivmsg(serverMessage)
# }}}
# {{{ self._log(): Log single message to stdout w/ timestamp
# {{{ _log(): Log single message to stdout w/ timestamp
def _log(self, msg):
print(time.strftime("%Y/%m/%d %H:%M:%S") + " " + msg)
# }}}
# {{{ uploadToImgur(): Upload single file to Imgur
def uploadToImgur(self, imgFilePath, imgName, imgTitle, apiKey):
# {{{ _uploadToImgur(): Upload single file to Imgur
def _uploadToImgur(self, imgFilePath, imgName, imgTitle, apiKey):
requestImageData = open(imgFilePath, "rb").read()
requestData = { \
"image": base64.b64encode(requestImageData), \
@ -199,6 +160,45 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
else:
return [responseHttp.status_code]
# }}}
# {{{ connect(): Connect to server and (re)initialise w/ optional timeout
def connect(self, timeout=None):
self._log("Connecting to {}:{}...".format(self.serverHname, self.serverPort))
if super().connect(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.clientChannelRejoin = False
return True
else:
return False
# }}}
# {{{ dispatch(): Read, parse, and dispatch single line from server
def dispatch(self):
while True:
if self.clientNextTimeout:
timeNow = time.time()
if self.clientNextTimeout <= timeNow:
self._dispatchTimer()
serverMessage = self.readline()
if serverMessage == None:
self._dispatchNone(); break;
elif serverMessage == "":
continue
elif serverMessage[1] == "001":
self._dispatch001(serverMessage)
elif serverMessage[1] == "353":
self._dispatch353(serverMessage)
elif serverMessage[1] == "JOIN":
self._dispatchJoin(serverMessage)
elif serverMessage[1] == "KICK":
self._dispatchKick(serverMessage)
elif serverMessage[1] == "MODE":
self._dispatchMode(serverMessage)
elif serverMessage[1] == "PING":
self._dispatchPing(serverMessage)
elif serverMessage[1] == "PRIVMSG":
self._dispatchPrivmsg(serverMessage)
# }}}
#
# Initialisation method

View File

@ -41,8 +41,8 @@ class MiRCART:
state = None;
inCurCol = None;
# {{{ ColourMapBold: mIRC colour number to RGBA map given ^B (bold)
ColourMapBold = [
# {{{ _ColourMapBold: mIRC colour number to RGBA map given ^B (bold)
_ColourMapBold = [
(255, 255, 255, 255), # White
(85, 85, 85, 255), # Grey
(85, 85, 255, 255), # Light Blue
@ -61,8 +61,8 @@ class MiRCART:
(255, 255, 255, 255), # White
]
# }}}
# {{{ ColourMapNormal: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline)
ColourMapNormal = [
# {{{ _ColourMapNormal: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline)
_ColourMapNormal = [
(255, 255, 255, 255), # White
(0, 0, 0, 255), # Black
(0, 0, 187, 255), # Blue
@ -81,41 +81,41 @@ class MiRCART:
(187, 187, 187, 255), # Light Grey
]
# }}}
# {{{ State: Parsing loop state
class State(Enum):
# {{{ _State: Parsing loop state
class _State(Enum):
STATE_CHAR = 1
STATE_COLOUR_SPEC = 2
# }}}
# {{{ getMaxCols(): Calculate widest row in lines, ignoring non-printable & mIRC control code sequences
def getMaxCols(self, lines):
# {{{ _getMaxCols(): Calculate widest row in lines, ignoring non-printable & mIRC control code sequences
def _getMaxCols(self, lines):
maxCols = 0;
for curRow in range(0, len(lines)):
curRowCols = 0; curState = self.State.STATE_CHAR;
curRowCols = 0; curState = self._State.STATE_CHAR;
curCol = 0; curColLen = len(lines[curRow]);
while curCol < curColLen:
curChar = lines[curRow][curCol]
if curState == self.State.STATE_CHAR:
if curState == self._State.STATE_CHAR:
if curChar == "":
curState = self.State.STATE_COLOUR_SPEC; curCol += 1;
curState = self._State.STATE_COLOUR_SPEC; curCol += 1;
elif curChar in string.printable:
curRowCols += 1; curCol += 1;
else:
curCol += 1;
elif curState == self.State.STATE_COLOUR_SPEC:
elif curState == self._State.STATE_COLOUR_SPEC:
if curChar in set(",0123456789"):
curCol += 1;
else:
curState = self.State.STATE_CHAR;
curState = self._State.STATE_CHAR;
maxCols = max(maxCols, curRowCols)
return maxCols
# }}}
# {{{ parseAsChar(): Parse single character as regular character and mutate state
def parseAsChar(self, char):
# {{{ _parseAsChar(): Parse single character as regular character and mutate state
def _parseAsChar(self, char):
if char == "":
self.inCurCol += 1; self.inCurBold = 0 if self.inCurBold else 1;
elif char == "":
self.state = self.State.STATE_COLOUR_SPEC; self.inCurCol += 1;
self._State = self._State.STATE_COLOUR_SPEC; self.inCurCol += 1;
elif char == "":
self.inCurCol += 1; self.inCurItalic = 0 if self.inCurItalic else 1;
elif char == "":
@ -129,20 +129,20 @@ class MiRCART:
self.inCurCol += 1; self.inCurUnderline = 0 if self.inCurUnderline else 1;
elif char == " ":
if self.inCurBold:
colourBg = self.ColourMapBold[self.outCurColourBg]
colourBg = self._ColourMapBold[self.outCurColourBg]
else:
colourBg = self.ColourMapNormal[self.outCurColourBg]
colourBg = self._ColourMapNormal[self.outCurColourBg]
self.outImgDraw.rectangle(((self.outCurX, self.outCurY), (self.outCurX + 7, self.outCurY + 14)), fill=colourBg)
if self.inCurUnderline:
self.outImgDraw.line((self.outCurX, self.outCurY + 11, self.outCurX + 7, self.outCurY + 11), fill=colourFg)
self.outCurX += 7; self.inCurCol += 1;
else:
if self.inCurBold:
colourBg = self.ColourMapBold[self.outCurColourBg]
colourFg = self.ColourMapBold[self.outCurColourFg]
colourBg = self._ColourMapBold[self.outCurColourBg]
colourFg = self._ColourMapBold[self.outCurColourFg]
else:
colourBg = self.ColourMapNormal[self.outCurColourBg]
colourFg = self.ColourMapNormal[self.outCurColourFg]
colourBg = self._ColourMapNormal[self.outCurColourBg]
colourFg = self._ColourMapNormal[self.outCurColourFg]
self.outImgDraw.rectangle(((self.outCurX, self.outCurY), (self.outCurX + 7, self.outCurY + 14)), fill=colourBg)
# XXX implement italic
self.outImgDraw.text((self.outCurX, self.outCurY), char, colourFg, self.outImgFont)
@ -150,8 +150,8 @@ class MiRCART:
self.outImgDraw.line((self.outCurX, self.outCurY + 11, self.outCurX + 7, self.outCurY + 11), fill=colourFg)
self.outCurX += 7; self.inCurCol += 1;
# }}}
# {{{ parseAsColourSpec(): Parse single character as mIRC colour control code sequence and mutate state
def parseAsColourSpec(self, char):
# {{{ _parseAsColourSpec(): Parse single character as mIRC colour control code sequence and mutate state
def _parseAsColourSpec(self, char):
if char in set(",0123456789"):
self.inCurColourSpec += char; self.inCurCol += 1;
else:
@ -163,7 +163,7 @@ class MiRCART:
self.outCurColourFg = int(self.inCurColourSpec[0])
else:
self.outCurColourBg = 1; self.outCurColourFg = 15;
self.inCurColourSpec = ""; self.state = self.State.STATE_CHAR;
self.inCurColourSpec = ""; self._State = self._State.STATE_CHAR;
# }}}
#
@ -171,23 +171,23 @@ class MiRCART:
def __init__(self, inFilePath, imgFilePath, fontFilePath="DejaVuSansMono.ttf", fontSize=11):
self.inFilePath = inFilePath; self.inFile = open(inFilePath, "r");
self.inLines = self.inFile.readlines()
self.inColsMax = self.getMaxCols(self.inLines)
self.inColsMax = self._getMaxCols(self.inLines)
self.inRows = len(self.inLines)
self.outFontFilePath = fontFilePath; self.outFontSize = int(fontSize);
self.outImg = Image.new("RGBA", (self.inColsMax * 7, self.inRows * 14), self.ColourMapNormal[1])
self.outImg = Image.new("RGBA", (self.inColsMax * 7, self.inRows * 14), self._ColourMapNormal[1])
self.outImgDraw = ImageDraw.Draw(self.outImg)
self.outImgFont = ImageFont.truetype(self.outFontFilePath, self.outFontSize)
self.outCurColourBg = 1; self.outCurColourFg = 15;
self.outCurX = 0; self.outCurY = 0;
for inCurRow in range(0, len(self.inLines)):
self.inCurBold = 0; self.inCurItalic = 0; self.inCurUnderline = 0;
self.inCurColourSpec = ""; self.state = self.State.STATE_CHAR;
self.inCurColourSpec = ""; self._State = self._State.STATE_CHAR;
self.inCurCol = 0;
while self.inCurCol < len(self.inLines[inCurRow]):
if self.state == self.State.STATE_CHAR:
self.parseAsChar(self.inLines[inCurRow][self.inCurCol])
elif self.state == self.State.STATE_COLOUR_SPEC:
self.parseAsColourSpec(self.inLines[inCurRow][self.inCurCol])
if self._State == self._State.STATE_CHAR:
self._parseAsChar(self.inLines[inCurRow][self.inCurCol])
elif self._State == self._State.STATE_COLOUR_SPEC:
self._parseAsColourSpec(self.inLines[inCurRow][self.inCurCol])
self.outCurX = 0; self.outCurY += 13;
self.inFile.close();
self.outImg.save(imgFilePath);