Пример #1
0
    def onNegotiateSession(self, accepted, username, host, port):
        """
        Callback method for incoming requests to start a peer-to-peer session.
        The username, host, and port of the requesting peer is provided as input.

        The value for 'accepted' is provided via a roundabout sequence of callback methods
        which poll for user input.
        """
        logger.debug('onNegotiateCallback(accepted=%s, username=%s, host=%s, port=%d)' % (accepted, username, host, port))
        if (not self.onNegotiateCallback == None) and (accepted == None) and (self.retryNegotiate == False):
            # we need user input on whether to accept, so we use chained callbacks to get that input
            # and end up back here with what we need
            deferredTrueNegotiate = defer.Deferred()
            sessionParams = {
                'username': username,
                'host': host,
                'port': port
            }
            deferredTrueNegotiate.addCallback(self.onNegotiateSession, **sessionParams)
            self.onNegotiateCallback(deferredTrueNegotiate, username)
        if (accepted == True) or ((accepted == None) and self.retryNegotiate):
            # we havent rejected OR we are trying with a new IP address
            status_bar.status_message('trying to share with %s' % username)
            logger.info('Establishing session with %s at %s:%d' % (username, host, port))
            logger.debug('accepted: %s, retryNegotiate: %s' % (accepted, self.retryNegotiate))
            session = base.BasePeer(username, self.sendPeerFailedToConnect)
            session.clientConnect(host, port)
            self.negotiateCallback(session)
        elif accepted == False:
            status_bar.status_message('share with %s rejected!' % username)
            logger.info('Rejected session with %s at %s:%d' % (username, host, port))
            self.msg(username, 'REJECTED')
Пример #2
0
 def acceptSessionRequest(self, username, host, port):
     self.logger.debug('accepted session request from %s at %s:%d)' % (username, host, port))
     status_bar.status_message('accepted session request from %s, trying to connect to %s:%d' % (username, host, port))
     self.logger.info('Establishing session with %s at %s:%d' % (username, host, port))
     session = basic.BasicPeer(username, self)
     session.clientConnect(host, port)
     registry.registerSession(session)
Пример #3
0
 def clientConnectionLost(self, connector, reason):
     if error.ConnectionDone == reason.type:
         self.disconnect()
     else:
         # may want to reconnect, but for now lets print why
         logger.error('Connection lost: %s - %s' % (reason.type, reason.value))
         status_bar.status_message('connection lost to %s' % self.str())
Пример #4
0
    def connect(self, host, port, username, password, **kwargs):
        """
        Connect to an instant messaging server.

        @param host: ip address or domain name of the host server
        @param port: C{int} port number of the host
        @param username: C{str} IM account username
        @param password: C{str} IM account password
        @param kwargs: {'channel': 'channelNameStringWoutPrefix'}

        @return: True on success
        """
        assert kwargs.has_key('channel')

        if self.isConnected():
            return

        # start a fresh connection
        if self.clientConnection:
            self.clientConnection.disconnect()

        # irc.IRCClient member setting
        self.nickname = username.encode()

        self.host = host.encode()
        self.port = port
        self.password = password.encode()
        self.channel = kwargs['channel'].encode()

        status_bar.status_message('connecting to %s' % self.str())
        self.clientConnection = reactor.connectTCP(self.host, self.port, self)
Пример #5
0
    def onNegotiateSession(self, accepted, username, host, port):
        """
        Callback method for incoming requests to start a peer-to-peer session.
        The username, host, and port of the requesting peer is provided as input.

        The value for 'accepted' is provided via a roundabout sequence of callback methods
        which poll for user input.
        """
        logger.debug(
            'onNegotiateCallback(accepted=%s, username=%s, host=%s, port=%d)' %
            (accepted, username, host, port))
        if (not self.onNegotiateCallback == None) and (accepted == None) and (
                self.retryNegotiate == False):
            # we need user input on whether to accept, so we use chained callbacks to get that input
            # and end up back here with what we need
            deferredTrueNegotiate = defer.Deferred()
            sessionParams = {'username': username, 'host': host, 'port': port}
            deferredTrueNegotiate.addCallback(self.onNegotiateSession,
                                              **sessionParams)
            self.onNegotiateCallback(deferredTrueNegotiate, username)
        if (accepted == True) or ((accepted == None) and self.retryNegotiate):
            # we havent rejected OR we are trying with a new IP address
            status_bar.status_message('trying to share with %s' % username)
            logger.info('Establishing session with %s at %s:%d' %
                        (username, host, port))
            logger.debug('accepted: %s, retryNegotiate: %s' %
                         (accepted, self.retryNegotiate))
            session = base.BasePeer(username, self.sendPeerFailedToConnect)
            session.clientConnect(host, port)
            self.negotiateCallback(session)
        elif accepted == False:
            status_bar.status_message('share with %s rejected!' % username)
            logger.info('Rejected session with %s at %s:%d' %
                        (username, host, port))
            self.msg(username, 'REJECTED')
