Mercurial > libervia-backend
diff src/plugins/plugin_misc_groupblog.py @ 1420:7c0acb966fd6
plugins groupblog, xep-0060: first pass of simplification
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 22 Apr 2015 20:21:55 +0200 |
parents | be2df1ddea8e |
children | 882e5fabf68c |
line wrap: on
line diff
--- a/src/plugins/plugin_misc_groupblog.py Wed Apr 22 18:30:28 2015 +0200 +++ b/src/plugins/plugin_misc_groupblog.py Wed Apr 22 20:21:55 2015 +0200 @@ -143,6 +143,8 @@ host.trigger.add("PubSubItemsReceived", self.pubSubItemsReceivedTrigger) + ## plugin management methods ## + def getHandler(self, profile): return GroupBlog_handler() @@ -212,6 +214,8 @@ return False return True + ## internal helping methodes ## + def _handleCommentsItems(self, items, service, node_identifier): """ Convert comments items to groupblog data, and send them as signals @@ -268,6 +272,8 @@ """ return NS_NODE_PREFIX + publisher.userhost() + ## publish ## + def _publishMblog(self, service, client, access_type, access_list, message, extra): """Actually publish the message on the group blog @@ -291,7 +297,7 @@ if extra.get('allow_comments', 'False').lower() == 'true': # XXX: use the item identifier? http://bugs.goffi.org/show_bug.cgi?id=63 - comments_node = self.__fillCommentsElement(mblog_data, None, node_name, service) + comments_node = self._fillCommentsElement(mblog_data, None, node_name, service) _options = {P.OPT_ACCESS_MODEL: access_model_value, P.OPT_PERSIST_ITEMS: 1, P.OPT_MAX_ITEMS: -1, @@ -335,7 +341,7 @@ entry_d.addCallback(itemCreated) return entry_d - def __fillCommentsElement(self, mblog_data, entry_id, node_name, service_jid): + def _fillCommentsElement(self, mblog_data, entry_id, node_name, service_jid): """ @param mblog_data: dict containing the microblog data @param entry_id: unique identifier of the entry @@ -356,6 +362,7 @@ def sendGroupBlog(self, access_type, access_list, message, extra, profile_key=C.PROF_KEY_NONE): """Publish a microblog with given item access + @param access_type: one of "PUBLIC", "GROUP", "JID" @param access_list: list of authorized entity (empty list for PUBLIC ACCESS, list of groups or list of jids) for this item @@ -385,80 +392,6 @@ return self._initialise(profile_key).addCallback(initialised) - def deleteGroupBlog(self, pub_data, comments, profile_key=C.PROF_KEY_NONE): - """Delete a microblog item from a node. - @param pub_data: a tuple (service, node identifier, item identifier) - @param comments: comments node identifier (for main item) or empty string - @param profile_key: %(doc_profile_key)s - """ - - def initialised(result): - profile, client = result - service, node, item_id = pub_data - service_jid = jid.JID(service) if service else client.item_access_pubsub - if comments or not node: # main item - node = self.getNodeName(client.jid) - if comments: - # remove the associated comments node - comments_service, comments_node = self.host.plugins["XEP-0277"].parseCommentUrl(comments) - d = self.host.plugins["XEP-0060"].deleteNode(comments_service, comments_node, profile_key=profile) - d.addErrback(lambda failure: log.error(u"Deletion of node %s failed: %s" % (comments_node, failure.getErrorMessage()))) - # remove the item itself - d = self.host.plugins["XEP-0060"].retractItems(service_jid, node, [item_id], profile_key=profile) - d.addErrback(lambda failure: log.error(u"Deletion of item %s from %s failed: %s" % (item_id, node, failure.getErrorMessage()))) - return d - - def notify(d): - # TODO: this works only on the same host, and notifications for item deletion should be - # implemented according to http://xmpp.org/extensions/xep-0060.html#publisher-delete-success-notify - # instead. The notification mechanism implemented in sat_pubsub and wokkel have apriori - # a problem with retrieving the subscriptions, or something else. - service, node, item_id = pub_data - publisher = self.host.getJidNStream(profile_key)[0] - profile = self.host.memory.getProfileName(profile_key) - gbdatum = {'id': item_id, 'type': 'main_item' if (comments or not node) else 'comment'} - self.host.bridge.personalEvent(publisher.full(), "MICROBLOG_DELETE", gbdatum, profile) - return d - - return self._initialise(profile_key).addCallback(initialised).addCallback(notify) - - def updateGroupBlog(self, pub_data, comments, message, extra, profile_key=C.PROF_KEY_NONE): - """Modify a microblog node - @param pub_data: a tuple (service, node identifier, item identifier) - @param comments: comments node identifier (for main item) or empty string - @param message: new message - @param extra: dict which option name as key, which can be: - - allow_comments: True to accept an other level of comments, False else (default: False) - - rich: if present, contain rich text in currently selected syntax - @param profile_key: %(doc_profile) - """ - - def initialised(result): - profile, client = result - mblog_data = {'content': message} - for attr in ['content_rich', 'title', 'title_rich']: - if attr in extra and extra[attr]: - mblog_data[attr] = extra[attr] - service, node, item_id = pub_data - service_jid = jid.JID(service) if service else client.item_access_pubsub - if comments or not node: # main item - node = self.getNodeName(client.jid) - mblog_data['id'] = unicode(item_id) - if 'published' in extra: - mblog_data['published'] = extra['published'] - if extra.get('allow_comments', 'False').lower() == 'true': - comments_service, comments_node = self.host.plugins["XEP-0277"].parseCommentUrl(comments) - # we could use comments_node directly but it's safer to rebuild it - # XXX: use the item identifier? http://bugs.goffi.org/show_bug.cgi?id=63 - entry_id = comments_node.split('_')[1].split('__')[0] - self.__fillCommentsElement(mblog_data, entry_id, node, service_jid) - entry_d = self.host.plugins["XEP-0277"].data2entry(mblog_data, profile) - entry_d.addCallback(lambda mblog_item: self.host.plugins["XEP-0060"].publish(service_jid, node, items=[mblog_item], profile_key=profile)) - entry_d.addErrback(lambda failure: log.error(u"Modification of %s failed: %s" % (pub_data, failure.getErrorMessage()))) - return entry_d - - return self._initialise(profile_key).addCallback(initialised) - def sendGroupBlogComment(self, node_url, message, extra, profile_key=C.PROF_KEY_NONE): """Publish a comment in the given node @param node url: link to the comments node as specified in XEP-0277 and given in microblog data's comments key @@ -519,6 +452,48 @@ d_list.append(self.item2gbdata(item).addCallback(cb)) return defer.DeferredList(d_list, consumeErrors=True).addCallback(lambda result: [value for (success, value) in result if success]) + ## modify ## + + def updateGroupBlog(self, pub_data, comments, message, extra, profile_key=C.PROF_KEY_NONE): + """Modify a microblog node + + @param pub_data: a tuple (service, node identifier, item identifier) + @param comments: comments node identifier (for main item) or empty string + @param message: new message + @param extra: dict which option name as key, which can be: + - allow_comments: True to accept an other level of comments, False else (default: False) + - rich: if present, contain rich text in currently selected syntax + @param profile_key: %(doc_profile) + """ + + def initialised(result): + profile, client = result + mblog_data = {'content': message} + for attr in ['content_rich', 'title', 'title_rich']: + if attr in extra and extra[attr]: + mblog_data[attr] = extra[attr] + service, node, item_id = pub_data + service_jid = jid.JID(service) if service else client.item_access_pubsub + if comments or not node: # main item + node = self.getNodeName(client.jid) + mblog_data['id'] = unicode(item_id) + if 'published' in extra: + mblog_data['published'] = extra['published'] + if extra.get('allow_comments', 'False').lower() == 'true': + comments_service, comments_node = self.host.plugins["XEP-0277"].parseCommentUrl(comments) + # we could use comments_node directly but it's safer to rebuild it + # XXX: use the item identifier? http://bugs.goffi.org/show_bug.cgi?id=63 + entry_id = comments_node.split('_')[1].split('__')[0] + self._fillCommentsElement(mblog_data, entry_id, node, service_jid) + entry_d = self.host.plugins["XEP-0277"].data2entry(mblog_data, profile) + entry_d.addCallback(lambda mblog_item: self.host.plugins["XEP-0060"].publish(service_jid, node, items=[mblog_item], profile_key=profile)) + entry_d.addErrback(lambda failure: log.error(u"Modification of %s failed: %s" % (pub_data, failure.getErrorMessage()))) + return entry_d + + return self._initialise(profile_key).addCallback(initialised) + + ## get ## + def _getOrCountComments(self, items, max=0, profile_key=C.PROF_KEY_NONE): """Get and/or count the comments of the given items. @@ -553,7 +528,7 @@ deferred_list.addCallback(lambda result: [value for (success, value) in result if success]) return deferred_list - def __getGroupBlogs(self, pub_jid_s, item_ids=None, rsm=None, max_comments=0, profile_key=C.PROF_KEY_NONE): + def _getGroupBlogs(self, pub_jid_s, item_ids=None, rsm=None, max_comments=0, profile_key=C.PROF_KEY_NONE): """Retrieve previously published items from a publish subscribe node. @param pub_jid_s: jid of the publisher @@ -594,7 +569,7 @@ - RSM response data """ max_comments = 0 if count_comments else DO_NOT_COUNT_COMMENTS - return self.__getGroupBlogs(pub_jid_s, item_ids=item_ids, rsm=rsm, max_comments=max_comments, profile_key=profile_key) + return self._getGroupBlogs(pub_jid_s, item_ids=item_ids, rsm=rsm, max_comments=max_comments, profile_key=profile_key) def getGroupBlogsWithComments(self, pub_jid_s, item_ids=None, rsm=None, max_comments=None, profile_key=C.PROF_KEY_NONE): """Get the published microblogs of the specified IDs and their comments. If @@ -614,7 +589,7 @@ if max_comments is None: max_comments = MAX_COMMENTS assert(max_comments > 0) # otherwise the return signature is not the same - return self.__getGroupBlogs(pub_jid_s, item_ids=item_ids, rsm=rsm, max_comments=max_comments, profile_key=profile_key) + return self._getGroupBlogs(pub_jid_s, item_ids=item_ids, rsm=rsm, max_comments=max_comments, profile_key=profile_key) def getGroupBlogsAtom(self, pub_jid_s, rsm=None, profile_key=C.PROF_KEY_NONE): """Get the atom feed of the last published microblogs @@ -719,6 +694,8 @@ #TODO: we need to use the server corresponding to the host of the jid return DeferredItemsFromMany(self, cb, profile_key).get(publishers_type, publishers, rsm=rsm) + ## subscribe ## + def subscribeGroupBlog(self, pub_jid, profile_key=C.PROF_KEY_NONE): def initialised(result): profile, client = result @@ -752,6 +729,46 @@ yield defer.DeferredList(d_list, consumeErrors=False) defer.returnValue(None) + ## delete ## + + def deleteGroupBlog(self, pub_data, comments, profile_key=C.PROF_KEY_NONE): + """Delete a microblog item from a node. + + @param pub_data: a tuple (service, node identifier, item identifier) + @param comments: comments node identifier (for main item) or empty string + @param profile_key: %(doc_profile_key)s + """ + + def initialised(result): + profile, client = result + service, node, item_id = pub_data + service_jid = jid.JID(service) if service else client.item_access_pubsub + if comments or not node: # main item + node = self.getNodeName(client.jid) + if comments: + # remove the associated comments node + comments_service, comments_node = self.host.plugins["XEP-0277"].parseCommentUrl(comments) + d = self.host.plugins["XEP-0060"].deleteNode(comments_service, comments_node, profile_key=profile) + d.addErrback(lambda failure: log.error(u"Deletion of node %s failed: %s" % (comments_node, failure.getErrorMessage()))) + # remove the item itself + d = self.host.plugins["XEP-0060"].retractItems(service_jid, node, [item_id], profile_key=profile) + d.addErrback(lambda failure: log.error(u"Deletion of item %s from %s failed: %s" % (item_id, node, failure.getErrorMessage()))) + return d + + def notify(d): + # TODO: this works only on the same host, and notifications for item deletion should be + # implemented according to http://xmpp.org/extensions/xep-0060.html#publisher-delete-success-notify + # instead. The notification mechanism implemented in sat_pubsub and wokkel have apriori + # a problem with retrieving the subscriptions, or something else. + service, node, item_id = pub_data + publisher = self.host.getJidNStream(profile_key)[0] + profile = self.host.memory.getProfileName(profile_key) + gbdatum = {'id': item_id, 'type': 'main_item' if (comments or not node) else 'comment'} + self.host.bridge.personalEvent(publisher.full(), "MICROBLOG_DELETE", gbdatum, profile) + return d + + return self._initialise(profile_key).addCallback(initialised).addCallback(notify) + def deleteAllGroupBlogsAndComments(self, profile_key=C.PROF_KEY_NONE): """Delete absolutely all the microblog data that the user has posted""" calls = [self.deleteAllGroupBlogs(profile_key), self.deleteAllGroupBlogsComments(profile_key)] @@ -865,9 +882,10 @@ return self._initialise(profile_key).addCallback(initialised) +## helper classes to manipulate items ## class DeferredItems(): - """Helper class to retrieve items using XEP-0060""" + """Retrieve items using XEP-0060""" def __init__(self, parent, cb, eb=None, profile_key=C.PROF_KEY_NONE): """ @@ -883,6 +901,7 @@ def get(self, node, item_ids=None, sub_id=None, rsm=None): """ + @param node (str): node identifier. @param item_ids (list[str]): list of items identifiers. @param sub_id (str): optional subscription identifier. @@ -898,7 +917,7 @@ profile, client = result rsm_ = wokkel_rsm.RSMRequest(**rsm) d = self.parent.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, - node, rsm_.max, + node, rsm_.max_, item_ids, sub_id, rsm_, profile_key=profile) @@ -924,7 +943,7 @@ self.cb = cb self.profile_key = profile_key - def __buildData(self, publishers_type, publishers, client): + def _buildData(self, publishers_type, publishers, client): jids = self.parent._getPublishersJIDs(publishers_type, publishers, client) return {publisher: self.parent.getNodeName(publisher) for publisher in jids} @@ -946,7 +965,7 @@ def initialised(result): profile, client = result - data = self.__buildData(publishers_type, publishers, client) + data = self._buildData(publishers_type, publishers, client) rsm_ = wokkel_rsm.RSMRequest(**rsm) d = self.parent.host.plugins["XEP-0060"].getItemsFromMany(client.item_access_pubsub, data, rsm_.max, sub_id,