anonymous on Sun Aug 31 16:52:50 2008, syntax: Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python

import subprocess

from twisted.internet import defer, stdio, protocol, reactor
from twisted.protocols import basic

class Repl(basic.LineReceiver):
    delimiter = '\n'
    prompt_string = '>>> '

    def prompt(self):
        self.transport.write(self.prompt_string)

    def connectionMade(self):
        self.sendLine('Welcome to Repl')
        # store factory and connector upon connection to the stdout
        self.factory = CFactory()
        self.connector = reactor.connectTCP(
            '127.0.0.1', 1234, self.factory)
        self.prompt()

    def lineReceived(self, line):
        if not line:
            self.prompt()
            return

        self.issueCommand(line)

    def issueCommand(self, command):
        # write to the connector's transport, not the one writing on stdout
        self.connector.transport.write("%s%s" % (command, self.delimiter))
        # register the callback on the factory's deferred
        self.factory.deferred.addCallback(self._checkResponse)

    def _checkResponse(self, args):
        success, num_lines, data = args
        if num_lines > 20:
            self.lessify(data)
        else:
            self.sendLine(data)
        self.prompt()
        # recreate the deferred each time we have the response
        self.factory.deferred = defer.Deferred()

    def lessify(self, data):
        p = subprocess.Popen(["less"], stdin=subprocess.PIPE)
        p.stdin.write(data)
        p.stdin.close()
        p.wait()


class Client(basic.LineReceiver):
    delimiter = '\n'

    def connectionMade(self):
        self.buffer = []
        self.cmd_success = True

    def lineReceived(self, line):
        if line.startswith('OK'):
            return
        if line.startswith('ERR'):
            self.cmd_success = False
            return

        if line == 'END':
            self.responseFinished(
                len(self.buffer), "\n".join(self.buffer))
            self.buffer = []
        else:
            self.buffer.append(line)

    def responseFinished(self, num_lines, data):
        # just fire the callback
        self.factory.deferred.callback((
            self.cmd_success, num_lines, data))

    def connectionLost(self, reason):
        reactor.stop()


class CFactory(protocol.ClientFactory):
    protocol = Client

    def __init__(self):
        self.deferred = defer.Deferred()

if __name__ == "__main__":
    stdio.StandardIO(Repl())
    reactor.run()