Пример #6
0
    def connect(self, host, port, username, password, **kwargs):
        """
        Connect to an instant messaging server.

        @param host: ip address or domain name of the host server
        @param port: C{int} port number of the host
        @param username: C{str} IM account username
        @param password: C{str} IM account password
        @param kwargs: {'channel': 'channelNameStringWoutPrefix'}

        @return: True on success
        """
        assert kwargs.has_key('channel')

        if self.isConnected():
            return

        # start a fresh connection
        if self.clientConnection:
            self.clientConnection.disconnect()

        # irc.IRCClient member setting
        self.nickname = username.encode()

        self.host = host.encode()
        self.port = port
        self.password = password.encode()
        self.channel = kwargs['channel'].encode()

        status_bar.status_message('connecting to %s' % self.str())
        # self.clientConnection = reactor.connectTCP(self.host, self.port, self)
        self.clientConnection = reactor.connectSSL(self.host, self.port, self, ssl.ClientContextFactory())
Пример #7
0
    def negotiateSession(self, username):
        """
        Negotiate through the instant messaging layer a direct peer-to-peer connection
        with the user that has the given username.  Note the username in question must
        represent another SubliminalCollaborator Negotiator instance used by another
        user.

        If the user identified by the given username is not in the C{Array} returned
        by listUsers(), the expectation is that successful execution of this function
        will result in the given username being added to the list of known users.
        """
        if (not username in self.peerUsers) and (not username
                                                 in self.unverifiedUsers):
            self.addUserToLists(username)
        if self.hostAddressToTryQueue == None or len(
                self.hostAddressToTryQueue) == 0:
            self.hostAddressToTryQueue = socket.gethostbyname_ex(
                socket.gethostname())[2]
        ipaddress = self.hostAddressToTryQueue.pop()
        session = basic.BasicPeer(username, self)
        port = session.hostConnect()
        self.logger.debug('attempting to start session with %s at %s:%d' %
                          (username, ipaddress, port))
        status_bar.status_message('trying to share with %s@%s' %
                                  (username, ipaddress))
        self.pendingSession = session
        registry.registerSession(session)
        self.ctcpMakeQuery(
            username, [('DCC CHAT', '%s %s %d' %
                        (base.DCC_PROTOCOL_COLLABORATE, ipaddress, port))])
Пример #8
0
    def negotiateSession(self, username, tryNext=False):
        """
        Negotiate through the instant messaging layer a direct peer-to-peer connection
        with the user that has the given username.  Note the username in question must
        represent another SubliminalCollaborator Negotiator instance used by another
        user.

        If the user identified by the given username is not in the C{Array} returned
        by listUsers(), the expectation is that successful execution of this function
        will result in the given username being added to the list of known users.
        """
        if (not username in self.peerUsers) and (not username in self.unverifiedUsers):
            self.addUserToLists(username)
        if not tryNext:
            self.hostAddressToTryQueue = socket.gethostbyname_ex(socket.gethostname())[2]
        if len(self.hostAddressToTryQueue) == 0:
            status_bar.status_message('failed to share with %s' % username)
            logger.warn('Unable to connect to peer %s, all host addresses tried and failed!' % username)
            # TODO error reporting in UI
            self.msg(username, 'NO-GOOD-HOST-IP')
            return
        ipaddress = self.hostAddressToTryQueue.pop()
        session = base.BasePeer(username)
        port = session.hostConnect()
        status_bar.status_message('trying to share with %s@%s' % (username, ipaddress))
        logger.debug('Negotiating collab session with %s with ip address %s on port %d' % (username, ipaddress, port))
        reactor.callFromThread(self.ctcpMakeQuery, username, [('DCC CHAT', 'collaborate %s %d' % (ipaddress, port))])
        self.negotiateCallback(session)
