Mercurial > libervia-backend
comparison src/plugins/plugin_misc_groupblog.py @ 938:fc7e0828b18e
plugin account, groupblog: user can erase all their microblogs at once
author | souliane <souliane@mailoo.org> |
---|---|
date | Thu, 27 Mar 2014 02:24:20 +0100 |
parents | 1a759096ccbd |
children | c6d8fc63b1db |
comparison
equal
deleted
inserted
replaced
937:255e6953b2c3 | 938:fc7e0828b18e |
---|---|
20 from sat.core.i18n import _ | 20 from sat.core.i18n import _ |
21 from sat.core.constants import Const as C | 21 from sat.core.constants import Const as C |
22 from logging import debug, info, warning, error | 22 from logging import debug, info, warning, error |
23 from twisted.internet import defer | 23 from twisted.internet import defer |
24 from twisted.words.protocols.jabber import jid | 24 from twisted.words.protocols.jabber import jid |
25 from twisted.words.xish.domish import Element | 25 from twisted.words.xish.domish import Element, generateElementsNamed |
26 from sat.core import exceptions | 26 from sat.core import exceptions |
27 from wokkel import disco, data_form, iwokkel | 27 from wokkel import disco, data_form, iwokkel |
28 from zope.interface import implements | 28 from zope.interface import implements |
29 from feed import date | 29 from feed import date |
30 import uuid | 30 import uuid |
51 'JID': None, #JID is not yet managed | 51 'JID': None, #JID is not yet managed |
52 } | 52 } |
53 | 53 |
54 PLUGIN_INFO = { | 54 PLUGIN_INFO = { |
55 "name": "Group blogging throught collections", | 55 "name": "Group blogging throught collections", |
56 "import_name": "groupblog", | 56 "import_name": "GROUPBLOG", |
57 "type": "MISC", | 57 "type": "MISC", |
58 "protocols": [], | 58 "protocols": [], |
59 "dependencies": ["XEP-0277"], | 59 "dependencies": ["XEP-0277"], |
60 "main": "GroupBlog", | 60 "main": "GroupBlog", |
61 "handler": "yes", | 61 "handler": "yes", |
413 return d | 413 return d |
414 | 414 |
415 def notify(d): | 415 def notify(d): |
416 # TODO: this works only on the same host, and notifications for item deletion should be | 416 # TODO: this works only on the same host, and notifications for item deletion should be |
417 # implemented according to http://xmpp.org/extensions/xep-0060.html#publisher-delete-success-notify | 417 # implemented according to http://xmpp.org/extensions/xep-0060.html#publisher-delete-success-notify |
418 # instead. The notification mechanisms implemented in sat_pubsub and wokkel seem not compatible, | 418 # instead. The notification mechanism implemented in sat_pubsub and wokkel have apriori |
419 # see wokkel.pubsub.PubSubClient._onEvent_items and sat_pubsub.backend._doNotifyRetraction | 419 # a problem with retrieving the subscriptions, or something else. |
420 service, node, item_id = pub_data | 420 service, node, item_id = pub_data |
421 publisher = self.host.getJidNStream(profile_key)[0] | 421 publisher = self.host.getJidNStream(profile_key)[0] |
422 profile = self.host.memory.getProfileName(profile_key) | 422 profile = self.host.memory.getProfileName(profile_key) |
423 gbdatum = {'id': item_id, 'type': 'main_item' if (comments or not node) else 'comment'} | 423 gbdatum = {'id': item_id, 'type': 'main_item' if (comments or not node) else 'comment'} |
424 self.host.bridge.personalEvent(publisher.full(), "MICROBLOG_DELETE", gbdatum, profile) | 424 self.host.bridge.personalEvent(publisher.full(), "MICROBLOG_DELETE", gbdatum, profile) |
570 | 570 |
571 d = self.__getGroupBlogs(pub_jid_s, item_ids=item_ids, profile_key=profile_key) | 571 d = self.__getGroupBlogs(pub_jid_s, item_ids=item_ids, profile_key=profile_key) |
572 d.addCallback(get_comments) | 572 d.addCallback(get_comments) |
573 return d | 573 return d |
574 | 574 |
575 | |
576 def getLastGroupBlogs(self, pub_jid_s, max_items=10, profile_key=C.PROF_KEY_NONE): | 575 def getLastGroupBlogs(self, pub_jid_s, max_items=10, profile_key=C.PROF_KEY_NONE): |
577 """Get the last published microblogs | 576 """Get the last published microblogs |
578 @param pub_jid_s: jid of the publisher | 577 @param pub_jid_s: jid of the publisher |
579 @param max_items: how many microblogs we want to get (see XEP-0060 #6.5.7) | 578 @param max_items: how many microblogs we want to get (see XEP-0060 #6.5.7) |
580 @param profile_key: profile key | 579 @param profile_key: profile key |
663 @param max_items: how many microblogs we want to get | 662 @param max_items: how many microblogs we want to get |
664 @param profile_key: profile key | 663 @param profile_key: profile key |
665 """ | 664 """ |
666 | 665 |
667 def sendResult(result): | 666 def sendResult(result): |
668 """send result of DeferredList (list of microblogs to the calling method""" | 667 """send result of DeferredList (dict of jid => microblogs) to the calling method""" |
669 | 668 |
670 ret = {} | 669 ret = {} |
671 | 670 |
672 for (success, value) in result: | 671 for (success, value) in result: |
673 if success: | 672 if success: |
691 else: | 690 else: |
692 raise UnknownType | 691 raise UnknownType |
693 | 692 |
694 mblogs = [] | 693 mblogs = [] |
695 | 694 |
696 | |
697 for jid_ in jids: | 695 for jid_ in jids: |
698 d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, self.getNodeName(jid_), | 696 d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, self.getNodeName(jid_), |
699 max_items=max_items, profile_key=profile_key) | 697 max_items=max_items, profile_key=profile_key) |
700 d.addCallback(self._itemsConstruction, jid_, client) | 698 d.addCallback(self._itemsConstruction, jid_, client) |
701 d.addCallback(lambda gbdata, source_jid: (source_jid, gbdata), jid_.full()) | 699 d.addCallback(lambda gbdata, source_jid: (source_jid, gbdata), jid_.full()) |
771 if publishers_type == "ALL" and publishers: | 769 if publishers_type == "ALL" and publishers: |
772 raise Exception("Publishers list must be empty when getting microblogs for all contacts") | 770 raise Exception("Publishers list must be empty when getting microblogs for all contacts") |
773 return self._initialise(profile_key).addCallback(initialised) | 771 return self._initialise(profile_key).addCallback(initialised) |
774 #TODO: we need to use the server corresponding the the host of the jid | 772 #TODO: we need to use the server corresponding the the host of the jid |
775 | 773 |
774 def deleteAllGroupBlogsAndComments(self, profile_key=C.PROF_KEY_NONE): | |
775 """Delete absolutely all the microblog data that the user has posted""" | |
776 calls = [self.deleteAllGroupBlogs(profile_key), self.deleteAllGroupBlogsComments(profile_key)] | |
777 return defer.DeferredList(calls) | |
778 | |
779 def deleteAllGroupBlogs(self, profile_key=C.PROF_KEY_NONE): | |
780 """Delete all the main items and their comments that the user has posted | |
781 """ | |
782 def initialised(result): | |
783 profile, client = result | |
784 service = client.item_access_pubsub | |
785 jid_ = client.jid | |
786 | |
787 main_node = self.getNodeName(jid_) | |
788 d = self.host.plugins["XEP-0060"].deleteNode(service, main_node, profile_key=profile) | |
789 d.addCallback(lambda dummy: info(_("All microblog's main items from %s have been deleted!") % jid_.userhost())) | |
790 d.addErrback(lambda failure: error(_("Deletion of node %(node)s failed: %(message)s") % | |
791 {'node': main_node, 'message': failure.getErrorMessage()})) | |
792 return d | |
793 | |
794 return self._initialise(profile_key).addCallback(initialised) | |
795 | |
796 def deleteAllGroupBlogsComments(self, profile_key=C.PROF_KEY_NONE): | |
797 """Delete all the comments that the user posted on other's main items. | |
798 We avoid the conversions from item to microblog data as we only need | |
799 to retrieve some attributes, no need to convert text syntax... | |
800 """ | |
801 def initialised(result): | |
802 """Get all the main items from our contact list | |
803 @return: a DeferredList | |
804 """ | |
805 profile, client = result | |
806 service = client.item_access_pubsub | |
807 jids = [contact.jid.userhostJID() for contact in client.roster.getItems()] | |
808 blogs = [] | |
809 for jid_ in jids: | |
810 main_node = self.getNodeName(jid_) | |
811 d = self.host.plugins["XEP-0060"].getItems(service, main_node, profile_key=profile) | |
812 d.addCallback(getComments, client) | |
813 d.addErrback(lambda failure, main_node: error(_("Retrieval of items for node %(node)s failed: %(message)s") % | |
814 {'node': main_node, 'message': failure.getErrorMessage()}), main_node) | |
815 blogs.append(d) | |
816 | |
817 return defer.DeferredList(blogs) | |
818 | |
819 def getComments(items, client): | |
820 """Get all the comments for a list of items | |
821 @param items: a list of main items for one user | |
822 @param client: the client of the user | |
823 @return: a DeferredList | |
824 """ | |
825 comments = [] | |
826 for item in items: | |
827 try: | |
828 entry = generateElementsNamed(item.elements(), 'entry').next() | |
829 link = generateElementsNamed(entry.elements(), 'link').next() | |
830 except StopIteration: | |
831 continue | |
832 href = link.getAttribute('href') | |
833 service, node = self.host.plugins['XEP-0277'].parseCommentUrl(href) | |
834 d = self.host.plugins["XEP-0060"].getItems(service, node, profile_key=profile_key) | |
835 d.addCallback(lambda items, service, node: (service, node, items), service, node) | |
836 d.addErrback(lambda failure, node: error(_("Retrieval of comments for node %(node)s failed: %(message)s") % | |
837 {'node': node, 'message': failure.getErrorMessage()}), node) | |
838 comments.append(d) | |
839 dlist = defer.DeferredList(comments) | |
840 dlist.addCallback(deleteComments, client) | |
841 return dlist | |
842 | |
843 def deleteComments(result, client): | |
844 """Delete all the comments of the user that are found in result | |
845 @param result: a list of couple (success, value) with success a | |
846 boolean and value a tuple (service as JID, node_id, comment_items) | |
847 @param client: the client of the user | |
848 @return: a DeferredList with the deletions result | |
849 """ | |
850 user_jid_s = client.jid.userhost() | |
851 for (success, value) in result: | |
852 if not success: | |
853 continue | |
854 service, node_id, comment_items = value | |
855 item_ids = [] | |
856 for comment_item in comment_items: # for all the comments on one post | |
857 try: | |
858 entry = generateElementsNamed(comment_item.elements(), 'entry').next() | |
859 author = generateElementsNamed(entry.elements(), 'author').next() | |
860 name = generateElementsNamed(author.elements(), 'name').next() | |
861 except StopIteration: | |
862 continue | |
863 if name.children[0] == user_jid_s: | |
864 item_ids.append(comment_item.getAttribute('id')) | |
865 deletions = [] | |
866 if item_ids: # remove the comments of the user on the given post | |
867 d = self.host.plugins['XEP-0060'].retractItems(service, node_id, item_ids, profile_key=profile_key) | |
868 d.addCallback(lambda dummy, node_id: debug(_('Comments of user %(user)s in node %(node)s have been retracted') % | |
869 {'user': user_jid_s, 'node': node_id}), node_id) | |
870 d.addErrback(lambda failure, node_id: error(_("Retraction of comments from %(user)s in node %(node)s failed: %(message)s") % | |
871 {'user': user_jid_s, 'node': node_id, 'message': failure.getErrorMessage()}), node_id) | |
872 deletions.append(d) | |
873 return defer.DeferredList(deletions) | |
874 | |
875 return self._initialise(profile_key).addCallback(initialised) | |
876 | |
776 | 877 |
777 class GroupBlog_handler(XMPPHandler): | 878 class GroupBlog_handler(XMPPHandler): |
778 implements(iwokkel.IDisco) | 879 implements(iwokkel.IDisco) |
779 | 880 |
780 def getDiscoInfo(self, requestor, target, nodeIdentifier=''): | 881 def getDiscoInfo(self, requestor, target, nodeIdentifier=''): |