14
14
# limitations under the License.
15
15
import collections .abc
16
16
import re
17
- from typing import (
18
- TYPE_CHECKING ,
19
- Any ,
20
- Callable ,
21
- Dict ,
22
- Iterable ,
23
- List ,
24
- Mapping ,
25
- Optional ,
26
- Union ,
27
- )
17
+ from typing import Any , Callable , Dict , Iterable , List , Mapping , Optional , Union
28
18
29
19
from frozendict import frozendict
30
20
31
21
from synapse .api .constants import EventContentFields , EventTypes , RelationTypes
32
22
from synapse .api .errors import Codes , SynapseError
33
23
from synapse .api .room_versions import RoomVersion
34
24
from synapse .types import JsonDict
35
- from synapse .util .async_helpers import yieldable_gather_results
36
25
from synapse .util .frozenutils import unfreeze
37
26
38
27
from . import EventBase
39
28
40
- if TYPE_CHECKING :
41
- from synapse .server import HomeServer
42
-
43
29
# Split strings on "." but not "\." This uses a negative lookbehind assertion for '\'
44
30
# (?<!stuff) matches if the current position in the string is not preceded
45
31
# by a match for 'stuff'.
@@ -385,17 +371,12 @@ class EventClientSerializer:
385
371
clients.
386
372
"""
387
373
388
- def __init__ (self , hs : "HomeServer" ):
389
- self .store = hs .get_datastore ()
390
- self ._msc1849_enabled = hs .config .experimental .msc1849_enabled
391
- self ._msc3440_enabled = hs .config .experimental .msc3440_enabled
392
-
393
- async def serialize_event (
374
+ def serialize_event (
394
375
self ,
395
376
event : Union [JsonDict , EventBase ],
396
377
time_now : int ,
397
378
* ,
398
- bundle_aggregations : bool = False ,
379
+ bundle_aggregations : Optional [ Dict [ str , JsonDict ]] = None ,
399
380
** kwargs : Any ,
400
381
) -> JsonDict :
401
382
"""Serializes a single event.
@@ -418,66 +399,41 @@ async def serialize_event(
418
399
serialized_event = serialize_event (event , time_now , ** kwargs )
419
400
420
401
# Check if there are any bundled aggregations to include with the event.
421
- #
422
- # Do not bundle aggregations if any of the following at true:
423
- #
424
- # * Support is disabled via the configuration or the caller.
425
- # * The event is a state event.
426
- # * The event has been redacted.
427
- if (
428
- self ._msc1849_enabled
429
- and bundle_aggregations
430
- and not event .is_state ()
431
- and not event .internal_metadata .is_redacted ()
432
- ):
433
- await self ._injected_bundled_aggregations (event , time_now , serialized_event )
402
+ if bundle_aggregations :
403
+ event_aggregations = bundle_aggregations .get (event .event_id )
404
+ if event_aggregations :
405
+ self ._injected_bundled_aggregations (
406
+ event ,
407
+ time_now ,
408
+ bundle_aggregations [event .event_id ],
409
+ serialized_event ,
410
+ )
434
411
435
412
return serialized_event
436
413
437
- async def _injected_bundled_aggregations (
438
- self , event : EventBase , time_now : int , serialized_event : JsonDict
414
+ def _injected_bundled_aggregations (
415
+ self ,
416
+ event : EventBase ,
417
+ time_now : int ,
418
+ aggregations : JsonDict ,
419
+ serialized_event : JsonDict ,
439
420
) -> None :
440
421
"""Potentially injects bundled aggregations into the unsigned portion of the serialized event.
441
422
442
423
Args:
443
424
event: The event being serialized.
444
425
time_now: The current time in milliseconds
426
+ aggregations: The bundled aggregation to serialize.
445
427
serialized_event: The serialized event which may be modified.
446
428
447
429
"""
448
- # Do not bundle aggregations for an event which represents an edit or an
449
- # annotation. It does not make sense for them to have related events.
450
- relates_to = event .content .get ("m.relates_to" )
451
- if isinstance (relates_to , (dict , frozendict )):
452
- relation_type = relates_to .get ("rel_type" )
453
- if relation_type in (RelationTypes .ANNOTATION , RelationTypes .REPLACE ):
454
- return
455
-
456
- event_id = event .event_id
457
- room_id = event .room_id
458
-
459
- # The bundled aggregations to include.
460
- aggregations = {}
461
-
462
- annotations = await self .store .get_aggregation_groups_for_event (
463
- event_id , room_id
464
- )
465
- if annotations .chunk :
466
- aggregations [RelationTypes .ANNOTATION ] = annotations .to_dict ()
430
+ # Make a copy in-case the object is cached.
431
+ aggregations = aggregations .copy ()
467
432
468
- references = await self .store .get_relations_for_event (
469
- event_id , room_id , RelationTypes .REFERENCE , direction = "f"
470
- )
471
- if references .chunk :
472
- aggregations [RelationTypes .REFERENCE ] = references .to_dict ()
473
-
474
- edit = None
475
- if event .type == EventTypes .Message :
476
- edit = await self .store .get_applicable_edit (event_id , room_id )
477
-
478
- if edit :
433
+ if RelationTypes .REPLACE in aggregations :
479
434
# If there is an edit replace the content, preserving existing
480
435
# relations.
436
+ edit = aggregations [RelationTypes .REPLACE ]
481
437
482
438
# Ensure we take copies of the edit content, otherwise we risk modifying
483
439
# the original event.
@@ -502,27 +458,19 @@ async def _injected_bundled_aggregations(
502
458
}
503
459
504
460
# If this event is the start of a thread, include a summary of the replies.
505
- if self ._msc3440_enabled :
506
- (
507
- thread_count ,
508
- latest_thread_event ,
509
- ) = await self .store .get_thread_summary (event_id , room_id )
510
- if latest_thread_event :
511
- aggregations [RelationTypes .THREAD ] = {
512
- # Don't bundle aggregations as this could recurse forever.
513
- "latest_event" : await self .serialize_event (
514
- latest_thread_event , time_now , bundle_aggregations = False
515
- ),
516
- "count" : thread_count ,
517
- }
518
-
519
- # If any bundled aggregations were found, include them.
520
- if aggregations :
521
- serialized_event ["unsigned" ].setdefault ("m.relations" , {}).update (
522
- aggregations
461
+ if RelationTypes .THREAD in aggregations :
462
+ # Serialize the latest thread event.
463
+ latest_thread_event = aggregations [RelationTypes .THREAD ]["latest_event" ]
464
+
465
+ # Don't bundle aggregations as this could recurse forever.
466
+ aggregations [RelationTypes .THREAD ]["latest_event" ] = self .serialize_event (
467
+ latest_thread_event , time_now , bundle_aggregations = None
523
468
)
524
469
525
- async def serialize_events (
470
+ # Include the bundled aggregations in the event.
471
+ serialized_event ["unsigned" ].setdefault ("m.relations" , {}).update (aggregations )
472
+
473
+ def serialize_events (
526
474
self , events : Iterable [Union [JsonDict , EventBase ]], time_now : int , ** kwargs : Any
527
475
) -> List [JsonDict ]:
528
476
"""Serializes multiple events.
@@ -535,9 +483,9 @@ async def serialize_events(
535
483
Returns:
536
484
The list of serialized events
537
485
"""
538
- return await yieldable_gather_results (
539
- self .serialize_event , events , time_now = time_now , ** kwargs
540
- )
486
+ return [
487
+ self .serialize_event ( event , time_now = time_now , ** kwargs ) for event in events
488
+ ]
541
489
542
490
543
491
def copy_power_levels_contents (
0 commit comments