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]