Skip to content

Commit 95120f9

Browse files
committed
feat(gdpr-api): add translations to gdpr data
Refs LINK-2012
1 parent 66a19eb commit 95120f9

File tree

3 files changed

+135
-26
lines changed

3 files changed

+135
-26
lines changed

events/models.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
from django.dispatch import receiver
3636
from django.utils import timezone
3737
from django.utils.translation import gettext_lazy as _
38-
from helsinki_gdpr.models import SerializableMixin
3938
from image_cropping import ImageRatioField
4039
from mptt.managers import TreeManager
4140
from mptt.models import MPTTModel, TreeForeignKey
@@ -45,6 +44,7 @@
4544
from reversion import revisions as reversion
4645

4746
from events import translation_utils
47+
from events.translation_utils import TranslatableSerializableMixin
4848
from notifications.models import (
4949
NotificationTemplateException,
5050
NotificationType,
@@ -157,7 +157,7 @@ def can_be_edited_by(self, user):
157157
return True
158158

159159

160-
class BaseSerializableManager(SerializableMixin.SerializableManager):
160+
class BaseSerializableManager(TranslatableSerializableMixin.SerializableManager):
161161
def get_queryset(self):
162162
return BaseQuerySet(self.model, using=self._db)
163163

@@ -178,7 +178,9 @@ def undelete(self):
178178
undelete.alters_data = True
179179

180180

181-
class BaseSerializableTreeManager(TreeManager, SerializableMixin.SerializableManager):
181+
class BaseSerializableTreeManager(
182+
TreeManager, TranslatableSerializableMixin.SerializableManager
183+
):
182184
def get_queryset(self):
183185
return BaseTreeQuerySet(self.model, using=self._db).order_by(
184186
self.tree_id_attr, self.left_attr
@@ -218,7 +220,7 @@ def __str__(self):
218220
return self.name
219221

220222

221-
class Image(SerializableMixin):
223+
class Image(TranslatableSerializableMixin):
222224
serialize_fields = [{"name": "name"}, {"name": "url"}]
223225

224226
jsonld_type = "ImageObject"
@@ -418,7 +420,7 @@ def save(self, update_fields=None, skip_last_modified_time=False, **kwargs):
418420
super().save(update_fields=update_fields, **kwargs)
419421

420422

421-
class Language(SerializableMixin):
423+
class Language(TranslatableSerializableMixin):
422424
serialize_fields = [
423425
{"name": "name"},
424426
{"name": "service_language"},
@@ -438,7 +440,7 @@ class Meta:
438440
verbose_name_plural = _("languages")
439441

440442

441-
class KeywordLabel(SerializableMixin):
443+
class KeywordLabel(TranslatableSerializableMixin):
442444
serialize_fields = [
443445
{"name": "name"},
444446
{"name": "language"},
@@ -471,7 +473,7 @@ def has_upcoming_events_update(self):
471473
qs.exclude(events__end_time__gte=now).update(has_upcoming_events=False)
472474

473475

474-
class Keyword(BaseModel, ImageMixin, ReplacedByMixin, SerializableMixin):
476+
class Keyword(BaseModel, ImageMixin, ReplacedByMixin, TranslatableSerializableMixin):
475477
serialize_fields = [
476478
{"name": "alt_labels"},
477479
]
@@ -639,7 +641,7 @@ class Place(
639641
SchemalessFieldMixin,
640642
ImageMixin,
641643
ReplacedByMixin,
642-
SerializableMixin,
644+
TranslatableSerializableMixin,
643645
):
644646
serialize_fields = [
645647
{"name": "name"},
@@ -841,7 +843,11 @@ class Meta:
841843

842844

843845
class Event(
844-
MPTTModel, BaseModel, SchemalessFieldMixin, ReplacedByMixin, SerializableMixin
846+
MPTTModel,
847+
BaseModel,
848+
SchemalessFieldMixin,
849+
ReplacedByMixin,
850+
TranslatableSerializableMixin,
845851
):
846852
jsonld_type = "Event/LinkedEvent"
847853
objects = BaseSerializableTreeManager()
@@ -1429,7 +1435,7 @@ def keyword_added_or_removed(
14291435
)
14301436

14311437

1432-
class Offer(SimpleValueMixin, SerializableMixin):
1438+
class Offer(SimpleValueMixin, TranslatableSerializableMixin):
14331439
serialize_fields = [{"name": "price"}, {"name": "description"}]
14341440

14351441
event = models.ForeignKey(
@@ -1476,7 +1482,7 @@ def value_fields(self):
14761482
return ["name", "language_id", "link"]
14771483

14781484

1479-
class Video(SimpleValueMixin, SerializableMixin):
1485+
class Video(SimpleValueMixin, TranslatableSerializableMixin):
14801486
serialize_fields = [{"name": "name"}, {"name": "url"}, {"name": "alt_text"}]
14811487

14821488
name = models.CharField(

events/translation_utils.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import modeltranslation
2+
from helsinki_gdpr.models import SerializableMixin
23
from modeltranslation.translator import translator
34

45

@@ -19,3 +20,34 @@ def expand_field(field_name):
1920
return [
2021
expanded for unexpanded in field_names for expanded in expand_field(unexpanded)
2122
]
23+
24+
25+
class TranslatableSerializableMixin(SerializableMixin):
26+
def _resolve_field(self, model, field_description):
27+
field_name = field_description.get("name")
28+
29+
try:
30+
options = translator.get_options_for_model(self._meta.model)
31+
except modeltranslation.translator.NotRegistered:
32+
return super()._resolve_field(model, field_description)
33+
34+
if field_name in options.get_field_names():
35+
fields = sorted([f.name for f in options.fields.get(field_name)])
36+
children = [
37+
{
38+
"key": f"{translated_field}".upper(),
39+
"value": getattr(model, f"{translated_field}", ""),
40+
}
41+
for translated_field in fields
42+
if getattr(model, f"{translated_field}", False)
43+
]
44+
45+
return {
46+
"key": field_name.upper(),
47+
"children": children,
48+
}
49+
50+
return super()._resolve_field(model, field_description)
51+
52+
class Meta:
53+
abstract = True

helevents/tests/test_gdpr_api_get.py

Lines changed: 86 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@
3737
SignUpProtectedDataFactory,
3838
)
3939

40+
TRANSLATION_LANGUAGES = sorted(
41+
[
42+
"sv",
43+
"ar",
44+
"zh_hans",
45+
"fi",
46+
"en",
47+
"ru",
48+
]
49+
)
50+
51+
4052
# === util methods ===
4153

4254

@@ -91,6 +103,17 @@ def _get_signup_group_profile_data(signup_group: Optional[SignUpGroup]) -> dict:
91103
return profile_data
92104

93105

106+
def _get_field_translations(obj: object, field_name: str) -> list:
107+
return [
108+
{
109+
"key": f"{field_name}_{lang}".upper(),
110+
"value": getattr(obj, f"{field_name}_{lang}"),
111+
}
112+
for lang in TRANSLATION_LANGUAGES
113+
if getattr(obj, f"{field_name}_{lang}", False)
114+
]
115+
116+
94117
def _get_event_data(user) -> list:
95118
events = Event.objects.filter(created_by=user)
96119

@@ -108,9 +131,15 @@ def _get_event_data(user) -> list:
108131
data = {
109132
"children": [
110133
{"key": "ID", "value": e.id},
111-
{"key": "NAME", "value": e.name},
112-
{"key": "DESCRIPTION", "value": e.description},
113-
{"key": "SHORT_DESCRIPTION", "value": e.short_description},
134+
{"key": "NAME", "children": _get_field_translations(e, "name")},
135+
{
136+
"key": "DESCRIPTION",
137+
"children": _get_field_translations(e, "description"),
138+
},
139+
{
140+
"key": "SHORT_DESCRIPTION",
141+
"children": _get_field_translations(e, "short_description"),
142+
},
114143
{"key": "START_TIME", "value": e.start_time},
115144
{"key": "END_TIME", "value": e.end_time},
116145
(
@@ -146,7 +175,10 @@ def _get_event_data(user) -> list:
146175
"children": [
147176
{
148177
"key": "NAME",
149-
"value": keyword_label.language.name,
178+
"children": _get_field_translations(
179+
keyword_label.language,
180+
"name",
181+
),
150182
},
151183
{
152184
"key": "SERVICE_LANGUAGE",
@@ -178,7 +210,12 @@ def _get_event_data(user) -> list:
178210
{
179211
"children": (
180212
[
181-
{"key": "NAME", "value": language.name},
213+
{
214+
"key": "NAME",
215+
"children": _get_field_translations(
216+
language, "name"
217+
),
218+
},
182219
{
183220
"key": "SERVICE_LANGUAGE",
184221
"value": language.service_language,
@@ -196,22 +233,44 @@ def _get_event_data(user) -> list:
196233
(
197234
{
198235
"children": [
199-
{"key": "NAME", "value": e.location.name},
236+
{
237+
"key": "NAME",
238+
"children": _get_field_translations(e.location, "name"),
239+
},
200240
{
201241
"key": "PUBLISHER",
202242
"value": f"{e.location.publisher.id} - {e.location.publisher.name}",
203243
},
204-
{"key": "INFO_URL", "value": e.location.info_url},
205-
{"key": "DESCRIPTION", "value": e.location.description},
244+
{
245+
"key": "INFO_URL",
246+
"children": _get_field_translations(
247+
e.location, "info_url"
248+
),
249+
},
250+
{
251+
"key": "DESCRIPTION",
252+
"children": _get_field_translations(
253+
e.location, "description"
254+
),
255+
},
206256
{"key": "EMAIL", "value": e.location.email},
207-
{"key": "TELEPHONE", "value": e.location.telephone},
257+
{
258+
"key": "TELEPHONE",
259+
"children": _get_field_translations(
260+
e.location, "telephone"
261+
),
262+
},
208263
{
209264
"key": "STREET_ADDRESS",
210-
"value": e.location.street_address,
265+
"children": _get_field_translations(
266+
e.location, "street_address"
267+
),
211268
},
212269
{
213270
"key": "ADDRESS_LOCALITY",
214-
"value": e.location.address_locality,
271+
"children": _get_field_translations(
272+
e.location, "address_locality"
273+
),
215274
},
216275
{
217276
"key": "ADDRESS_REGION",
@@ -237,8 +296,18 @@ def _get_event_data(user) -> list:
237296
[
238297
{
239298
"children": [
240-
{"key": "PRICE", "value": offer.price},
241-
{"key": "DESCRIPTION", "value": offer.description},
299+
{
300+
"key": "PRICE",
301+
"children": _get_field_translations(
302+
offer, "price"
303+
),
304+
},
305+
{
306+
"key": "DESCRIPTION",
307+
"children": _get_field_translations(
308+
offer, "description"
309+
),
310+
},
242311
],
243312
"key": "OFFER",
244313
}
@@ -281,7 +350,9 @@ def _get_event_data(user) -> list:
281350
"children": [
282351
{
283352
"key": "NAME",
284-
"value": audience_label.language.name,
353+
"children": _get_field_translations(
354+
language, "name"
355+
),
285356
},
286357
{
287358
"key": "SERVICE_LANGUAGE",
@@ -304,7 +375,7 @@ def _get_event_data(user) -> list:
304375
if audience
305376
else []
306377
),
307-
{"key": "INFO_URL", "value": e.info_url},
378+
{"key": "INFO_URL", "children": _get_field_translations(e, "info_url")},
308379
],
309380
"key": "EVENT",
310381
}

0 commit comments

Comments
 (0)