Example #1
0
def test_ColourCodeParser_bold_off():
    ccp = ColourCodeParser()
    inline = '\x1b[1mfoo\x1b[22mbar'
    ml = ccp.parseline(inline)
    print ml.fores.items()
    assert ml.fores.items() == [(0, fg_code(WHITE, True)),
                                               (3, fg_code(WHITE, False))]
Example #2
0
def test_ColourCodeParser_fg_change():
    ccp = ColourCodeParser()
    inline = 'foo\x1b[30mbar'
    ml = ccp.parseline(inline)
    assert ml.fores.items() == [(0, fg_code(WHITE, False)), 
                                               (3, fg_code(BLACK, False))], \
           ml.fores.items()
    assert ml.line == 'foobar'
Example #3
0
def test_ColourCodeParser_funky_real_example():
    ccp = ColourCodeParser()
    inline = '\x1b[33mfoo\x1b[0m'
    ml = ccp.parseline(inline)
    print ml.fores.items()
    assert ml.fores.items() == [(0, fg_code(YELLOW, False)),
                               (3, fg_code(WHITE, False))]
    assert ml.backs.items() == [(0, bg_code(BLACK))]
Example #4
0
def test_ColOurCodeParser_redundant_back_reset():
    ccp = ColourCodeParser()
    inline = "foo\x1b[48m"
    ml = ccp.parseline(inline)
    assert ml.backs == {0: bg_code(BLACK)}
Example #5
0
def test_ColourCodeParser_redundant_back_change():
    ccp = ColourCodeParser()
    inline = 'foo\x1b[40m'
    ml = ccp.parseline(inline)
    assert ml.backs == {0: bg_code(BLACK)}, ml.backs
Example #6
0
def test_ColOurCodeParser_redundant_fore_reset():
    ccp = ColourCodeParser()
    inline = "foo\x1b[38m"
    ml = ccp.parseline(inline)
    assert ml.fores == {0: fg_code(WHITE, False)}
Example #7
0
def test_ColourCodeParser_redundant_fore_change():
    ccp = ColourCodeParser()
    inline = 'foo\x1b[37m'
    ml = ccp.parseline(inline)
    assert ml.fores == {0: fg_code(WHITE, False)}
Example #8
0
def test_ColourCodeParser_bg_change():
    ccp = ColourCodeParser()
    inline = 'foo\x1b[46mbar'
    ml = ccp.parseline(inline)
    assert ml.backs.items() == [(0, bg_code(BLACK)),
                                               (3, bg_code(CYAN))]
Example #9
0
def test_ColourCodeParser_normalises_ANSI_colours():
    ccp = ColourCodeParser()
    inline = '\x1b[01mfoobar'
    ml = ccp.parseline(inline)
    assert ml.fores.items() == [(0, fg_code(WHITE, True))], \
           ml.fores.items()
Example #10
0
def test_ColourCodeParser_add_reset_back_change_made():
    ccp = ColourCodeParser()
    inline = "\x1b[47mfoo\x1b[0m"
    ml = ccp.parseline(inline)
    assert ml.backs == {0: bg_code(WHITE),
                        3: bg_code(BLACK)}
Example #11
0
def test_ColourCodeParser_add_reset_fore_change_made():
    ccp = ColourCodeParser()
    inline = "\x1b[30mfoo\x1b[0m"
    ml = ccp.parseline(inline)
    assert ml.fores == {0: fg_code(BLACK, False),
                        3: fg_code(WHITE, False)}, ml.fores
Example #12
0
def test_ColourCodeParser_all_reset_bold_change_made():
    ccp = ColourCodeParser()
    inline = "\x1b[1mfoo\x1b[0m"
    ml = ccp.parseline(inline)
    assert ml.fores == {0: fg_code(WHITE, True),
                        3: fg_code(WHITE, False)}, ml.fores
Example #13
0
def test_ColourCodeParser_all_reset_fore_and_back_not_needed():
    ccp = ColourCodeParser()
    inline = "foo\x1b[0m"
    ml = ccp.parseline(inline)
    assert ml.fores == {0: fg_code(WHITE, False)}
    assert ml.backs == {0: bg_code(BLACK)}
Example #14
0
def test_ColourCodeParser_no_line():
    ccp = ColourCodeParser()
    inline = ''
    ml = ccp.parseline(inline)
    assert ml.fores.items() == [(0, fg_code(WHITE, False))]
    assert ml.backs.items() == [(0, bg_code(BLACK))]
Example #15
0
def test_ColourCodeParser_redundant_bolding():
    ccp = ColourCodeParser()
    inline = '\x1b[1mfoo\x1b[1m'
    ml = ccp.parseline(inline)
    assert ml.fores == {0: fg_code(WHITE, True)}, ml.fores
Example #16
0
def test_ColourCodeParser_bold_on_and_off_remembers_colour():
    ccp = ColourCodeParser()
    inline = '\x1b[30;1mfoo\x1b[22mbar'
    ml = ccp.parseline(inline)
    assert ml.fores.items() == [(0, fg_code(BLACK, True)),
                                               (3, fg_code(BLACK, False))]
