<s> import optparse , sys <EOL> from twisted . internet import defer <EOL> from twisted . internet . protocol import Protocol , ClientFactory <EOL> from twisted . protocols . basic import NetstringReceiver <EOL> def parse_args ( ) : <EOL> usage = """<STR_LIT>""" <EOL> parser = optparse . OptionParser ( usage ) <EOL> _ , addresses = parser . parse_args ( ) <EOL> if len ( addresses ) < <NUM_LIT:2> : <EOL> print parser . format_help ( ) <EOL> parser . exit ( ) <EOL> def parse_address ( addr ) : <EOL> if '<STR_LIT::>' not in addr : <EOL> host = '<STR_LIT:127.0.0.1>' <EOL> port = addr <EOL> else : <EOL> host , port = addr . split ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> if not port . isdigit ( ) : <EOL> parser . error ( '<STR_LIT>' ) <EOL> return host , int ( port ) <EOL> return map ( parse_address , addresses ) <EOL> class PoetryProtocol ( Protocol ) : <EOL> poem = '<STR_LIT>' <EOL> def dataReceived ( self , data ) : <EOL> self . poem += data <EOL> def connectionLost ( self , reason ) : <EOL> self . poemReceived ( self . poem ) <EOL> def poemReceived ( self , poem ) : <EOL> self . factory . poem_finished ( poem ) <EOL> class PoetryClientFactory ( ClientFactory ) : <EOL> protocol = PoetryProtocol <EOL> def __init__ ( self , deferred ) : <EOL> self . deferred = deferred <EOL> def poem_finished ( self , poem ) : <EOL> if self . deferred is not None : <EOL> d , self . deferred = self . deferred , None <EOL> d . callback ( poem ) <EOL> def clientConnectionFailed ( self , connector , reason ) : <EOL> if self . deferred is not None : <EOL> d , self . deferred = self . deferred , None <EOL> d . errback ( reason ) <EOL> class TransformClientProtocol ( NetstringReceiver ) : <EOL> def connectionMade ( self ) : <EOL> self . sendRequest ( self . factory . xform_name , self . factory . poem ) <EOL> def sendRequest ( self , xform_name , poem ) : <EOL> self . sendString ( xform_name + '<STR_LIT:.>' + poem ) <EOL> def stringReceived ( self , s ) : <EOL> self . transport . loseConnection ( ) <EOL> self . poemReceived ( s ) <EOL> def poemReceived ( self , poem ) : <EOL> self . factory . handlePoem ( poem ) <EOL> class TransformClientFactory ( ClientFactory ) : <EOL> protocol = TransformClientProtocol <EOL> def __init__ ( self , xform_name , poem ) : <EOL> self . xform_name = xform_name <EOL> self . poem = poem <EOL> self . deferred = defer . Deferred ( ) <EOL> def handlePoem ( self , poem ) : <EOL> d , self . deferred = self . deferred , None <EOL> d . callback ( poem ) <EOL> def clientConnectionLost ( self , _ , reason ) : <EOL> if self . deferred is not None : <EOL> d , self . deferred = self . deferred , None <EOL> d . errback ( reason ) <EOL> clientConnectionFailed = clientConnectionLost <EOL> class TransformProxy ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , host , port ) : <EOL> self . host = host <EOL> self . port = port <EOL> def xform ( self , xform_name , poem ) : <EOL> factory = TransformClientFactory ( xform_name , poem ) <EOL> from twisted . internet import reactor <EOL> reactor . connectTCP ( self . host , self . port , factory ) <EOL> return factory . deferred <EOL> def get_poetry ( host , port ) : <EOL> """<STR_LIT>""" <EOL> d = defer . Deferred ( ) <EOL> from twisted . internet import reactor <EOL> factory = PoetryClientFactory ( d ) <EOL> reactor . connectTCP ( host , port , factory ) <EOL> return d <EOL> def poetry_main ( ) : <EOL> addresses = parse_args ( ) <EOL> xform_addr = addresses . pop ( <NUM_LIT:0> ) <EOL> proxy = TransformProxy ( * xform_addr ) <EOL> from twisted . internet import reactor <EOL> results = [ ] <EOL> @ defer . inlineCallbacks <EOL> def get_transformed_poem ( host , port ) : <EOL> try : <EOL> poem = yield get_poetry ( host , port ) <EOL> except Exception , e : <EOL> print >> sys . stderr , '<STR_LIT>' , e <EOL> raise <EOL> try : <EOL> poem = yield proxy . xform ( '<STR_LIT>' , poem ) <EOL> except Exception : <EOL> print >> sys . stderr , '<STR_LIT>' <EOL> defer . returnValue ( poem ) <EOL> def got_poem ( poem ) : <EOL> print poem <EOL> def poem_done ( _ ) : <EOL> results . append ( _ ) <EOL> if len ( results ) == len ( addresses ) : <EOL> reactor . stop ( ) <EOL> for address in addresses : <EOL> host , port = address <EOL> d = get_transformed_poem ( host , port ) <EOL> d . addCallbacks ( got_poem ) <EOL> d . addBoth ( poem_done ) <EOL> reactor . run ( ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> poetry_main ( ) </s>
