From 4d6c4dc7b507c2cd5ab5b9f315e7a0ab79f98635 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Mon, 26 Feb 2018 20:04:11 +0000 Subject: [PATCH] Split long lines Use textwrap to they are split on word boundaries. 400 characters is used as an approximation of a safe line length without dealing with the complexity of determining the exact value for specific conditions. In practice, we've seen lines truncated at 435 chars. We sleep between issuing chunks, however, we sleep less than the normal flood protection interval so the bot still appears responsive. Change-Id: I87d26228f0e025d911b29a1662a069a2b6d0e497 --- ptgbot/bot.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/ptgbot/bot.py b/ptgbot/bot.py index 3af836f..02a1309 100644 --- a/ptgbot/bot.py +++ b/ptgbot/bot.py @@ -24,6 +24,7 @@ import logging.config import os import time import ssl +import textwrap import ptgbot.db @@ -38,6 +39,11 @@ except ImportError: # irc-client-should-not-crash-on-failed # ^ This is why pep8 is a bad idea. irc.client.ServerConnection.buffer_class.errors = 'replace' +# If a long message is split, how long to sleep between sending parts +# of a message. This is lower than the general recommended interval, +# but in practice freenode allows short bursts at a higher rate. +MESSAGE_CONTINUATION_SLEEP = 0.5 +# The amount of time to sleep between messages. ANTI_FLOOD_SLEEP = 2 DOC_URL = 'https://git.openstack.org/cgit/openstack/ptgbot/tree/README.rst' @@ -188,7 +194,14 @@ class PTGBot(irc.bot.SingleServerIRCBot): return def send(self, channel, msg): - self.connection.privmsg(channel, msg) + # 400 chars is an estimate of a safe line length (which can vary) + chunks = textwrap.wrap(msg, 400) + if len(chunks) > 10: + raise Exception("Unusually large message: %s" % (msg,)) + for count, chunk in enumerate(chunks): + self.connection.privmsg(channel, chunk) + if count: + time.sleep(MESSAGE_CONTINUATION_SLEEP) time.sleep(ANTI_FLOOD_SLEEP)