Browse Source

Improve detection of maximum IRC message length.

tags/v0.3
Ben Kurtovic 9 years ago
parent
commit
696d24432d
2 changed files with 30 additions and 4 deletions
  1. +1
    -0
      CHANGELOG
  2. +29
    -4
      earwigbot/irc/connection.py

+ 1
- 0
CHANGELOG View File

@@ -1,6 +1,7 @@
v0.3 (unreleased): v0.3 (unreleased):


- Added !remind all. - Added !remind all.
- Improved detection of maximum IRC message length.


v0.2 (released November 8, 2015): v0.2 (released November 8, 2015):




+ 29
- 4
earwigbot/irc/connection.py View File

@@ -45,6 +45,7 @@ class IRCConnection(object):
self._last_recv = time() self._last_recv = time()
self._last_send = 0 self._last_send = 0
self._last_ping = 0 self._last_ping = 0
self._myhost = "." * 63 # default: longest possible hostname


def __repr__(self): def __repr__(self):
"""Return the canonical string representation of the IRCConnection.""" """Return the canonical string representation of the IRCConnection."""
@@ -100,8 +101,19 @@ class IRCConnection(object):
self.logger.debug(msg) self.logger.debug(msg)
self._last_send = time() self._last_send = time()


def _split(self, msgs, maxlen, maxsplits=3):
"""Split a large message into multiple messages smaller than maxlen."""
def _get_maxlen(self, extra):
"""Return our best guess of the maximum length of a standard message.

This applies mainly to PRIVMSGs and NOTICEs.
"""
base_max = 512
userhost = len(self.nick) + len(self.ident) + len(self._myhost) + 2
padding = 4 # "\r\n" at end, ":" at beginning, and " " after userhost
return base_max - userhost - padding - extra

def _split(self, msgs, extralen, maxsplits=3):
"""Split a large message into multiple messages."""
maxlen = self._get_maxlen(extralen)
words = msgs.split(" ") words = msgs.split(" ")
splits = 0 splits = 0
while words and splits < maxsplits: while words and splits < maxsplits:
@@ -128,6 +140,19 @@ class IRCConnection(object):
self._last_recv = time() self._last_recv = time()
if line[0] == "PING": # If we are pinged, pong back if line[0] == "PING": # If we are pinged, pong back
self.pong(line[1][1:]) self.pong(line[1][1:])
elif line[1] == "001": # Update nickname on startup
if line[2] != self.nick:
self.logger.warn("Nickname changed from {0} to {1}".format(
self.nick, line[2]))
self._nick = line[2]
elif line[1] == "376": # After sign-on, get our userhost
self._send("WHOIS {0}".format(self.nick))
elif line[1] == "311": # Receiving WHOIS result
if line[2] == self.nick:
self._ident = line[4]
self._myhost = line[5]
elif line[1] == "396": # Hostname change
self._myhost = line[3]


def _process_message(self, line): def _process_message(self, line):
"""To be overridden in subclasses.""" """To be overridden in subclasses."""
@@ -163,7 +188,7 @@ class IRCConnection(object):


def say(self, target, msg, hidelog=False): def say(self, target, msg, hidelog=False):
"""Send a private message to a target on the server.""" """Send a private message to a target on the server."""
for msg in self._split(msg, 400):
for msg in self._split(msg, len(target) + 10):
msg = "PRIVMSG {0} :{1}".format(target, msg) msg = "PRIVMSG {0} :{1}".format(target, msg)
self._send(msg, hidelog) self._send(msg, hidelog)


@@ -182,7 +207,7 @@ class IRCConnection(object):


def notice(self, target, msg, hidelog=False): def notice(self, target, msg, hidelog=False):
"""Send a notice to a target on the server.""" """Send a notice to a target on the server."""
for msg in self._split(msg, 400):
for msg in self._split(msg, len(target) + 9):
msg = "NOTICE {0} :{1}".format(target, msg) msg = "NOTICE {0} :{1}".format(target, msg)
self._send(msg, hidelog) self._send(msg, hidelog)




Loading…
Cancel
Save