<s> """<STR_LIT>""" <EOL> import argparse <EOL> import collections <EOL> import json <EOL> import logging <EOL> import SimpleHTTPServer <EOL> import SocketServer <EOL> import sys <EOL> import threading <EOL> import time <EOL> import SimpleWebSocketServer <EOL> HTTP_PORT = <NUM_LIT> <EOL> WEBSOCKET_PORT = <NUM_LIT> <EOL> LOGFMT = '<STR_LIT>' <EOL> class SocketHandler ( SimpleWebSocketServer . WebSocket ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , sockets , server , sock , address ) : <EOL> super ( SocketHandler , self ) . __init__ ( server , sock , address ) <EOL> self . _sockets = sockets <EOL> self . _channels = [ ] <EOL> def handleMessage ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . data is None : <EOL> return <EOL> try : <EOL> logging . info ( '<STR_LIT>' , self . data ) <EOL> data = json . loads ( self . data . decode ( '<STR_LIT:utf-8>' ) ) <EOL> self . _channels . append ( data [ '<STR_LIT>' ] ) <EOL> self . _sockets [ data [ '<STR_LIT>' ] ] . append ( self ) <EOL> except : <EOL> logging . error ( '<STR_LIT>' , exc_info = sys . exc_info ( ) ) <EOL> def handleConnected ( self ) : <EOL> logging . info ( '<STR_LIT>' , self . address ) <EOL> def handleClose ( self ) : <EOL> logging . info ( '<STR_LIT>' , self . address , exc_info = sys . exc_info ( ) ) <EOL> for channel in self . _channels : <EOL> self . _sockets [ channel ] . remove ( self ) <EOL> class ServerHandler ( SimpleHTTPServer . SimpleHTTPRequestHandler ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , sockets , request , client_address , server ) : <EOL> self . _sockets = sockets <EOL> SimpleHTTPServer . SimpleHTTPRequestHandler . __init__ ( <EOL> self , request , client_address , server ) <EOL> def do_POST ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> channel = self . path . split ( '<STR_LIT:/>' ) [ - <NUM_LIT:1> ] <EOL> content_len = int ( self . headers . getheader ( '<STR_LIT>' , <NUM_LIT:0> ) ) <EOL> post_body = self . rfile . read ( content_len ) <EOL> for socket in self . _sockets [ channel ] : <EOL> socket . sendMessage ( post_body ) <EOL> self . send_response ( <NUM_LIT> , '<STR_LIT>' ) <EOL> except : <EOL> logging . error ( '<STR_LIT>' , exc_info = sys . exc_info ( ) ) <EOL> class SimplePusher ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , args ) : <EOL> self . _args = args <EOL> self . _sockets = collections . defaultdict ( list ) <EOL> self . _httpd = None <EOL> self . _httpd_thread = None <EOL> self . _websocket_server = None <EOL> self . _websocket_server_thread = None <EOL> def _http_request_handler ( self , request , client_address , server ) : <EOL> return ServerHandler ( self . _sockets , request , client_address , server ) <EOL> def _websocket_request_handler ( self , server , sock , addr ) : <EOL> return SocketHandler ( self . _sockets , server , sock , addr ) <EOL> def start ( self ) : <EOL> """<STR_LIT>""" <EOL> logging . info ( '<STR_LIT>' ) <EOL> self . _httpd = SocketServer . TCPServer ( <EOL> ( '<STR_LIT>' , self . _args . http_port ) , self . _http_request_handler ) <EOL> self . _httpd_thread = threading . Thread ( target = self . _httpd . serve_forever ) <EOL> self . _httpd_thread . start ( ) <EOL> self . _websocket_server = SimpleWebSocketServer . SimpleWebSocketServer ( <EOL> '<STR_LIT>' , self . _args . websocket_port , self . _websocket_request_handler ) <EOL> self . _websocket_server_thread = threading . Thread ( <EOL> target = self . _websocket_server . serveforever ) <EOL> self . _websocket_server_thread . start ( ) <EOL> def stop ( self ) : <EOL> """<STR_LIT>""" <EOL> logging . info ( '<STR_LIT>' ) <EOL> self . _httpd . shutdown ( ) <EOL> self . _httpd_thread . join ( ) <EOL> self . _websocket_server . close ( ) <EOL> self . _websocket_server_thread . join ( ) <EOL> def main ( ) : <EOL> logging . basicConfig ( format = LOGFMT , level = logging . DEBUG ) <EOL> parser = argparse . ArgumentParser ( ) <EOL> parser . add_argument ( '<STR_LIT>' , <EOL> default = HTTP_PORT ) <EOL> parser . add_argument ( '<STR_LIT>' , <EOL> default = WEBSOCKET_PORT ) <EOL> args = parser . parse_args ( ) <EOL> pusher = SimplePusher ( args ) <EOL> pusher . start ( ) <EOL> try : <EOL> while True : <EOL> time . sleep ( <NUM_LIT:100> ) <EOL> except : <EOL> pass <EOL> pusher . stop ( ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> main ( ) </s>
