start adding node configuration, but unfortunately ejabberd doesn't support this...
[plcapi.git] / omf / omf-slicemgr.py
index 24cf701..a2756aa 100644 (file)
@@ -96,7 +96,8 @@ class BaseClient(object):
 
     def message_chat(self, m):
         n = domish.Element((None, "message"))
-        n['to'], n['from'] = m['from'], m['to']
+        n['to'] = m['from']
+        n['from'] = self.id.full()
         n.addElement("body", content = "don't have time to chat. working!")
         self.xmlstream.send(n)
 
@@ -121,6 +122,8 @@ class PubSubClient(BaseClient):
         xs.addObserver("/iq/pubsub/create", self.result_create_node)
         xs.addObserver("/iq/pubsub/delete", self.result_delete_node)
         xs.addObserver("/iq/query[@xmlns='http://jabber.org/protocol/disco#items']", self.result_discover)
+        xs.addObserver("/iq/pubsub/subscription[@subscription='subscribed']", self.result_subscribe_to_node)
+        xs.addObserver("/iq/pubsub/configure", self.result_configure_node)
 
     def __iq(self, t="get"):
         iq = domish.Element((None, "iq"))
@@ -130,6 +133,12 @@ class PubSubClient(BaseClient):
         iq.addUniqueId()
         return iq
 
+    def __add_pubsub(self, iq):
+        pubsub = iq.addElement("pubsub")
+        pubsub['xmlns'] = "http://jabber.org/protocol/pubsub"
+        return pubsub
+
+
     def discover(self, node = None):
         iq = self.__iq("get")
         query = iq.addElement("query")
@@ -140,18 +149,63 @@ class PubSubClient(BaseClient):
         self.xmlstream.send(iq)
 
     def result_discover(self, iq):
-        if self.verbose: self.info("Items for node: %s" % self.requests[iq['id']])
-        
         hook = self.hooks.get('discover', None)
-        for i in iq.query.elements():
-            if self.verbose: self.msg(i.toXml())
-            if hook: hook(i)
+        if hook:
+            hook(iq)
+            self.delete_result_hook('discover')
+
         self.requests.pop(iq['id'])
 
+
+    def subscribe_to_node(self, node):
+        iq = self.__iq("set")
+        pubsub = self.__add_pubsub(iq)
+        subscribe = pubsub.addElement("subscribe")
+        subscribe['node'] = node
+        subscribe['jid'] = self.id.full()
+        self.requests[iq['id']] = node
+        self.xmlstream.send(iq)
+
+    def result_subscribe_to_node(self, iq):
+        self.requests.pop(iq['id'])
+
+
+    def publish_to_node(self, node, payload):
+        iq = self.__iq("set")
+        pubsub = self.__add_pubsub(iq)
+        publish = pubsub.addElement("publish")
+        publish['node'] = node
+        items = publish.addElement("item", content=payload)
+        self.requests[iq['id']] = node
+        self.xmlstream.send(iq)
+
+    def result_publish_to_node(self, iq):
+        self.requests.pop(iq['id'])
+
+
+    # TODO: ejabberd doesn't have the node configuration feature implmented yet!
+    def configure_node(self, node, fields=None):
+        iq = self.__iq("set")
+        pubsub = self.__add_pubsub(iq)
+        configure = pubsub.addElement("configure")
+        configure['node'] = node
+        
+        # TODO: add fields
+
+        self.requests[iq['id']] = node
+        self.xmlstream.send(iq)
+        
+    def result_configure_node(self, iq):
+        hook = self.hooks.get('configure', None)
+        if hook:
+            hook(iq)
+            self.delete_result_hook('configure')
+        self.requests.pop(iq['id'])
+
+
     def create_node(self, node = None):
         iq = self.__iq("set")
-        pubsub = iq.addElement("pubsub")
-        pubsub['xmlns'] = "http://jabber.org/protocol/pubsub"
+        pubsub = self.__add_pubsub(iq)
         create = pubsub.addElement("create")
         if node:
             create['node'] = node
@@ -160,27 +214,27 @@ class PubSubClient(BaseClient):
         self.xmlstream.send(iq)
 
     def result_create_node(self, iq):