Пример #9
0
 def stopCollab(self):
     """
     Notify the connected peer that we are terminating the collaborating session.
     """
     if (self.peerType == interface.CLIENT) and (self.view != None):
         self.view.set_read_only(False)
         self.view = None
     status_bar.status_message('stopped sharing with %s' % self.str())
Пример #10
0
 def stopCollab(self):
     """
     Notify the connected peer that we are terminating the collaborating session.
     """
     if (self.peerType == interface.CLIENT) and (self.view != None):
         self.view.set_read_only(False)
         self.view = None
     status_bar.status_message('stopped sharing with %s' % self.str())
Пример #11
0
 def clientConnectionLost(self, connector, reason):
     self.state = interface.STATE_DISCONNECTED
     if error.ConnectionDone == reason.type:
         self.disconnect()
     else:
         status_bar.status_message('lost share session with %s' % self.str())
         # may want to reconnect, but for now lets print why
         logger.error('Connection lost: %s - %s' % (reason.type, reason.value))
Пример #12
0
 def clientConnectionLost(self, connector, reason):
     if error.ConnectionDone == reason.type:
         self.disconnect()
     else:
         # may want to reconnect, but for now lets print why
         self.logger.error('Connection lost: %s - %s' %
                           (reason.type, reason.value))
         status_bar.status_message('connection lost to %s' % self.str())
Пример #13
0
 def __init__(self):
     sublime_plugin.ApplicationCommand.__init__(self)
     irc.IRCNegotiator.negotiateCallback = self.openSession
     irc.IRCNegotiator.onNegotiateCallback = self.acceptSessionRequest
     irc.IRCNegotiator.rejectedOrFailedCallback = self.killHostedSession
     base.BasePeer.peerConnectedCallback = self.shareView
     base.BasePeer.peerRecvdViewCallback = self.addSharedView
     base.BasePeer.acceptSwapRole = self.acceptSwapRole
     status_bar.status_message('ready')
Пример #14
0
 def clientConnectionLost(self, connector, reason):
     registry.removeSession(self)
     self.state = base.STATE_DISCONNECTED
     if error.ConnectionDone == reason.type:
         self.disconnect()
     else:
         status_bar.status_message('lost share session with %s' % self.str())
         # may want to reconnect, but for now lets print why
         self.logger.error('Connection lost: %s - %s' % (reason.type, reason.value))
Пример #15
0
 def __init__(self):
     sublime_plugin.ApplicationCommand.__init__(self)
     irc.IRCNegotiator.negotiateCallback = self.openSession
     irc.IRCNegotiator.onNegotiateCallback = self.acceptSessionRequest
     irc.IRCNegotiator.rejectedOrFailedCallback = self.killHostedSession
     base.BasePeer.peerConnectedCallback = self.shareView
     base.BasePeer.peerRecvdViewCallback = self.addSharedView
     base.BasePeer.acceptSwapRole = self.acceptSwapRole
     status_bar.status_message('ready')
Пример #16
0
def connectAllChat():
    logger.info('Connecting to all configured chat servers')
    chatClientKeys = chatClientConfig.keys()
    for connectedClient in negotiatorInstances.keys():
        chatClientKeys.remove(connectedClient)
    for client in chatClientKeys:
        logger.info('Connecting to chat %s' % client)
        negotiatorInstances[client] = negotiatorFactoryMap[client.split('|', 1)[0]]()
        negotiatorInstances[client].connect(**chatClientConfig[client])
        status_bar.status_message('connected clients: %d' % len(negotiatorInstances))
Пример #17
0
 def acceptSessionRequest(self, username, host, port):
     self.logger.debug('accepted session request from %s at %s:%d)' %
                       (username, host, port))
     status_bar.status_message(
         'accepted session request from %s, trying to connect to %s:%d' %
         (username, host, port))
     self.logger.info('Establishing session with %s at %s:%d' %
                      (username, host, port))
     session = basic.BasicPeer(username, self)
     session.clientConnect(host, port)
     registry.registerSession(session)
Пример #18
0
 def onDisconnect(self):
     """
     Callback method if we are disconnected.
     """
     if self.peerType == base.CLIENT:
         self.logger.debug('Disconnecting from peer at %s:%d' % (self.host, self.port))
     else:
         self.logger.debug('Disconnecting from peer at %d' % self.port)
     self.disconnect()
     self.state = base.STATE_DISCONNECTED
     self.logger.info('Disconnected from peer %s' % self.sharingWithUser)
     status_bar.status_message('Stopped sharing with %s' % self.sharingWithUser)
Пример #19
0
def connectAllChat():
    logger.info('Connecting to all configured chat servers')
    chatClientKeys = chatClientConfig.keys()
    for connectedClient in negotiatorInstances.keys():
        chatClientKeys.remove(connectedClient)
    for client in chatClientKeys:
        logger.info('Connecting to chat %s' % client)
        negotiatorInstances[client] = negotiatorFactoryMap[client.split(
            '|', 1)[0]]()
        negotiatorInstances[client].connect(**chatClientConfig[client])
        status_bar.status_message('connected clients: %d' %
                                  len(negotiatorInstances))
Пример #20
0
 def onDisconnect(self):
     """
     Callback method if we are disconnected.
     """
     if self.peerType == interface.CLIENT:
         logger.debug('Disconnecting from peer at %s:%d' % (self.host, self.port))
     else:
         logger.debug('Disconnecting from peer at %d' % self.port)
     self.disconnect()
     self.state = interface.STATE_DISCONNECTED
     logger.info('Disconnected from peer %s' % self.sharingWithUser)
     status_bar.status_message('Stopped sharing with %s' % self.sharingWithUser)
Пример #21
0
 def disconnect(self):
     """
     Disconnect from the instant messaging server.
     """
     if self.clientConnection:
         if self.clientConnection.state == 'disconnected':
             return
         reactor.callFromThread(self.clientConnection.disconnect)
         logger.info('Disconnected from %s' % self.host)
         status_bar.status_message('disconnected from %s' % self.str())
     self._registered = False
     self.peerUsers = None
     self.unverifiedUsers = None
Пример #22
0
 def disconnect(self):
     """
     Disconnect from the instant messaging server.
     """
     if self.clientConnection:
         if self.clientConnection.state == 'disconnected':
             return
         reactor.callFromThread(self.clientConnection.disconnect)
         logger.info('Disconnected from %s' % self.host)
         status_bar.status_message('disconnected from %s' % self.str())
     self._registered = False
     self.peerUsers = None
     self.unverifiedUsers = None
Пример #23
0
 def resyncCollab(self):
     """
     Resync the shared editor contents between the host and the partner.
     """
     status_bar.status_message('RESYNCING VIEW CONTENT WITH PEER')
     self.view.set_read_only(True)
     totalToSend = self.view.size()
     begin = 0
     end = MAX_CHUNK_SIZE
     # now we make sure we are connected... better way to do this?
     while not self.state == interface.STATE_CONNECTED:
         time.sleep(1.0)
         if (self.state == interface.STATE_DISCONNECTING) or (
                 self.state == interface.STATE_DISCONNECTED):
             logger.error(
                 'While waiting to resync view over a connection the peer was disconnected!'
             )
             self.disconnect()
             return
     view_name = self.view.file_name()
     if not view_name:
         view_name = self.view.name()
     logger.info('Resyncing view %s with %s' %
                 (view_name, self.sharingWithUser))
     self.toAck = []
     self.sendMessage(interface.RESHARE_VIEW, payload=str(totalToSend))
     while begin < totalToSend:
         chunkToSend = self.view.substr(sublime.Region(begin, end))
         self.toAck.append(len(chunkToSend))
         self.sendMessage(interface.VIEW_CHUNK, payload=chunkToSend)
         begin = begin + MAX_CHUNK_SIZE
         end = end + MAX_CHUNK_SIZE
         status_bar.progress_message(
             "sending view to %s" % self.sharingWithUser, begin,
             totalToSend)
     self.sendMessage(interface.END_OF_VIEW,
                      payload=self.view.settings().get('syntax'))
     self.view.set_read_only(False)
     # send view position as it stands now so the partner view is positioned appropriately post-resync
     viewRegionLines = self.view.split_by_newlines(
         self.view.visible_region())
     lineIdx = len(viewRegionLines) / 2 - 1
     if lineIdx < 0:
         lineIdx = 0
     viewCenterRegion = viewRegionLines[lineIdx]
     self.sendViewPositionUpdate(viewCenterRegion)
     # start the view monitoring thread if not already running
     if not self.viewMonitorThread.is_alive():
         self.viewMonitorThread.start()
Пример #24
0
    def connect(self):
        """
        Connect to an instant messaging server.

        @return: True on success
        """
        if self.isConnected():
            return

        # start a fresh connection
        if self.clientConnection:
            self.clientConnection.disconnect()

        status_bar.status_message('connecting to %s' % self.str())
        if self.useSSL:
            self.logger.info('connecting to %s with ssl' % self.str())
            self.clientConnection = reactor.connectSSL(self.host, self.port, self, ssl.ClientContextFactory())
        else:
            self.logger.info('connecting to %s' % self.str())
            self.clientConnection = reactor.connectTCP(self.host, self.port, self)
Пример #25
0
 def resyncCollab(self):
     """
     Resync the shared editor contents between the host and the partner.
     """
     status_bar.status_message('RESYNCING VIEW CONTENT WITH PEER')
     self.view.set_read_only(True)
     totalToSend = self.view.size()
     begin = 0
     end = MAX_CHUNK_SIZE
     # now we make sure we are connected... better way to do this?
     while not self.state == interface.STATE_CONNECTED:
         time.sleep(1.0)
         if (self.state == interface.STATE_DISCONNECTING) or (self.state == interface.STATE_DISCONNECTED):
             logger.error('While waiting to resync view over a connection the peer was disconnected!')
             self.disconnect()
             return
     view_name = self.view.file_name()
     if not view_name:
         view_name = self.view.name()
     logger.info('Resyncing view %s with %s' % (view_name, self.sharingWithUser))
     self.toAck = []
     self.sendMessage(interface.RESHARE_VIEW, payload=str(totalToSend))
     while begin < totalToSend:
         chunkToSend = self.view.substr(sublime.Region(begin, end))
         self.toAck.append(len(chunkToSend))
         self.sendMessage(interface.VIEW_CHUNK, payload=chunkToSend)
         begin = begin + MAX_CHUNK_SIZE
         end = end + MAX_CHUNK_SIZE
         status_bar.progress_message("sending view to %s" % self.sharingWithUser, begin, totalToSend)
     self.sendMessage(interface.END_OF_VIEW, payload=self.view.settings().get('syntax'))
     self.view.set_read_only(False)
     # send view position as it stands now so the partner view is positioned appropriately post-resync
     viewRegionLines = self.view.split_by_newlines(self.view.visible_region())
     lineIdx = len(viewRegionLines) / 2 - 1
     if lineIdx < 0:
         lineIdx = 0
     viewCenterRegion = viewRegionLines[lineIdx]
     self.sendViewPositionUpdate(viewCenterRegion)
     # start the view monitoring thread if not already running
     if not self.viewMonitorThread.is_alive():
         self.viewMonitorThread.start()
Пример #26
0
    def connect(self):
        """
        Connect to an instant messaging server.

        @return: True on success
        """
        if self.isConnected():
            return

        # start a fresh connection
        if self.clientConnection:
            self.clientConnection.disconnect()

        status_bar.status_message('connecting to %s' % self.str())
        if self.useSSL:
            self.logger.info('connecting to %s with ssl' % self.str())
            self.clientConnection = reactor.connectSSL(
                self.host, self.port, self, ssl.ClientContextFactory())
        else:
            self.logger.info('connecting to %s' % self.str())
            self.clientConnection = reactor.connectTCP(self.host, self.port,
                                                       self)
Пример #27
0
    def negotiateSession(self, username):
        """
        Negotiate through the instant messaging layer a direct peer-to-peer connection
        with the user that has the given username.  Note the username in question must
        represent another SubliminalCollaborator Negotiator instance used by another
        user.

        If the user identified by the given username is not in the C{Array} returned
        by listUsers(), the expectation is that successful execution of this function
        will result in the given username being added to the list of known users.
        """
        if (not username in self.peerUsers) and (not username in self.unverifiedUsers):
            self.addUserToLists(username)
        if self.hostAddressToTryQueue == None or len(self.hostAddressToTryQueue) == 0:
            self.hostAddressToTryQueue = socket.gethostbyname_ex(socket.gethostname())[2]
        ipaddress = self.hostAddressToTryQueue.pop()
        session = basic.BasicPeer(username, self)
        port = session.hostConnect()
        self.logger.debug('attempting to start session with %s at %s:%d' % (username, ipaddress, port))
        status_bar.status_message('trying to share with %s@%s' % (username, ipaddress))
        self.pendingSession = session
        registry.registerSession(session)
        self.ctcpMakeQuery(username, [('DCC CHAT', '%s %s %d' % (base.DCC_PROTOCOL_COLLABORATE, ipaddress, port))])
Пример #28
0
    def negotiateSession(self, username, tryNext=False):
        """
        Negotiate through the instant messaging layer a direct peer-to-peer connection
        with the user that has the given username.  Note the username in question must
        represent another SubliminalCollaborator Negotiator instance used by another
        user.

        If the user identified by the given username is not in the C{Array} returned
        by listUsers(), the expectation is that successful execution of this function
        will result in the given username being added to the list of known users.
        """
        if (not username in self.peerUsers) and (not username
                                                 in self.unverifiedUsers):
            self.addUserToLists(username)
        if not tryNext:
            self.hostAddressToTryQueue = socket.gethostbyname_ex(
                socket.gethostname())[2]
        if len(self.hostAddressToTryQueue) == 0:
            status_bar.status_message('failed to share with %s' % username)
            logger.warn(
                'Unable to connect to peer %s, all host addresses tried and failed!'
                % username)
            # TODO error reporting in UI
            self.msg(username, 'NO-GOOD-HOST-IP')
            return
        ipaddress = self.hostAddressToTryQueue.pop()
        session = base.BasePeer(username)
        port = session.hostConnect()
        status_bar.status_message('trying to share with %s@%s' %
                                  (username, ipaddress))
        logger.debug(
            'Negotiating collab session with %s with ip address %s on port %d'
            % (username, ipaddress, port))
        reactor.callFromThread(self.ctcpMakeQuery, username,
                               [('DCC CHAT', 'collaborate %s %d' %
                                 (ipaddress, port))])
        self.negotiateCallback(session)
Пример #29
0
 def clientConnectionFailed(self, connector, reason):
     self.logger.error('Connection failed: %s - %s' %
                       (reason.type, reason.value))
     status_bar.status_message('connection failed to %s' % self.str())
     self.connectionFailed = True
     self.disconnect()
Пример #30
0
 def __init__(self):
     sublime_plugin.ApplicationCommand.__init__(self)
     sublime_plugin.EventListener.__init__(self)
     status_bar.status_message('ready')
Пример #31
0
 def __init__(self):
     sublime_plugin.ApplicationCommand.__init__(self)
     sublime_plugin.EventListener.__init__(self)
     status_bar.status_message('ready')
Пример #32
0
 def signedOn(self):
     # join the channel after we have connected
     # part of the Negotiator connection process
     status_bar.status_message('connected to %s' % self.str())
     self.join(self.channel)
Пример #33
0
 def clientConnectionFailed(self, connector, reason):
     logger.error('Connection failed: %s - %s' % (reason.type, reason.value))
     status_bar.status_message('connection failed to %s' % self.str())
     self.connectionFailed = True
     self.disconnect()
Пример #34
0
 def signedOn(self):
     # join the channel after we have connected
     # part of the Negotiator connection process
     status_bar.status_message('connected to %s' % self.str())
     self.join(self.channel)
Пример #35
0
 def signedOn(self):
     # join the channel after we have connected
     # part of the Negotiator connection process
     status_bar.status_message('connected to ' + self.str())
     self.logger.info('Joining channel ' + self.channel)
     self.join(self.channel)
Пример #36
0
 def signedOn(self):
     # join the channel after we have connected
     # part of the Negotiator connection process
     status_bar.status_message('connected to ' + self.str())
     self.logger.info('Joining channel ' + self.channel)
     self.join(self.channel)