Source code for irc.ctcp
"""
Handle Client-to-Client protocol per the `best available
spec <http://www.irchelp.org/irchelp/rfc/ctcpspec.html>`_.
"""
import re
LOW_LEVEL_QUOTE = '\x10'
LEVEL_QUOTE = "\\"
DELIMITER = '\x01'
low_level_mapping = {"0": '\x00', "n": "\n", "r": "\r", LEVEL_QUOTE: LEVEL_QUOTE}
low_level_regexp = re.compile(LOW_LEVEL_QUOTE + "(.)")
def _low_level_replace(match_obj):
ch = match_obj.group(1)
# If low_level_mapping doesn't have the character as key, we
# should just return the character.
return low_level_mapping.get(ch, ch)
[docs]def dequote(message):
"""
Dequote a message according to CTCP specifications.
The function returns a list where each element can be either a
string (normal message) or a tuple of one or two strings (tagged
messages). If a tuple has only one element (ie is a singleton),
that element is the tag; otherwise the tuple has two elements: the
tag and the data.
Arguments:
message -- The message to be decoded.
"""
# Perform the substitution
message = low_level_regexp.sub(_low_level_replace, message)
if DELIMITER not in message:
return [message]
# Split it into parts.
chunks = message.split(DELIMITER)
return list(_gen_messages(chunks))
def _gen_messages(chunks):
i = 0
while i < len(chunks) - 1:
# Add message if it's non-empty.
if len(chunks[i]) > 0:
yield chunks[i]
if i < len(chunks) - 2:
# Aye! CTCP tagged data ahead!
yield tuple(chunks[i + 1].split(" ", 1))
i = i + 2
if len(chunks) % 2 == 0:
# Hey, a lonely _CTCP_DELIMITER at the end! This means
# that the last chunk, including the delimiter, is a
# normal message! (This is according to the CTCP
# specification.)
yield DELIMITER + chunks[-1]