55from stream_framework .utils import epoch_to_datetime , datetime_to_epoch
66from stream_framework .serializers .base import BaseAggregatedSerializer
77import six
8+ import re
89
910
1011class AggregatedActivitySerializer (BaseAggregatedSerializer ):
@@ -23,7 +24,6 @@ class AggregatedActivitySerializer(BaseAggregatedSerializer):
2324 #: indicates if dumps returns dehydrated aggregated activities
2425 dehydrate = True
2526 identifier = 'v3'
26- reserved_characters = [';' , ',' , ';;' ]
2727 date_fields = ['created_at' , 'updated_at' , 'seen_at' , 'read_at' ]
2828
2929 activity_serializer_class = ActivitySerializer
@@ -55,7 +55,8 @@ def dumps(self, aggregated):
5555 else :
5656 for activity in aggregated .activities :
5757 serialized = activity_serializer .dumps (activity )
58- check_reserved (serialized , [';' , ';;' ])
58+ # we use semicolons as delimiter, so need to escape
59+ serialized = serialized .replace (";" , "\;" )
5960 serialized_activities .append (serialized )
6061
6162 serialized_activities_part = ';' .join (serialized_activities )
@@ -86,15 +87,20 @@ def loads(self, serialized_aggregated):
8687 date_value = epoch_to_datetime (float (v ))
8788 setattr (aggregated , k , date_value )
8889
90+ # looks for ; not \;
91+ unescaped_semicolons_regex = re .compile ("(?<=[^\\ \]);" )
8992 # write the activities
90- serializations = parts [5 ]. split ( ';' )
93+ serializations = unescaped_semicolons_regex . split ( parts [5 ])
9194 if self .dehydrate :
9295 activity_ids = list (map (int , serializations ))
9396 aggregated ._activity_ids = activity_ids
9497 aggregated .dehydrated = True
9598 else :
96- activities = [activity_serializer .loads (s )
97- for s in serializations ]
99+ activities = []
100+ for s in serializations :
101+ s = s .replace ("\;" , ";" )
102+ deserialized = activity_serializer .loads (s )
103+ activities .append (deserialized )
98104 aggregated .activities = activities
99105 aggregated .dehydrated = False
100106
0 commit comments