Mercurial > libervia-backend
comparison 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 |
comparison
equal
deleted
inserted
replaced
307:1e4575e12581 | 308:ce3607b7198d |
---|---|
18 You should have received a copy of the GNU General Public License | 18 You should have received a copy of the GNU General Public License |
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 """ | 20 """ |
21 | 21 |
22 from logging import debug, info, error | 22 from logging import debug, info, error |
23 from twisted.internet import protocol | 23 from twisted.internet import protocol, defer |
24 from twisted.words.protocols.jabber import jid | 24 from twisted.words.protocols.jabber import jid |
25 from twisted.words.protocols.jabber import error as jab_error | 25 from twisted.words.protocols.jabber import error as jab_error |
26 import twisted.internet.error | 26 import twisted.internet.error |
27 from twisted.words.xish import domish | 27 from twisted.words.xish import domish |
28 from sat.tools.xml_tools import ElementParser | 28 from sat.tools.xml_tools import ElementParser |
30 from wokkel import disco,pubsub | 30 from wokkel import disco,pubsub |
31 from feed.atom import Entry, Author | 31 from feed.atom import Entry, Author |
32 import uuid | 32 import uuid |
33 from time import time | 33 from time import time |
34 | 34 |
35 NS_BLOG_COLLECTION = 'urn:xmpp:blogcollection:0' | |
36 MBLOG_COLLECTION = 'MBLOGCOLLECTION' | 35 MBLOG_COLLECTION = 'MBLOGCOLLECTION' |
37 CONFIG_NODE = 'CONFIG' | 36 CONFIG_NODE = 'CONFIG' |
38 NS_ACCESS_MODEL = 'pubsub#access_model' | 37 NS_ACCESS_MODEL = 'pubsub#access_model' |
39 NS_PERSIST_ITEMS = 'pubsub#persist_items' | 38 NS_PERSIST_ITEMS = 'pubsub#persist_items' |
40 NS_MAX_ITEMS = 'pubsub#max_items' | 39 NS_MAX_ITEMS = 'pubsub#max_items' |
53 } | 52 } |
54 | 53 |
55 class NodeCreationError(Exception): | 54 class NodeCreationError(Exception): |
56 pass | 55 pass |
57 | 56 |
57 class NodeDeletionError(Exception): | |
58 pass | |
59 | |
58 class GroupBlog(): | 60 class GroupBlog(): |
59 """This class use a PubSub Collection to manage roster access on microblog""" | 61 """This class use a PubSub Collection to manage roster access on microblog""" |
60 | 62 |
61 def __init__(self, host): | 63 def __init__(self, host): |
62 info(_("Group blog plugin initialization")) | 64 info(_("Group blog plugin initialization")) |
63 self.host = host | 65 self.host = host |
64 self._blog_nodes={} | 66 self._blog_nodes={} |
65 """host.bridge.addMethod("getLastMicroblogs", ".communication", | 67 |
66 in_sign='sis', out_sign='aa{ss}', | 68 host.bridge.addMethod("cleanBlogCollection", ".communication", in_sign='s', out_sign='', |
67 method=self.getLastMicroblogs, | 69 method=self.cleanBlogCollection, |
68 async = True, | |
69 doc = { 'summary':'retrieve items', | |
70 'param_0':'jid: publisher of wanted microblog', | |
71 'param_1':'max_items: see XEP-0060 #6.5.7', | |
72 'param_2':'%(doc_profile)s', | |
73 'return':'list of microblog data (dict)' | |
74 }) | |
75 host.bridge.addMethod("setMicroblogAccess", ".communication", in_sign='ss', out_sign='', | |
76 method=self.setMicroblogAccess, | |
77 doc = { | |
78 })""" | |
79 | |
80 host.bridge.addMethod("initBlogCollection", ".communication", in_sign='s', out_sign='', | |
81 method=self.initBlogCollection, | |
82 doc = { | 70 doc = { |
83 }) | 71 }) |
84 | 72 |
85 host.bridge.addMethod("getMblogNodes", ".communication", in_sign='s', out_sign='a{sas}', | 73 host.bridge.addMethod("getMblogNodes", ".communication", in_sign='s', out_sign='a{sas}', |
86 method=self.getMblogNodes, | 74 method=self.getMblogNodes, |
145 client = self.host.getClient(profile) | 133 client = self.host.getClient(profile) |
146 if not client: | 134 if not client: |
147 error(_('No client for this profile key: %s') % profile_key) | 135 error(_('No client for this profile key: %s') % profile_key) |
148 return | 136 return |
149 client.client_initialized.addCallback(after_init) | 137 client.client_initialized.addCallback(after_init) |
150 | |
151 | |
152 def initBlogCollection(self, profile_key="@DEFAULT@"): | |
153 _jid, xmlstream = self.host.getJidNStream(profile_key) | |
154 _options = {NS_NODE_TYPE:TYPE_COLLECTION} | |
155 def cb(result): | |
156 #Node is created with right permission | |
157 debug(_("Microblog node collection created")) | |
158 | |
159 def fatal_err(s_error): | |
160 #Something went wrong | |
161 error(_("Can't create node collection")) | |
162 | |
163 def err_cb(s_error): | |
164 #If the node already exists, the condition is "conflict", | |
165 #else we have an unmanaged error | |
166 if s_error.value.condition=='conflict': | |
167 fatal_err(s_error) | |
168 else: | |
169 fatal_err(s_error) | |
170 | |
171 def create_node(): | |
172 #return self.host.plugins["XEP-0060"].createNode(_jid.userhostJID(), NS_BLOG_COLLECTION, _options, profile_key=profile_key) | |
173 return self.host.plugins["XEP-0060"].createNode(jid.JID("pubsub.tazar.int"), self._getRootNode(_jid), _options, profile_key=profile_key) | |
174 | |
175 create_node().addCallback(cb).addErrback(err_cb) | |
176 | 138 |
177 def _publishMblog(self, name, message, pubsub_ent, profile): | 139 def _publishMblog(self, name, message, pubsub_ent, profile): |
178 """Actually publish the message on the group blog | 140 """Actually publish the message on the group blog |
179 @param name: name of the node where we publish | 141 @param name: name of the node where we publish |
180 @param message: message to publish | 142 @param message: message to publish |
288 if not client: | 250 if not client: |
289 error(_('No client for this profile key: %s') % profile_key) | 251 error(_('No client for this profile key: %s') % profile_key) |
290 return | 252 return |
291 client.client_initialized.addCallback(after_init) | 253 client.client_initialized.addCallback(after_init) |
292 | 254 |
255 def _doCleaning(self, result, pubsub_ent, profile): | |
256 """Compare the node in config node, and the existing nodes, and delete unknown ones""" | |
257 #TODO: manage groups which don't exist anymore | |
258 assert(len(result)==2) | |
259 assert(result[0][0]==True and result[1][0]==True) | |
260 config_nodes = [item.firstChildElement()["node"] for item in result[0][1]] | |
261 existing_nodes = [item.nodeIdentifier for item in result[1][1]._items] | |
262 to_delete = set(config_nodes).symmetric_difference(existing_nodes) | |
263 def check_deletion(result): | |
264 for (success, value) in result: | |
265 if not success: | |
266 msg = _("Can't delete node") | |
267 error(msg) | |
268 raise NodeDeletionError(msg) | |
269 #TODO: log node which was not deleted | |
270 | |
271 | |
272 d = defer.DeferredList([self.host.plugins["XEP-0060"].deleteNode(pubsub_ent, node, profile) for node in to_delete]) | |
273 d.addCallback(check_deletion) | |
274 | |
275 def cleanBlogCollection(self, profile_key='@DEFAULT@'): | |
276 """Remove blog nodes not referenced in config node""" | |
277 debug(_('Getting mblog nodes')) | |
278 profile = self.host.memory.getProfileName(profile_key) | |
279 if not profile: | |
280 error(_("Unknown profile")) | |
281 return {} | |
282 | |
283 def after_init(ignore): | |
284 pubsub_ent = self.host.memory.getServerServiceEntity("pubsub", "service", profile) | |
285 _jid, xmlstream = self.host.getJidNStream(profile_key) | |
286 d_config = self.host.plugins["XEP-0060"].getItems(pubsub_ent, self._getConfigNode(_jid), profile_key=profile_key) | |
287 d_root = client.disco.requestItems(pubsub_ent, self._getRootNode(client.jid)) | |
288 defer.DeferredList([d_config, d_root]).addCallback(self._doCleaning, pubsub_ent, profile) | |
289 | |
290 client = self.host.getClient(profile) | |
291 if not client: | |
292 error(_('No client for this profile key: %s') % profile_key) | |
293 return | |
294 client.client_initialized.addCallback(after_init) | |
295 |