<s> import sys <EOL> from rospkg . environment import get_ros_paths <EOL> from zope . interface import implements <EOL> from twisted . python import log <EOL> from twisted . cred . credentials import UsernamePassword <EOL> from twisted . spread . pb import PBClientFactory , DeadReferenceError , PBConnectionLost <EOL> from autobahn . websocket import listenWS <EOL> from rce . util . converter import Converter <EOL> from rce . util . loader import Loader <EOL> from rce . util . interface import verifyObject <EOL> from rce . comm . error import DeadConnection <EOL> from rce . comm . interfaces import IRobotRealm , IProtocol , IRobot , IMessageReceiver <EOL> from rce . comm . server import CloudEngineWebSocketFactory <EOL> from rce . monitor . interface . robot import PublisherConverter , SubscriberConverter , ServiceClientConverter , ServiceProviderConverter , PublisherForwarder , SubscriberForwarder , ServiceClientForwarder , ServiceProviderForwarder <EOL> from rce . slave . endpoint import Endpoint <EOL> from rce . slave . namespace import Namespace <EOL> from rce . slave . interface import Types <EOL> class ForwardingError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class Connection ( object ) : <EOL> """<STR_LIT>""" <EOL> implements ( IRobot , IMessageReceiver ) <EOL> def __init__ ( self , client , userID , robotID ) : <EOL> """<STR_LIT>""" <EOL> client . registerConnection ( self ) <EOL> self . _client = client <EOL> self . _userID = userID <EOL> self . _robotID = robotID <EOL> self . _avatar = None <EOL> self . _view = None <EOL> self . _namespace = None <EOL> self . _protocol = None <EOL> @ property <EOL> def userID ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _userID <EOL> @ property <EOL> def robotID ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _robotID <EOL> def destroy ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _protocol : <EOL> self . _protocol . dropConnection ( ) <EOL> if self . _client : <EOL> self . _client . unregisterConnection ( self ) <EOL> if self . _view : <EOL> self . _view . destroy ( ) <EOL> if self . _namespace : <EOL> self . _namespace . destroy ( ) <EOL> self . _client = None <EOL> self . _namespace = None <EOL> self . _view = None <EOL> self . _avatar = None <EOL> self . _protocol = None <EOL> def registerAvatar ( self , avatar ) : <EOL> """<STR_LIT>""" <EOL> assert self . _avatar is None <EOL> self . _avatar = avatar <EOL> def registerView ( self , view ) : <EOL> """<STR_LIT>""" <EOL> assert self . _view is None <EOL> self . _view = view <EOL> def registerNamespace ( self , namespace ) : <EOL> """<STR_LIT>""" <EOL> assert self . _namespace is None <EOL> self . _namespace = namespace <EOL> def registerProtocol ( self , protocol ) : <EOL> """<STR_LIT>""" <EOL> assert self . _protocol is None <EOL> verifyObject ( IProtocol , protocol ) <EOL> self . _protocol = protocol <EOL> def unregisterProtocol ( self , protocol ) : <EOL> """<STR_LIT>""" <EOL> self . _protocol = None <EOL> def reportError ( self , msg ) : <EOL> self . _protocol . sendErrorMessage ( msg ) <EOL> reportError . __doc__ = IProtocol . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def sendMessage ( self , iTag , clsName , msgID , msg ) : <EOL> if not self . _protocol : <EOL> return <EOL> self . _protocol . sendDataMessage ( iTag , clsName , msgID , msg ) <EOL> sendMessage . __doc__ = IProtocol . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def sendInterfaceStatusUpdate ( self , iTag , status ) : <EOL> if not self . _protocol : <EOL> return <EOL> self . _protocol . sendInterfaceStatusUpdateMessage ( iTag , status ) <EOL> sendInterfaceStatusUpdate . __doc__ = IProtocol . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def createContainer ( self , tag , data = { } ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . createContainer ( tag , data ) <EOL> createContainer . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def destroyContainer ( self , tag ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . destroyContainer ( tag ) <EOL> destroyContainer . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def addNode ( self , cTag , nTag , pkg , exe , args = '<STR_LIT>' , name = '<STR_LIT>' , namespace = '<STR_LIT>' ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . addNode ( cTag , nTag , pkg , exe , args , name , namespace ) <EOL> addNode . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def removeNode ( self , cTag , nTag ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . removeNode ( cTag , nTag ) <EOL> removeNode . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def addInterface ( self , eTag , iTag , iType , clsName , addr = '<STR_LIT>' ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . addInterface ( eTag , iTag , iType , clsName , addr ) <EOL> addInterface . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def removeInterface ( self , eTag , iTag ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . removeInterface ( eTag , iTag ) <EOL> removeInterface . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def addParameter ( self , cTag , name , value ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . addParameter ( cTag , name , value ) <EOL> addParameter . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def removeParameter ( self , cTag , name ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . removeParameter ( cTag , name ) <EOL> removeParameter . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def addConnection ( self , tagA , tagB ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . addConnection ( tagA , tagB ) <EOL> addConnection . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def removeConnection ( self , tagA , tagB ) : <EOL> if not self . _view : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _view . removeConnection ( tagA , tagB ) <EOL> removeConnection . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def processReceivedMessage ( self , iTag , clsName , msgID , msg ) : <EOL> if not self . _namespace : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> self . _namespace . receivedFromClient ( iTag , clsName , msgID , msg ) <EOL> processReceivedMessage . __doc__ = IMessageReceiver . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> class RobotView ( object ) : <EOL> """<STR_LIT>""" <EOL> implements ( IRobot ) <EOL> def __init__ ( self , view , connection ) : <EOL> """<STR_LIT>""" <EOL> self . _view = view <EOL> self . _connection = connection <EOL> def _reportError ( self , failure ) : <EOL> """<STR_LIT>""" <EOL> self . _connection . reportError ( failure . getErrorMessage ( ) ) <EOL> def createContainer ( self , tag , data = { } ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , tag , data ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> createContainer . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def destroyContainer ( self , tag ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , tag ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> destroyContainer . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def addNode ( self , cTag , nTag , pkg , exe , args = '<STR_LIT>' , name = '<STR_LIT>' , namespace = '<STR_LIT>' ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , cTag , nTag , pkg , exe , args , <EOL> name , namespace ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> addNode . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def removeNode ( self , cTag , nTag ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , cTag , nTag ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> removeNode . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def addInterface ( self , eTag , iTag , iType , clsName , addr = '<STR_LIT>' ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , eTag , iTag , iType , <EOL> clsName , addr ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> addInterface . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def removeInterface ( self , eTag , iTag ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , eTag , iTag ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> removeInterface . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def addParameter ( self , cTag , name , value ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , cTag , name , value ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> addParameter . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def removeParameter ( self , cTag , name ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , cTag , name ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> removeParameter . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def addConnection ( self , tagA , tagB ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , tagA , tagB ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> addConnection . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def removeConnection ( self , tagA , tagB ) : <EOL> try : <EOL> d = self . _view . callRemote ( '<STR_LIT>' , tagA , tagB ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> d . addErrback ( self . _reportError ) <EOL> removeConnection . __doc__ = IRobot . get ( '<STR_LIT>' ) . getDoc ( ) <EOL> def destroy ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _connection = None <EOL> self . _view = None <EOL> class Robot ( Namespace ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , endpoint , connection ) : <EOL> """<STR_LIT>""" <EOL> Namespace . __init__ ( self , endpoint ) <EOL> interface_map = { <EOL> Types . encode ( '<STR_LIT>' ) : PublisherConverter , <EOL> Types . encode ( '<STR_LIT>' ) : SubscriberConverter , <EOL> Types . encode ( '<STR_LIT>' ) : ServiceClientConverter , <EOL> Types . encode ( '<STR_LIT>' ) : ServiceProviderConverter , <EOL> Types . encode ( '<STR_LIT>' ) : PublisherForwarder , <EOL> Types . encode ( '<STR_LIT>' ) : SubscriberForwarder , <EOL> Types . encode ( '<STR_LIT>' ) : ServiceClientForwarder , <EOL> Types . encode ( '<STR_LIT>' ) : ServiceProviderForwarder <EOL> } <EOL> self . _map . update ( interface_map ) <EOL> self . _connection = connection <EOL> @ property <EOL> def converter ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _endpoint . converter <EOL> def receivedFromClient ( self , iTag , clsName , msgID , msg ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> self . _interfaces [ iTag ] . receive ( clsName , msgID , msg ) <EOL> except ( DeadReferenceError , PBConnectionLost ) : <EOL> raise DeadConnection <EOL> def sendToClient ( self , iTag , msgType , msgID , msg ) : <EOL> """<STR_LIT>""" <EOL> if not self . _connection : <EOL> return <EOL> self . _connection . sendMessage ( iTag , msgType , msgID , msg ) <EOL> def sendToClientInterfaceStatusUpdate ( self , iTag , status ) : <EOL> """<STR_LIT>""" <EOL> if not self . _connection : <EOL> return <EOL> self . _connection . sendInterfaceStatusUpdate ( iTag , status ) <EOL> def destroy ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _connection = None <EOL> Namespace . remote_destroy ( self ) <EOL> def remote_destroy ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _connection : <EOL> self . _connection . destroy ( ) <EOL> self . destroy ( ) <EOL> class RobotClient ( Endpoint ) : <EOL> """<STR_LIT>""" <EOL> implements ( IRobotRealm ) <EOL> CONNECT_TIMEOUT = <NUM_LIT:30> <EOL> RECONNECT_TIMEOUT = <NUM_LIT:10> <EOL> def __init__ ( self , reactor , masterIP , masterPort , commPort , extIP , extPort , <EOL> loader , converter ) : <EOL> """<STR_LIT>""" <EOL> Endpoint . __init__ ( self , reactor , loader , commPort ) <EOL> self . _masterIP = masterIP <EOL> self . _masterPort = masterPort <EOL> self . _extAddress = '<STR_LIT>' . format ( extIP , extPort ) <EOL> self . _loader = loader <EOL> self . _converter = converter <EOL> self . _connections = set ( ) <EOL> self . _deathCandidates = { } <EOL> @ property <EOL> def converter ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _converter <EOL> def registerConnection ( self , connection ) : <EOL> assert connection not in self . _connections <EOL> self . _connections . add ( connection ) <EOL> assert connection not in self . _deathCandidates <EOL> deathCall = self . _reactor . callLater ( self . CONNECT_TIMEOUT , <EOL> self . _killConnection , connection ) <EOL> self . _deathCandidates [ connection ] = deathCall <EOL> def unregisterConnection ( self , connection ) : <EOL> assert connection in self . _connections <EOL> deathCall = self . _deathCandidates . pop ( connection , None ) <EOL> if deathCall and deathCall . active ( ) : <EOL> deathCall . cancel ( ) <EOL> self . _connections . remove ( connection ) <EOL> def _killConnection ( self , connection ) : <EOL> """<STR_LIT>""" <EOL> assert connection in self . _connections <EOL> assert connection in self . _deathCandidates <EOL> deathCall = self . _deathCandidates . pop ( connection ) <EOL> if deathCall . active ( ) : <EOL> deathCall . cancel ( ) <EOL> connection . destroy ( ) <EOL> def _cbAuthenticated ( self , avatar , connection ) : <EOL> """<STR_LIT>""" <EOL> connection . registerAvatar ( avatar ) <EOL> return avatar . callRemote ( '<STR_LIT>' , False ) <EOL> def _cbConnected ( self , view , connection ) : <EOL> """<STR_LIT>""" <EOL> if not self . _avatar : <EOL> raise ForwardingError ( '<STR_LIT>' ) <EOL> view = RobotView ( view , connection ) <EOL> namespace = Robot ( self , connection ) <EOL> connection . registerView ( view ) <EOL> connection . registerNamespace ( namespace ) <EOL> return self . _avatar . callRemote ( '<STR_LIT>' , namespace , <EOL> connection . userID , connection . robotID ) <EOL> def login ( self , userID , robotID , password ) : <EOL> """<STR_LIT>""" <EOL> conn = Connection ( self , userID , robotID ) <EOL> factory = PBClientFactory ( ) <EOL> self . _reactor . connectTCP ( self . _masterIP , self . _masterPort , factory ) <EOL> d = factory . login ( UsernamePassword ( userID , password ) ) <EOL> d . addCallback ( self . _cbAuthenticated , conn ) <EOL> d . addCallback ( self . _cbConnected , conn ) <EOL> d . addCallback ( lambda _ : conn ) <EOL> return d <EOL> def registerWebsocketProtocol ( self , connection , protocol ) : <EOL> """<STR_LIT>""" <EOL> assert connection in self . _deathCandidates <EOL> connection . registerProtocol ( protocol ) <EOL> self . _deathCandidates . pop ( connection ) . cancel ( ) <EOL> def unregisterWebsocketProtocol ( self , connection , protocol ) : <EOL> """<STR_LIT>""" <EOL> assert connection not in self . _deathCandidates <EOL> deathCall = self . _reactor . callLater ( self . RECONNECT_TIMEOUT , <EOL> self . _killConnection , connection ) <EOL> self . _deathCandidates [ connection ] = deathCall <EOL> connection . unregisterProtocol ( protocol ) <EOL> def remote_getWebsocketAddress ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _extAddress <EOL> def terminate ( self ) : <EOL> """<STR_LIT>""" <EOL> for call in self . _deathCandidates . itervalues ( ) : <EOL> call . cancel ( ) <EOL> self . _deathCandidates = { } <EOL> for connection in self . _connections . copy ( ) : <EOL> connection . destroy ( ) <EOL> assert len ( self . _connections ) == <NUM_LIT:0> <EOL> Endpoint . terminate ( self ) <EOL> def main ( reactor , cred , masterIP , masterPort , consolePort , <EOL> extIP , extPort , commPort , pkgPath , customConverters ) : <EOL> log . startLogging ( sys . stdout ) <EOL> def _err ( reason ) : <EOL> print ( reason ) <EOL> reactor . stop ( ) <EOL> factory = PBClientFactory ( ) <EOL> reactor . connectTCP ( masterIP , masterPort , factory ) <EOL> rosPath = [ ] <EOL> for path in get_ros_paths ( ) + [ p for p , _ in pkgPath ] : <EOL> if path not in rosPath : <EOL> rosPath . append ( path ) <EOL> loader = Loader ( rosPath ) <EOL> converter = Converter ( loader ) <EOL> for customConverter in customConverters : <EOL> module , className = customConverter . rsplit ( '<STR_LIT:.>' , <NUM_LIT:1> ) <EOL> mod = __import__ ( module , fromlist = [ className ] ) <EOL> converter . addCustomConverter ( getattr ( mod , className ) ) <EOL> client = RobotClient ( reactor , masterIP , consolePort , commPort , extIP , <EOL> extPort , loader , converter ) <EOL> d = factory . login ( cred , client ) <EOL> d . addCallback ( lambda ref : setattr ( client , '<STR_LIT>' , ref ) ) <EOL> d . addErrback ( _err ) <EOL> robot = CloudEngineWebSocketFactory ( client , <EOL> '<STR_LIT>' . format ( extPort ) ) <EOL> listenWS ( robot ) <EOL> reactor . addSystemEventTrigger ( '<STR_LIT>' , '<STR_LIT>' , client . terminate ) <EOL> reactor . run ( ) </s>
