diff --git a/ynr/apps/people/forms/forms.py b/ynr/apps/people/forms/forms.py index 16dcca8037..e42cf5ee00 100644 --- a/ynr/apps/people/forms/forms.py +++ b/ynr/apps/people/forms/forms.py @@ -19,6 +19,7 @@ StrippedCharField, ) from people.helpers import ( + clean_linkedin_url, clean_mastodon_username, clean_twitter_username, clean_wikidata_id, @@ -128,6 +129,18 @@ def clean_twitter_username(self, username): except ValueError as e: raise ValidationError(e) + def clean_linkedin_url(self, url): + if self.instance.value != url: + self.instance.internal_identifier = None + + if self.instance.internal_identifier: + return url + + try: + clean_linkedin_url(url) + except ValueError as e: + raise ValidationError(e) + def clean_mastodon_username(self, username): if self.instance.value != username: self.instance.internal_identifier = None diff --git a/ynr/apps/people/helpers.py b/ynr/apps/people/helpers.py index a8df99634c..30434de559 100644 --- a/ynr/apps/people/helpers.py +++ b/ynr/apps/people/helpers.py @@ -8,6 +8,7 @@ ) from dateutil import parser from django.conf import settings +from django.core.exceptions import ValidationError from django_date_extensions.fields import ApproximateDate @@ -120,6 +121,15 @@ def clean_twitter_username(username): return username +def clean_linkedin_url(url): + parsed_url = urlparse(url) + if parsed_url.netloc != "linkedin.com" or not parsed_url.path.startswith( + "/in/" + ): + raise ValidationError("Please enter a valid LinkedIn URL.") + return url + + def clean_wikidata_id(identifier): identifier = identifier.strip().lower() m = re.search(r"^.*wikidata.org/(wiki|entity)/(\w+)", identifier) diff --git a/ynr/apps/people/management/commands/reformat_person_indentifiers.py b/ynr/apps/people/management/commands/reformat_person_indentifiers.py new file mode 100644 index 0000000000..ea33cdb751 --- /dev/null +++ b/ynr/apps/people/management/commands/reformat_person_indentifiers.py @@ -0,0 +1,40 @@ +from urllib.parse import urlparse + +from django.core.management import call_command +from django.core.management.base import BaseCommand +from people.models import Person + + +class Command(BaseCommand): + def handle(self, *args, **options): + """ + Iterate over all PersonIdentifier objects and reformat the LinkedIn urls as needed. + """ + + people = Person.objects.all() + for person in people: + person_identifiers = person.get_all_identifiers + linkedin_person_identifiers = [ + identifier + for identifier in person_identifiers + if identifier.value_type == "linkedin_url" + ] + # if the parsed_url netloc is uk.linkedin.com, + # then this is a redirect and we need to reformat it to www.linkedin.com + for identifier in linkedin_person_identifiers: + parsed_url = urlparse(identifier.value) + + if parsed_url.netloc == "uk.linkedin.com": + # remove the uk. from the netloc + identifier.value = identifier.value.replace("uk.", "www.") + identifier.save() + self.stdout.write( + f"Reformatted LinkedIn URL for {person.name} to {identifier.value}" + ) + else: + self.stdout.write( + f"LinkedIn URL for {person.name} is already in the correct format." + ) + pass + + call_command("identify_inactive_person_links") diff --git a/ynr/apps/people/tests/test_person_form_identifier_crud.py b/ynr/apps/people/tests/test_person_form_identifier_crud.py index d081f0249d..2b0b30d301 100644 --- a/ynr/apps/people/tests/test_person_form_identifier_crud.py +++ b/ynr/apps/people/tests/test_person_form_identifier_crud.py @@ -209,6 +209,14 @@ def test_mastodon_full_url(self): qs = PersonIdentifier.objects.all() self.assertEqual(qs[0].value, "joe") + def test_bad_linkedin_url(self): + resp = self._submit_values("http://example.com/@blah", "linkedin_url") + form = resp.context["identifiers_formset"] + self.assertFalse(form.is_valid()) + self.assertEqual( + form[0].non_field_errors(), ["Please enter a valid LinkedIn URL."] + ) + def test_bad_email_address(self): resp = self._submit_values("whoops", "email") form = resp.context["identifiers_formset"] diff --git a/ynr/apps/ynr_refactoring/settings.py b/ynr/apps/ynr_refactoring/settings.py index 42f89e619d..308f01cdf4 100644 --- a/ynr/apps/ynr_refactoring/settings.py +++ b/ynr/apps/ynr_refactoring/settings.py @@ -12,7 +12,7 @@ class PersonIdentifierFields(Enum): facebook_personal_url = "Facebook Personal" homepage_url = "Homepage" blog_url = "Blog" - linkedin_url = "Linkedin" + linkedin_url = "LinkedIn URL" party_ppc_page_url = "Party Candidate Page" twitter_username = "Twitter" mastodon_username = "Mastodon"