diff src/plugins/plugin_misc_groupblog.py @ 308:ce3607b7198d

plugin group blog: blog collection cleaning
author Goffi <goffi@goffi.org>
date Thu, 07 Apr 2011 23:40:33 +0200
parents 1e4575e12581
children 53adec87d1d7
line wrap: on
line diff
--- a/src/plugins/plugin_misc_groupblog.py	Thu Apr 07 22:23:48 2011 +0200
+++ b/src/plugins/plugin_misc_groupblog.py	Thu Apr 07 23:40:33 2011 +0200
@@ -20,7 +20,7 @@
 """
 
 from logging import debug, info, error
-from twisted.internet import protocol
+from twisted.internet import protocol, defer
 from twisted.words.protocols.jabber import jid
 from twisted.words.protocols.jabber import error as jab_error
 import twisted.internet.error
@@ -32,7 +32,6 @@
 import uuid
 from time import time
 
-NS_BLOG_COLLECTION = 'urn:xmpp:blogcollection:0'
 MBLOG_COLLECTION = 'MBLOGCOLLECTION'
 CONFIG_NODE = 'CONFIG'
 NS_ACCESS_MODEL = 'pubsub#access_model'
@@ -55,6 +54,9 @@
 class NodeCreationError(Exception):
     pass
 
+class NodeDeletionError(Exception):
+    pass
+
 class GroupBlog():
     """This class use a PubSub Collection to manage roster access on microblog"""
 
@@ -62,23 +64,9 @@
         info(_("Group blog plugin initialization"))
         self.host = host
         self._blog_nodes={}
-        """host.bridge.addMethod("getLastMicroblogs", ".communication",
-                              in_sign='sis', out_sign='aa{ss}',
-                              method=self.getLastMicroblogs,
-                              async = True,
-                              doc = { 'summary':'retrieve items',
-                                      'param_0':'jid: publisher of wanted microblog',
-                                      'param_1':'max_items: see XEP-0060 #6.5.7',
-                                      'param_2':'%(doc_profile)s',
-                                      'return':'list of microblog data (dict)'
-                                    })
-        host.bridge.addMethod("setMicroblogAccess", ".communication", in_sign='ss', out_sign='',
-                               method=self.setMicroblogAccess,
-                               doc = {
-                                     })"""
 
-        host.bridge.addMethod("initBlogCollection", ".communication", in_sign='s', out_sign='',
-                               method=self.initBlogCollection,
+        host.bridge.addMethod("cleanBlogCollection", ".communication", in_sign='s', out_sign='',
+                               method=self.cleanBlogCollection,
                                doc = {
                                      })
         
@@ -148,32 +136,6 @@
             return
         client.client_initialized.addCallback(after_init)
 
-
-    def initBlogCollection(self, profile_key="@DEFAULT@"):
-        _jid, xmlstream = self.host.getJidNStream(profile_key)
-        _options = {NS_NODE_TYPE:TYPE_COLLECTION}
-        def cb(result):
-            #Node is created with right permission
-            debug(_("Microblog node collection created"))
-
-        def fatal_err(s_error):
-            #Something went wrong
-            error(_("Can't create node collection"))
-
-        def err_cb(s_error):
-            #If the node already exists, the condition is "conflict",
-            #else we have an unmanaged error
-            if s_error.value.condition=='conflict':
-                fatal_err(s_error)
-            else:
-                fatal_err(s_error)
-        
-        def create_node():
-            #return self.host.plugins["XEP-0060"].createNode(_jid.userhostJID(), NS_BLOG_COLLECTION, _options, profile_key=profile_key)
-            return self.host.plugins["XEP-0060"].createNode(jid.JID("pubsub.tazar.int"), self._getRootNode(_jid), _options, profile_key=profile_key)
-
-        create_node().addCallback(cb).addErrback(err_cb)
-
     def _publishMblog(self, name, message, pubsub_ent, profile):
         """Actually publish the message on the group blog
         @param name: name of the node where we publish
@@ -290,3 +252,44 @@
             return
         client.client_initialized.addCallback(after_init)
 
+    def _doCleaning(self, result, pubsub_ent, profile):
+        """Compare the node in config node, and the existing nodes, and delete unknown ones"""
+        #TODO: manage groups which don't exist anymore
+        assert(len(result)==2)
+        assert(result[0][0]==True and result[1][0]==True)
+        config_nodes = [item.firstChildElement()["node"] for item in result[0][1]]
+        existing_nodes = [item.nodeIdentifier for item in result[1][1]._items]
+        to_delete = set(config_nodes).symmetric_difference(existing_nodes)
+        def check_deletion(result):
+            for (success, value) in result:
+                if not success:
+                    msg = _("Can't delete node")
+                    error(msg)
+                    raise NodeDeletionError(msg)
+                    #TODO: log node which was not deleted
+
+        
+        d = defer.DeferredList([self.host.plugins["XEP-0060"].deleteNode(pubsub_ent, node, profile) for node in to_delete])
+        d.addCallback(check_deletion)
+
+    def cleanBlogCollection(self, profile_key='@DEFAULT@'):
+        """Remove blog nodes not referenced in config node"""
+        debug(_('Getting mblog nodes'))
+        profile = self.host.memory.getProfileName(profile_key)
+        if not profile:
+            error(_("Unknown profile"))
+            return {}
+        
+        def after_init(ignore):
+            pubsub_ent = self.host.memory.getServerServiceEntity("pubsub", "service", profile)
+            _jid, xmlstream = self.host.getJidNStream(profile_key)
+            d_config = self.host.plugins["XEP-0060"].getItems(pubsub_ent, self._getConfigNode(_jid), profile_key=profile_key)
+            d_root = client.disco.requestItems(pubsub_ent, self._getRootNode(client.jid))
+            defer.DeferredList([d_config, d_root]).addCallback(self._doCleaning, pubsub_ent, profile)
+
+        client = self.host.getClient(profile)
+        if not client:
+            error(_('No client for this profile key: %s') % profile_key)
+            return
+        client.client_initialized.addCallback(after_init)
+