diff options
-rw-r--r-- | sleekxmpp/plugins/stanza_pubsub.py | 135 | ||||
-rw-r--r-- | sleekxmpp/xmlstream/stanzabase.py | 5 | ||||
-rw-r--r-- | tests/test_pubsubstanzas.py | 100 |
3 files changed, 158 insertions, 82 deletions
diff --git a/sleekxmpp/plugins/stanza_pubsub.py b/sleekxmpp/plugins/stanza_pubsub.py index 9bae7c94..900f3c82 100644 --- a/sleekxmpp/plugins/stanza_pubsub.py +++ b/sleekxmpp/plugins/stanza_pubsub.py @@ -51,9 +51,25 @@ class Affiliations(ElementBase): self.xml.append(affiliation.xml) return self.iterables.append(affiliation) - stanzaPlugin(Pubsub, Affiliations) + +class Subscription(ElementBase): + namespace = 'http://jabber.org/protocol/pubsub' + name = 'subscription' + plugin_attrib = name + interfaces = set(('jid', 'node', 'subscription')) + plugin_attrib_map = {} + plugin_tag_map = {} + + def setJid(self, value): + self._setAttr('jid', str(value)) + + def getJid(self): + return JID(self._getAttr('jid')) + +stanzaPlugin(Pubsub, Subscription) + class Subscriptions(ElementBase): namespace = 'http://jabber.org/protocol/pubsub' name = 'subscriptions' @@ -61,6 +77,7 @@ class Subscriptions(ElementBase): interfaces = set(tuple()) plugin_attrib_map = {} plugin_tag_map = {} + subitem = Subscription def __init__(self, *args, **kwargs): ElementBase.__init__(self, *args, **kwargs) @@ -97,25 +114,8 @@ class Subscriptions(ElementBase): stanzaPlugin(Pubsub, Subscriptions) - -class Subscription(ElementBase): - namespace = 'http://jabber.org/protocol/pubsub' - name = 'subscription' - plugin_attrib = name - interfaces = set(('jid', 'node', 'subid', 'subscription')) - plugin_attrib_map = {} - plugin_tag_map = {} - - def setJid(self, value): - self._setAttr('jid', str(value)) - - def getJid(self): - return JID(self._getAttr('from')) - -stanzaPlugin(Pubsub, Subscription) - class OptionalSetting(object): - interfaces = set(('required')) + interfaces = set(('required',)) def setRequired(self, value): value = bool(value) @@ -140,55 +140,13 @@ class OptionalSetting(object): class SubscribeOptions(ElementBase, OptionalSetting): namespace = 'http://jabber.org/protocol/pubsub' name = 'subscribe-options' - plugin_attrib = 'options' + plugin_attrib = 'suboptions' plugin_attrib_map = {} plugin_tag_map = {} + interfaces = set(('required',)) stanzaPlugin(Subscription, SubscribeOptions) -class Items(ElementBase): - namespace = 'http://jabber.org/protocol/pubsub' - name = 'items' - plugin_attrib = 'items' - interfaces = set(tuple()) - plugin_attrib_map = {} - plugin_tag_map = {} - - def __init__(self, *args, **kwargs): - ElementBase.__init__(self, *args, **kwargs) - self.items = [] - self.idx = 0 - - def __iter__(self): - self.idx = 0 - return self - - def __next__(self): - self.idx += 1 - if self.idx + 1 > len(self.items): - self.idx = 0 - raise StopIteration - return self.items[self.idx] - - def __len__(self): - return len(self.items) - - def append(self, item): - if not isinstance(item, Item): - raise TypeError - self.xml.append(item.xml) - return self.items.append(item) - - def pop(self, idx=0): - aff = self.items.pop(idx) - self.xml.remove(aff.xml) - return aff - - def find(self, item): - return self.items.find(item) - -stanzaPlugin(Pubsub, Items) - class Item(ElementBase): namespace = 'http://jabber.org/protocol/pubsub' name = 'item' @@ -209,30 +167,41 @@ class Item(ElementBase): for child in self.xml.getchildren(): self.xml.remove(child) -class Create(ElementBase): +class Items(ElementBase): namespace = 'http://jabber.org/protocol/pubsub' - name = 'create' - plugin_attrib = name - interfaces = set(('node')) + name = 'items' + plugin_attrib = 'items' + interfaces = set(tuple()) plugin_attrib_map = {} plugin_tag_map = {} + subitem = Item -stanzaPlugin(Pubsub, Create) +stanzaPlugin(Pubsub, Items) -class Default(ElementBase): +class Create(ElementBase): namespace = 'http://jabber.org/protocol/pubsub' - name = 'default' + name = 'create' plugin_attrib = name - interfaces = set(('node', 'type')) + interfaces = set(('node',)) plugin_attrib_map = {} plugin_tag_map = {} - def getType(self): - t = self._getAttr('type') - if not t: t == 'leaf' - return t +stanzaPlugin(Pubsub, Create) -stanzaPlugin(Pubsub, Default) +#class Default(ElementBase): +# namespace = 'http://jabber.org/protocol/pubsub' +# name = 'default' +# plugin_attrib = name +# interfaces = set(('node', 'type')) +# plugin_attrib_map = {} +# plugin_tag_map = {} +# +# def getType(self): +# t = self._getAttr('type') +# if not t: t == 'leaf' +# return t +# +#stanzaPlugin(Pubsub, Default) class Publish(Items): namespace = 'http://jabber.org/protocol/pubsub' @@ -280,7 +249,7 @@ class Subscribe(ElementBase): self._setAttr('jid', str(value)) def getJid(self): - return JID(self._getAttr('from')) + return JID(self._getAttr('jid')) stanzaPlugin(Pubsub, Subscribe) @@ -313,11 +282,12 @@ class Configure(ElementBase): self.xml.remove(config) stanzaPlugin(Pubsub, Configure) +stanzaPlugin(Create, Configure) class DefaultConfig(ElementBase): namespace = 'http://jabber.org/protocol/pubsub' name = 'default' - plugin_attrib = 'defaultconfig' + plugin_attrib = 'default' interfaces = set(('node', 'type', 'config')) plugin_attrib_map = {} plugin_tag_map = {} @@ -340,6 +310,11 @@ class DefaultConfig(ElementBase): config = self.xml.find('{jabber:x:data}x') self.xml.remove(config) + def getType(self): + t = self._getAttr('type') + if not t: t == 'leaf' + return t + stanzaPlugin(Pubsub, DefaultConfig) class Options(ElementBase): @@ -372,10 +347,10 @@ class Options(ElementBase): self._setAttr('jid', str(value)) def getJid(self): - return JID(self._getAttr('from')) + return JID(self._getAttr('jid')) stanzaPlugin(Pubsub, Options) - +stanzaPlugin(Subscribe, Options) #iq = Iq() #iq['pubsub']['defaultconfig'] diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py index 8bdcb0b0..277882e8 100644 --- a/sleekxmpp/xmlstream/stanzabase.py +++ b/sleekxmpp/xmlstream/stanzabase.py @@ -64,7 +64,8 @@ class ElementBase(object): if not isinstance(item, ElementBase): raise TypeError self.xml.append(item.xml) - return self.iterables.append(item) + self.iterables.append(item) + return self def pop(self, idx=0): aff = self.iterables.pop(idx) @@ -236,7 +237,7 @@ class ElementBase(object): self.plugins[interface].setValues(attrib[interface]) return self - def append(self, xml): + def appendxml(self, xml): self.xml.append(xml) return self diff --git a/tests/test_pubsubstanzas.py b/tests/test_pubsubstanzas.py index 37deeca1..b84a5170 100644 --- a/tests/test_pubsubstanzas.py +++ b/tests/test_pubsubstanzas.py @@ -1,4 +1,5 @@ import unittest +from xml.etree import cElementTree as ET class testpubsubstanzas(unittest.TestCase): @@ -24,5 +25,104 @@ class testpubsubstanzas(unittest.TestCase): iq3.setValues(values) self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) + def testSubscriptions(self): + "Testing iq/pubsub/subscriptions/subscription stanzas" + iq = self.ps.Iq() + sub1 = self.ps.Subscription() + sub1['node'] = 'testnode' + sub1['jid'] = 'steve@myserver.tld/someresource' + sub2 = self.ps.Subscription() + sub2['node'] = 'testnode2' + sub2['jid'] = 'boogers@bork.top/bill' + iq['pubsub']['subscriptions'].append(sub1) + iq['pubsub']['subscriptions'].append(sub2) + xmlstring = """<iq id="0"><pubsub xmlns="http://jabber.org/protocol/pubsub"><subscriptions><subscription node="testnode" jid="steve@myserver.tld/someresource" /><subscription node="testnode2" jid="boogers@bork.top/bill" /></subscriptions></pubsub></iq>""" + iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) + iq3 = self.ps.Iq() + values = iq2.getValues() + iq3.setValues(values) + self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) + + def testOptionalSettings(self): + "Testing iq/pubsub/subscription/subscribe-options stanzas" + iq = self.ps.Iq() + iq['pubsub']['subscription']['suboptions']['required'] = True + iq['pubsub']['subscription']['node'] = 'testnode alsdkjfas' + iq['pubsub']['subscription']['jid'] = "fritzy@netflint.net/sleekxmpp" + iq['pubsub']['subscription']['subscription'] = 'unconfigured' + xmlstring = """<iq id="0"><pubsub xmlns="http://jabber.org/protocol/pubsub"><subscription node="testnode alsdkjfas" jid="fritzy@netflint.net/sleekxmpp" subscription="unconfigured"><subscribe-options><required /></subscribe-options></subscription></pubsub></iq>""" + iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) + iq3 = self.ps.Iq() + values = iq2.getValues() + iq3.setValues(values) + self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) + + def testItems(self): + iq = self.ps.Iq() + iq['pubsub']['items'] + payload = ET.fromstring("""<thinger xmlns="http://andyet.net/protocol/thinger" x="1" y='2'><child1 /><child2 normandy='cheese' foo='bar' /></thinger>""") + payload2 = ET.fromstring("""<thinger2 xmlns="http://andyet.net/protocol/thinger2" x="12" y='22'><child12 /><child22 normandy='cheese2' foo='bar2' /></thinger2>""") + item = self.ps.Item() + item['id'] = 'asdf' + item['payload'] = payload + item2 = self.ps.Item() + item2['id'] = 'asdf2' + item2['payload'] = payload2 + iq['pubsub']['items'].append(item) + iq['pubsub']['items'].append(item2) + xmlstring = """<iq id="0"><pubsub xmlns="http://jabber.org/protocol/pubsub"><items><item id="asdf"><thinger xmlns="http://andyet.net/protocol/thinger" y="2" x="1"><child1 /><child2 foo="bar" normandy="cheese" /></thinger></item><item id="asdf2"><thinger2 xmlns="http://andyet.net/protocol/thinger2" y="22" x="12"><child12 /><child22 foo="bar2" normandy="cheese2" /></thinger2></item></items></pubsub></iq>""" + iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) + iq3 = self.ps.Iq() + values = iq2.getValues() + iq3.setValues(values) + self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) + + def testCreate(self): + from sleekxmpp.plugins import xep_0004 + iq = self.ps.Iq() + iq['pubsub']['create']['configure'] + iq['pubsub']['create']['node'] = 'mynode' + form = xep_0004.Form() + form.addField('pubsub#title', ftype='text-single', value='This thing is awesome') + iq['pubsub']['create']['configure']['config'] = form + xmlstring = """<iq id="0"><pubsub xmlns="http://jabber.org/protocol/pubsub"><create node="mynode"><configure><x xmlns="jabber:x:data" type="form"><field var="pubsub#title" type="text-single"><value>This thing is awesome</value></field></x></configure></create></pubsub></iq>""" + iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) + iq3 = self.ps.Iq() + values = iq2.getValues() + iq3.setValues(values) + self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) + + def testDefault(self): + from sleekxmpp.plugins import xep_0004 + iq = self.ps.Iq() + iq['pubsub']['default'] + iq['pubsub']['default']['node'] = 'mynode' + form = xep_0004.Form() + form.addField('pubsub#title', ftype='text-single', value='This thing is awesome') + iq['pubsub']['default']['config'] = form + xmlstring = """<iq id="0"><pubsub xmlns="http://jabber.org/protocol/pubsub"><default node="mynode"><x xmlns="jabber:x:data" type="form"><field var="pubsub#title" type="text-single"><value>This thing is awesome</value></field></x></default></pubsub></iq>""" + iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) + iq3 = self.ps.Iq() + values = iq2.getValues() + iq3.setValues(values) + self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) + + def testSubscribe(self): + from sleekxmpp.plugins import xep_0004 + iq = self.ps.Iq() + iq['pubsub']['subscribe']['options'] + iq['pubsub']['subscribe']['node'] = 'cheese' + iq['pubsub']['subscribe']['jid'] = 'fritzy@netflint.net/sleekxmpp' + iq['pubsub']['subscribe']['options']['node'] = 'cheese' + iq['pubsub']['subscribe']['options']['jid'] = 'fritzy@netflint.net/sleekxmpp' + form = xep_0004.Form() + form.addField('pubsub#title', ftype='text-single', value='This thing is awesome') + iq['pubsub']['subscribe']['options']['options'] = form + xmlstring = """<iq id="0"><pubsub xmlns="http://jabber.org/protocol/pubsub"><subscribe node="cheese" jid="fritzy@netflint.net/sleekxmpp"><options node="cheese" jid="fritzy@netflint.net/sleekxmpp"><x xmlns="jabber:x:data" type="form"><field var="pubsub#title" type="text-single"><value>This thing is awesome</value></field></x></options></subscribe></pubsub></iq>""" + iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) + iq3 = self.ps.Iq() + values = iq2.getValues() + iq3.setValues(values) + self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) suite = unittest.TestLoader().loadTestsFromTestCase(testpubsubstanzas) |