Example #17
0
def test_ColourCodeParser_redundant_unbolding():
    ccp = ColourCodeParser()
    inline = "foo\x1b[22m"
    ml = ccp.parseline(inline)
    assert ml.fores == {0: fg_code(WHITE, False)}
Example #18
0
class TelnetClient(Telnet, LineOnlyReceiver):

    """The link to the MUD."""

    delimiter = '\n'

    def __init__(self, factory):
        Telnet.__init__(self)
        self.commandMap[GA] = self.ga_received
        self.negotiationMap[COMPRESS2] = self.turn_on_compression
        self.negotiationMap[GMCP] = self.handle_gmcp
        #LineOnlyReceiver doesn't have an __init__ method, weirdly.
        self.factory = factory
        self.allowing_compress = False
        self._colourparser = ColourCodeParser()
        self.fix_broken_godwars_line_endings = True

    def negotiate(self, bytes):
        
        command, bytes = bytes[0], bytes[1:]
        cmdFunc = self.negotiationMap.get(command)
        if cmdFunc is None:
            self.unhandledSubnegotiation(command, bytes)
        else:
            cmdFunc(bytes)


    def connectionMade(self):
        """Call our superclasses.
        
        Late initialisation should also go here.
        """
        
        self.factory.realm.connectionMade()
        Telnet.connectionMade(self)
        LineOnlyReceiver.connectionMade(self)
    def commandReceived(self, command, argument):
        
        Telnet.commandReceived(self, command, argument)
        if argument==GMCP and command == WILL and self.factory.realm.gmcp_handler:
            for msg in self.factory.realm.gmcp_handler.handshakeMessages():
                self.requestNegotiation(GMCP, msg)
            
            
        
    def enableRemote(self, option):
        """Allow MCCP to be turned on."""
        if option == COMPRESS2:
            self.allowing_compress = True
            return True
        if option == GMCP:
            
            self.allow_gmcp = True
            return True
        
        elif option == ECHO:
            self.factory.realm.server_echo = True
            #hide the command line
            self.factory.gui.command_line.set_visibility(False)
            return True
        else:
            return False

    def disableRemote(self, option):
        """Allow MCCP to be turned off."""
        if option == COMPRESS2:
            self.allowing_compress = False
        if option == GMCP:
            self.allow_gmcp = False
        elif option == ECHO:
            self.factory.realm.server_echo = False
            self.factory.gui.command_line.set_visibility(True)

    def turn_on_compression(self, bytes):
        """Actually enable MCCP."""
        #invalid states.   
        if not self.allowing_compress or bytes:
            return
        self.transport.their_mccp_active = True
        
    def handle_gmcp(self, bytes):
        if self.allow_gmcp == True and self.factory.realm.gmcp_handler:
            self.factory.realm.gmcp_handler.process(bytes,self.factory.realm)
        
    def unhandledSubnegotiation(self, command, bytes):
        print("Unhandled subnegotiation %d"%ord(command))

    def dataReceived(self, data):
        if self.fix_broken_godwars_line_endings:
            while broken_line_ending_pattern.match(data):
                data = re.sub(broken_line_ending_pattern, "\\1\r\n", data, 1)
        try:
            Telnet.dataReceived(self, data)
        except ValueError as e:
            print('Telnet error: %s'%e)

    applicationDataReceived = LineOnlyReceiver.dataReceived

    def close(self):
        """Convenience: close the connection."""
        self.transport.loseConnection()

    def sendLine(self, line):
        """Send a line plus a line delimiter to the MUD.

        We need to override this because Telnet converts \\r\\n -> \\n, so
        LineReceiver's delimiter needs to be \\n, but we need to -send- lines
        terminated by \\r\\n. Sigh.
        """
        line = line.encode(self.factory.encoding)
        #double IAC, else it might be interpreted as a command
        line = line.replace(IAC, IAC + IAC)
        return self.transport.writeSequence([line, '\r\n'])

    def connectionLost(self, reason):
        """Clean up and let the superclass handle it."""
        Telnet.connectionLost(self, reason)
        LineOnlyReceiver.connectionLost(self, reason)
        #flush out the buffer
        if self._buffer:
            self.lineReceived(self._buffer)
        self.factory.realm.connectionLost()

    def ga_received(self, _):
        """A GA's been received. We treat these kind of like line endings."""
        #uses the internals of LineOnyReceiver
        self._handle_line(self._buffer, from_ga = True)
        self._buffer = ''

    def lineReceived(self, line):
        """A normally terminated line's been received from the MUD."""
        self._handle_line(line, from_ga = False)

    def _handle_line(self, line, from_ga):
        """Clean the line, split out the colour codes, and feed it to the 
        realm as a metaline.
        """
        line = line.decode(self.factory.encoding)
        metaline = self._colourparser.parseline(make_string_sane(line))
        if from_ga:
            metaline.line_end = 'soft'
        else:
            metaline.line_end = 'hard'
        metaline.wrap = True
        self.factory.realm.metalineReceived(metaline)
Example #19
0
def test_ColourCodeParser_deals_with_blank_colours_as_0():
    ccp = ColourCodeParser()
    inline = 'foo\x1b[30;mbar'
    ml = ccp.parseline(inline)
    assert ml.fores.items() == [(0, fg_code(WHITE, False))]