Add more documentation to the custom stanza examples.
This commit is contained in:
parent
ba854e7d85
commit
e0bcd5d722
@ -37,8 +37,8 @@ else:
|
|||||||
class ActionBot(sleekxmpp.ClientXMPP):
|
class ActionBot(sleekxmpp.ClientXMPP):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
A simple SleekXMPP bot that provides a basic
|
A simple SleekXMPP bot that receives a custom stanza
|
||||||
adhoc command.
|
from another client.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, jid, password):
|
def __init__(self, jid, password):
|
||||||
@ -54,7 +54,12 @@ class ActionBot(sleekxmpp.ClientXMPP):
|
|||||||
self.registerHandler(
|
self.registerHandler(
|
||||||
Callback('Some custom iq',
|
Callback('Some custom iq',
|
||||||
StanzaPath('iq@type=set/action'),
|
StanzaPath('iq@type=set/action'),
|
||||||
self._handleAction))
|
self._handle_action))
|
||||||
|
|
||||||
|
self.add_event_handler('custom_action',
|
||||||
|
self._handle_action_event,
|
||||||
|
threaded=True)
|
||||||
|
|
||||||
register_stanza_plugin(Iq, Action)
|
register_stanza_plugin(Iq, Action)
|
||||||
|
|
||||||
def start(self, event):
|
def start(self, event):
|
||||||
@ -73,17 +78,34 @@ class ActionBot(sleekxmpp.ClientXMPP):
|
|||||||
self.send_presence()
|
self.send_presence()
|
||||||
self.get_roster()
|
self.get_roster()
|
||||||
|
|
||||||
def _handleAction(self, iq):
|
def _handle_action(self, iq):
|
||||||
if iq['action']['method'] == 'is_prime' and iq['action']['param'] == '2':
|
"""
|
||||||
print("got message: " + str(iq))
|
Raise an event for the stanza so that it can be processed in its
|
||||||
|
own thread without blocking the main stanza processing loop.
|
||||||
|
"""
|
||||||
|
self.event('custom_action', iq)
|
||||||
|
|
||||||
|
def _handle_action_event(self, iq):
|
||||||
|
"""
|
||||||
|
Respond to the custom action event.
|
||||||
|
|
||||||
|
Since one of the actions is to disconnect, this
|
||||||
|
event handler needs to be run in threaded mode, by
|
||||||
|
using `threaded=True` in the `add_event_handler` call.
|
||||||
|
"""
|
||||||
|
method = iq['action']['method']
|
||||||
|
param = iq['action']['param']
|
||||||
|
|
||||||
|
if method == 'is_prime' and param == '2':
|
||||||
|
print("got message: %s" % iq)
|
||||||
iq.reply()
|
iq.reply()
|
||||||
iq['action']['status'] = 'done'
|
iq['action']['status'] = 'done'
|
||||||
iq.send()
|
iq.send()
|
||||||
elif iq['action']['method'] == 'bye':
|
elif method == 'bye':
|
||||||
print("got message: " + str(iq))
|
print("got message: %s" % iq)
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
else:
|
else:
|
||||||
print("got message: " + str(iq))
|
print("got message: %s" % iq)
|
||||||
iq.reply()
|
iq.reply()
|
||||||
iq['action']['status'] = 'error'
|
iq['action']['status'] = 'error'
|
||||||
iq.send()
|
iq.send()
|
||||||
|
@ -15,8 +15,10 @@ import getpass
|
|||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
import sleekxmpp
|
import sleekxmpp
|
||||||
|
from sleekxmpp import Iq
|
||||||
|
from sleekxmpp.exceptions import XMPPError
|
||||||
from sleekxmpp.xmlstream import register_stanza_plugin
|
from sleekxmpp.xmlstream import register_stanza_plugin
|
||||||
|
|
||||||
from stanza import Action
|
from stanza import Action
|
||||||
|
|
||||||
# Python versions before 3.0 do not use UTF-8 encoding
|
# Python versions before 3.0 do not use UTF-8 encoding
|
||||||
@ -33,8 +35,8 @@ else:
|
|||||||
class ActionUserBot(sleekxmpp.ClientXMPP):
|
class ActionUserBot(sleekxmpp.ClientXMPP):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
A simple SleekXMPP bot that uses the adhoc command
|
A simple SleekXMPP bot that sends a custom action stanza
|
||||||
provided by the adhoc_provider.py example.
|
to another client.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, jid, password, other):
|
def __init__(self, jid, password, other):
|
||||||
@ -47,10 +49,10 @@ class ActionUserBot(sleekxmpp.ClientXMPP):
|
|||||||
# and the XML streams are ready for use. We want to
|
# and the XML streams are ready for use. We want to
|
||||||
# listen for this event so that we we can initialize
|
# listen for this event so that we we can initialize
|
||||||
# our roster.
|
# our roster.
|
||||||
self.add_event_handler("session_start", self.start)
|
self.add_event_handler("session_start", self.start, threaded=True)
|
||||||
self.add_event_handler("message", self.message)
|
self.add_event_handler("message", self.message)
|
||||||
|
|
||||||
register_stanza_plugin(sleekxmpp.Iq, Action)
|
register_stanza_plugin(Iq, Action)
|
||||||
|
|
||||||
def start(self, event):
|
def start(self, event):
|
||||||
"""
|
"""
|
||||||
@ -71,12 +73,16 @@ class ActionUserBot(sleekxmpp.ClientXMPP):
|
|||||||
self.send_custom_iq()
|
self.send_custom_iq()
|
||||||
|
|
||||||
def send_custom_iq(self):
|
def send_custom_iq(self):
|
||||||
|
"""Create and send two custom actions.
|
||||||
|
|
||||||
|
If the first action was successful, then send
|
||||||
|
a shutdown command and then disconnect.
|
||||||
|
"""
|
||||||
iq = self.Iq()
|
iq = self.Iq()
|
||||||
iq['to'] = self.action_provider
|
iq['to'] = self.action_provider
|
||||||
iq['type'] = 'set'
|
iq['type'] = 'set'
|
||||||
iq.enable('action')
|
|
||||||
iq['action']['method'] = 'is_prime'
|
iq['action']['method'] = 'is_prime'
|
||||||
iq['action']['param'] = str(2)
|
iq['action']['param'] = '2'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resp = iq.send()
|
resp = iq.send()
|
||||||
@ -85,12 +91,14 @@ class ActionUserBot(sleekxmpp.ClientXMPP):
|
|||||||
iq2 = self.Iq()
|
iq2 = self.Iq()
|
||||||
iq2['to'] = self.action_provider
|
iq2['to'] = self.action_provider
|
||||||
iq2['type'] = 'set'
|
iq2['type'] = 'set'
|
||||||
iq2.enable('action')
|
|
||||||
iq2['action']['method'] = 'bye'
|
iq2['action']['method'] = 'bye'
|
||||||
iq2.send(block = False)
|
iq2.send(block=False)
|
||||||
self.disconnect()
|
|
||||||
except sleekxmpp.exceptions.XMPPError:
|
# The wait=True delays the disconnect until the queue
|
||||||
pass
|
# of stanzas to be sent becomes empty.
|
||||||
|
self.disconnect(wait=True)
|
||||||
|
except XMPPError:
|
||||||
|
print('There was an error sending the custom action.')
|
||||||
|
|
||||||
def message(self, msg):
|
def message(self, msg):
|
||||||
"""
|
"""
|
||||||
|
@ -1,8 +1,56 @@
|
|||||||
from sleekxmpp.xmlstream import ElementBase
|
from sleekxmpp.xmlstream import ElementBase
|
||||||
|
|
||||||
class Action(ElementBase):
|
class Action(ElementBase):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A stanza class for XML content of the form:
|
||||||
|
|
||||||
|
<action xmlns="sleekxmpp:custom:actions">
|
||||||
|
<method>X</method>
|
||||||
|
<param>X</param>
|
||||||
|
<status>X</status>
|
||||||
|
</action>
|
||||||
|
"""
|
||||||
|
|
||||||
|
#: The `name` field refers to the basic XML tag name of the
|
||||||
|
#: stanza. Here, the tag name will be 'action'.
|
||||||
name = 'action'
|
name = 'action'
|
||||||
|
|
||||||
|
#: The namespace of the main XML tag.
|
||||||
namespace = 'sleekxmpp:custom:actions'
|
namespace = 'sleekxmpp:custom:actions'
|
||||||
|
|
||||||
|
#: The `plugin_attrib` value is the name that can be used
|
||||||
|
#: with a parent stanza to access this stanza. For example
|
||||||
|
#: from an Iq stanza object, accessing:
|
||||||
|
#:
|
||||||
|
#: iq['action']
|
||||||
|
#:
|
||||||
|
#: would reference an Action object, and will even create
|
||||||
|
#: an Action object and append it to the Iq stanza if
|
||||||
|
#: one doesn't already exist.
|
||||||
plugin_attrib = 'action'
|
plugin_attrib = 'action'
|
||||||
|
|
||||||
|
#: Stanza objects expose dictionary-like interfaces for
|
||||||
|
#: accessing and manipulating substanzas and other values.
|
||||||
|
#: The set of interfaces defined here are the names of
|
||||||
|
#: these dictionary-like interfaces provided by this stanza
|
||||||
|
#: type. For example, an Action stanza object can use:
|
||||||
|
#:
|
||||||
|
#: action['method'] = 'foo'
|
||||||
|
#: print(action['param'])
|
||||||
|
#: del action['status']
|
||||||
|
#:
|
||||||
|
#: to set, get, or remove its values.
|
||||||
interfaces = set(('method', 'param', 'status'))
|
interfaces = set(('method', 'param', 'status'))
|
||||||
|
|
||||||
|
#: By default, values in the `interfaces` set are mapped to
|
||||||
|
#: attribute values. This can be changed such that an interface
|
||||||
|
#: maps to a subelement's text value by adding interfaces to
|
||||||
|
#: the sub_interfaces set. For example, here all interfaces
|
||||||
|
#: are marked as sub_interfaces, and so the XML produced will
|
||||||
|
#: look like:
|
||||||
|
#:
|
||||||
|
#: <action xmlns="sleekxmpp:custom:actions">
|
||||||
|
#: <method>foo</method>
|
||||||
|
#: </action>
|
||||||
sub_interfaces = interfaces
|
sub_interfaces = interfaces
|
||||||
|
Loading…
Reference in New Issue
Block a user