diff options
author | Lance Stout <lancestout@gmail.com> | 2011-08-17 21:21:37 -0700 |
---|---|---|
committer | Lance Stout <lancestout@gmail.com> | 2011-08-17 21:21:37 -0700 |
commit | 961668d420d2241541f4facc64265932c66ad81c (patch) | |
tree | 3b31e69d1148a94b61541a85bba49adc8c5cea6e | |
parent | 01061a0355b05c8452b1ef8ca998cd2c51ab4c9e (diff) | |
download | slixmpp-961668d420d2241541f4facc64265932c66ad81c.tar.gz slixmpp-961668d420d2241541f4facc64265932c66ad81c.tar.bz2 slixmpp-961668d420d2241541f4facc64265932c66ad81c.tar.xz slixmpp-961668d420d2241541f4facc64265932c66ad81c.zip |
Add guide for sending a message and then disconnecting.
-rw-r--r-- | docs/api/basexmpp.rst | 8 | ||||
-rw-r--r-- | docs/api/xmlstream.rst | 8 | ||||
-rw-r--r-- | docs/features.rst | 2 | ||||
-rw-r--r-- | docs/getting_started/echobot.rst | 126 | ||||
-rw-r--r-- | docs/getting_started/sendlogout.rst | 95 | ||||
-rw-r--r-- | docs/index.rst | 14 | ||||
-rw-r--r-- | docs/plugin_arch.rst | 2 | ||||
-rwxr-xr-x | examples/send_client.py | 55 |
8 files changed, 147 insertions, 163 deletions
diff --git a/docs/api/basexmpp.rst b/docs/api/basexmpp.rst new file mode 100644 index 00000000..841df3db --- /dev/null +++ b/docs/api/basexmpp.rst @@ -0,0 +1,8 @@ +======== +basexmpp +======== + +.. module:: sleekxmpp.basexmpp + +.. autoclass:: BaseXMPP + :members: diff --git a/docs/api/xmlstream.rst b/docs/api/xmlstream.rst new file mode 100644 index 00000000..7835bf57 --- /dev/null +++ b/docs/api/xmlstream.rst @@ -0,0 +1,8 @@ +========= +xmlstream +========= + +.. module:: sleekxmpp.xmlstream + +.. autoclass:: XMLStream + :members: diff --git a/docs/features.rst b/docs/features.rst new file mode 100644 index 00000000..4d93d5c3 --- /dev/null +++ b/docs/features.rst @@ -0,0 +1,2 @@ +How to Use Stream Features +========================== diff --git a/docs/getting_started/echobot.rst b/docs/getting_started/echobot.rst index 9defca6b..053a76f2 100644 --- a/docs/getting_started/echobot.rst +++ b/docs/getting_started/echobot.rst @@ -1,3 +1,5 @@ +.. _echobot: + =============================== SleekXMPP Quickstart - Echo Bot =============================== @@ -386,127 +388,3 @@ can also be found in the SleekXMPP `examples directory <http://github.com/fritzy .. include:: ../../examples/echo_client.py :literal: - - -.. -.. #!/usr/bin/env python -.. # -*- coding: utf-8 -*- -.. import sys -.. import logging -.. import time -.. import getpass -.. from optparse import OptionParser -.. -.. import sleekxmpp -.. -.. -.. class EchoBot(sleekxmpp.ClientXMPP): -.. -.. """ -.. A simple SleekXMPP bot that will echo messages it -.. receives, along with a short thank you message. -.. """ -.. -.. def __init__(self, jid, password): -.. sleekxmpp.ClientXMPP.__init__(self, jid, password) -.. -.. # 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 intialize -.. # our roster. -.. self.add_event_handler("session_start", self.start) -.. -.. # The message event is triggered whenever a message -.. # stanza is received. Be aware that that includes -.. # MUC messages and error messages. -.. self.add_event_handler("message", self.message) -.. -.. def start(self, event): -.. """ -.. Process the session_start event. -.. -.. Typical actions for the session_start event are -.. requesting the roster and broadcasting an intial -.. presence stanza. -.. -.. Arguments: -.. event -- An empty dictionary. The session_start -.. event does not provide any additional -.. data. -.. """ -.. self.send_presence() -.. self.get_roster() -.. -.. def message(self, msg): -.. """ -.. Process incoming message stanzas. Be aware that this also -.. includes MUC messages and error messages. It is usually -.. a good idea to check the messages's type before processing -.. or sending replies. -.. -.. Arguments: -.. msg -- The received message stanza. See the documentation -.. for stanza objects and the Message stanza to see -.. how it may be used. -.. """ -.. if msg['type'] in ('normal', 'chat'): -.. msg.reply("Thanks for sending\n%(body)s" % msg).send() -.. -.. -.. 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: ") -.. -.. # Setup the EchoBot and register plugins. Note that while plugins may -.. # have interdependencies, the order in which you register them does -.. # not matter. -.. xmpp = EchoBot(opts.jid, opts.password) -.. xmpp.register_plugin('xep_0030') # Service Discovery -.. 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 -.. -.. # Connect to the XMPP server and start processing XMPP stanzas. -.. if xmpp.connect(): -.. # If you do not have the pydns 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(threaded=False) -.. print("Done") -.. else: -.. print("Unable to connect.") diff --git a/docs/getting_started/sendlogout.rst b/docs/getting_started/sendlogout.rst index 2f9f1edf..a1352db9 100644 --- a/docs/getting_started/sendlogout.rst +++ b/docs/getting_started/sendlogout.rst @@ -1,5 +1,94 @@ -Login, Send a Message, and Disconnect -===================================== +Sign in, Send a Message, and Disconnect +======================================= + +.. note:: + + If you have any issues working through this quickstart guide + or the other tutorials here, please either send a message to the + `mailing list <http://groups.google.com/group/sleekxmpp-discussion>`_ + or join the chat room at `sleek@conference.jabber.org + <xmpp:sleek@conference.jabber.org?join>`_. A common use case for SleekXMPP is to send one-off messages from -time to time. +time to time. For example, one use case could be sending out a notice when +a shell script finishes a task. + +We will create our one-shot bot based on the pattern explained in :ref:`echobot`. To +start, we create a client class based on :class:`ClientXMPP <sleekxmpp.clientxmpp.ClientXMPP>` and +register a handler for the :term:`session_start` event. We will also accept parameters +for the JID that will receive our message, and the string content of the message. + +.. code-block:: python + + import sleekxmpp + + + class SendMsgBot(sleekxmpp.ClientXMPP): + + def __init__(self, jid, password, recipient, msg): + super(SendMsgBot, self).__init__(jid, password) + + self.recipient = recipient + self.msg = msg + + self.add_event_handler('session_start', self.start) + + def start(self, event): + self.send_presence() + self.get_roster() + +Note that as in :ref:`echobot`, we need to include send an initial presence and request +the roster. Next, we want to send our message, and to do that we will use :meth:`send_message <sleekxmpp.basexmpp.BaseXMPP.send_message>`. + +.. code-block:: python + + def start(self, event): + self.send_presence() + self.get_roster() + + self.send_message(mto=self.recipient, mbody=self.msg) + +Finally, we need to disconnect the client using :meth:`disconnect <sleekxmpp.xmlstream.XMLStream.disconnect>`. +Now, sent stanzas are placed in a queue to pass them to the send thread. If we were to call +:meth:`disconnect <sleekxmpp.xmlstream.XMLStream.disconnect>` without any parameters, then it is possible +for the client to disconnect before the send queue is processed and the message is actually +sent on the wire. To ensure that our message is processed, we use +:meth:`disconnect(wait=True) <sleekxmpp.xmlstream.XMLStream.disconnect>`. + +.. code-block:: python + + def start(self, event): + self.send_presence() + self.get_roster() + + self.send_message(mto=self.recipient, mbody=self.msg) + + self.disconnect(wait=True) + +.. warning:: + + If you happen to be adding stanzas to the send queue faster than the send thread + can process them, then :meth:`disconnect(wait=True) <sleekxmpp.xmlstream.XMLStream.disconnect>` + will block and not disconnect. + +Final Product +------------- + +.. compound:: + + The final step is to create a small runner script for initialising our ``SendMsgBot`` class and adding some + basic configuration options. By following the basic boilerplate pattern in :ref:`echobot`, we arrive + at the code below. To experiment with this example, you can use: + + .. code-block:: sh + + python send_client.py -d -j oneshot@example.com -t someone@example.net -m "This is a message" + + which will prompt for the password and then log in, send your message, and then disconnect. To test, open + your regular IM client with the account you wish to send messages to. When you run the ``send_client.py`` + example and instruct it to send your IM client account a message, you should receive the message you + gave. If the two JIDs you use also have a mutual presence subscription (they're on each other's buddy lists) + then you will also see the ``SendMsgBot`` client come online and then go offline. + +.. include:: ../../examples/send_client.py + :literal: diff --git a/docs/index.rst b/docs/index.rst index 95e49743..5da389b9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -67,7 +67,7 @@ SleekXMPP's design goals and philosphy are: Getting Started (with Examples) ------------------------------- .. toctree:: - :maxdepth: 2 + :maxdepth: 1 getting_started/echobot getting_started/sendlogout @@ -82,27 +82,29 @@ Getting Started (with Examples) Tutorials, FAQs, and How To Guides ---------------------------------- .. toctree:: - :maxdepth: 2 + :maxdepth: 1 xeps xmpp_tdg create_plugin + features sasl handlersmatchers Plugin Guides ~~~~~~~~~~~~~ .. toctree:: - :maxdepth: 2 + :maxdepth: 1 guide_xep_0030 SleekXMPP Architecture and Design --------------------------------- .. toctree:: - :maxdepth: 2 + :maxdepth: 3 - architecture.rst + architecture + plugin_arch API Reference ------------- @@ -111,6 +113,8 @@ API Reference event_index api/clientxmpp + api/basexmpp + api/xmlstream Additional Info --------------- diff --git a/docs/plugin_arch.rst b/docs/plugin_arch.rst new file mode 100644 index 00000000..0141b793 --- /dev/null +++ b/docs/plugin_arch.rst @@ -0,0 +1,2 @@ +Plugin Architecture +=================== diff --git a/examples/send_client.py b/examples/send_client.py index fd99e8c9..b3673512 100755 --- a/examples/send_client.py +++ b/examples/send_client.py @@ -29,13 +29,18 @@ if sys.version_info < (3, 0): class SendMsgBot(sleekxmpp.ClientXMPP): """ - A simple SleekXMPP bot that will echo messages it - receives, along with a short thank you message. + A basic SleekXMPP bot that will log in, send a message, + and then log out. """ - def __init__(self, jid, password): + def __init__(self, jid, password, recipient, message): sleekxmpp.ClientXMPP.__init__(self, jid, password) + # The message we wish to send, and the JID that + # will receive it. + self.recipient = recipient + self.msg = message + # 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 @@ -43,11 +48,6 @@ class SendMsgBot(sleekxmpp.ClientXMPP): # our roster. self.add_event_handler("session_start", self.start) - # The message event is triggered whenever a message - # stanza is received. Be aware that that includes - # MUC messages and error messages. - self.add_event_handler("message", self.message) - def start(self, event): """ Process the session_start event. @@ -63,27 +63,14 @@ class SendMsgBot(sleekxmpp.ClientXMPP): """ self.send_presence() self.get_roster() - msg = self.Message() - msg['to'] = 'user@example.com' - msg['type'] = 'chat' - msg['body'] = "Hello there!" - msg.send() - self.disconnect() - - def message(self, msg): - """ - Process incoming message stanzas. Be aware that this also - includes MUC messages and error messages. It is usually - a good idea to check the messages's type before processing - or sending replies. - Arguments: - msg -- The received message stanza. See the documentation - for stanza objects and the Message stanza to see - how it may be used. - """ - #msg.reply("Thanks for sending\n%(body)s" % msg).send() - print "Msg rceived from %(body)s: %(jid)s" % msg + self.send_message(mto=self.recipient, + mbody=self.msg, + mtype='chat') + + # Using wait=True ensures that the send queue will be + # emptied before ending the session. + self.disconnect(wait=True) if __name__ == '__main__': @@ -106,6 +93,10 @@ if __name__ == '__main__': help="JID to use") optp.add_option("-p", "--password", dest="password", help="password to use") + optp.add_option("-t", "--to", dest="to", + help="JID to send the message to") + optp.add_option("-m", "--message", dest="message", + help="message to send") opts, args = optp.parse_args() @@ -117,14 +108,16 @@ if __name__ == '__main__': opts.jid = raw_input("Username: ") if opts.password is None: opts.password = getpass.getpass("Password: ") + if opts.to is None: + opts.to = raw_input("Send To: ") + if opts.message is None: + opts.message = raw_input("Message: ") # Setup the EchoBot and register plugins. Note that while plugins may # have interdependencies, the order in which you register them does # not matter. - xmpp = SendMsgBot(opts.jid, opts.password) + xmpp = SendMsgBot(opts.jid, opts.password, opts.to, opts.message) xmpp.register_plugin('xep_0030') # Service Discovery - xmpp.register_plugin('xep_0004') # Data Forms - xmpp.register_plugin('xep_0060') # PubSub xmpp.register_plugin('xep_0199') # XMPP Ping # If you are working with an OpenFire server, you may need |