changeset 85:ec557449d1aa

Implement node retraction, with storage support for pgsql.
author Ralph Meijer <ralphm@ik.nu>
date Tue, 09 Nov 2004 16:48:20 +0000
parents 34be83a0bd2e
children 479895007e3f
files idavoll/backend.py idavoll/idavoll.py idavoll/pgsql_backend.py idavoll/pubsub.py
diffstat 4 files changed, 89 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/idavoll/backend.py	Tue Nov 09 15:58:06 2004 +0000
+++ b/idavoll/backend.py	Tue Nov 09 16:48:20 2004 +0000
@@ -346,3 +346,37 @@
             return d
         else:
             return self.parent.storage.get_items(node_id, max_items)
+
+class RetractionService(service.Service):
+
+    __implements__ = IRetractionService,
+                                                                                
+    def retract_item(self, node_id, item_ids, requestor):
+        d1 = self.parent.storage.get_node_configuration(node_id)
+        d2 = self.parent.storage.get_affiliation(node_id, requestor)
+        d = defer.DeferredList([d1, d2], fireOnOneErrback=1)
+        d.addErrback(lambda x: x.value[0])
+        d.addCallback(self._do_retract, node_id, item_ids)
+        return d
+                                                                                
+    def _do_retract(self, result, node_id, item_ids):
+        configuration = result[0][1]
+        persist_items = configuration["persist_items"]
+        affiliation = result[1][1]
+                                                                                
+        if affiliation not in ['owner', 'publisher']:
+            raise NotAuthorized
+                                                                                
+        if not persist_items:
+            raise NodeNotPersistent
+                                                                                
+        d = self.parent.storage.remove_items(node_id, item_ids)
+        d.addCallback(self._do_notify_retraction, node_id)
+        return d
+                                                                                
+    def _do_notify_retraction(self, result, node_id):
+        self.parent.dispatch({ 'item_ids': result, 'node_id': node_id },
+                             '//event/pubsub/retract')
+                                                                                
+    def purge_node(self, node_id, requestor):
+        pass
--- a/idavoll/idavoll.py	Tue Nov 09 15:58:06 2004 +0000
+++ b/idavoll/idavoll.py	Tue Nov 09 16:48:20 2004 +0000
@@ -167,6 +167,10 @@
         bsc.setServiceParent(bs)
         component.IService(bsc).setServiceParent(sm)
 
+        bsc = b.RetractionService()
+        bsc.setServiceParent(bs)
+        component.IService(bsc).setServiceParent(sm)
+
     s = IdavollService()
     s.setServiceParent(sm)
 
--- a/idavoll/pgsql_backend.py	Tue Nov 09 15:58:06 2004 +0000
+++ b/idavoll/pgsql_backend.py	Tue Nov 09 16:48:20 2004 +0000
@@ -289,6 +289,24 @@
         result = cursor.fetchall()
         return [r[0] for r in result]
 
+    def remove_items(self, node_id, item_ids):
+        return self.dbpool.runInteraction(self._remove_items, node_id, item_ids)
+
+    def _remove_items(self, cursor, node_id, item_ids):
+        deleted = []
+
+        for item_id in item_ids:
+            cursor.execute("""DELETE FROM items WHERE
+                              node_id=(SELECT id FROM nodes WHERE node=%s) AND
+                              item=%s""",
+                           (node_id.encode('utf-8'),
+                            item_id.encode('utf-8')))
+
+            if cursor.rowcount:
+                deleted.append(item_id)
+
+        return deleted
+
 class BackendService(backend.BackendService):
     """ PostgreSQL backend Service for a JEP-0060 pubsub service """
 
@@ -309,3 +327,6 @@
 
 class ItemRetrievalService(backend.ItemRetrievalService):
     pass
+
+class RetractionService(backend.RetractionService):
+    pass
--- a/idavoll/pubsub.py	Tue Nov 09 15:58:06 2004 +0000
+++ b/idavoll/pubsub.py	Tue Nov 09 16:48:20 2004 +0000
@@ -27,6 +27,7 @@
 PUBSUB_CONFIGURE_SET = PUBSUB_SET + '/configure'
 PUBSUB_AFFILIATIONS = PUBSUB_GET + '/affiliations'
 PUBSUB_ITEMS = PUBSUB_GET + '/items'
+PUBSUB_RETRACT = PUBSUB_SET + '/retract'
 
 class Error(Exception):
     pubsub_error = None
@@ -407,3 +408,32 @@
         return [reply]
 
 components.registerAdapter(ComponentServiceFromItemRetrievalService, backend.IItemRetrievalService, component.IService)
+
+class ComponentServiceFromRetractionService(Service):
+
+    def componentConnected(self, xmlstream):
+        xmlstream.addObserver(PUBSUB_RETRACT, self.onRetract)
+
+    def onRetract(self, iq):
+        self.handler_wrapper(self._onRetract, iq)
+
+    def _onRetract(self, iq):
+        try:
+            node = iq.pubsub.retract["node"]
+        except KeyError:
+            raise BadRequest
+
+        item_ids = []
+        for child in iq.pubsub.retract.children:
+            if child.__class__ == domish.Element and child.name == 'item':
+                try:
+                    item_ids.append(child["id"])
+                except KeyError:
+                    raise BadRequest
+
+        print item_ids
+
+        return self.backend.retract_item(node, item_ids,
+                                    jid.JID(iq["from"]).userhostJID())
+
+components.registerAdapter(ComponentServiceFromRetractionService, backend.IRetractionService, component.IService)