started transition to xep_0060 rewrite
This commit is contained in:
		
							
								
								
									
										313
									
								
								sleekxmpp/plugins/xep_0060/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								sleekxmpp/plugins/xep_0060/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,313 @@ | ||||
| from __future__ import with_statement | ||||
| from sleekxmpp.plugins import base | ||||
| import logging | ||||
| #from xml.etree import cElementTree as ET | ||||
| from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin, ElementBase, ET | ||||
| from sleekxmpp.plugins import stanza_pubsub | ||||
| from sleekxmpp.plugins.xep_0004 import Form | ||||
|  | ||||
|  | ||||
| log = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| class xep_0060(base.base_plugin): | ||||
| 	""" | ||||
| 	XEP-0060 Publish Subscribe | ||||
| 	""" | ||||
|  | ||||
| 	def plugin_init(self): | ||||
| 		self.xep = '0060' | ||||
| 		self.description = 'Publish-Subscribe' | ||||
|  | ||||
| 	def create_node(self, jid, node, config=None, collection=False, ntype=None): | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub}pubsub') | ||||
| 		create = ET.Element('create') | ||||
| 		create.set('node', node) | ||||
| 		pubsub.append(create) | ||||
| 		configure = ET.Element('configure') | ||||
| 		if collection: | ||||
| 			ntype = 'collection' | ||||
| 		#if config is None: | ||||
| 		#	submitform = self.xmpp.plugin['xep_0004'].makeForm('submit') | ||||
| 		#else: | ||||
| 		if config is not None: | ||||
| 			submitform = config | ||||
| 			if 'FORM_TYPE' in submitform.field: | ||||
| 				submitform.field['FORM_TYPE'].setValue('http://jabber.org/protocol/pubsub#node_config') | ||||
| 			else: | ||||
| 				submitform.addField('FORM_TYPE', 'hidden', value='http://jabber.org/protocol/pubsub#node_config') | ||||
| 			if ntype: | ||||
| 				if 'pubsub#node_type' in submitform.field: | ||||
| 					submitform.field['pubsub#node_type'].setValue(ntype) | ||||
| 				else: | ||||
| 					submitform.addField('pubsub#node_type', value=ntype) | ||||
| 			else: | ||||
| 				if 'pubsub#node_type' in submitform.field: | ||||
| 					submitform.field['pubsub#node_type'].setValue('leaf') | ||||
| 				else: | ||||
| 					submitform.addField('pubsub#node_type', value='leaf') | ||||
| 			submitform['type'] = 'submit' | ||||
| 			configure.append(submitform.xml) | ||||
| 		pubsub.append(configure) | ||||
| 		iq = self.xmpp.makeIqSet(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		result = iq.send() | ||||
| 		if result is False or result is None or result['type'] == 'error': return False | ||||
| 		return True | ||||
|  | ||||
| 	def subscribe(self, jid, node, bare=True, subscribee=None): | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub}pubsub') | ||||
| 		subscribe = ET.Element('subscribe') | ||||
| 		subscribe.attrib['node'] = node | ||||
| 		if subscribee is None: | ||||
| 			if bare: | ||||
| 				subscribe.attrib['jid'] = self.xmpp.boundjid.bare | ||||
| 			else: | ||||
| 				subscribe.attrib['jid'] = self.xmpp.boundjid.full | ||||
| 		else: | ||||
| 			subscribe.attrib['jid'] = subscribee | ||||
| 		pubsub.append(subscribe) | ||||
| 		iq = self.xmpp.makeIqSet(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		result = iq.send() | ||||
| 		if result is False or result is None or result['type'] == 'error': return False | ||||
| 		return True | ||||
|  | ||||
| 	def unsubscribe(self, jid, node, bare=True, subscribee=None): | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub}pubsub') | ||||
| 		unsubscribe = ET.Element('unsubscribe') | ||||
| 		unsubscribe.attrib['node'] = node | ||||
| 		if subscribee is None: | ||||
| 			if bare: | ||||
| 				unsubscribe.attrib['jid'] = self.xmpp.boundjid.bare | ||||
| 			else: | ||||
| 				unsubscribe.attrib['jid'] = self.xmpp.boundjid.full | ||||
| 		else: | ||||
| 			unsubscribe.attrib['jid'] = subscribee | ||||
| 		pubsub.append(unsubscribe) | ||||
| 		iq = self.xmpp.makeIqSet(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		result = iq.send() | ||||
| 		if result is False or result is None or result['type'] == 'error': return False | ||||
| 		return True | ||||
|  | ||||
| 	def getNodeConfig(self, jid, node=None): # if no node, then grab default | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub#owner}pubsub') | ||||
| 		if node is not None: | ||||
| 			configure = ET.Element('configure') | ||||
| 			configure.attrib['node'] = node | ||||
| 		else: | ||||
| 			configure = ET.Element('default') | ||||
| 		pubsub.append(configure) | ||||
| 		#TODO: Add configure support. | ||||
| 		iq = self.xmpp.makeIqGet() | ||||
| 		iq.append(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		#self.xmpp.add_handler("<iq id='%s'/>" % id, self.handlerCreateNodeResponse) | ||||
| 		result = iq.send() | ||||
| 		if result is None or result == False or result['type'] == 'error': | ||||
| 			log.warning("got error instead of config") | ||||
| 			return False | ||||
| 		if node is not None: | ||||
| 			form = result.find('{http://jabber.org/protocol/pubsub#owner}pubsub/{http://jabber.org/protocol/pubsub#owner}configure/{jabber:x:data}x') | ||||
| 		else: | ||||
| 			form = result.find('{http://jabber.org/protocol/pubsub#owner}pubsub/{http://jabber.org/protocol/pubsub#owner}default/{jabber:x:data}x') | ||||
| 		if not form or form is None: | ||||
| 			log.error("No form found.") | ||||
| 			return False | ||||
| 		return Form(xml=form) | ||||
|  | ||||
| 	def getNodeSubscriptions(self, jid, node): | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub#owner}pubsub') | ||||
| 		subscriptions = ET.Element('subscriptions') | ||||
| 		subscriptions.attrib['node'] = node | ||||
| 		pubsub.append(subscriptions) | ||||
| 		iq = self.xmpp.makeIqGet() | ||||
| 		iq.append(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		result = iq.send() | ||||
| 		if result is None or result == False or result['type'] == 'error': | ||||
| 			log.warning("got error instead of config") | ||||
| 			return False | ||||
| 		else: | ||||
| 			results = result.findall('{http://jabber.org/protocol/pubsub#owner}pubsub/{http://jabber.org/protocol/pubsub#owner}subscriptions/{http://jabber.org/protocol/pubsub#owner}subscription') | ||||
| 			if results is None: | ||||
| 				return False | ||||
| 			subs = {} | ||||
| 			for sub in results: | ||||
| 				subs[sub.get('jid')] = sub.get('subscription') | ||||
| 			return subs | ||||
|  | ||||
| 	def getNodeAffiliations(self, jid, node): | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub#owner}pubsub') | ||||
| 		affiliations = ET.Element('affiliations') | ||||
| 		affiliations.attrib['node'] = node | ||||
| 		pubsub.append(affiliations) | ||||
| 		iq = self.xmpp.makeIqGet() | ||||
| 		iq.append(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		result = iq.send() | ||||
| 		if result is None or result == False or result['type'] == 'error': | ||||
| 			log.warning("got error instead of config") | ||||
| 			return False | ||||
| 		else: | ||||
| 			results = result.findall('{http://jabber.org/protocol/pubsub#owner}pubsub/{http://jabber.org/protocol/pubsub#owner}affiliations/{http://jabber.org/protocol/pubsub#owner}affiliation') | ||||
| 			if results is None: | ||||
| 				return False | ||||
| 			subs = {} | ||||
| 			for sub in results: | ||||
| 				subs[sub.get('jid')] = sub.get('affiliation') | ||||
| 			return subs | ||||
|  | ||||
| 	def deleteNode(self, jid, node): | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub#owner}pubsub') | ||||
| 		iq = self.xmpp.makeIqSet() | ||||
| 		delete = ET.Element('delete') | ||||
| 		delete.attrib['node'] = node | ||||
| 		pubsub.append(delete) | ||||
| 		iq.append(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		result = iq.send() | ||||
| 		if result is not None and result is not False and result['type'] != 'error': | ||||
| 			return True | ||||
| 		else: | ||||
| 			return False | ||||
|  | ||||
|  | ||||
| 	def setNodeConfig(self, jid, node, config): | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub#owner}pubsub') | ||||
| 		configure = ET.Element('configure') | ||||
| 		configure.attrib['node'] = node | ||||
| 		config = config.getXML('submit') | ||||
| 		configure.append(config) | ||||
| 		pubsub.append(configure) | ||||
| 		iq = self.xmpp.makeIqSet(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		result = iq.send() | ||||
| 		if result is None or result['type'] == 'error': | ||||
| 			return False | ||||
| 		return True | ||||
|  | ||||
| 	def setItem(self, jid, node, items=[]): | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub}pubsub') | ||||
| 		publish = ET.Element('publish') | ||||
| 		publish.attrib['node'] = node | ||||
| 		for pub_item in items: | ||||
| 			id, payload = pub_item | ||||
| 			item = ET.Element('item') | ||||
| 			if id is not None: | ||||
| 				item.attrib['id'] = id | ||||
| 			item.append(payload) | ||||
| 			publish.append(item) | ||||
| 		pubsub.append(publish) | ||||
| 		iq = self.xmpp.makeIqSet(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		result = iq.send() | ||||
| 		if result is None or result is False or result['type'] == 'error': return False | ||||
| 		return True | ||||
|  | ||||
| 	def addItem(self, jid, node, items=[]): | ||||
| 		return self.setItem(jid, node, items) | ||||
|  | ||||
| 	def deleteItem(self, jid, node, item): | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub}pubsub') | ||||
| 		retract = ET.Element('retract') | ||||
| 		retract.attrib['node'] = node | ||||
| 		itemn = ET.Element('item') | ||||
| 		itemn.attrib['id'] = item | ||||
| 		retract.append(itemn) | ||||
| 		pubsub.append(retract) | ||||
| 		iq = self.xmpp.makeIqSet(pubsub) | ||||
| 		iq.attrib['to'] = jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		result = iq.send() | ||||
| 		if result is None or result is False or result['type'] == 'error': return False | ||||
| 		return True | ||||
|  | ||||
| 	def getNodes(self, jid): | ||||
| 		response = self.xmpp.plugin['xep_0030'].getItems(jid) | ||||
| 		items = response.findall('{http://jabber.org/protocol/disco#items}query/{http://jabber.org/protocol/disco#items}item') | ||||
| 		nodes = {} | ||||
| 		if items is not None and items is not False: | ||||
| 			for item in items: | ||||
| 				nodes[item.get('node')] = item.get('name') | ||||
| 		return nodes | ||||
|  | ||||
| 	def getItems(self, jid, node): | ||||
| 		response = self.xmpp.plugin['xep_0030'].getItems(jid, node) | ||||
| 		items = response.findall('{http://jabber.org/protocol/disco#items}query/{http://jabber.org/protocol/disco#items}item') | ||||
| 		nodeitems = [] | ||||
| 		if items is not None and items is not False: | ||||
| 			for item in items: | ||||
| 				nodeitems.append(item.get('node')) | ||||
| 		return nodeitems | ||||
|  | ||||
| 	def addNodeToCollection(self, jid, child, parent=''): | ||||
| 		config = self.getNodeConfig(jid, child) | ||||
| 		if not config or config is None: | ||||
| 			self.lasterror = "Config Error" | ||||
| 			return False | ||||
| 		try: | ||||
| 			config.field['pubsub#collection'].setValue(parent) | ||||
| 		except KeyError: | ||||
| 			log.warning("pubsub#collection doesn't exist in config, trying to add it") | ||||
| 			config.addField('pubsub#collection', value=parent) | ||||
| 		if not self.setNodeConfig(jid, child, config): | ||||
| 			return False | ||||
| 		return True | ||||
|  | ||||
| 	def modifyAffiliation(self, ps_jid, node, user_jid, affiliation): | ||||
| 		if affiliation not in ('owner', 'publisher', 'member', 'none', 'outcast'): | ||||
| 			raise TypeError | ||||
| 		pubsub = ET.Element('{http://jabber.org/protocol/pubsub#owner}pubsub') | ||||
| 		affs = ET.Element('affiliations') | ||||
| 		affs.attrib['node'] = node | ||||
| 		aff = ET.Element('affiliation') | ||||
| 		aff.attrib['jid'] = user_jid | ||||
| 		aff.attrib['affiliation'] = affiliation | ||||
| 		affs.append(aff) | ||||
| 		pubsub.append(affs) | ||||
| 		iq = self.xmpp.makeIqSet(pubsub) | ||||
| 		iq.attrib['to'] = ps_jid | ||||
| 		iq.attrib['from'] = self.xmpp.boundjid.full | ||||
| 		id = iq['id'] | ||||
| 		result = iq.send() | ||||
| 		if result is None or result is False or result['type'] == 'error': | ||||
| 		    return False | ||||
| 		return True | ||||
|  | ||||
| 	def addNodeToCollection(self, jid, child, parent=''): | ||||
| 		config = self.getNodeConfig(jid, child) | ||||
| 		if not config or config is None: | ||||
| 			self.lasterror = "Config Error" | ||||
| 			return False | ||||
| 		try: | ||||
| 			config.field['pubsub#collection'].setValue(parent) | ||||
| 		except KeyError: | ||||
| 			log.warning("pubsub#collection doesn't exist in config, trying to add it") | ||||
| 			config.addField('pubsub#collection', value=parent) | ||||
| 		if not self.setNodeConfig(jid, child, config): | ||||
| 			return False | ||||
| 		return True | ||||
|  | ||||
| 	def removeNodeFromCollection(self, jid, child): | ||||
| 		self.addNodeToCollection(jid, child, '') | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Nathan Fritz
					Nathan Fritz