mirror of
https://github.com/correl/SleekXMPP.git
synced 2024-11-23 19:19:53 +00:00
Fix typos in XEP-0060, start of docs and tests.
This commit is contained in:
parent
e3e985220e
commit
d12949ff1c
2 changed files with 182 additions and 33 deletions
|
@ -1,16 +1,22 @@
|
|||
from __future__ import with_statement
|
||||
from sleekxmpp.plugins import base
|
||||
"""
|
||||
SleekXMPP: The Sleek XMPP Library
|
||||
Copyright (C) 2011 Nathanael C. Fritz
|
||||
This file is part of SleekXMPP.
|
||||
|
||||
See the file LICENSE for copying permission.
|
||||
"""
|
||||
|
||||
import logging
|
||||
#from xml.etree import cElementTree as ET
|
||||
from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin, ElementBase, ET
|
||||
|
||||
from sleekxmpp.plugins.base import base_plugin
|
||||
from sleekxmpp.plugins.xep_0060 import stanza
|
||||
from sleekxmpp.plugins.xep_0004 import Form
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class xep_0060(base.base_plugin):
|
||||
class xep_0060(base_plugin):
|
||||
|
||||
"""
|
||||
XEP-0060 Publish Subscribe
|
||||
"""
|
||||
|
@ -18,44 +24,81 @@ class xep_0060(base.base_plugin):
|
|||
def plugin_init(self):
|
||||
self.xep = '0060'
|
||||
self.description = 'Publish-Subscribe'
|
||||
self.stanza = stanza
|
||||
|
||||
def create_node(self, jid, node, config=None, ntype=None):
|
||||
iq = IQ(sto=jid, stype='set', sfrom=self.xmpp.jid)
|
||||
def create_node(self, jid, node, config=None, ntype=None, ifrom=None,
|
||||
block=True, callback=None, timeout=None):
|
||||
"""
|
||||
Create and configure a new pubsub node.
|
||||
|
||||
A server MAY use a different name for the node than the one provided,
|
||||
so be sure to check the result stanza for a server assigned name.
|
||||
|
||||
If no configuration form is provided, the node will be created using
|
||||
the server's default configuration. To get the default configuration
|
||||
use get_node_config().
|
||||
|
||||
Arguments:
|
||||
jid -- The JID of the pubsub service.
|
||||
node -- Optional name of the node to create. If no name is
|
||||
provided, the server MAY generate a node ID for you.
|
||||
The server can also assign a different name than the
|
||||
one you provide; check the result stanza to see if
|
||||
the server assigned a name.
|
||||
config -- Optional XEP-0004 data form of configuration settings.
|
||||
ntype -- The type of node to create. Servers typically default
|
||||
to using 'leaf' if no type is provided.
|
||||
ifrom -- Specify the sender's JID.
|
||||
block -- Specify if the send call will block until a response
|
||||
is received, or a timeout occurs. Defaults to True.
|
||||
timeout -- The length of time (in seconds) to wait for a response
|
||||
before exiting the send call if blocking is used.
|
||||
Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT
|
||||
callback -- Optional reference to a stream handler function. Will
|
||||
be executed when a reply stanza is received.
|
||||
"""
|
||||
iq = self.xmpp.Iq(sto=jid, stype='set')
|
||||
if ifrom:
|
||||
iq['from'] = ifrom
|
||||
iq['pubsub']['create']['node'] = node
|
||||
if ntype is None:
|
||||
ntype = 'leaf'
|
||||
|
||||
if config is not None:
|
||||
if 'FORM_TYPE' in submitform.field:
|
||||
config.field['FORM_TYPE'].setValue('http://jabber.org/protocol/pubsub#node_config')
|
||||
form_type = 'http://jabber.org/protocol/pubsub#node_config'
|
||||
if 'FORM_TYPE' in config['fields']:
|
||||
config.field['FORM_TYPE']['value'] = form_type
|
||||
else:
|
||||
config.addField('FORM_TYPE', 'hidden', value='http://jabber.org/protocol/pubsub#node_config')
|
||||
if 'pubsub#node_type' in submitform.field:
|
||||
config.field['pubsub#node_type'].setValue(ntype)
|
||||
else:
|
||||
config.addField('pubsub#node_type', value=ntype)
|
||||
iq['pubsub']['configure']['form'] = config
|
||||
return iq.send()
|
||||
config.add_field(var='FORM_TYPE',
|
||||
ftype='hidden',
|
||||
value=form_type)
|
||||
if ntype:
|
||||
if 'pubsub#node_type' in config['fields']:
|
||||
config.field['pubsub#node_type']['value'] = ntype
|
||||
else:
|
||||
config.add_field(var='pubsub#node_type', value=ntype)
|
||||
iq['pubsub']['configure'].append(config)
|
||||
|
||||
return iq.send(block=block, callback=callback, timeout=timeout)
|
||||
|
||||
def subscribe(self, jid, node, bare=True, subscribee=None):
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='set')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='set')
|
||||
iq['pubsub']['subscribe']['node'] = node
|
||||
if subscribee is None:
|
||||
if bare:
|
||||
iq['pubsub']['subscribe']['jid'] = self.xmpp.jid.bare
|
||||
iq['pubsub']['subscribe']['jid'] = self.xmpp.boundjid.bare
|
||||
else:
|
||||
iq['pubsub']['subscribe']['jid'] = self.xmpp.jid.full
|
||||
iq['pubsub']['subscribe']['jid'] = self.xmpp.boundjid.full
|
||||
else:
|
||||
iq['pubsub']['subscribe']['jid'] = subscribee
|
||||
return iq.send()
|
||||
|
||||
def unsubscribe(self, jid, node, subid=None, bare=True, subscribee=None):
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='set')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='set')
|
||||
iq['pubsub']['unsubscribe']['node'] = node
|
||||
if subscribee is None:
|
||||
if bare:
|
||||
iq['pubsub']['unsubscribe']['jid'] = self.xmpp.jid.bare
|
||||
iq['pubsub']['unsubscribe']['jid'] = self.xmpp.boundjid.bare
|
||||
else:
|
||||
iq['pubsub']['unsubscribe']['jid'] = self.xmpp.jid.full
|
||||
iq['pubsub']['unsubscribe']['jid'] = self.xmpp.boundjid.full
|
||||
else:
|
||||
iq['pubsub']['unsubscribe']['jid'] = subscribee
|
||||
if subid is not None:
|
||||
|
@ -63,7 +106,7 @@ class xep_0060(base.base_plugin):
|
|||
return iq.send()
|
||||
|
||||
def get_node_config(self, jid, node=None): # if no node, then grab default
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='get')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='get')
|
||||
if node is None:
|
||||
iq['pubsub_owner']['default']
|
||||
else:
|
||||
|
@ -71,28 +114,28 @@ class xep_0060(base.base_plugin):
|
|||
return iq.send()
|
||||
|
||||
def get_node_subscriptions(self, jid, node):
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='get')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='get')
|
||||
iq['pubsub_owner']['subscriptions']['node'] = node
|
||||
return iq.send()
|
||||
|
||||
def get_node_affiliations(self, jid, node):
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='get')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='get')
|
||||
iq['pubsub_owner']['affiliations']['node'] = node
|
||||
return iq.send()
|
||||
|
||||
def delete_node(self, jid, node):
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='get')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='get')
|
||||
iq['pubsub_owner']['delete']['node'] = node
|
||||
return iq.send()
|
||||
|
||||
def set_node_config(self, jid, node, config):
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='set')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='set')
|
||||
iq['pubsub_owner']['configure']['node'] = node
|
||||
iq['pubsub_owner']['configure']['config'] = config
|
||||
return iq.send()
|
||||
|
||||
def publish(self, jid, node, items=[]):
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='set')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='set')
|
||||
iq['pubsub']['publish']['node'] = node
|
||||
for id, payload in items:
|
||||
item = stanza.pubsub.Item()
|
||||
|
@ -103,7 +146,7 @@ class xep_0060(base.base_plugin):
|
|||
return iq.send()
|
||||
|
||||
def retract(self, jid, node, item):
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='set')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='set')
|
||||
iq['pubsub']['retract']['node'] = node
|
||||
item = stanza.pubsub.Item()
|
||||
item['id'] = item
|
||||
|
@ -117,7 +160,7 @@ class xep_0060(base.base_plugin):
|
|||
return self.xmpp.plugin['xep_0030'].get_items(jid, node)
|
||||
|
||||
def modify_affiliation(self, jid, node, affiliation, user_jid=None):
|
||||
iq = IQ(sto=jid, sfrom=self.xmpp.jid, stype='set')
|
||||
iq = self.xmpp.Iq(sto=jid, sfrom=self.xmpp.boundjid, stype='set')
|
||||
iq['pubsub_owner']['affiliations']
|
||||
aff = stanza.pubsub.Affiliation()
|
||||
aff['node'] = node
|
||||
|
|
106
tests/test_stream_xep_0060.py
Normal file
106
tests/test_stream_xep_0060.py
Normal file
|
@ -0,0 +1,106 @@
|
|||
import sys
|
||||
import time
|
||||
import threading
|
||||
|
||||
from sleekxmpp.test import *
|
||||
|
||||
|
||||
class TestStreamPubsub(SleekTest):
|
||||
|
||||
"""
|
||||
Test using the XEP-0030 plugin.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.stream_start()
|
||||
|
||||
def tearDown(self):
|
||||
self.stream_close()
|
||||
|
||||
def testCreateInstantNode(self):
|
||||
"""Test creating an instant node"""
|
||||
t = threading.Thread(name='create_node',
|
||||
target=self.xmpp['xep_0060'].create_node,
|
||||
args=('pubsub.example.com', None))
|
||||
t.start()
|
||||
|
||||
self.send("""
|
||||
<iq type="set" id="1" to="pubsub.example.com">
|
||||
<pubsub xmlns="http://jabber.org/protocol/pubsub">
|
||||
<create />
|
||||
</pubsub>
|
||||
</iq>
|
||||
""")
|
||||
|
||||
self.recv("""
|
||||
<iq type="result" id="1"
|
||||
to="tester@localhost" from="pubsub.example.com">
|
||||
<pubsub xmlns="http://jabber.org/protocol/pubsub">
|
||||
<create node="25e3d37dabbab9541f7523321421edc5bfeb2dae" />
|
||||
</pubsub>
|
||||
</iq>
|
||||
""")
|
||||
|
||||
t.join()
|
||||
|
||||
def testCreateNodeNoConfig(self):
|
||||
"""Test creating a node without a config"""
|
||||
t = threading.Thread(name='create_node',
|
||||
target=self.xmpp['xep_0060'].create_node,
|
||||
args=('pubsub.example.com', 'princely_musings'))
|
||||
t.start()
|
||||
|
||||
self.send("""
|
||||
<iq type="set" id="1" to="pubsub.example.com">
|
||||
<pubsub xmlns="http://jabber.org/protocol/pubsub">
|
||||
<create node="princely_musings" />
|
||||
</pubsub>
|
||||
</iq>
|
||||
""")
|
||||
|
||||
self.recv("""
|
||||
<iq type="result" id="1"
|
||||
to="tester@localhost" from="pubsub.example.com" />
|
||||
""")
|
||||
|
||||
t.join()
|
||||
|
||||
def testCreateNodeConfig(self):
|
||||
"""Test creating a node with a config"""
|
||||
form = self.xmpp['xep_0004'].stanza.Form()
|
||||
form['type'] = 'submit'
|
||||
form.add_field(var='pubsub#access_model', value='whitelist')
|
||||
|
||||
t = threading.Thread(name='create_node',
|
||||
target=self.xmpp['xep_0060'].create_node,
|
||||
args=('pubsub.example.com', 'princely_musings'),
|
||||
kwargs={'config': form})
|
||||
t.start()
|
||||
|
||||
self.send("""
|
||||
<iq type="set" id="1" to="pubsub.example.com">
|
||||
<pubsub xmlns="http://jabber.org/protocol/pubsub">
|
||||
<create node="princely_musings" />
|
||||
<configure>
|
||||
<x xmlns="jabber:x:data" type="submit">
|
||||
<field var="pubsub#access_model">
|
||||
<value>whitelist</value>
|
||||
</field>
|
||||
<field var="FORM_TYPE">
|
||||
<value>http://jabber.org/protocol/pubsub#node_config</value>
|
||||
</field>
|
||||
</x>
|
||||
</configure>
|
||||
</pubsub>
|
||||
</iq>
|
||||
""")
|
||||
|
||||
self.recv("""
|
||||
<iq type="result" id="1"
|
||||
to="tester@localhost" from="pubsub.example.com" />
|
||||
""")
|
||||
|
||||
t.join()
|
||||
|
||||
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamPubsub)
|
Loading…
Reference in a new issue