From 84cddc869877792ba05bd8cdba3952fe7594a5a2 Mon Sep 17 00:00:00 2001 From: Sushil Tiwari Date: Fri, 13 Sep 2024 17:00:40 +0545 Subject: [PATCH] Add title and skip summary translation logic --- api/admin.py | 2 +- ...ort_title_fieldreport_title_ar_and_more.py | 38 +++++++++++++++++++ api/models.py | 25 +++++++++++- api/serializers.py | 3 +- api/translation.py | 4 +- lang/tasks.py | 5 ++- 6 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 api/migrations/0214_fieldreport_title_fieldreport_title_ar_and_more.py diff --git a/api/admin.py b/api/admin.py index 4e4a97793..f36951600 100644 --- a/api/admin.py +++ b/api/admin.py @@ -318,7 +318,7 @@ class FieldReportAdmin(CompareVersionAdmin, RegionRestrictedAdmin, TranslationAd "districts", ) - readonly_fields = ("report_date", "created_at", "updated_at") + readonly_fields = ("report_date", "created_at", "updated_at", "summary") list_filter = [MembershipFilter] actions = [ "create_events", diff --git a/api/migrations/0214_fieldreport_title_fieldreport_title_ar_and_more.py b/api/migrations/0214_fieldreport_title_fieldreport_title_ar_and_more.py new file mode 100644 index 000000000..38925900b --- /dev/null +++ b/api/migrations/0214_fieldreport_title_fieldreport_title_ar_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.15 on 2024-09-13 08:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0213_merge_20240807_1001'), + ] + + operations = [ + migrations.AddField( + model_name='fieldreport', + name='title', + field=models.CharField(blank=True, max_length=256), + ), + migrations.AddField( + model_name='fieldreport', + name='title_ar', + field=models.CharField(blank=True, max_length=256, null=True), + ), + migrations.AddField( + model_name='fieldreport', + name='title_en', + field=models.CharField(blank=True, max_length=256, null=True), + ), + migrations.AddField( + model_name='fieldreport', + name='title_es', + field=models.CharField(blank=True, max_length=256, null=True), + ), + migrations.AddField( + model_name='fieldreport', + name='title_fr', + field=models.CharField(blank=True, max_length=256, null=True), + ), + ] diff --git a/api/models.py b/api/models.py index afe4f0cc2..eb3c5429c 100644 --- a/api/models.py +++ b/api/models.py @@ -750,6 +750,7 @@ class Event(models.Model): ) image = models.ImageField(verbose_name=_("image"), null=True, blank=True, upload_to=snippet_image_path) summary = HTMLField(verbose_name=_("summary"), blank=True, default="") + # title = models.CharField(max_length=256, blank=True) num_injured = models.IntegerField(verbose_name=_("number of injured"), null=True, blank=True) num_dead = models.IntegerField(verbose_name=_("number of dead"), null=True, blank=True) @@ -1436,6 +1437,8 @@ class RecentAffected(models.IntegerChoices): # Used to differentiate reports that have and have not been synced from DMIS rid = models.CharField(verbose_name=_("r id"), max_length=100, null=True, blank=True, editable=False) summary = models.TextField(verbose_name=_("summary"), blank=True) + # Title field is used for the translation and later adding formated into the summary + title = models.CharField(max_length=256, blank=True) description = HTMLField(verbose_name=_("description"), blank=True, default="") dtype = models.ForeignKey(DisasterType, verbose_name=_("disaster type"), on_delete=models.PROTECT) event = models.ForeignKey( @@ -1643,7 +1646,24 @@ class Meta: # filters = models.Q(visibility__in=[VisibilityChoices.MEMBERSHIP, VisibilityChoices.PUBLIC]) # if is_user_ifrc(user): # filters = models.Q() - # return FieldReport.objects.filter(filters) + + def generate_formatted_summary(self) -> str: + translations = { + "summary_en": self.title_en, + "summary_fr": self.title_fr, + "summary_es": self.title_es, + "summary_ar": self.title_ar, + } + country = self.countries.first() + disater = self.dtype + start_date = self.start_date.strftime("%m-%Y") + + field_report_number = FieldReport.objects.filter(countries=country).count() + date = timezone.now().strftime("%Y-%m-%d") + for summary_field, title in translations.items(): + if title: + summary = f"{country.iso3}: {disater.name} - {start_date} {title} #{field_report_number} ({date})" + setattr(self, summary_field, summary) def save(self, *args, **kwargs): # On save, is report_date or start_date is not set, set it to now. @@ -1651,6 +1671,9 @@ def save(self, *args, **kwargs): self.report_date = timezone.now() if not self.id and not self.start_date: self.start_date = timezone.now() + # NOTE: Overriding the summary field with translated title + self.generate_formatted_summary() + return super(FieldReport, self).save(*args, **kwargs) def indexing(self): diff --git a/api/serializers.py b/api/serializers.py index f616a5a4b..0ab8c4b1b 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -2023,10 +2023,11 @@ class FieldReportSerializer( class Meta: model = FieldReport fields = "__all__" + read_only_fields = ("summary",) def create_event(self, report): event = Event.objects.create( - name=report.summary, + name=report.title, dtype=report.dtype, summary=report.description or "", disaster_start_date=report.start_date, diff --git a/api/translation.py b/api/translation.py index 44007ead5..46ffc0d38 100644 --- a/api/translation.py +++ b/api/translation.py @@ -79,6 +79,7 @@ class DisasterTypeTO(TranslationOptions): @register(Event) class EventTO(TranslationOptions): fields = ("name", "summary") + skip_fields = ("name",) # XXX: CUSTOM field Not used by TranslationOptions, but used in lang/tasks.py @register(ExternalPartner) @@ -88,7 +89,8 @@ class ExternalPartnerTO(TranslationOptions): @register(FieldReport) class FieldReportTO(TranslationOptions): - fields = ("summary", "description", "actions_others", "other_sources") + fields = ("title", "summary", "description", "actions_others", "other_sources") + skip_fields = ("summary",) # XXX: CUSTOM field Not used by TranslationOptions, but used in lang/tasks.py @register(GDACSEvent) diff --git a/lang/tasks.py b/lang/tasks.py index 10ff176c5..af97b53d6 100644 --- a/lang/tasks.py +++ b/lang/tasks.py @@ -96,7 +96,10 @@ def get_translatable_models(cls, only_models: typing.Optional[typing.List[models @classmethod def get_translatable_fields(cls, model): - return list(translator.get_options_for_model(model).fields.keys()) + translation_options = translator.get_options_for_model(model) + # NOTE: Some skipped fields are handled manually. + skipped_fields = set(getattr(translation_options, "skip_fields", [])) + return [field for field in translation_options.fields.keys() if field not in skipped_fields] def translate_model_fields(self, obj, translatable_fields=None): if skip_auto_translation(obj):