comparison sat/plugins/plugin_xep_0329.py @ 3333:ac9342f359e9

plugin XEP-0329: download thumbnails: - thumbnails are now downloaded directly when BoB is used, `filename` is then filled - `utils.asDeferred` is now used for Jingle methods, so `async` coroutines can be used - (XEP-0231): fixed `dumpData`
author Goffi <goffi@goffi.org>
date Thu, 13 Aug 2020 23:46:18 +0200
parents 8bbd2ed924e8
children 33d9b38b5890
comparison
equal deleted inserted replaced
3332:1512cbd6c4ac 3333:ac9342f359e9
42 C.PI_NAME: "File Information Sharing", 42 C.PI_NAME: "File Information Sharing",
43 C.PI_IMPORT_NAME: "XEP-0329", 43 C.PI_IMPORT_NAME: "XEP-0329",
44 C.PI_TYPE: "XEP", 44 C.PI_TYPE: "XEP",
45 C.PI_MODES: C.PLUG_MODE_BOTH, 45 C.PI_MODES: C.PLUG_MODE_BOTH,
46 C.PI_PROTOCOLS: ["XEP-0329"], 46 C.PI_PROTOCOLS: ["XEP-0329"],
47 C.PI_DEPENDENCIES: ["XEP-0234", "XEP-0300", "XEP-0106"], 47 C.PI_DEPENDENCIES: ["XEP-0231", "XEP-0234", "XEP-0300", "XEP-0106"],
48 C.PI_MAIN: "XEP_0329", 48 C.PI_MAIN: "XEP_0329",
49 C.PI_HANDLER: "yes", 49 C.PI_HANDLER: "yes",
50 C.PI_DESCRIPTION: _("""Implementation of File Information Sharing"""), 50 C.PI_DESCRIPTION: _("""Implementation of File Information Sharing"""),
51 } 51 }
52 52
270 class XEP_0329(object): 270 class XEP_0329(object):
271 def __init__(self, host): 271 def __init__(self, host):
272 log.info(_("File Information Sharing initialization")) 272 log.info(_("File Information Sharing initialization"))
273 self.host = host 273 self.host = host
274 ShareNode.host = host 274 ShareNode.host = host
275 self._b = host.plugins["XEP-0231"]
275 self._h = host.plugins["XEP-0300"] 276 self._h = host.plugins["XEP-0300"]
276 self._jf = host.plugins["XEP-0234"] 277 self._jf = host.plugins["XEP-0234"]
277 host.bridge.addMethod( 278 host.bridge.addMethod(
278 "FISList", 279 "FISList",
279 ".plugin", 280 ".plugin",
670 def onComponentRequest(self, iq_elt, client): 671 def onComponentRequest(self, iq_elt, client):
671 return self._requestHandler( 672 return self._requestHandler(
672 client, iq_elt, self._compGetRootNodesCb, self._compGetFilesFromNodeCb 673 client, iq_elt, self._compGetRootNodesCb, self._compGetFilesFromNodeCb
673 ) 674 )
674 675
675 def _parseResult(self, iq_elt, client): 676 async def _parseResult(self, client, peer_jid, iq_elt):
676 query_elt = next(iq_elt.elements(NS_FIS, "query")) 677 query_elt = next(iq_elt.elements(NS_FIS, "query"))
677 files = [] 678 files = []
678 679
679 for elt in query_elt.elements(): 680 for elt in query_elt.elements():
680 if elt.name == "file": 681 if elt.name == "file":
681 # we have a file 682 # we have a file
682 try: 683 try:
683 file_data = self._jf.parseFileElement(client, elt) 684 file_data = await self._jf.parseFileElement(client, elt)
684 except exceptions.DataError: 685 except exceptions.DataError:
685 continue 686 continue
686 file_data["type"] = C.FILE_TYPE_FILE 687 file_data["type"] = C.FILE_TYPE_FILE
688 try:
689 thumbs = file_data['extra'][C.KEY_THUMBNAILS]
690 except KeyError:
691 log.debug(f"No thumbnail found for {file_data}")
692 else:
693 for thumb in thumbs:
694 if 'url' not in thumb and "id" in thumb:
695 try:
696 file_path = await self._b.getFile(client, peer_jid, thumb['id'])
697 except Exception as e:
698 log.warning(f"Can't get thumbnail {thumb['id']!r} for {file_data}: {e}")
699 else:
700 thumb['filename'] = file_path.name
701
687 elif elt.name == "directory" and elt.uri == NS_FIS: 702 elif elt.name == "directory" and elt.uri == NS_FIS:
688 # we have a directory 703 # we have a directory
689 704
690 file_data = {"name": elt["name"], "type": C.FILE_TYPE_DIRECTORY} 705 file_data = {"name": elt["name"], "type": C.FILE_TYPE_DIRECTORY}
691 self.host.trigger.point( 706 self.host.trigger.point(
1016 return files_data 1031 return files_data
1017 1032
1018 def _listFiles(self, target_jid, path, extra, profile): 1033 def _listFiles(self, target_jid, path, extra, profile):
1019 client = self.host.getClient(profile) 1034 client = self.host.getClient(profile)
1020 target_jid = client.jid if not target_jid else jid.JID(target_jid) 1035 target_jid = client.jid if not target_jid else jid.JID(target_jid)
1021 d = self.listFiles(client, target_jid, path or None) 1036 d = defer.ensureDeferred(self.listFiles(client, target_jid, path or None))
1022 d.addCallback(self._serializeData) 1037 d.addCallback(self._serializeData)
1023 return d 1038 return d
1024 1039
1025 def listFiles(self, client, target_jid, path=None, extra=None): 1040 async def listFiles(self, client, peer_jid, path=None, extra=None):
1026 """List file shared by an entity 1041 """List file shared by an entity
1027 1042
1028 @param target_jid(jid.JID): jid of the sharing entity 1043 @param peer_jid(jid.JID): jid of the sharing entity
1029 @param path(unicode, None): path to the directory containing shared files 1044 @param path(unicode, None): path to the directory containing shared files
1030 None to get root directories 1045 None to get root directories
1031 @param extra(dict, None): extra data 1046 @param extra(dict, None): extra data
1032 @return list(dict): shared files 1047 @return list(dict): shared files
1033 """ 1048 """
1034 iq_elt = client.IQ("get") 1049 iq_elt = client.IQ("get")
1035 iq_elt["to"] = target_jid.full() 1050 iq_elt["to"] = peer_jid.full()
1036 query_elt = iq_elt.addElement((NS_FIS, "query")) 1051 query_elt = iq_elt.addElement((NS_FIS, "query"))
1037 if path: 1052 if path:
1038 query_elt["node"] = path 1053 query_elt["node"] = path
1039 d = iq_elt.send() 1054 iq_result_elt = await iq_elt.send()
1040 d.addCallback(self._parseResult, client) 1055 return await self._parseResult(client, peer_jid, iq_result_elt)
1041 return d
1042 1056
1043 def _localSharesGet(self, profile): 1057 def _localSharesGet(self, profile):
1044 client = self.host.getClient(profile) 1058 client = self.host.getClient(profile)
1045 return self.localSharesGet(client) 1059 return self.localSharesGet(client)
1046 1060