-#         if hasattr(iq, "error"):
-#             node = self.requests[iq['id']]
-#             if hasattr(iq.error, "conflict"):
-#                 # node is already there, nothing important.
-#                 self.warn("NodeID exists: %s" % node)
-#             else:
-#                 err_type = ""
-#                 err_name = ""
-#                 if iq.error:
-#                     if iq.error.has_key('type'):
-#                         err_type = iq.error['type']
-#                     if iq.error.firstChildElement and hasattr(iq.error.firstChildElement, "name"):
-#                         err_name = iq.error.firstChildElement.name
-#                 self.error("Can not create node: %s (error type: %s, %s)" %  (node, err_type, err_name))
+        node = self.requests[iq['id']]
+        if iq.error:
+            if iq.error.conflict:
+                # node is already there, nothing important.
+                self.warn("NodeID exists: %s" % node)
+            else:
+                err_type = ""
+                if iq.error['type']:
+                    err_type = iq.error['type']
+                self.error("Can not create node: %s (error type: %s)" %  (node, err_type))
+        else:
+            # no errors
+            # try subscribing to the node for debugging purposes
+            self.subscribe_to_node(node)
+
         self.requests.pop(iq['id'])
 
 
     def delete_node(self, node):
         iq = self.__iq("set")
-        pubsub = iq.addElement("pubsub")
-        pubsub['xmlns'] = "http://jabber.org/protocol/pubsub#owner"
+        pubsub = self.__add_pubsub(iq)
         delete = pubsub.addElement("delete")
         delete['node'] = node
         self.requests[iq['id']] = node
@@ -189,7 +243,59 @@ class PubSubClient(BaseClient):
     def result_delete_node(self, iq):
         self.requests.pop(iq['id'])
 
-
+    def message_chat(self, m):
+        body = ""
+        for e in m.elements():
+            if e.name == "body":
+                body = "%s" % e
+                break
+
+#         try:
+#             node = m.event.items['node']
+#             n = domish.Element((None, "message"))
+#             n.addElement("body", content = "published to: %s\n%s" % (node, m.event.items.toXml()))
+#             # for each listener in promiscuous mode send the published event
+#             self.xmlstream.send(n)
+#             return
+#         except:
+#             # not a pubsub message continue on
+#             pass
+
+        if body == "list groups":
+            def list_groups(iq):
+                reply = ""
+                for i in iq.query.elements():
+                    reply += "%s\n" % i['node']
+                n = domish.Element((None, "message"))
+                n['to'] = m['from']
+                n['from'] = self.id.full()
+                n.addElement("body", content = reply)
+                self.xmlstream.send(n)
+
+            self.add_result_hook("discover", list_groups)
+            self.discover()
+
+        elif body.startswith("configuration"):
+            # "configuration NODE"
+            node = ""
+            try:
+                node = body.split()[1].strip()
+            except IndexError:
+                pass
+
+            def get_configuration(iq):
+                reply = iq.toXml()
+                n = domish.Element((None, "message"))
+                n['to'] = m['from']
+                n['from'] = self.id.full()
+                n.addElement("body", content = reply)
+                self.xmlstream.send(n)
+
+            self.add_result_hook("configure", get_configuration)
+            self.configure_node(node)
+
+        else:
+            BaseClient.message_chat(self, m)
 
 
 class Slicemgr(xmlrpc.XMLRPC, PubSubClient):
@@ -234,13 +340,13 @@ class Slicemgr(xmlrpc.XMLRPC, PubSubClient):
         slice_prefix = "/".join([self.DOMAIN,slice])
         resource_prefix = "/".join([self.DOMAIN,slice,self.RESOURCES])
         def delete_slice_resources(iq):
-            node = iq['node']
-            if node.startswith(resource_prefix):
-                self.command_que.put(self.delete_node, node)
+            for i in iq.query.elements():
+                node = i['node']
+                if node.startswith(resource_prefix):
+                    self.command_que.put(self.delete_node, node)
 
         self.add_result_hook("discover", delete_slice_resources)
         self.discover()
-        self.delete_result_hook("discover")
 
         self.command_queue.put(( self.delete_node, resource_prefix) )
         self.command_queue.put(( self.delete_node, slice_prefix) )