36
36
ThumbnailInfo ,
37
37
respond_404 ,
38
38
respond_with_file ,
39
+ respond_with_multipart_responder ,
39
40
respond_with_responder ,
40
41
)
41
- from synapse .media .media_storage import MediaStorage
42
+ from synapse .media .media_storage import FileResponder , MediaStorage
43
+ from synapse .storage .databases .main .media_repository import LocalMedia
42
44
43
45
if TYPE_CHECKING :
44
46
from synapse .media .media_repository import MediaRepository
@@ -271,6 +273,7 @@ async def respond_local_thumbnail(
271
273
method : str ,
272
274
m_type : str ,
273
275
max_timeout_ms : int ,
276
+ for_federation : bool ,
274
277
) -> None :
275
278
media_info = await self .media_repo .get_local_media_info (
276
279
request , media_id , max_timeout_ms
@@ -290,6 +293,8 @@ async def respond_local_thumbnail(
290
293
media_id ,
291
294
url_cache = bool (media_info .url_cache ),
292
295
server_name = None ,
296
+ for_federation = for_federation ,
297
+ media_info = media_info ,
293
298
)
294
299
295
300
async def select_or_generate_local_thumbnail (
@@ -301,6 +306,7 @@ async def select_or_generate_local_thumbnail(
301
306
desired_method : str ,
302
307
desired_type : str ,
303
308
max_timeout_ms : int ,
309
+ for_federation : bool ,
304
310
) -> None :
305
311
media_info = await self .media_repo .get_local_media_info (
306
312
request , media_id , max_timeout_ms
@@ -326,10 +332,16 @@ async def select_or_generate_local_thumbnail(
326
332
327
333
responder = await self .media_storage .fetch_media (file_info )
328
334
if responder :
329
- await respond_with_responder (
330
- request , responder , info .type , info .length
331
- )
332
- return
335
+ if for_federation :
336
+ await respond_with_multipart_responder (
337
+ self .hs .get_clock (), request , responder , media_info
338
+ )
339
+ return
340
+ else :
341
+ await respond_with_responder (
342
+ request , responder , info .type , info .length
343
+ )
344
+ return
333
345
334
346
logger .debug ("We don't have a thumbnail of that size. Generating" )
335
347
@@ -344,7 +356,15 @@ async def select_or_generate_local_thumbnail(
344
356
)
345
357
346
358
if file_path :
347
- await respond_with_file (request , desired_type , file_path )
359
+ if for_federation :
360
+ await respond_with_multipart_responder (
361
+ self .hs .get_clock (),
362
+ request ,
363
+ FileResponder (open (file_path , "rb" )),
364
+ media_info ,
365
+ )
366
+ else :
367
+ await respond_with_file (request , desired_type , file_path )
348
368
else :
349
369
logger .warning ("Failed to generate thumbnail" )
350
370
raise SynapseError (400 , "Failed to generate thumbnail." )
@@ -360,9 +380,10 @@ async def select_or_generate_remote_thumbnail(
360
380
desired_type : str ,
361
381
max_timeout_ms : int ,
362
382
ip_address : str ,
383
+ use_federation : bool ,
363
384
) -> None :
364
385
media_info = await self .media_repo .get_remote_media_info (
365
- server_name , media_id , max_timeout_ms , ip_address
386
+ server_name , media_id , max_timeout_ms , ip_address , use_federation
366
387
)
367
388
if not media_info :
368
389
respond_404 (request )
@@ -424,12 +445,13 @@ async def respond_remote_thumbnail(
424
445
m_type : str ,
425
446
max_timeout_ms : int ,
426
447
ip_address : str ,
448
+ use_federation : bool ,
427
449
) -> None :
428
450
# TODO: Don't download the whole remote file
429
451
# We should proxy the thumbnail from the remote server instead of
430
452
# downloading the remote file and generating our own thumbnails.
431
453
media_info = await self .media_repo .get_remote_media_info (
432
- server_name , media_id , max_timeout_ms , ip_address
454
+ server_name , media_id , max_timeout_ms , ip_address , use_federation
433
455
)
434
456
if not media_info :
435
457
return
@@ -448,6 +470,7 @@ async def respond_remote_thumbnail(
448
470
media_info .filesystem_id ,
449
471
url_cache = False ,
450
472
server_name = server_name ,
473
+ for_federation = False ,
451
474
)
452
475
453
476
async def _select_and_respond_with_thumbnail (
@@ -461,7 +484,9 @@ async def _select_and_respond_with_thumbnail(
461
484
media_id : str ,
462
485
file_id : str ,
463
486
url_cache : bool ,
487
+ for_federation : bool ,
464
488
server_name : Optional [str ] = None ,
489
+ media_info : Optional [LocalMedia ] = None ,
465
490
) -> None :
466
491
"""
467
492
Respond to a request with an appropriate thumbnail from the previously generated thumbnails.
@@ -476,6 +501,8 @@ async def _select_and_respond_with_thumbnail(
476
501
file_id: The ID of the media that a thumbnail is being requested for.
477
502
url_cache: True if this is from a URL cache.
478
503
server_name: The server name, if this is a remote thumbnail.
504
+ for_federation: whether the request is from the federation /thumbnail request
505
+ media_info: metadata about the media being requested.
479
506
"""
480
507
logger .debug (
481
508
"_select_and_respond_with_thumbnail: media_id=%s desired=%sx%s (%s) thumbnail_infos=%s" ,
@@ -511,13 +538,20 @@ async def _select_and_respond_with_thumbnail(
511
538
512
539
responder = await self .media_storage .fetch_media (file_info )
513
540
if responder :
514
- await respond_with_responder (
515
- request ,
516
- responder ,
517
- file_info .thumbnail .type ,
518
- file_info .thumbnail .length ,
519
- )
520
- return
541
+ if for_federation :
542
+ assert media_info is not None
543
+ await respond_with_multipart_responder (
544
+ self .hs .get_clock (), request , responder , media_info
545
+ )
546
+ return
547
+ else :
548
+ await respond_with_responder (
549
+ request ,
550
+ responder ,
551
+ file_info .thumbnail .type ,
552
+ file_info .thumbnail .length ,
553
+ )
554
+ return
521
555
522
556
# If we can't find the thumbnail we regenerate it. This can happen
523
557
# if e.g. we've deleted the thumbnails but still have the original
@@ -558,12 +592,18 @@ async def _select_and_respond_with_thumbnail(
558
592
)
559
593
560
594
responder = await self .media_storage .fetch_media (file_info )
561
- await respond_with_responder (
562
- request ,
563
- responder ,
564
- file_info .thumbnail .type ,
565
- file_info .thumbnail .length ,
566
- )
595
+ if for_federation :
596
+ assert media_info is not None
597
+ await respond_with_multipart_responder (
598
+ self .hs .get_clock (), request , responder , media_info
599
+ )
600
+ else :
601
+ await respond_with_responder (
602
+ request ,
603
+ responder ,
604
+ file_info .thumbnail .type ,
605
+ file_info .thumbnail .length ,
606
+ )
567
607
else :
568
608
# This might be because:
569
609
# 1. We can't create thumbnails for the given media (corrupted or
0 commit comments