From aab2682f9ac12a77dedc085dba8de635e4f6a393 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Fri, 15 Jun 2012 16:03:22 -0700 Subject: [PATCH] Add examples for using IBB. --- examples/ibb_transfer/ibb_receiver.py | 149 ++++++++++++++++++++++++++ examples/ibb_transfer/ibb_sender.py | 145 +++++++++++++++++++++++++ 2 files changed, 294 insertions(+) create mode 100755 examples/ibb_transfer/ibb_receiver.py create mode 100755 examples/ibb_transfer/ibb_sender.py diff --git a/examples/ibb_transfer/ibb_receiver.py b/examples/ibb_transfer/ibb_receiver.py new file mode 100755 index 00000000..b11acabf --- /dev/null +++ b/examples/ibb_transfer/ibb_receiver.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + SleekXMPP: The Sleek XMPP Library + Copyright (C) 2010 Nathanael C. Fritz + This file is part of SleekXMPP. + + See the file LICENSE for copying permission. +""" + +import sys +import logging +import getpass +from optparse import OptionParser + +import sleekxmpp + +# Python versions before 3.0 do not use UTF-8 encoding +# by default. To ensure that Unicode is handled properly +# throughout SleekXMPP, we will set the default encoding +# ourselves to UTF-8. +if sys.version_info < (3, 0): + reload(sys) + sys.setdefaultencoding('utf8') +else: + raw_input = input + + +class IBBReceiver(sleekxmpp.ClientXMPP): + + """ + A basic example of creating and using an in-band bytestream. + """ + + def __init__(self, jid, password): + sleekxmpp.ClientXMPP.__init__(self, jid, password) + + self.register_plugin('xep_0030') # Service Discovery + self.register_plugin('xep_0047', { + 'accept_stream': self.accept_stream + }) # In-band Bytestreams + + # The session_start event will be triggered when + # the bot establishes its connection with the server + # and the XML streams are ready for use. We want to + # listen for this event so that we we can initialize + # our roster. + self.add_event_handler("session_start", self.start) + + self.add_event_handler("ibb_stream_start", self.stream_opened) + self.add_event_handler("ibb_stream_data", self.stream_data) + + def start(self, event): + """ + Process the session_start event. + + Typical actions for the session_start event are + requesting the roster and broadcasting an initial + presence stanza. + + Arguments: + event -- An empty dictionary. The session_start + event does not provide any additional + data. + """ + self.send_presence() + self.get_roster() + + def accept_stream(self, iq): + """ + Check that it is ok to accept a stream request. + + Controlling stream acceptance can be done via either: + - setting 'auto_accept' to False in the plugin + configuration. The default is True. + - setting 'accept_stream' to a function which accepts + an Iq stanza as its argument, like this one. + + The accept_stream function will be used if it exists, and the + auto_accept value will be used otherwise. + """ + return True + + def stream_opened(self, stream): + # NOTE: IBB streams are bi-directional, so the original sender is + # now the opened stream's receiver. + print('Stream opened: %s from ' % (stream.sid, stream.receiver)) + + # You could run a loop reading from the stream using stream.recv(), + # or use the ibb_stream_data event. + + def stream_data(self, event): + print(event['data']) + +if __name__ == '__main__': + # Setup the command line arguments. + optp = OptionParser() + + # Output verbosity options. + optp.add_option('-q', '--quiet', help='set logging to ERROR', + action='store_const', dest='loglevel', + const=logging.ERROR, default=logging.INFO) + optp.add_option('-d', '--debug', help='set logging to DEBUG', + action='store_const', dest='loglevel', + const=logging.DEBUG, default=logging.INFO) + optp.add_option('-v', '--verbose', help='set logging to COMM', + action='store_const', dest='loglevel', + const=5, default=logging.INFO) + + # JID and password options. + optp.add_option("-j", "--jid", dest="jid", + help="JID to use") + optp.add_option("-p", "--password", dest="password", + help="password to use") + + opts, args = optp.parse_args() + + # Setup logging. + logging.basicConfig(level=opts.loglevel, + format='%(levelname)-8s %(message)s') + + if opts.jid is None: + opts.jid = raw_input("Username: ") + if opts.password is None: + opts.password = getpass.getpass("Password: ") + + xmpp = IBBReceiver(opts.jid, opts.password) + + # If you are working with an OpenFire server, you may need + # to adjust the SSL version used: + # xmpp.ssl_version = ssl.PROTOCOL_SSLv3 + + # If you want to verify the SSL certificates offered by a server: + # xmpp.ca_certs = "path/to/ca/cert" + + # Connect to the XMPP server and start processing XMPP stanzas. + if xmpp.connect(): + # If you do not have the dnspython library installed, you will need + # to manually specify the name of the server if it does not match + # the one in the JID. For example, to use Google Talk you would + # need to use: + # + # if xmpp.connect(('talk.google.com', 5222)): + # ... + xmpp.process(block=True) + print("Done") + else: + print("Unable to connect.") diff --git a/examples/ibb_transfer/ibb_sender.py b/examples/ibb_transfer/ibb_sender.py new file mode 100755 index 00000000..cd856378 --- /dev/null +++ b/examples/ibb_transfer/ibb_sender.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + SleekXMPP: The Sleek XMPP Library + Copyright (C) 2010 Nathanael C. Fritz + This file is part of SleekXMPP. + + See the file LICENSE for copying permission. +""" + +import sys +import logging +import getpass +from optparse import OptionParser + +import sleekxmpp + +# Python versions before 3.0 do not use UTF-8 encoding +# by default. To ensure that Unicode is handled properly +# throughout SleekXMPP, we will set the default encoding +# ourselves to UTF-8. +if sys.version_info < (3, 0): + reload(sys) + sys.setdefaultencoding('utf8') +else: + raw_input = input + + +class IBBSender(sleekxmpp.ClientXMPP): + + """ + A basic example of creating and using an in-band bytestream. + """ + + def __init__(self, jid, password, receiver, filename): + sleekxmpp.ClientXMPP.__init__(self, jid, password) + + self.receiver = receiver + self.filename = filename + + # The session_start event will be triggered when + # the bot establishes its connection with the server + # and the XML streams are ready for use. We want to + # listen for this event so that we we can initialize + # our roster. + self.add_event_handler("session_start", self.start) + + def start(self, event): + """ + Process the session_start event. + + Typical actions for the session_start event are + requesting the roster and broadcasting an initial + presence stanza. + + Arguments: + event -- An empty dictionary. The session_start + event does not provide any additional + data. + """ + self.send_presence() + self.get_roster() + + # For the purpose of demonstration, we'll set a very small block + # size. The default block size is 4096. We'll also use a window + # allowing sending multiple blocks at a time; in this case, three + # block transfers may be in progress at any time. + stream = self['xep_0047'].open_stream(self.receiver) + + with open(self.filename) as f: + data = f.read() + stream.sendall(data) + + +if __name__ == '__main__': + # Setup the command line arguments. + optp = OptionParser() + + # Output verbosity options. + optp.add_option('-q', '--quiet', help='set logging to ERROR', + action='store_const', dest='loglevel', + const=logging.ERROR, default=logging.INFO) + optp.add_option('-d', '--debug', help='set logging to DEBUG', + action='store_const', dest='loglevel', + const=logging.DEBUG, default=logging.INFO) + optp.add_option('-v', '--verbose', help='set logging to COMM', + action='store_const', dest='loglevel', + const=5, default=logging.INFO) + + # JID and password options. + optp.add_option("-j", "--jid", dest="jid", + help="JID to use") + optp.add_option("-p", "--password", dest="password", + help="password to use") + optp.add_option("-r", "--receiver", dest="receiver", + help="JID to use") + optp.add_option("-f", "--file", dest="filename", + help="JID to use") + + opts, args = optp.parse_args() + + # Setup logging. + logging.basicConfig(level=opts.loglevel, + format='%(levelname)-8s %(message)s') + + if opts.jid is None: + opts.jid = raw_input("Username: ") + if opts.password is None: + opts.password = getpass.getpass("Password: ") + if opts.receiver is None: + opts.receiver = raw_input("Receiver: ") + if opts.filename is None: + opts.filename = raw_input("File path: ") + + # Setup the EchoBot and register plugins. Note that while plugins may + # have interdependencies, the order in which you register them does + # not matter. + xmpp = IBBSender(opts.jid, opts.password, opts.receiver, opts.filename) + xmpp.register_plugin('xep_0030') # Service Discovery + xmpp.register_plugin('xep_0004') # Data Forms + xmpp.register_plugin('xep_0047') # In-band Bytestreams + xmpp.register_plugin('xep_0060') # PubSub + xmpp.register_plugin('xep_0199') # XMPP Ping + + # If you are working with an OpenFire server, you may need + # to adjust the SSL version used: + # xmpp.ssl_version = ssl.PROTOCOL_SSLv3 + + # If you want to verify the SSL certificates offered by a server: + # xmpp.ca_certs = "path/to/ca/cert" + + # Connect to the XMPP server and start processing XMPP stanzas. + if xmpp.connect(): + # If you do not have the dnspython library installed, you will need + # to manually specify the name of the server if it does not match + # the one in the JID. For example, to use Google Talk you would + # need to use: + # + # if xmpp.connect(('talk.google.com', 5222)): + # ... + xmpp.process(block=True) + print("Done") + else: + print("Unable to connect.")