From a6b5d99289d00c14641044173dc860a405aef3a1 Mon Sep 17 00:00:00 2001 From: Virginia Dooley Date: Tue, 2 Jul 2024 15:38:44 +0100 Subject: [PATCH] Record a timestamp on PersonImage - Show the last updated timestamp for PersonImage - Test migration and template for PersonImage timestamps - Fix timezone --- .../templates/candidates/_photo-credit.html | 4 +- ...ge_options_personimage_created_and_more.py | 58 +++++++++++++++++++ ynr/apps/people/models.py | 2 +- ynr/apps/people/tests/test_person_models.py | 37 ++++++++++++ 4 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 ynr/apps/people/migrations/0047_alter_personimage_options_personimage_created_and_more.py diff --git a/ynr/apps/candidates/templates/candidates/_photo-credit.html b/ynr/apps/candidates/templates/candidates/_photo-credit.html index 76bcc9f8c..83cb5aee4 100644 --- a/ynr/apps/candidates/templates/candidates/_photo-credit.html +++ b/ynr/apps/candidates/templates/candidates/_photo-credit.html @@ -5,7 +5,9 @@ {% with user_comment=image.user_notes %} {% if contributor %} - This photo was uploaded by the user ‘{{ contributor }}’. + This photo was uploaded by the user ‘{{ contributor }}’ on {{ image.modified }}. + {% else%} + This photo was uploaded on {{ image.modified }}. {% endif %} {% if user_reason and user_reason != 'other' %} Their justification for its use on the site was: diff --git a/ynr/apps/people/migrations/0047_alter_personimage_options_personimage_created_and_more.py b/ynr/apps/people/migrations/0047_alter_personimage_options_personimage_created_and_more.py new file mode 100644 index 000000000..b91527707 --- /dev/null +++ b/ynr/apps/people/migrations/0047_alter_personimage_options_personimage_created_and_more.py @@ -0,0 +1,58 @@ +# Generated by Django 4.2.11 on 2024-07-02 13:44 + +import django.utils.timezone +import django_extensions.db.fields +from django.db import migrations + + +def get_timestamp_from_queued_image(apps, schema_editor): + """Set the created and modified timestamps on the image + to the timestamp of the first and last approved queued image""" + + PersonImage = apps.get_model("people", "PersonImage") + for personimage in PersonImage.objects.all(): + person = personimage.person + queued_images = person.queuedimage_set.all() + if not queued_images: + continue + modified = queued_images.filter(decision="approved").last().updated + created = queued_images.filter(decision="approved").last().created + if modified: + personimage.modified = modified + personimage.created = created + personimage.save() + + +class Migration(migrations.Migration): + dependencies = [ + ("people", "0046_alter_personidentifier_unique_together"), + ] + + operations = [ + migrations.AlterModelOptions( + name="personimage", + options={"get_latest_by": "modified"}, + ), + migrations.AddField( + model_name="personimage", + name="created", + field=django_extensions.db.fields.CreationDateTimeField( + auto_now_add=True, + default=django.utils.timezone.now, + verbose_name="created", + ), + preserve_default=False, + ), + migrations.AddField( + model_name="personimage", + name="modified", + field=django_extensions.db.fields.ModificationDateTimeField( + auto_now=True, verbose_name="modified" + ), + ), + ( + migrations.RunPython( + get_timestamp_from_queued_image, migrations.RunPython.noop + ) + ), + ] diff --git a/ynr/apps/people/models.py b/ynr/apps/people/models.py index 9eb3eadb3..8403001c9 100644 --- a/ynr/apps/people/models.py +++ b/ynr/apps/people/models.py @@ -53,7 +53,7 @@ class EditLimitationStatuses(Enum): EDITS_PREVENTED = "Edits prevented" -class PersonImage(models.Model): +class PersonImage(TimeStampedModel): """ Images of people, uploaded by users of the site. It's important we keep track of the copyright the uploading user asserts over the image, and any diff --git a/ynr/apps/people/tests/test_person_models.py b/ynr/apps/people/tests/test_person_models.py index 9841219bc..144aa00a6 100644 --- a/ynr/apps/people/tests/test_person_models.py +++ b/ynr/apps/people/tests/test_person_models.py @@ -7,6 +7,7 @@ from candidates.tests.helpers import TmpMediaRootMixin from candidates.tests.uk_examples import UK2015ExamplesMixin from django.contrib.auth import get_user_model +from django.utils import timezone from django_webtest import WebTest from moderation_queue.models import QueuedImage from moderation_queue.tests.paths import EXAMPLE_IMAGE_FILENAME @@ -47,6 +48,42 @@ def test_get_display_image_url(self): person = Person.objects.get() self.assertEqual(person.get_display_image_url(), url) + def test_all_person_images_have_a_timestamp(self): + """ensure that all person images have a timestamp""" + person = PersonFactory(name=faker_factory.name()) + pi = PersonImage.objects.create_from_file( + filename=EXAMPLE_IMAGE_FILENAME, + new_filename="images/jowell-pilot.jpg", + defaults={ + "person": person, + "source": "Taken from Wikipedia", + "copyright": "example-license", + "user_notes": "A photo of Tessa Jowell", + }, + ) + self.assertIsNotNone(pi.created) + self.assertIsNotNone(pi.modified) + + def test_person_image_modified_timestamp(self): + """visit the person-view.html template and check the response for the modified timestamp""" + person = PersonFactory(name=faker_factory.name()) + pi = PersonImage.objects.create_from_file( + filename=EXAMPLE_IMAGE_FILENAME, + new_filename="images/jowell-pilot.jpg", + defaults={ + "person": person, + "source": "Taken from Wikipedia", + "copyright": "example-license", + "user_notes": "A photo of Tessa Jowell", + }, + ) + modified = timezone.localtime(pi.modified) + response = self.app.get(f"/person/{person.id}", user=self.user) + self.assertIn( + f"This photo was uploaded on {modified.strftime('%-d %B %Y %H:%M')}.", + response.text, + ) + def test_get_alive_now(self): alive_person = PersonFactory(name=faker_factory.name()) PersonFactory(name=faker_factory.name(), death_date="2016-01-01")