comparison sat/plugins/plugin_comp_file_sharing.py @ 3348:12c427156cac

component file sharing: generate thumbnails for videos
author Goffi <goffi@goffi.org>
date Tue, 25 Aug 2020 08:55:16 +0200
parents 2ad14b834730
children 000b6722bd35
comparison
equal deleted inserted replaced
3347:c8033a9357e7 3348:12c427156cac
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18
19 import os 19 import os
20 import os.path 20 import os.path
21 import mimetypes 21 import mimetypes
22 import tempfile
22 from functools import partial 23 from functools import partial
23 import shortuuid 24 import shortuuid
24 import unicodedata 25 import unicodedata
25 from urllib.parse import urljoin, urlparse, quote, unquote 26 from urllib.parse import urljoin, urlparse, quote, unquote
26 from pathlib import Path 27 from pathlib import Path
27 from sat.core.i18n import _ 28 from sat.core.i18n import _
28 from sat.core.constants import Const as C 29 from sat.core.constants import Const as C
29 from sat.core import exceptions 30 from sat.core import exceptions
30 from sat.core.log import getLogger 31 from sat.core.log import getLogger
31 from sat.tools import stream 32 from sat.tools import stream
33 from sat.tools import video
32 from sat.tools.common import regex 34 from sat.tools.common import regex
33 from sat.tools.common import uri 35 from sat.tools.common import uri
34 from sat.tools.common import files_utils 36 from sat.tools.common import files_utils
35 from sat.tools.common import tls 37 from sat.tools.common import tls
36 from twisted.internet import defer, reactor 38 from twisted.internet import defer, reactor
397 regex.pathEscape(client.profile), 399 regex.pathEscape(client.profile),
398 ) 400 )
399 if not os.path.exists(path): 401 if not os.path.exists(path):
400 os.makedirs(path) 402 os.makedirs(path)
401 403
404 async def generate_thumbnails(self, extra: dict, image_path: Path):
405 thumbnails = extra.setdefault(C.KEY_THUMBNAILS, [])
406 for max_thumb_size in self._t.SIZES:
407 try:
408 thumb_size, thumb_id = await self._t.generateThumbnail(
409 image_path,
410 max_thumb_size,
411 #  we keep thumbnails for 6 months
412 60 * 60 * 24 * 31 * 6,
413 )
414 except Exception as e:
415 log.warning(_("Can't create thumbnail: {reason}").format(reason=e))
416 break
417 thumbnails.append({"id": thumb_id, "size": thumb_size})
418
402 async def registerReceivedFile( 419 async def registerReceivedFile(
403 self, client, peer_jid, file_data, file_path, public_id=None, extra=None): 420 self, client, peer_jid, file_data, file_path, public_id=None, extra=None):
404 """Post file reception tasks 421 """Post file reception tasks
405 422
406 once file is received, this method create hash/thumbnails if necessary 423 once file is received, this method create hash/thumbnails if necessary
413 mime_type = file_data.get("mime_type") 430 mime_type = file_data.get("mime_type")
414 if not mime_type or mime_type == "application/octet-stream": 431 if not mime_type or mime_type == "application/octet-stream":
415 mime_type = mimetypes.guess_type(name)[0] 432 mime_type = mimetypes.guess_type(name)[0]
416 433
417 is_image = mime_type is not None and mime_type.startswith("image") 434 is_image = mime_type is not None and mime_type.startswith("image")
435 is_video = mime_type is not None and mime_type.startswith("video")
418 436
419 if file_data.get("hash_algo") == HASH_ALGO: 437 if file_data.get("hash_algo") == HASH_ALGO:
420 log.debug(_("Reusing already generated hash")) 438 log.debug(_("Reusing already generated hash"))
421 file_hash = file_data["hash_hasher"].hexdigest() 439 file_hash = file_data["hash_hasher"].hexdigest()
422 else: 440 else:
438 "file [{file_hash}] moved to {files_path}".format( 456 "file [{file_hash}] moved to {files_path}".format(
439 file_hash=file_hash, files_path=self.files_path 457 file_hash=file_hash, files_path=self.files_path
440 ) 458 )
441 ) 459 )
442 460
443
444 if is_image: 461 if is_image:
445 thumbnails = extra.setdefault(C.KEY_THUMBNAILS, []) 462 await self.generate_thumbnails(extra, final_path)
446 for max_thumb_size in self._t.SIZES: 463 elif is_video:
464 with tempfile.TemporaryDirectory() as tmp_dir:
465 thumb_path = Path(tmp_dir) / "thumbnail.jpg"
447 try: 466 try:
448 thumb_size, thumb_id = await self._t.generateThumbnail( 467 await video.get_thumbnail(final_path, thumb_path)
449 final_path,
450 max_thumb_size,
451 #  we keep thumbnails for 6 months
452 60 * 60 * 24 * 31 * 6,
453 )
454 except Exception as e: 468 except Exception as e:
455 log.warning(_("Can't create thumbnail: {reason}").format(reason=e)) 469 log.warning(_("Can't get thumbnail for {final_path}: {e}").format(
456 break 470 final_path=final_path, e=e))
457 thumbnails.append({"id": thumb_id, "size": thumb_size}) 471 else:
472 await self.generate_thumbnails(extra, thumb_path)
458 473
459 self.host.memory.setFile( 474 self.host.memory.setFile(
460 client, 475 client,
461 name=name, 476 name=name,
462 version="", 477 version="",