Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
196 lines (131 sloc) 4.69 KB
# This is the Twisted Get Poetry Now! client, version 6.0
import optparse, sys
from twisted.internet import defer
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.protocols.basic import NetstringReceiver
def parse_args():
usage = """usage: %prog [options] [hostname]:port ...
This is the Get Poetry Now! client, Twisted version 6.0
Run it like this:
python xform-port port1 port2 ...
If you are in the base directory of the twisted-intro package,
you could run it like this:
python twisted-client-6/ 10001 10002 10003
to grab poetry from servers on ports 10002, and 10003 and transform
it using the server on port 10001.
Of course, there need to be appropriate servers listening on those
ports for that to work.
parser = optparse.OptionParser(usage)
_, addresses = parser.parse_args()
if len(addresses) < 2:
print parser.format_help()
def parse_address(addr):
if ':' not in addr:
host = ''
port = addr
host, port = addr.split(':', 1)
if not port.isdigit():
parser.error('Ports must be integers.')
return host, int(port)
return map(parse_address, addresses)
class PoetryProtocol(Protocol):
poem = ''
def dataReceived(self, data):
self.poem += data
def connectionLost(self, reason):
def poemReceived(self, poem):
class PoetryClientFactory(ClientFactory):
protocol = PoetryProtocol
def __init__(self, deferred):
self.deferred = deferred
def poem_finished(self, poem):
if self.deferred is not None:
d, self.deferred = self.deferred, None
def clientConnectionFailed(self, connector, reason):
if self.deferred is not None:
d, self.deferred = self.deferred, None
class TransformClientProtocol(NetstringReceiver):
def connectionMade(self):
self.sendRequest(self.factory.xform_name, self.factory.poem)
def sendRequest(self, xform_name, poem):
self.sendString(xform_name + '.' + poem)
def stringReceived(self, s):
def poemReceived(self, poem):
class TransformClientFactory(ClientFactory):
protocol = TransformClientProtocol
def __init__(self, xform_name, poem):
self.xform_name = xform_name
self.poem = poem
self.deferred = defer.Deferred()
def handlePoem(self, poem):
d, self.deferred = self.deferred, None
def clientConnectionLost(self, _, reason):
if self.deferred is not None:
d, self.deferred = self.deferred, None
clientConnectionFailed = clientConnectionLost
class TransformProxy(object):
I proxy requests to a transformation service.
def __init__(self, host, port): = host
self.port = port
def xform(self, xform_name, poem):
factory = TransformClientFactory(xform_name, poem)
from twisted.internet import reactor
reactor.connectTCP(, self.port, factory)
return factory.deferred
def get_poetry(host, port):
Download a poem from the given host and port. This function
returns a Deferred which will be fired with the complete text of
the poem or a Failure if the poem could not be downloaded.
d = defer.Deferred()
from twisted.internet import reactor
factory = PoetryClientFactory(d)
reactor.connectTCP(host, port, factory)
return d
def poetry_main():
addresses = parse_args()
xform_addr = addresses.pop(0)
proxy = TransformProxy(*xform_addr)
from twisted.internet import reactor
poems = []
errors = []
def try_to_cummingsify(poem):
d = proxy.xform('cummingsify', poem)
def fail(err):
print >>sys.stderr, 'Cummingsify failed!'
return poem
return d.addErrback(fail)
def got_poem(poem):
print poem
def poem_failed(err):
print >>sys.stderr, 'The poem download failed.'
def poem_done(_):
if len(poems) + len(errors) == len(addresses):
for address in addresses:
host, port = address
d = get_poetry(host, port)
d.addCallbacks(got_poem, poem_failed)
if __name__ == '__main__':