<s> import sys <EOL> import argparse <EOL> import subprocess <EOL> import requests <EOL> import threading <EOL> import webob <EOL> import logging <EOL> from simplejson import loads , dumps <EOL> from webob import Request , Response , exc <EOL> class LookupService : <EOL> def __init__ ( self , url ) : <EOL> self . url = url <EOL> def announce_presence ( self , myid , url ) : <EOL> print ( "<STR_LIT>" % ( myid , url , self . url ) ) <EOL> data = { "<STR_LIT:key>" : "<STR_LIT>" , <EOL> "<STR_LIT:message>" : dumps ( { "<STR_LIT:url>" : url } ) , <EOL> "<STR_LIT>" : "<STR_LIT>" } <EOL> r = requests . post ( self . url + "<STR_LIT:/>" + myid , <EOL> data = dumps ( data ) , <EOL> headers = { "<STR_LIT>" : "<STR_LIT:application/json>" } ) <EOL> assert r . status_code == <NUM_LIT:200> <EOL> def get_other_address ( self , id ) : <EOL> r = requests . get ( self . url + "<STR_LIT:/>" + id ) <EOL> assert r . status_code == <NUM_LIT:200> <EOL> result = r . json ( ) [ "<STR_LIT:result>" ] <EOL> addresses = loads ( result [ "<STR_LIT:message>" ] ) <EOL> return addresses [ "<STR_LIT:url>" ] <EOL> def main ( args = None ) : <EOL> from wsgiref import simple_server <EOL> parser = argparse . ArgumentParser ( ) <EOL> parser . add_argument ( <EOL> '<STR_LIT>' , default = '<STR_LIT>' , <EOL> help = '<STR_LIT>' ) <EOL> parser . add_argument ( <EOL> '<STR_LIT>' , '<STR_LIT>' , default = <NUM_LIT> , type = int , <EOL> help = '<STR_LIT>' ) <EOL> parser . add_argument ( "<STR_LIT>" , help = "<STR_LIT>" ) <EOL> parser . add_argument ( "<STR_LIT>" , help = "<STR_LIT>" , default = None , nargs = "<STR_LIT:?>" ) <EOL> if args is None : <EOL> args = sys . argv [ <NUM_LIT:1> : ] <EOL> args = parser . parse_args ( ) <EOL> my_hostname = subprocess . check_output ( "<STR_LIT>" ) . strip ( ) <EOL> if not my_hostname . endswith ( "<STR_LIT>" ) : <EOL> my_hostname += "<STR_LIT>" <EOL> my_url = "<STR_LIT>" % ( my_hostname , args . port ) <EOL> lookup = LookupService ( args . lookup ) <EOL> uithread = InputThread ( args . myid , lookup ) <EOL> uithread . setDaemon ( True ) <EOL> if args . otherid is not None : <EOL> uithread . add_id ( args . otherid ) <EOL> uithread . start ( ) <EOL> app = ReceiveApp ( uithread ) <EOL> server = simple_server . make_server ( my_hostname , args . port , app ) <EOL> print ( '<STR_LIT>' % ( my_hostname , args . port ) ) <EOL> lookup . announce_presence ( args . myid , my_url ) <EOL> server . serve_forever ( ) <EOL> class InputThread ( threading . Thread ) : <EOL> def __init__ ( self , myid , lookup ) : <EOL> super ( InputThread , self ) . __init__ ( ) <EOL> self . myid = myid <EOL> self . lookup = lookup <EOL> self . id2address = { } <EOL> def add_id ( self , otherid ) : <EOL> if otherid not in self . id2address : <EOL> logging . info ( "<STR_LIT>" % otherid ) <EOL> address = self . lookup . get_other_address ( otherid ) <EOL> if not address : <EOL> logging . warn ( "<STR_LIT>" % args . otherid ) <EOL> else : <EOL> self . id2address [ otherid ] = address <EOL> def run ( self ) : <EOL> while <NUM_LIT:1> : <EOL> line = raw_input ( ) <EOL> if line : <EOL> self . send_line ( line ) <EOL> def send_line ( self , line ) : <EOL> if not self . id2address : <EOL> logging . info ( "<STR_LIT>" ) <EOL> return <EOL> for otherid , address in self . id2address . copy ( ) . items ( ) : <EOL> data = { "<STR_LIT>" : self . myid , "<STR_LIT>" : line } <EOL> r = requests . post ( address , dumps ( data ) , <EOL> headers = { "<STR_LIT>" : "<STR_LIT:application/json>" } ) <EOL> if r . status_code != <NUM_LIT:200> : <EOL> logging . error ( "<STR_LIT>" % ( r . status_code , address ) ) <EOL> del self . id2address [ otherid ] <EOL> class ReceiveApp ( object ) : <EOL> def __init__ ( self , uithread ) : <EOL> self . uithread = uithread <EOL> def __call__ ( self , environ , start_response ) : <EOL> req = Request ( environ ) <EOL> try : <EOL> meth = getattr ( self , req . method , None ) <EOL> if meth is None : <EOL> raise exc . HTTPMethodNotAllowed ( <EOL> "<STR_LIT>" % req . method ) <EOL> resp = meth ( req ) <EOL> except ValueError , e : <EOL> resp = exc . HTTPBadRequest ( str ( e ) ) <EOL> except exc . HTTPException , e : <EOL> resp = e <EOL> return resp ( environ , start_response ) <EOL> def POST ( self , req ) : <EOL> json = loads ( req . body ) <EOL> myid = json [ "<STR_LIT>" ] <EOL> line = json [ "<STR_LIT>" ] <EOL> self . uithread . add_id ( myid ) <EOL> print "<STR_LIT>" % ( myid , line ) <EOL> return Response ( status = <NUM_LIT:200> ) </s>
