From 8509b67c71fce21a3b98b0fc9221dae080f9314f Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Tue, 16 Jan 2024 16:43:29 +0300 Subject: [PATCH 01/23] Make order outcome field multi-select --- peachjam/admin.py | 2 +- ...nge_order_outcome_field_to_many_to_many.py | 22 +++++++++++++++++++ peachjam/models/judgment.py | 5 +---- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 peachjam/migrations/0115_change_order_outcome_field_to_many_to_many.py diff --git a/peachjam/admin.py b/peachjam/admin.py index cd2fe373b..a3303943e 100644 --- a/peachjam/admin.py +++ b/peachjam/admin.py @@ -730,7 +730,7 @@ class JudgmentAdmin(ImportExportMixin, DocumentAdmin): CaseNumberAdmin, JudgmentRelationshipStackedInline, ] + DocumentAdmin.inlines - filter_horizontal = ("judges", "attorneys") + filter_horizontal = ("judges", "attorneys", "order_outcome") list_filter = (*DocumentAdmin.list_filter, "court") fieldsets = copy.deepcopy(DocumentAdmin.fieldsets) diff --git a/peachjam/migrations/0115_change_order_outcome_field_to_many_to_many.py b/peachjam/migrations/0115_change_order_outcome_field_to_many_to_many.py new file mode 100644 index 000000000..81f8d388a --- /dev/null +++ b/peachjam/migrations/0115_change_order_outcome_field_to_many_to_many.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2.19 on 2024-01-16 13:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("peachjam", "0114_alter_court_country"), + ] + + operations = [ + migrations.RemoveField( + model_name="judgment", + name="order_outcome", + ), + migrations.AddField( + model_name="judgment", + name="order_outcome", + field=models.ManyToManyField(blank=True, to="peachjam.OrderOutcome"), + ), + ] diff --git a/peachjam/models/judgment.py b/peachjam/models/judgment.py index d7f0349ad..35d53726d 100644 --- a/peachjam/models/judgment.py +++ b/peachjam/models/judgment.py @@ -202,11 +202,8 @@ class Judgment(CoreDocument): attorneys = models.ManyToManyField( Attorney, blank=True, verbose_name=_("attorneys") ) - order_outcome = models.ForeignKey( + order_outcome = models.ManyToManyField( OrderOutcome, - on_delete=models.PROTECT, - null=True, - related_name="judgments", blank=True, ) case_summary = models.TextField(_("case summary"), null=True, blank=True) From 66c628bfd4acb9e4b9fc3c50576fd916e7acc281 Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Wed, 17 Jan 2024 12:30:45 +0300 Subject: [PATCH 02/23] Add data migration --- peachjam/admin.py | 2 +- ...nd_delete_old_order_outcome_field_data.py} | 20 +++++++++++++------ peachjam/models/judgment.py | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) rename peachjam/migrations/{0115_change_order_outcome_field_to_many_to_many.py => 0115_copy_and_delete_old_order_outcome_field_data.py} (55%) diff --git a/peachjam/admin.py b/peachjam/admin.py index a3303943e..c222663f7 100644 --- a/peachjam/admin.py +++ b/peachjam/admin.py @@ -730,7 +730,7 @@ class JudgmentAdmin(ImportExportMixin, DocumentAdmin): CaseNumberAdmin, JudgmentRelationshipStackedInline, ] + DocumentAdmin.inlines - filter_horizontal = ("judges", "attorneys", "order_outcome") + filter_horizontal = ("judges", "attorneys", "order_outcomes") list_filter = (*DocumentAdmin.list_filter, "court") fieldsets = copy.deepcopy(DocumentAdmin.fieldsets) diff --git a/peachjam/migrations/0115_change_order_outcome_field_to_many_to_many.py b/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py similarity index 55% rename from peachjam/migrations/0115_change_order_outcome_field_to_many_to_many.py rename to peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py index 81f8d388a..7e80f734a 100644 --- a/peachjam/migrations/0115_change_order_outcome_field_to_many_to_many.py +++ b/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py @@ -1,22 +1,30 @@ -# Generated by Django 3.2.19 on 2024-01-16 13:40 +# Generated by Django 3.2.19 on 2024-01-17 09:20 from django.db import migrations, models -class Migration(migrations.Migration): +def copy_data(apps, schema_editor): + Judgment = apps.get_model("peachjam", "Judgment") + + for judgment in Judgment.objects.all().iterator(chunk_size=100): + judgment.order_outcomes.add(judgment.order_outcome) + judgment.save() + +class Migration(migrations.Migration): dependencies = [ ("peachjam", "0114_alter_court_country"), ] operations = [ - migrations.RemoveField( + migrations.AddField( model_name="judgment", - name="order_outcome", + name="order_outcomes", + field=models.ManyToManyField(blank=True, to="peachjam.OrderOutcome"), ), - migrations.AddField( + migrations.RunPython(copy_data), + migrations.RemoveField( model_name="judgment", name="order_outcome", - field=models.ManyToManyField(blank=True, to="peachjam.OrderOutcome"), ), ] diff --git a/peachjam/models/judgment.py b/peachjam/models/judgment.py index 35d53726d..c4e999d74 100644 --- a/peachjam/models/judgment.py +++ b/peachjam/models/judgment.py @@ -202,7 +202,7 @@ class Judgment(CoreDocument): attorneys = models.ManyToManyField( Attorney, blank=True, verbose_name=_("attorneys") ) - order_outcome = models.ManyToManyField( + order_outcomes = models.ManyToManyField( OrderOutcome, blank=True, ) From f7039933e68d06d39bdfe69bdb102fca45c9044c Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Wed, 17 Jan 2024 13:38:19 +0300 Subject: [PATCH 03/23] Add order outcomes field to admin section --- peachjam/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peachjam/admin.py b/peachjam/admin.py index c222663f7..c01171204 100644 --- a/peachjam/admin.py +++ b/peachjam/admin.py @@ -737,7 +737,7 @@ class JudgmentAdmin(ImportExportMixin, DocumentAdmin): fieldsets[0][1]["fields"].insert(3, "court") fieldsets[0][1]["fields"].insert(4, "registry") fieldsets[0][1]["fields"].insert(5, "case_name") - fieldsets[0][1]["fields"].insert(6, "order_outcome") + fieldsets[0][1]["fields"].insert(6, "order_outcomes") fieldsets[0][1]["fields"].insert(7, "mnc") fieldsets[0][1]["fields"].insert(8, "serial_number_override") fieldsets[0][1]["fields"].insert(9, "serial_number") From c184cd5bf41f26b628f0a00bde3ec8ceaebc0d87 Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Wed, 17 Jan 2024 13:56:55 +0300 Subject: [PATCH 04/23] Add order outcomes to judgment meta data --- .../templates/peachjam/judgment_detail.html | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/peachjam/templates/peachjam/judgment_detail.html b/peachjam/templates/peachjam/judgment_detail.html index a43fe7ae4..7b2e6c981 100644 --- a/peachjam/templates/peachjam/judgment_detail.html +++ b/peachjam/templates/peachjam/judgment_detail.html @@ -42,14 +42,18 @@ {{ document.registry.name }} {% endif %} - {% if document.order_outcome %} -
- {% trans 'Order' %} -
-
- {{ document.order_outcome.name }} -
- {% endif %} + {% with document.order_outcomes.all as order_outcomes %} + {% if document.order_outcomes %} +
+ {% trans 'Order' %} +
+
+ {% for order_outcome in order_outcomes %} + {% if not forloop.last %}{{ order_outcome.name }},{% endif %} + {% endfor %} +
+ {% endif %} + {% endwith %} {% with document.case_numbers.all as case_numbers %} {% if case_numbers %}
From c52610b4b458c995cf1eaa3fd52a51e716410b45 Mon Sep 17 00:00:00 2001 From: Nick Mwangemi Date: Wed, 17 Jan 2024 05:59:45 -0500 Subject: [PATCH 05/23] Update peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py Co-authored-by: Greg Kempe --- .../0115_copy_and_delete_old_order_outcome_field_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py b/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py index 7e80f734a..1c198917c 100644 --- a/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py +++ b/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py @@ -6,7 +6,7 @@ def copy_data(apps, schema_editor): Judgment = apps.get_model("peachjam", "Judgment") - for judgment in Judgment.objects.all().iterator(chunk_size=100): + for judgment in Judgment.objects.filter(order_outcome__isnull=False).iterator(chunk_size=100): judgment.order_outcomes.add(judgment.order_outcome) judgment.save() From 484c55c4cd4d7ddd911ae3816d591018a0b507f1 Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Wed, 17 Jan 2024 14:32:42 +0300 Subject: [PATCH 06/23] Linting --- .../0115_copy_and_delete_old_order_outcome_field_data.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py b/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py index 1c198917c..c4cf5b978 100644 --- a/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py +++ b/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py @@ -6,7 +6,9 @@ def copy_data(apps, schema_editor): Judgment = apps.get_model("peachjam", "Judgment") - for judgment in Judgment.objects.filter(order_outcome__isnull=False).iterator(chunk_size=100): + for judgment in Judgment.objects.filter(order_outcome__isnull=False).iterator( + chunk_size=100 + ): judgment.order_outcomes.add(judgment.order_outcome) judgment.save() From ad21a904b5c0963a3350186ffef2ed8656c32073 Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Wed, 17 Jan 2024 14:56:11 +0300 Subject: [PATCH 07/23] Fix tests --- peachjam/views/courts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peachjam/views/courts.py b/peachjam/views/courts.py index 05753c879..546dafb99 100644 --- a/peachjam/views/courts.py +++ b/peachjam/views/courts.py @@ -97,7 +97,7 @@ def populate_facets(self, context): self.get_base_queryset(), exclude="order_outcomes" ) .order_by() - .values_list("order_outcome__name", flat=True) + .values_list("order_outcomes__name", flat=True) .distinct() if order_outcome ) From 3c5ddc153e52059aa9a1fb7dc4ef01632da4c754 Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Thu, 18 Jan 2024 13:48:31 +0300 Subject: [PATCH 08/23] Serialize order outcomes --- peachjam_search/documents.py | 20 +++++++++++--------- peachjam_search/serializers.py | 10 +++++++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/peachjam_search/documents.py b/peachjam_search/documents.py index f46e7f684..5dd12e069 100644 --- a/peachjam_search/documents.py +++ b/peachjam_search/documents.py @@ -76,11 +76,11 @@ class SearchableDocument(Document): registry_fr = fields.KeywordField() registry_pt = fields.KeywordField() - order_outcome = fields.KeywordField(attr="order_outcome.name") - order_outcome_en = fields.KeywordField() - order_outcome_sw = fields.KeywordField() - order_outcome_fr = fields.KeywordField() - order_outcome_pt = fields.KeywordField() + order_outcomes = fields.KeywordField(attr="order_outcome.name") + order_outcomes_en = fields.KeywordField() + order_outcomes_sw = fields.KeywordField() + order_outcomes_fr = fields.KeywordField() + order_outcomes_pt = fields.KeywordField() # GenericDocument, LegalInstrument authors = fields.KeywordField() @@ -107,7 +107,7 @@ class SearchableDocument(Document): translated_fields = [ ("court", "name"), ("registry", "name"), - ("order_outcome", "name"), + ("order_outcomes", "name"), ("nature", "name"), ] @@ -234,9 +234,11 @@ def prepare_nature(self, instance): if hasattr(instance, "nature") and instance.nature: return instance.nature.name - def prepare_order_outcome(self, instance): - if hasattr(instance, "order_outcome") and instance.order_outcome: - return instance.order_outcome.name + def prepare_order_outcomes(self, instance): + if hasattr(instance, "order_outcomes") and instance.order_outcomes: + return [ + order_outcome.name for order_outcome in instance.order_outcomes.all() + ] def prepare_pages(self, instance): """Text content of pages extracted from PDF.""" diff --git a/peachjam_search/serializers.py b/peachjam_search/serializers.py index 2fa0744cd..0cb3ba7b1 100644 --- a/peachjam_search/serializers.py +++ b/peachjam_search/serializers.py @@ -10,7 +10,7 @@ class SearchableDocumentSerializer(DocumentSerializer): pages = SerializerMethodField() court = SerializerMethodField() nature = SerializerMethodField() - order_outcome = SerializerMethodField() + order_outcomes = SerializerMethodField() registry = SerializerMethodField() labels = CharField(allow_null=True) _score = FloatField(source="meta.score") @@ -72,8 +72,12 @@ def get_court(self, obj): def get_nature(self, obj): return obj["nature" + self.language_suffix] - def get_order_outcome(self, obj): - return obj["order_outcome" + self.language_suffix] + def get_order_outcomes(self, obj): + order_outcomes = obj["order_outcomes"] + if order_outcomes: + return [ + order_outcome + self.language_suffix for order_outcome in order_outcomes + ] def get_registry(self, obj): return obj["registry" + self.language_suffix] From ee692398d1e110737f0f1d8ebba7686ad433c0fb Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Thu, 18 Jan 2024 13:59:02 +0300 Subject: [PATCH 09/23] Fix migrations --- ...y => 0116_copy_and_delete_old_order_outcome_field_data.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename peachjam/migrations/{0115_copy_and_delete_old_order_outcome_field_data.py => 0116_copy_and_delete_old_order_outcome_field_data.py} (87%) diff --git a/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py b/peachjam/migrations/0116_copy_and_delete_old_order_outcome_field_data.py similarity index 87% rename from peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py rename to peachjam/migrations/0116_copy_and_delete_old_order_outcome_field_data.py index c4cf5b978..e036ee61a 100644 --- a/peachjam/migrations/0115_copy_and_delete_old_order_outcome_field_data.py +++ b/peachjam/migrations/0116_copy_and_delete_old_order_outcome_field_data.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.19 on 2024-01-17 09:20 +# Generated by Django 3.2.19 on 2024-01-18 10:57 from django.db import migrations, models @@ -15,7 +15,7 @@ def copy_data(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ("peachjam", "0114_alter_court_country"), + ("peachjam", "0115_peachjamsettings_linkedin_link"), ] operations = [ From 3c643e5044b0bb545fde2915d15dd06a240daea4 Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Thu, 18 Jan 2024 17:14:31 +0300 Subject: [PATCH 10/23] Create model DocumentMedia --- peachjam/migrations/0117_documentmedia.py | 55 +++++++++++++++++++++++ peachjam/models/core_document_model.py | 16 +++++++ 2 files changed, 71 insertions(+) create mode 100644 peachjam/migrations/0117_documentmedia.py diff --git a/peachjam/migrations/0117_documentmedia.py b/peachjam/migrations/0117_documentmedia.py new file mode 100644 index 000000000..87a865a58 --- /dev/null +++ b/peachjam/migrations/0117_documentmedia.py @@ -0,0 +1,55 @@ +# Generated by Django 3.2.19 on 2024-01-18 14:10 + +import django.db.models.deletion +from django.db import migrations, models + +import peachjam.models.core_document_model + + +class Migration(migrations.Migration): + + dependencies = [ + ("peachjam", "0116_copy_and_delete_old_order_outcome_field_data"), + ] + + operations = [ + migrations.CreateModel( + name="DocumentMedia", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "filename", + models.CharField(max_length=1024, verbose_name="filename"), + ), + ( + "file", + models.FileField( + max_length=1024, + upload_to=peachjam.models.core_document_model.file_location, + verbose_name="file", + ), + ), + ( + "mimetype", + models.CharField(max_length=1024, verbose_name="mimetype"), + ), + ( + "document", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="document_media", + to="peachjam.coredocument", + verbose_name="document", + ), + ), + ], + ), + ] diff --git a/peachjam/models/core_document_model.py b/peachjam/models/core_document_model.py index 126e45de7..84d305989 100644 --- a/peachjam/models/core_document_model.py +++ b/peachjam/models/core_document_model.py @@ -912,3 +912,19 @@ def update_or_create_for_document(cls, document): )[0] document.document_content = doc_content return doc_content + + +class DocumentMedia(models.Model): + document = models.ForeignKey( + CoreDocument, + on_delete=models.CASCADE, + related_name="document_media", + verbose_name=_("document"), + ) + filename = models.CharField(_("filename"), max_length=1024, null=False, blank=False) + file = models.FileField( + _("file"), + upload_to=file_location, + max_length=1024, + ) + mimetype = models.CharField(_("mimetype"), max_length=1024, null=False, blank=False) From baab43c7d07c42bd36c312da1a4a928100489346 Mon Sep 17 00:00:00 2001 From: Nick Mwangemi Date: Thu, 18 Jan 2024 09:44:19 -0500 Subject: [PATCH 11/23] Update peachjam_search/serializers.py Co-authored-by: Greg Kempe --- peachjam_search/serializers.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/peachjam_search/serializers.py b/peachjam_search/serializers.py index 0cb3ba7b1..803a3ee95 100644 --- a/peachjam_search/serializers.py +++ b/peachjam_search/serializers.py @@ -73,11 +73,7 @@ def get_nature(self, obj): return obj["nature" + self.language_suffix] def get_order_outcomes(self, obj): - order_outcomes = obj["order_outcomes"] - if order_outcomes: - return [ - order_outcome + self.language_suffix for order_outcome in order_outcomes - ] + return obj["order_outcomes" + self.language_suffix] def get_registry(self, obj): return obj["registry" + self.language_suffix] From 1b921e72f03ae2aa5fdbe06242df334f2f8b3e39 Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Thu, 18 Jan 2024 17:45:10 +0300 Subject: [PATCH 12/23] Revert --- peachjam/models/core_document_model.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/peachjam/models/core_document_model.py b/peachjam/models/core_document_model.py index 84d305989..126e45de7 100644 --- a/peachjam/models/core_document_model.py +++ b/peachjam/models/core_document_model.py @@ -912,19 +912,3 @@ def update_or_create_for_document(cls, document): )[0] document.document_content = doc_content return doc_content - - -class DocumentMedia(models.Model): - document = models.ForeignKey( - CoreDocument, - on_delete=models.CASCADE, - related_name="document_media", - verbose_name=_("document"), - ) - filename = models.CharField(_("filename"), max_length=1024, null=False, blank=False) - file = models.FileField( - _("file"), - upload_to=file_location, - max_length=1024, - ) - mimetype = models.CharField(_("mimetype"), max_length=1024, null=False, blank=False) From 03d584d8e75b4ade5c4ce46c0b01c60ade5f02fe Mon Sep 17 00:00:00 2001 From: Nick Mwangemi Date: Thu, 18 Jan 2024 09:48:11 -0500 Subject: [PATCH 13/23] Delete peachjam/migrations/0117_documentmedia.py --- peachjam/migrations/0117_documentmedia.py | 55 ----------------------- 1 file changed, 55 deletions(-) delete mode 100644 peachjam/migrations/0117_documentmedia.py diff --git a/peachjam/migrations/0117_documentmedia.py b/peachjam/migrations/0117_documentmedia.py deleted file mode 100644 index 87a865a58..000000000 --- a/peachjam/migrations/0117_documentmedia.py +++ /dev/null @@ -1,55 +0,0 @@ -# Generated by Django 3.2.19 on 2024-01-18 14:10 - -import django.db.models.deletion -from django.db import migrations, models - -import peachjam.models.core_document_model - - -class Migration(migrations.Migration): - - dependencies = [ - ("peachjam", "0116_copy_and_delete_old_order_outcome_field_data"), - ] - - operations = [ - migrations.CreateModel( - name="DocumentMedia", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "filename", - models.CharField(max_length=1024, verbose_name="filename"), - ), - ( - "file", - models.FileField( - max_length=1024, - upload_to=peachjam.models.core_document_model.file_location, - verbose_name="file", - ), - ), - ( - "mimetype", - models.CharField(max_length=1024, verbose_name="mimetype"), - ), - ( - "document", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="document_media", - to="peachjam.coredocument", - verbose_name="document", - ), - ), - ], - ), - ] From 97d8f3401f4857babb7cb1030635479c3a61fa74 Mon Sep 17 00:00:00 2001 From: Nick Mwangemi Date: Fri, 19 Jan 2024 01:33:07 -0500 Subject: [PATCH 14/23] Update peachjam/templates/peachjam/judgment_detail.html Co-authored-by: Greg Kempe --- peachjam/templates/peachjam/judgment_detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peachjam/templates/peachjam/judgment_detail.html b/peachjam/templates/peachjam/judgment_detail.html index 7b2e6c981..11ae93ab4 100644 --- a/peachjam/templates/peachjam/judgment_detail.html +++ b/peachjam/templates/peachjam/judgment_detail.html @@ -43,7 +43,7 @@ {% endif %} {% with document.order_outcomes.all as order_outcomes %} - {% if document.order_outcomes %} + {% if order_outcomes %}
{% trans 'Order' %}
From 31d542251a0adb1b6a96588440e19588598d3874 Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Fri, 19 Jan 2024 09:34:39 +0300 Subject: [PATCH 15/23] Always render order outcome --- peachjam/templates/peachjam/judgment_detail.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/peachjam/templates/peachjam/judgment_detail.html b/peachjam/templates/peachjam/judgment_detail.html index 11ae93ab4..6e26aafe9 100644 --- a/peachjam/templates/peachjam/judgment_detail.html +++ b/peachjam/templates/peachjam/judgment_detail.html @@ -49,7 +49,8 @@
{% for order_outcome in order_outcomes %} - {% if not forloop.last %}{{ order_outcome.name }},{% endif %} + {{ order_outcome.name }} + {% if not forloop.last %},{% endif %} {% endfor %}
{% endif %} From cde22970b23d7ba698d78d2bd8359fe80a744b0a Mon Sep 17 00:00:00 2001 From: nickmwangemi Date: Fri, 19 Jan 2024 09:44:57 +0300 Subject: [PATCH 16/23] Update filtering of judgments by order outcomes --- peachjam/forms.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/peachjam/forms.py b/peachjam/forms.py index 139d02e7b..1768ece27 100644 --- a/peachjam/forms.py +++ b/peachjam/forms.py @@ -158,7 +158,9 @@ def filter_queryset(self, queryset, exclude=None): queryset = queryset.filter(attorneys__name__in=attorneys) if order_outcomes and exclude != "order_outcomes": - queryset = queryset.filter(order_outcome__name__in=order_outcomes) + queryset = queryset.filter( + order_outcomes__name__in=order_outcomes + ).distinct() return queryset From a4943f2f2e2fc1c4341b8f8efcddf21856aece00 Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Sat, 20 Jan 2024 16:32:02 +0200 Subject: [PATCH 17/23] mark migration as reversible --- .../0116_copy_and_delete_old_order_outcome_field_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peachjam/migrations/0116_copy_and_delete_old_order_outcome_field_data.py b/peachjam/migrations/0116_copy_and_delete_old_order_outcome_field_data.py index e036ee61a..dbb84c562 100644 --- a/peachjam/migrations/0116_copy_and_delete_old_order_outcome_field_data.py +++ b/peachjam/migrations/0116_copy_and_delete_old_order_outcome_field_data.py @@ -24,7 +24,7 @@ class Migration(migrations.Migration): name="order_outcomes", field=models.ManyToManyField(blank=True, to="peachjam.OrderOutcome"), ), - migrations.RunPython(copy_data), + migrations.RunPython(copy_data, migrations.RunPython.noop), migrations.RemoveField( model_name="judgment", name="order_outcome", From 034766743f0a00a6df880c9dd550aced69d5f3e2 Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Wed, 17 Jan 2024 16:25:45 +0200 Subject: [PATCH 18/23] cross-origin popups --- peachjam/resolver.py | 114 ++++++++++++++++++ peachjam/settings.py | 6 + .../templates/peachjam/document_popup.html | 14 ++- peachjam/views/documents.py | 113 +---------------- peachjam/views/widgets.py | 92 ++++++++++++-- pyproject.toml | 1 + 6 files changed, 220 insertions(+), 120 deletions(-) create mode 100644 peachjam/resolver.py diff --git a/peachjam/resolver.py b/peachjam/resolver.py new file mode 100644 index 000000000..f1906ea13 --- /dev/null +++ b/peachjam/resolver.py @@ -0,0 +1,114 @@ +from django.conf import settings + + +class RedirectResolver: + RESOLVER_MAPPINGS = { + "africanlii": { + "country_code": "aa", + "domain": "africanlii.org", + }, + "eswatinilii": { + "country_code": "sz", + "domain": "eswatinilii.org", + }, + "ghalii": { + "country_code": "gh", + "domain": "ghalii.org", + }, + "lawlibrary": { + "country_code": "za", + "domain": "lawlibrary.org.za", + }, + "leslii": { + "country_code": "ls", + "domain": "lesotholii.org", + }, + "malawilii": { + "country_code": "mw", + "domain": "malawilii.org", + }, + "mauritiuslii": { + "country_code": "mu", + "domain": "mauritiuslii.org", + }, + "namiblii": { + "country_code": "na", + "domain": "namiblii.org", + }, + "nigerialii": { + "country_code": "ng", + "domain": "nigerialii.org", + }, + "open by-laws": { + "place_code": [], + "domain": "openbylaws.org.za", + }, + "rwandalii": { + "country_code": "rw", + "domain": "rwandalii.org", + }, + "seylii": { + "country_code": "sc", + "domain": "seylii.org", + }, + "sierralii": { + "country_code": "sl", + "domain": "sierralii.org", + }, + "tanzlii": { + "country_code": "tz", + "domain": "tanzlii.org", + }, + "tcilii": { + "country_code": "tc", + "domain": "tcilii.org", + }, + "ulii": { + "country_code": "ug", + "domain": "ulii.org", + }, + "zambialii": { + "country_code": "zm", + "domain": "zambialii.org", + }, + "zanzibarlii": { + "place_code": "tz-znz", + "domain": "zanzibarlii.org", + }, + "zimlii": { + "country_code": "zw", + "domain": "zimlii.org", + }, + } + + def __init__(self, app_name): + self.current_authority = self.RESOLVER_MAPPINGS[app_name.lower()] + + def get_domain_for_frbr_uri(self, parsed_frbr_uri): + best_domain = self.get_best_domain(parsed_frbr_uri) + if best_domain != self.current_authority["domain"]: + return best_domain + return None + + def get_url_for_frbr_uri(self, parsed_frbr_uri, raw_frbr_uri): + domain = self.get_domain_for_frbr_uri(parsed_frbr_uri) + if domain: + return f"https://{domain}{raw_frbr_uri}" + + def get_best_domain(self, parsed_uri): + country_code = parsed_uri.country + place_code = parsed_uri.place + + if country_code != place_code: + for key, mapping in self.RESOLVER_MAPPINGS.items(): + if mapping.get("place_code") == place_code: + return mapping.get("domain") + + # if no domain matching with place code is found use country code + for key, mapping in self.RESOLVER_MAPPINGS.items(): + if mapping.get("country_code") == country_code: + return mapping.get("domain") + return None + + +resolver = RedirectResolver(settings.PEACHJAM["APP_NAME"]) diff --git a/peachjam/settings.py b/peachjam/settings.py index 5e8ebaafe..56608962c 100644 --- a/peachjam/settings.py +++ b/peachjam/settings.py @@ -77,6 +77,7 @@ "drf_spectacular", "django_advanced_password_validation", "martor", + "corsheaders", ] MIDDLEWARE = [ @@ -87,6 +88,7 @@ "whitenoise.middleware.WhiteNoiseMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.locale.LocaleMiddleware", + "corsheaders.middleware.CorsMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", @@ -607,3 +609,7 @@ def before_send(event, hint): } # disable the normal martor theme which pulls in another bootstrap version MARTOR_ALTERNATIVE_CSS_FILE_THEME = "martor/css/peachjam.css" + +# CORS +# disable regex matches, we do matching using signals +CORS_URLS_REGEX = r"^$" diff --git a/peachjam/templates/peachjam/document_popup.html b/peachjam/templates/peachjam/document_popup.html index 14f0d179a..f8a7b8f9c 100644 --- a/peachjam/templates/peachjam/document_popup.html +++ b/peachjam/templates/peachjam/document_popup.html @@ -7,7 +7,7 @@ {% endblock %} {% else %} -
+
{% block title %} {{ document.title }} @@ -19,13 +19,21 @@ {% endblock %}
{% block citation %} - {% if document.citation %} + {% if document.citation and document.citation != document.title %}
{{ document.citation }}
{% endif %} {% endblock %} + {% block date %}
{{ document.date }}
{% endblock %}
- {% block date %}
{{ document.date }}
{% endblock %} + {% block offsite_request %} + {% if offsite_request %} + + {% endif %} + {% endblock %} {% endif %}
diff --git a/peachjam/views/documents.py b/peachjam/views/documents.py index 535a038a6..64a3a4560 100644 --- a/peachjam/views/documents.py +++ b/peachjam/views/documents.py @@ -1,5 +1,4 @@ from cobalt import FrbrUri -from django.conf import settings from django.http import Http404, HttpResponse from django.shortcuts import get_object_or_404, redirect, reverse from django.utils.decorators import method_decorator @@ -9,111 +8,7 @@ from peachjam.helpers import add_slash, add_slash_to_frbr_uri from peachjam.models import CoreDocument from peachjam.registry import registry - - -class RedirectResolver: - RESOLVER_MAPPINGS = { - "africanlii": { - "country_code": "aa", - "domain": "africanlii.org", - }, - "eswatinilii": { - "country_code": "sz", - "domain": "eswatinilii.org", - }, - "ghalii": { - "country_code": "gh", - "domain": "ghalii.org", - }, - "lawlibrary": { - "country_code": "za", - "domain": "lawlibrary.org.za", - }, - "leslii": { - "country_code": "ls", - "domain": "lesotholii.org", - }, - "malawilii": { - "country_code": "mw", - "domain": "malawilii.org", - }, - "mauritiuslii": { - "country_code": "mu", - "domain": "mauritiuslii.org", - }, - "namiblii": { - "country_code": "na", - "domain": "namiblii.org", - }, - "nigerialii": { - "country_code": "ng", - "domain": "nigerialii.org", - }, - "open by-laws": { - "place_code": [], - "domain": "openbylaws.org.za", - }, - "rwandalii": { - "country_code": "rw", - "domain": "rwandalii.org", - }, - "seylii": { - "country_code": "sc", - "domain": "seylii.org", - }, - "sierralii": { - "country_code": "sl", - "domain": "sierralii.org", - }, - "tanzlii": { - "country_code": "tz", - "domain": "tanzlii.org", - }, - "tcilii": { - "country_code": "tc", - "domain": "tcilii.org", - }, - "ulii": { - "country_code": "ug", - "domain": "ulii.org", - }, - "zambialii": { - "country_code": "zm", - "domain": "zambialii.org", - }, - "zanzibarlii": { - "place_code": "tz-znz", - "domain": "zanzibarlii.org", - }, - "zimlii": { - "country_code": "zw", - "domain": "zimlii.org", - }, - } - - def __init__(self, app_name): - self.current_authority = self.RESOLVER_MAPPINGS[app_name.lower()] - - def get_domain_for_frbr_uri(self, parsed_uri): - best_domain = self.get_best_domain(parsed_uri) - if best_domain != self.current_authority["domain"]: - return best_domain - return None - - def get_best_domain(self, parsed_uri): - country_code = parsed_uri.country - place_code = parsed_uri.place - - if country_code != place_code: - for key, mapping in self.RESOLVER_MAPPINGS.items(): - if mapping.get("place_code") == place_code: - return mapping.get("domain") - - # if no domain matching with place code is found use country code - for key, mapping in self.RESOLVER_MAPPINGS.items(): - if mapping.get("country_code") == country_code: - return mapping.get("domain") - return None +from peachjam.resolver import resolver class DocumentDetailViewResolver(View): @@ -145,10 +40,8 @@ def dispatch(self, request, *args, **kwargs): ) if not obj: - resolver = RedirectResolver(settings.PEACHJAM["APP_NAME"]) - domain = resolver.get_domain_for_frbr_uri(parsed_frbr_uri) - if domain: - url = f"https://{domain}{frbr_uri}" + url = resolver.get_url_for_frbr_uri(parsed_frbr_uri, frbr_uri) + if url: return redirect(url) raise Http404() diff --git a/peachjam/views/widgets.py b/peachjam/views/widgets.py index c7f2d4cd1..1187a4f47 100644 --- a/peachjam/views/widgets.py +++ b/peachjam/views/widgets.py @@ -1,32 +1,87 @@ +import re +from urllib.parse import urlparse + import lxml.html from cobalt.uri import FrbrUri +from corsheaders.signals import check_request_enabled +from django.conf import settings from django.http import Http404 +from django.shortcuts import redirect from django.utils.translation import get_language from django.views.generic import DetailView from peachjam.helpers import add_slash, parse_utf8_html from peachjam.models import CoreDocument +from peachjam.resolver import RedirectResolver, resolver class DocumentPopupView(DetailView): - """Shows a popup with basic details for a document.""" + """Shows a popup with basic details for a document. + + An affiliate site may use this by redirecting a local popup to a popup on (this) LII website. + So we allow CORS requests, provided the origin matches the partner website. + + For example: + + 1. The user hovers over a link to /akn/xx/act/2009/1 on africanlii.org + 2. The browser asks africanlii.org for the popup, but it doesn't exist on africanlii.org + 3. So africanlii.org uses peachjam's resolver logic to identify that xxlii.org is responsible for /akn/xx/... + and redirects the user's browser to xxlii.org/p/africanlii.org/e/popup/akn/xx/act/2009/1 + 4. This view loads on xxlii.org and shows the popup, because the request came from africanlii.org + which matches the partner code in the URL + """ model = CoreDocument context_object_name = "document" template_name = "peachjam/document_popup.html" + partner_domains = [x["domain"] for x in RedirectResolver.RESOLVER_MAPPINGS.values()] + localhost = ["localhost", "127.0.0.1"] + frbr_uri = None + + def get(self, request, partner, frbr_uri, *args, **kwargs): + # check partner matches requesting host + if not self.valid_partner(request, partner): + raise Http404() + + try: + self.object = self.get_object() + except Http404: + if self.frbr_uri: + # use the resolver to send a redirect if it's probably off-site somewhere + domain = resolver.get_domain_for_frbr_uri(self.frbr_uri) + if domain: + return redirect(f"https://{domain}{self.request.path}") + raise + + context = self.get_context_data(object=self.object) + return self.render_to_response(context) + + def valid_partner(self, request, partner): + # only allow this page to be embedded from valid partners + # first, the partner must match the referer (or origin, for CORS requests) + referrer = request.META.get("HTTP_REFERER") or request.META.get("HTTP_ORIGIN") + if referrer and not settings.DEBUG: + try: + parsed = urlparse(referrer) + if parsed.hostname != partner and parsed.hostname not in self.localhost: + return False + except ValueError: + return False + # second, the partner must be in the list of valid partners + return partner in self.partner_domains or partner in self.localhost def get_object(self, *args, **kwargs): try: - frbr_uri = FrbrUri.parse(add_slash(self.kwargs["frbr_uri"])) + self.frbr_uri = FrbrUri.parse(add_slash(self.kwargs["frbr_uri"])) except ValueError: raise Http404() - self.portion = frbr_uri.portion - frbr_uri.portion = None - if frbr_uri.expression_date: - uri = frbr_uri.expression_uri() + self.portion = self.frbr_uri.portion + self.frbr_uri.portion = None + if self.frbr_uri.expression_date: + uri = self.frbr_uri.expression_uri() else: - uri = frbr_uri.work_uri() + uri = self.frbr_uri.work_uri() obj = self.model.objects.best_for_frbr_uri(uri, get_language())[0] if not obj: @@ -51,4 +106,27 @@ def get_context_data(self, **kwargs): except ValueError: raise Http404() + # is this a CORS request from off-site? (the partner host is not the same as the local host) + context["offsite_request"] = self.request.get_host() != self.kwargs["partner"] + return context + + +url_re = re.compile("^/p/([^/]+)/e/.*") + + +def check_cors_and_partner(sender, request, **kwargs): + """Check if we should mark this request as CORS-enabled. We do so if it's popup URL and + the origin matches the partner domain.""" + match = url_re.match(request.path_info) + if match: + # allow a CORS request if the partner portion of the URL matches the origin + origin = request.META.get("HTTP_ORIGIN") + if origin: + try: + return urlparse(origin).hostname == match.group(1) + except ValueError: + return False + + +check_request_enabled.connect(check_cors_and_partner) diff --git a/pyproject.toml b/pyproject.toml index f039ec1a0..1f5738797 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,7 @@ dependencies = [ "django-background-tasks>=1.2.5", "django-ckeditor>=6.4.2", "django-compressor>=3.1", + "django-cors-headers>=4.3.1", "django-countries-plus>=1.3.2", "django-debug-toolbar>=3.2.4,<4.2.0", "django-elasticsearch-debug-toolbar>=3.0.2", From d6b59602a772dcfe37baedb01cb2e98806d74628 Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Sat, 20 Jan 2024 17:26:00 +0200 Subject: [PATCH 19/23] handle resolver without current authority; tests --- peachjam/resolver.py | 4 ++-- peachjam/tests/test_resolver.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/peachjam/resolver.py b/peachjam/resolver.py index f1906ea13..c92900812 100644 --- a/peachjam/resolver.py +++ b/peachjam/resolver.py @@ -82,11 +82,11 @@ class RedirectResolver: } def __init__(self, app_name): - self.current_authority = self.RESOLVER_MAPPINGS[app_name.lower()] + self.current_authority = self.RESOLVER_MAPPINGS.get(app_name.lower()) def get_domain_for_frbr_uri(self, parsed_frbr_uri): best_domain = self.get_best_domain(parsed_frbr_uri) - if best_domain != self.current_authority["domain"]: + if self.current_authority and best_domain != self.current_authority["domain"]: return best_domain return None diff --git a/peachjam/tests/test_resolver.py b/peachjam/tests/test_resolver.py index d170ed195..4796b4880 100644 --- a/peachjam/tests/test_resolver.py +++ b/peachjam/tests/test_resolver.py @@ -1,7 +1,7 @@ from cobalt import FrbrUri from django.test import TestCase -from peachjam.views.documents import RedirectResolver +from peachjam.resolver import RedirectResolver urls = [ "/akn/zm/judgment/zmsc/2021/7/eng@2021-01-19", From 0e79ae45695d09056abcd71867d671d42b816576 Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Mon, 22 Jan 2024 11:06:44 +0200 Subject: [PATCH 20/23] get translated order outcomes when indexing in ES --- peachjam_search/documents.py | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/peachjam_search/documents.py b/peachjam_search/documents.py index 5dd12e069..1e9a70c3e 100644 --- a/peachjam_search/documents.py +++ b/peachjam_search/documents.py @@ -25,6 +25,11 @@ log = logging.getLogger(__name__) +# the languages that translated fields support, that will be indexed into ES +# TODO: where should this language list be configured? they are languages that the interface is translated into +TRANSLATED_FIELD_LANGS = ["en", "fr", "pt", "sw"] + + class RankField(fields.DEDField, RankFeature): pass @@ -107,7 +112,6 @@ class SearchableDocument(Document): translated_fields = [ ("court", "name"), ("registry", "name"), - ("order_outcomes", "name"), ("nature", "name"), ] @@ -240,6 +244,18 @@ def prepare_order_outcomes(self, instance): order_outcome.name for order_outcome in instance.order_outcomes.all() ] + def prepare_order_outcomes_en(self, instance): + return get_translated_m2m_name(instance, "order_outcomes", "en") + + def prepare_order_outcomes_fr(self, instance): + return get_translated_m2m_name(instance, "order_outcomes", "fr") + + def prepare_order_outcomes_pt(self, instance): + return get_translated_m2m_name(instance, "order_outcomes", "pt") + + def prepare_order_outcomes_sw(self, instance): + return get_translated_m2m_name(instance, "order_outcomes", "sw") + def prepare_pages(self, instance): """Text content of pages extracted from PDF.""" if not instance.content_html: @@ -292,6 +308,15 @@ def get_queryset(self): return super().get_queryset().order_by("-pk") +def get_translated_m2m_name(instance, field, lang): + """Get the translated name of a many-to-many field.""" + if hasattr(instance, field) and getattr(instance, field): + return [ + getattr(v, f"name_{lang}", None) or v.name + for v in getattr(instance, field).all() + ] + + def prepare_translated_field(self, instance, field, attr, lang): if getattr(instance, field, None): fld = getattr(instance, field) @@ -306,8 +331,7 @@ def make_prepare(field, attr, lang): # add preparation methods for translated fields to avoid lots of copy-and-paste for field, attr in SearchableDocument.translated_fields: - # TODO: where should this language list be configured? they are languages that the interface is translated into - for lang in ["en", "fr", "pt", "sw"]: + for lang in TRANSLATED_FIELD_LANGS: # we must call make_prepare so that the variables are evaluated now, not when the function is called setattr( SearchableDocument, From 80f7d5731fa778592bcce7cf87306c1f2277ce6c Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Mon, 22 Jan 2024 11:08:40 +0200 Subject: [PATCH 21/23] adjustments for order_outcome and search it's far simpler to retain the singular field name in ES, because it cleanly supports both single and multiple fields. it's a lot more complex to move the field. --- peachjam_search/documents.py | 20 ++++++++++---------- peachjam_search/serializers.py | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/peachjam_search/documents.py b/peachjam_search/documents.py index 1e9a70c3e..ae4013854 100644 --- a/peachjam_search/documents.py +++ b/peachjam_search/documents.py @@ -81,11 +81,11 @@ class SearchableDocument(Document): registry_fr = fields.KeywordField() registry_pt = fields.KeywordField() - order_outcomes = fields.KeywordField(attr="order_outcome.name") - order_outcomes_en = fields.KeywordField() - order_outcomes_sw = fields.KeywordField() - order_outcomes_fr = fields.KeywordField() - order_outcomes_pt = fields.KeywordField() + order_outcome = fields.KeywordField() + order_outcome_en = fields.KeywordField() + order_outcome_sw = fields.KeywordField() + order_outcome_fr = fields.KeywordField() + order_outcome_pt = fields.KeywordField() # GenericDocument, LegalInstrument authors = fields.KeywordField() @@ -238,22 +238,22 @@ def prepare_nature(self, instance): if hasattr(instance, "nature") and instance.nature: return instance.nature.name - def prepare_order_outcomes(self, instance): + def prepare_order_outcome(self, instance): if hasattr(instance, "order_outcomes") and instance.order_outcomes: return [ order_outcome.name for order_outcome in instance.order_outcomes.all() ] - def prepare_order_outcomes_en(self, instance): + def prepare_order_outcome_en(self, instance): return get_translated_m2m_name(instance, "order_outcomes", "en") - def prepare_order_outcomes_fr(self, instance): + def prepare_order_outcome_fr(self, instance): return get_translated_m2m_name(instance, "order_outcomes", "fr") - def prepare_order_outcomes_pt(self, instance): + def prepare_order_outcome_pt(self, instance): return get_translated_m2m_name(instance, "order_outcomes", "pt") - def prepare_order_outcomes_sw(self, instance): + def prepare_order_outcome_sw(self, instance): return get_translated_m2m_name(instance, "order_outcomes", "sw") def prepare_pages(self, instance): diff --git a/peachjam_search/serializers.py b/peachjam_search/serializers.py index 803a3ee95..847b07eed 100644 --- a/peachjam_search/serializers.py +++ b/peachjam_search/serializers.py @@ -10,7 +10,7 @@ class SearchableDocumentSerializer(DocumentSerializer): pages = SerializerMethodField() court = SerializerMethodField() nature = SerializerMethodField() - order_outcomes = SerializerMethodField() + order_outcome = SerializerMethodField() registry = SerializerMethodField() labels = CharField(allow_null=True) _score = FloatField(source="meta.score") @@ -72,8 +72,8 @@ def get_court(self, obj): def get_nature(self, obj): return obj["nature" + self.language_suffix] - def get_order_outcomes(self, obj): - return obj["order_outcomes" + self.language_suffix] + def get_order_outcome(self, obj): + return list(obj["order_outcome" + self.language_suffix]) def get_registry(self, obj): return obj["registry" + self.language_suffix] From acb019f6bab869cb631f5ec29923efbfdae6960c Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Mon, 22 Jan 2024 12:15:19 +0200 Subject: [PATCH 22/23] fix search --- peachjam_search/serializers.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/peachjam_search/serializers.py b/peachjam_search/serializers.py index 847b07eed..7ae2ba0d6 100644 --- a/peachjam_search/serializers.py +++ b/peachjam_search/serializers.py @@ -73,7 +73,10 @@ def get_nature(self, obj): return obj["nature" + self.language_suffix] def get_order_outcome(self, obj): - return list(obj["order_outcome" + self.language_suffix]) + val = obj["order_outcome" + self.language_suffix] + if val is not None: + val = list(val) + return val def get_registry(self, obj): return obj["registry" + self.language_suffix] From a14ab8cc151df0fd20e7defddfecb7b025199f6b Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Mon, 22 Jan 2024 13:18:45 +0200 Subject: [PATCH 23/23] don't fetch bills from indigo --- peachjam/adapters/adapters.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/peachjam/adapters/adapters.py b/peachjam/adapters/adapters.py index dcce7da84..b0ef27180 100644 --- a/peachjam/adapters/adapters.py +++ b/peachjam/adapters/adapters.py @@ -110,6 +110,10 @@ def get_doc_list(self): while url: res = self.client_get(url).json() + # ignore bills + # TODO: later, make this configurable + res["results"] = [r for r in res["results"] if r["nature"] != "bill"] + # Filter by actor, if setting is present actor = self.settings.get("actor", None) if actor: