john pfeiffer
  • Home
  • Categories
  • Tags
  • Archives

xmpp client authenticate discover

import sys
import time
from twisted.words.protocols.jabber import xmlstream, client, jid
from twisted.internet import reactor
from twisted.words.xish import domish
from twisted.internet.defer import Deferred

from twisted.internet.error import ReactorNotRunning

from twisted.internet import stdio


class XMPPClient( object ):

    def __init__( self ):
        self.xmppClientFactory = None
        self.full_jid = None
        self.password = None
        self.session_id = None
        self.reactor = None     # so the client can control it's own reactor.stop()


    def initialize_factory( self ):
        """ initializes the factory with an authenticator, uses xmpp-tls
        """
        self.xmppClientFactory = client.XMPPClientFactory( self.full_jid, self.password )
            # auth = domish.Element((NS_XMPP_SASL, 'auth')) , auth.toXml() -> <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'/>
            # jabber.sasl.sendAuth()


    def connected( self, xml_stream ):
        """ override the xmlstream methods
        """
        print 'Connected.'
        xml_stream.rawDataOutFn = self.rawDataOut
        xml_stream.rawDataInFn = self.rawDataIn


    def rawDataOut( self, buf ):
        print "SEND: %s" % unicode( buf , 'utf-8' ).encode( 'ascii' , 'replace' )


    def rawDataIn( self, buf ):
        print "RECV: %s" % unicode( buf , 'utf-8' ).encode( 'ascii' , 'replace' )


    def disconnected( self, xml_stream ):
        """ called when there's an EndStreamEvent (i.e. other side closed the connection)
        """
        print 'Disconnected.'
    # try:
    #         self.reactor.stop()
    #     except ReactorNotRunning:
    #         pass
    #     # TODO: exit the application (use a Deferred?)


    def authenticated( self, xml_stream ):
        print "Authenticated."

        # presence = domish.Element( (None , 'presence') )    # <presence/>
        # xml_stream.send( presence )
            # RECV: <iq type='result' id='H_1'/>
            # RECV: <presence to='48340_325144@chat.hipchat.com' from='48340_325144@chat.hipchat.com/lenovo'/>


        # deferred = self.send_discovery( self.full_jid.host, xml_stream )
        # deferred.addCallbacks( XMPPClient.deferred_default, XMPPClient.deferred_error )
        # # TODO: extract the items, and continue the discovery process (recursion?)

        # time.sleep( 1 )
        # xml_stream.sendFooter()     # http://xmpp.org/extensions/xep-0198.html#closure , the server sets status unavailable



    @staticmethod
    def deferred_default( result ):
        print "DEFERRED FIRED", type( result )
        print result.toXml()


    @staticmethod
    def deferred_error( failure ):
        print "Deferred error"
        print failure
        # TODO: check if reactor is running first?
        reactor.stop()


    @staticmethod
    def deferred_quit( ):
        reactor.stop()



    def send_presence( self, xml_stream, status ):
        presence = domish.Element( (None , 'presence') )    # <presence/>
        presence['type'] = status
        xml_stream.send( presence )


    def send_discovery( self, to, xml_stream ):
        discovery_iq = xmlstream.IQ( xml_stream, "get" )
        discovery_iq[ 'to' ] = to
        query = domish.Element(( "http://jabber.org/protocol/disco#items", 'query') )
        discovery_iq.addChild( query )
        iq_deferred = discovery_iq.send()       # returns a deferred that is fired when the response is received
        return iq_deferred



if __name__ == '__main__':

    if len( sys.argv ) != 3 :
        print "correct usage: python xmppclient.py fulljid@chat.hipchat.com/device password"
        sys.exit( 1 )

    xmpp_client = XMPPClient()
    xmpp_client.full_jid = jid.JID( sys.argv[1] )
    xmpp_client.password = sys.argv[2]
    xmpp_client.initialize_factory()

    xmpp_client.xmppClientFactory.addBootstrap( xmlstream.STREAM_CONNECTED_EVENT , xmpp_client.connected )    # when there's a connected event, use the connected function
    xmpp_client.xmppClientFactory.addBootstrap( xmlstream.STREAM_END_EVENT , xmpp_client.disconnected )       # when there's a stream end event, use the disconnected function
    xmpp_client.xmppClientFactory.addBootstrap( xmlstream.STREAM_AUTHD_EVENT , xmpp_client.authenticated )

    xmpp_client.reactor = reactor
    xmpp_client.reactor.connectTCP( 'chat.hipchat.com' ,5222, xmpp_client.xmppClientFactory )           # connects to the host:port, then depends on the factory's callBacks

    xmpp_client.reactor.run()

  • « deferToThread blocking call LoopingCall
  • Unrar rarcrack »

Published

Jul 20, 2013

Category

python-twisted

~342 words

Tags

  • authenticate 2
  • client 14
  • discover 1
  • python 180
  • twisted 20
  • xmpp 4