comparison sat/plugins/plugin_xep_0277.py @ 3513:753d151da886

XEP-0277: new preview/mbPreview method: This method does more or less the same thing as sending, but without actually sending the item, and parse the generated element just after. This way, the triggers are run, and a preview of the item can be made for the resulting microblog data.
author Goffi <goffi@goffi.org>
date Thu, 29 Apr 2021 15:49:59 +0200
parents 6132d363f0e9
children 02eec2a5b5f9
comparison
equal deleted inserted replaced
3512:d018d2d8a9e5 3513:753d151da886
95 "mbSend", 95 "mbSend",
96 ".plugin", 96 ".plugin",
97 in_sign="ssss", 97 in_sign="ssss",
98 out_sign="", 98 out_sign="",
99 method=self._mbSend, 99 method=self._mbSend,
100 async_=True,
101 )
102 host.bridge.addMethod(
103 "mbPreview",
104 ".plugin",
105 in_sign="ssss",
106 out_sign="s",
107 method=self._mbPreview,
100 async_=True, 108 async_=True,
101 ) 109 )
102 host.bridge.addMethod( 110 host.bridge.addMethod(
103 "mbRetract", 111 "mbRetract",
104 ".plugin", 112 ".plugin",
649 "XEP-0277_data2entry", client, data, entry_elt, item_elt 657 "XEP-0277_data2entry", client, data, entry_elt, item_elt
650 ) 658 )
651 659
652 defer.returnValue(item_elt) 660 defer.returnValue(item_elt)
653 661
654 ## publish ## 662 ## publish/preview ##
655 663
656 def getCommentsNode(self, item_id): 664 def getCommentsNode(self, item_id):
657 """Generate comment node 665 """Generate comment node
658 666
659 @param item_id(unicode): id of the parent item 667 @param item_id(unicode): id of the parent item
801 809
802 yield self._p.setNodeAffiliations( 810 yield self._p.setNodeAffiliations(
803 client, comments_service, comments_node, comments_affiliations 811 client, comments_service, comments_node, comments_affiliations
804 ) 812 )
805 813
814 def friendlyId(self, data):
815 """Generate a user friendly id from title or content"""
816 id_base = regex.urlFriendlyText(data.get('title') or data.get('content', ''))
817 return f"{id_base}-{token_urlsafe(3)}"
818
806 def _mbSend(self, service, node, data, profile_key): 819 def _mbSend(self, service, node, data, profile_key):
807 service = jid.JID(service) if service else None 820 service = jid.JID(service) if service else None
808 node = node if node else NS_MICROBLOG 821 node = node if node else NS_MICROBLOG
809 client = self.host.getClient(profile_key) 822 client = self.host.getClient(profile_key)
810 data = data_format.deserialise(data) 823 data = data_format.deserialise(data)
811 return self.send(client, data, service, node) 824 return defer.ensureDeferred(self.send(client, data, service, node))
812 825
813 def friendlyId(self, data): 826 async def send(
814 """Generate a user friendly id from title or content""" 827 self,
815 id_base = regex.urlFriendlyText(data.get('title') or data.get('content', '')) 828 client: SatXMPPEntity,
816 return f"{id_base}-{token_urlsafe(3)}" 829 data: dict,
817 830 service: Optional[jid.JID] = None,
818 @defer.inlineCallbacks 831 node: Optional[str] = NS_MICROBLOG
819 def send(self, client, data, service=None, node=NS_MICROBLOG): 832 ) -> None:
820 """Send XEP-0277's microblog data 833 """Send XEP-0277's microblog data
821 834
822 @param data(dict): microblog data (must include at least a "content" or a "title" key). 835 @param data: microblog data (must include at least a "content" or a "title" key).
823 see http://wiki.goffi.org/wiki/Bridge_API_-_Microblogging/en for details 836 see http://wiki.goffi.org/wiki/Bridge_API_-_Microblogging/en for details
824 @param service(jid.JID, None): PubSub service where the microblog must be published 837 @param service: PubSub service where the microblog must be published
825 None to publish on profile's PEP 838 None to publish on profile's PEP
826 @param node(unicode, None): PubSub node to use (defaut to microblog NS) 839 @param node: PubSub node to use (defaut to microblog NS)
827 None is equivalend as using default value 840 None is equivalend as using default value
828 """ 841 """
829 # TODO: check that all data keys are used, this would avoid sending publicly a private message 842 # TODO: check that all data keys are used, this would avoid sending publicly a private message
830 # by accident (e.g. if group plugin is not loaded, and "group*" key are not used) 843 # by accident (e.g. if group plugin is not loaded, and "group*" key are not used)
831 if node is None: 844 if node is None:
837 item_id = self.friendlyId(data) 850 item_id = self.friendlyId(data)
838 else: 851 else:
839 item_id = str(shortuuid.uuid()) 852 item_id = str(shortuuid.uuid())
840 853
841 try: 854 try:
842 yield self._manageComments(client, data, service, node, item_id, access=None) 855 await self._manageComments(client, data, service, node, item_id, access=None)
843 except error.StanzaError: 856 except error.StanzaError:
844 log.warning("Can't create comments node for item {}".format(item_id)) 857 log.warning("Can't create comments node for item {}".format(item_id))
845 item = yield self.data2entry(client, data, item_id, service, node) 858 item = await self.data2entry(client, data, item_id, service, node)
846 ret = yield self._p.publish(client, service, node, [item]) 859 return await self._p.publish(client, service, node, [item])
847 defer.returnValue(ret) 860
861 def _mbPreview(self, service, node, data, profile_key):
862 service = jid.JID(service) if service else None
863 node = node if node else NS_MICROBLOG
864 client = self.host.getClient(profile_key)
865 data = data_format.deserialise(data)
866 d = defer.ensureDeferred(self.preview(client, data, service, node))
867 d.addCallback(data_format.serialise)
868 return d
869
870 async def preview(
871 self,
872 client: SatXMPPEntity,
873 data: dict,
874 service: Optional[jid.JID] = None,
875 node: Optional[str] = NS_MICROBLOG
876 ) -> dict:
877 """Preview microblog data without publishing them
878
879 params are the same as for [send]
880 @return: microblog data as would be retrieved from published item
881 """
882 if node is None:
883 node = NS_MICROBLOG
884
885 item_id = data.get("id", "")
886
887 # we have to serialise then deserialise to be sure that all triggers are called
888 item_elt = await self.data2entry(client, data, item_id, service, node)
889 item_elt.uri = pubsub.NS_PUBSUB
890 return await self.item2mbdata(client, item_elt, service, node)
891
848 892
849 ## retract ## 893 ## retract ##
850 894
851 def _mbRetract(self, service_jid_s, nodeIdentifier, itemIdentifier, profile_key): 895 def _mbRetract(self, service_jid_s, nodeIdentifier, itemIdentifier, profile_key):
852 """Call self._p._retractItem, but use default node if node is empty""" 896 """Call self._p._retractItem, but use default node if node is empty"""