From 8b4f8b25458794d06d7fd3766a5b3408a98a5a4e Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Sun, 12 Feb 2017 10:44:53 -0600 Subject: [PATCH] move message splitting into IRCBot.reply() leaves IRCBot.privmsg() pretty vanilla. this should make it clearer which version for modules/etc to use (hint: it's reply) bss/dr.botzo#21 --- ircbot/bot.py | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/ircbot/bot.py b/ircbot/bot.py index 57516c6..2f43767 100644 --- a/ircbot/bot.py +++ b/ircbot/bot.py @@ -53,6 +53,11 @@ class LenientServerConnection(irc.client.ServerConnection): buffer_class = irc.buffer.LenientDecodingLineBuffer + def _prep_message(self, string): + """Override SimpleIRCClient._prep_message to add some logging.""" + log.debug("preparing message %s", string) + return super(LenientServerConnection, self)._prep_message(string) + class DrReactor(irc.client.Reactor): """Customize the basic IRC library's Reactor with more features.""" @@ -318,6 +323,7 @@ class IRCBot(irc.client.SimpleIRCClient): """A single-server IRC bot class.""" reactor_class = DrReactor + splitter = "..." def __init__(self, reconnection_interval=60): super(IRCBot, self).__init__() @@ -832,33 +838,7 @@ class IRCBot(irc.client.SimpleIRCClient): return log.debug("OUTGOING PRIVMSG: t[%s] m[%s]", target, text) - - splitter = "..." - - # split messages that are too long. Max length is 512. - # TODO: this does not properly handle when the nickmask has been masked by the ircd - # is the above still the case? - space = 512 - len('\r\n') - len(' PRIVMSG ') - len(target) - len(' :') - len(self.nickmask) - len(' :') - splitspace = space - (len(splitter) + 1) - - if len(text) > space: - times = 1 - - while len(text) > splitspace: - splitpos = text.rfind(' ', 0, splitspace) - splittext = text[0:splitpos] + ' ' + splitter - text = splitter + ' ' + text[splitpos+1:] - self.connection.send_raw("PRIVMSG {0:s} :{1:s}".format(target, splittext)) - - times = times + 1 - if times >= 4: - # this is stupidly long, abort - return - - # done splitting - self.connection.send_raw("PRIVMSG {0:s} :{1:s}".format(target, text)) - else: - self.connection.send_raw("PRIVMSG {0:s} :{1:s}".format(target, text)) + self.connection.send_raw("PRIVMSG {0:s} :{1:s}".format(target, text)) def reply(self, event, replystr, stop=False): """Reply over IRC to replypath or return a string with the reply. @@ -894,6 +874,19 @@ class IRCBot(irc.client.SimpleIRCClient): else: replies = replystr.split('\n') for reply in replies: + # split messages that are too long. max length is 512, but we also need to + # account for display and that'll show our hostname + space = 512 - len(':{0:s} PRIVMSG {1:s} :\r\n'.format(self.nickmask, replypath)) + splitspace = space - (len(self.splitter) + 1) + + while len(reply) > space: + # do splitting + splitpos = reply.rfind(' ', 0, splitspace) + splittext = reply[0:splitpos] + ' ' + self.splitter + reply = self.splitter + ' ' + reply[splitpos + 1:] + self.privmsg(replypath, splittext) + + # done splitting, or it was never necessary self.privmsg(replypath, reply) if stop: return "NO MORE"