<commit_before>"""
IMC2 packets. These are pretty well documented at:
http://www.mudbytes.net/index.php?a=articles&s=imc2_protocol
"""
import shlex
if __name__ == "__main__":
    class settings:
        IMC2_MUDNAME = "BLAH"
else:
    from django.conf import settings

class Lexxer(shlex.shlex):
    """
    A lexical parser for interpreting IMC2 packets.
    """
    def __init__(self, packet_str, posix=True):
        shlex.shlex.__init__(self, packet_str, posix=True)
        # Single-quotes are notably not present. This is important!
        self.quotes = '"'
        self.commenters = ''
        # This helps denote what constitutes a continuous token.
        self.wordchars += "~`!@#$%^&*()-_+=[{]}|\\;:',<.>/?"

class IMC2Packet(object):
    """
    Base IMC2 packet class. This is generally sub-classed, aside from using it
    to parse incoming packets from the IMC2 network server.
    """
    def __init__(self, packet_str=None):
        """
        Optionally, parse a packet and load it up.
        """
        # The following fields are all according to the basic packet format of:
        # <sender>@<origin> <sequence> <route> <packet-type> <target>@<destination> <data...> 
        self.sender = None
        self.origin = settings.IMC2_MUDNAME
        self.sequence = None
        self.route = settings.IMC2_MUDNAME
        self.packet_type = None
        self.target = None
        self.destination = None
        # Optional data.
        self.optional_data = []
        # Reference to the IMC2Protocol object doing the sending.
        self.imc2_protocol = None
        
        if packet_str:
            # The lexxer handles the double quotes correctly, unlike just
            # splitting. Spaces throw things off, so shlex handles it
            # gracefully, ala POSIX shell-style parsing.
            lex = Lexxer(packet_str)
            
            # Token counter.
            counter = 0
            for token in lex:
                if counter == 0:
                    # This is the sender@origin token.
                    sender_origin = token
                    print token
                    split_sender_origin = sender_origin.split('@')
                    self.sender = split_sender_origin[0].strip()
                    self.origin = split_sender_origin[1]
                elif counter == 1:
                    # Numeric time-based sequence.
                    self.sequence = token
                elif counter == 2:
                    # Packet routing info.
                    self.route = token
                elif counter == 3:
                    # Packet type string.
                    self.packet_type = token
                elif counter == 4:
                    # Get values for the target and destination attributes.
                    target_destination = token
                    split_target_destination = target_destination.split('@')
                    self.target = split_target_destination[0]
                    self.destination = split_target_destination[1]
                elif counter > 4:
                    # Populate optional data.
                    key, value = token.split('=', 1)
                    self.optional_data.append((key, value))
                # Increment and continue to the next token (if applicable)<commit_msg>Looks like the 'who' packet doesn't have a target element in the target@destination segment of the packet. Handle this semi-intelligently when ran into.<commit_after>"""
IMC2 packets. These are pretty well documented at:
http://www.mudbytes.net/index.php?a=articles&s=imc2_protocol
"""
import shlex
if __name__ == "__main__":
    class settings:
        IMC2_MUDNAME = "BLAH"
else:
    from django.conf import settings

class Lexxer(shlex.shlex):
    """
    A lexical parser for interpreting IMC2 packets.
    """
    def __init__(self, packet_str, posix=True):
        shlex.shlex.__init__(self, packet_str, posix=True)
        # Single-quotes are notably not present. This is important!
        self.quotes = '"'
        self.commenters = ''
        # This helps denote what constitutes a continuous token.
        self.wordchars += "~`!@#$%^&*()-_+=[{]}|\\;:',<.>/?"

class IMC2Packet(object):
    """
    Base IMC2 packet class. This is generally sub-classed, aside from using it
    to parse incoming packets from the IMC2 network server.
    """
    def __init__(self, packet_str=None):
        """
        Optionally, parse a packet and load it up.
        """
        # The following fields are all according to the basic packet format of:
        # <sender>@<origin> <sequence> <route> <packet-type> <target>@<destination> <data...> 
        self.sender = None
        self.origin = settings.IMC2_MUDNAME
        self.sequence = None
        self.route = settings.IMC2_MUDNAME
        self.packet_type = None
        self.target = None
        self.destination = None
        # Optional data.
        self.optional_data = []
        # Reference to the IMC2Protocol object doing the sending.
        self.imc2_protocol = None
        
        if packet_str:
            # The lexxer handles the double quotes correctly, unlike just
            # splitting. Spaces throw things off, so shlex handles it
            # gracefully, ala POSIX shell-style parsing.
            lex = Lexxer(packet_str)
            
            # Token counter.
            counter = 0
            for token in lex:
                if counter == 0:
                    # This is the sender@origin token.
                    sender_origin = token
                    print token
                    split_sender_origin = sender_origin.split('@')
                    self.sender = split_sender_origin[0].strip()
                    self.origin = split_sender_origin[1]
                elif counter == 1:
                    # Numeric time-based sequence.
                    self.sequence = token
                elif counter == 2:
                    # Packet routing info.
                    self.route = token
                elif counter == 3:
                    # Packet type string.
                    self.packet_type = token
                elif counter == 4:
                    # Get values for the target and destination attributes.
                    target_destination = token
                    split_target_destination = target_destination.split('@')
                    self.target = split_target_destination[0]
                    try:
                        self.destination = split_target_destination[1]
                    except IndexError:
                        # There is only one element to the target@dest segment
                        # of the packet. Wipe the target and move the captured
                        # value to the destination attrib.
                        self.target = '*'
                        self.destination = split_target_destination[0]
                elif counter > 4:
                    # Populate optional data.
                    key, value = token.split('=', 1)
                    self.optional_data.append((key, value))
                # Increment and continue to the next token (if applicable)
{'fraction_non_alphanumeric': 0.08520743120547562, 'fraction_numerical': 0.006565162732225171, 'mean_word_length': 1.640117994100295, 'pattern_counts': {'":': 2, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3471373', 'n_tokens_mistral': 1886, 'n_tokens_neox': 1782, 'n_words': 561}