comparison sat/plugins/plugin_xep_0234.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 5887fb414758
children 3dc8835d96cc
comparison
equal deleted inserted replaced
3332:1512cbd6c4ac 3333:ac9342f359e9
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 2
3 # SAT plugin for Jingle File Transfer (XEP-0234) 3 # SàT plugin for Jingle File Transfer (XEP-0234)
4 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org) 4 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org)
5 5
6 # This program is free software: you can redistribute it and/or modify 6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License as published by 7 # it under the terms of the GNU Affero General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or 8 # the Free Software Foundation, either version 3 of the License, or
179 if kwargs: 179 if kwargs:
180 file_data = file_data.copy() 180 file_data = file_data.copy()
181 file_data.update(kwargs) 181 file_data.update(kwargs)
182 return self.buildFileElement(client, **file_data) 182 return self.buildFileElement(client, **file_data)
183 183
184 def parseFileElement( 184 async def parseFileElement(
185 self, client, file_elt, file_data=None, given=False, parent_elt=None, 185 self, client, file_elt, file_data=None, given=False, parent_elt=None,
186 keep_empty_range=False): 186 keep_empty_range=False):
187 """Parse a <file> element and file dictionary accordingly 187 """Parse a <file> element and file dictionary accordingly
188 188
189 @param file_data(dict, None): dict where the data will be set 189 @param file_data(dict, None): dict where the data will be set
449 file_data["path"] = extra["path"] 449 file_data["path"] = extra["path"]
450 self.buildFileElementFromDict(client, file_data, file_elt=file_elt) 450 self.buildFileElementFromDict(client, file_data, file_elt=file_elt)
451 451
452 return desc_elt 452 return desc_elt
453 453
454 def jingleRequestConfirmation(self, client, action, session, content_name, desc_elt): 454 async def jingleRequestConfirmation(
455 self, client, action, session, content_name, desc_elt
456 ):
455 """This method request confirmation for a jingle session""" 457 """This method request confirmation for a jingle session"""
456 content_data = session["contents"][content_name] 458 content_data = session["contents"][content_name]
457 senders = content_data["senders"] 459 senders = content_data["senders"]
458 if senders not in (self._j.ROLE_INITIATOR, self._j.ROLE_RESPONDER): 460 if senders not in (self._j.ROLE_INITIATOR, self._j.ROLE_RESPONDER):
459 log.warning("Bad sender, assuming initiator") 461 log.warning("Bad sender, assuming initiator")
465 raise failure.Failure(exceptions.DataError) 467 raise failure.Failure(exceptions.DataError)
466 file_data = {"progress_id": self.getProgressId(session, content_name)} 468 file_data = {"progress_id": self.getProgressId(session, content_name)}
467 469
468 if senders == self._j.ROLE_RESPONDER: 470 if senders == self._j.ROLE_RESPONDER:
469 # we send the file 471 # we send the file
470 return self._fileSendingRequestConf( 472 return await self._fileSendingRequestConf(
471 client, session, content_data, content_name, file_data, file_elt 473 client, session, content_data, content_name, file_data, file_elt
472 ) 474 )
473 else: 475 else:
474 # we receive the file 476 # we receive the file
475 return self._fileReceivingRequestConf( 477 return await self._fileReceivingRequestConf(
476 client, session, content_data, content_name, file_data, file_elt 478 client, session, content_data, content_name, file_data, file_elt
477 ) 479 )
478 480
479 @defer.inlineCallbacks 481 async def _fileSendingRequestConf(
480 def _fileSendingRequestConf(
481 self, client, session, content_data, content_name, file_data, file_elt 482 self, client, session, content_data, content_name, file_data, file_elt
482 ): 483 ):
483 """parse file_elt, and handle file retrieving/permission checking""" 484 """parse file_elt, and handle file retrieving/permission checking"""
484 self.parseFileElement(client, file_elt, file_data) 485 await self.parseFileElement(client, file_elt, file_data)
485 content_data["application_data"]["file_data"] = file_data 486 content_data["application_data"]["file_data"] = file_data
486 finished_d = content_data["finished_d"] = defer.Deferred() 487 finished_d = content_data["finished_d"] = defer.Deferred()
487 488
488 # confirmed_d is a deferred returning confimed value (only used if cont is False) 489 # confirmed_d is a deferred returning confimed value (only used if cont is False)
489 cont, confirmed_d = self.host.trigger.returnPoint( 490 cont, confirmed_d = self.host.trigger.returnPoint(
494 content_name, 495 content_name,
495 file_data, 496 file_data,
496 file_elt, 497 file_elt,
497 ) 498 )
498 if not cont: 499 if not cont:
499 confirmed = yield confirmed_d 500 confirmed = await confirmed_d
500 if confirmed: 501 if confirmed:
501 args = [client, session, content_name, content_data] 502 args = [client, session, content_name, content_data]
502 finished_d.addCallbacks( 503 finished_d.addCallbacks(
503 self._finishedCb, self._finishedEb, args, None, args 504 self._finishedCb, self._finishedEb, args, None, args
504 ) 505 )
505 defer.returnValue(confirmed) 506 return confirmed
506 507
507 log.warning(_("File continue is not implemented yet")) 508 log.warning(_("File continue is not implemented yet"))
508 defer.returnValue(False) 509 return False
509 510
510 def _fileReceivingRequestConf( 511 async def _fileReceivingRequestConf(
511 self, client, session, content_data, content_name, file_data, file_elt 512 self, client, session, content_data, content_name, file_data, file_elt
512 ): 513 ):
513 """parse file_elt, and handle user permission/file opening""" 514 """parse file_elt, and handle user permission/file opening"""
514 self.parseFileElement(client, file_elt, file_data, given=True) 515 await self.parseFileElement(client, file_elt, file_data, given=True)
515 try: 516 try:
516 hash_algo, file_data["given_file_hash"] = self._hash.parseHashElt(file_elt) 517 hash_algo, file_data["given_file_hash"] = self._hash.parseHashElt(file_elt)
517 except exceptions.NotFound: 518 except exceptions.NotFound:
518 try: 519 try:
519 hash_algo = self._hash.parseHashUsedElt(file_elt) 520 hash_algo = self._hash.parseHashUsedElt(file_elt)
538 file_data["name"] = name.replace("/", "_").replace("\\", "_") 539 file_data["name"] = name.replace("/", "_").replace("\\", "_")
539 540
540 content_data["application_data"]["file_data"] = file_data 541 content_data["application_data"]["file_data"] = file_data
541 542
542 # now we actualy request permission to user 543 # now we actualy request permission to user
543 def gotConfirmation(confirmed):
544 if confirmed:
545 args = [client, session, content_name, content_data]
546 finished_d.addCallbacks(
547 self._finishedCb, self._finishedEb, args, None, args
548 )
549 return confirmed
550 544
551 # deferred to track end of transfer 545 # deferred to track end of transfer
552 finished_d = content_data["finished_d"] = defer.Deferred() 546 finished_d = content_data["finished_d"] = defer.Deferred()
553 d = self._f.getDestDir( 547 confirmed = await self._f.getDestDir(
554 client, session["peer_jid"], content_data, file_data, stream_object=True 548 client, session["peer_jid"], content_data, file_data, stream_object=True
555 ) 549 )
556 d.addCallback(gotConfirmation) 550 if confirmed:
557 return d 551 args = [client, session, content_name, content_data]
552 finished_d.addCallbacks(
553 self._finishedCb, self._finishedEb, args, None, args
554 )
555 return confirmed
558 556
559 @defer.inlineCallbacks 557 @defer.inlineCallbacks
560 def jingleHandler(self, client, action, session, content_name, desc_elt): 558 def jingleHandler(self, client, action, session, content_name, desc_elt):
561 content_data = session["contents"][content_name] 559 content_data = session["contents"][content_name]
562 application_data = content_data["application_data"] 560 application_data = content_data["application_data"]