diff --git a/amy/api/v1/serializers.py b/amy/api/v1/serializers.py index e30935102..f472597bf 100644 --- a/amy/api/v1/serializers.py +++ b/amy/api/v1/serializers.py @@ -119,6 +119,7 @@ class Meta: "country", "github", "twitter", + "bluesky", "url", "orcid", "affiliation", @@ -492,6 +493,7 @@ class Meta: "country", "github", "twitter", + "bluesky", "url", "orcid", "affiliation", diff --git a/amy/api/v1/tests/test_export.py b/amy/api/v1/tests/test_export.py index 1cb591dbc..685ad86d0 100644 --- a/amy/api/v1/tests/test_export.py +++ b/amy/api/v1/tests/test_export.py @@ -297,6 +297,7 @@ def test_all_related_objects_shown(self): "gender", "github", "twitter", + "bluesky", "url", "user_notes", "affiliation", diff --git a/amy/api/v2/serializers.py b/amy/api/v2/serializers.py index 87f054776..8bc69a874 100644 --- a/amy/api/v2/serializers.py +++ b/amy/api/v2/serializers.py @@ -245,6 +245,7 @@ class Meta: "airport", "github", "twitter", + "bluesky", "url", "user_notes", "affiliation", @@ -304,8 +305,6 @@ class Meta: "event", "person", "role", - "title", - "url", "seat_membership", "seat_public", "seat_open_training", diff --git a/amy/autoemails/actions.py b/amy/autoemails/actions.py index 5c5646d3a..177b2ef0c 100644 --- a/amy/autoemails/actions.py +++ b/amy/autoemails/actions.py @@ -788,7 +788,7 @@ def get_additional_context(self, objects, *args, **kwargs): task_emails = [t.person.email for t in tasks] contacts = event.contact.split(TAG_SEPARATOR) - context["all_emails"] = list(filter(bool, task_emails + contacts)) + context["all_emails"] = sorted(filter(bool, task_emails + contacts)) context["assignee"] = ( event.assigned_to.full_name if event.assigned_to else "Regional Coordinator" diff --git a/amy/autoemails/tests/test_instructorshostintroductionaction.py b/amy/autoemails/tests/test_instructorshostintroductionaction.py index a367a8631..130aae65e 100644 --- a/amy/autoemails/tests/test_instructorshostintroductionaction.py +++ b/amy/autoemails/tests/test_instructorshostintroductionaction.py @@ -250,13 +250,13 @@ def testContext(self): supporting_instructor2=supporting_instructor2.person, hosts=[host.person], all_emails=[ - "hp@magic.uk", - "rw@magic.uk", "hg@magic.uk", - "peter@webslinger.net", + "hp@magic.uk", "me@stark.com", - "test@hogwart.com", + "peter@webslinger.net", + "rw@magic.uk", "test2@magic.uk", + "test@hogwart.com", ], assignee="Regional Coordinator", tags=["automated-email", "LC"], @@ -314,11 +314,11 @@ def testRecipients(self): self.assertEqual( email.to, [ + "hg@magic.uk", "hp@magic.uk", "rw@magic.uk", - "hg@magic.uk", - "test@hogwart.com", "test2@magic.uk", + "test@hogwart.com", ], ) @@ -409,6 +409,6 @@ def test_drop_empty_contacts(self): ) ctx = a.get_additional_context(objects=dict(event=e)) - expected = ["rw@magic.uk", "hg@magic.uk"] + expected = ["hg@magic.uk", "rw@magic.uk"] self.assertEqual(ctx["all_emails"], expected) self.assertEqual(a.all_recipients(), "rw@magic.uk, hg@magic.uk") diff --git a/amy/dashboard/forms.py b/amy/dashboard/forms.py index 2ce25dafe..e31144151 100644 --- a/amy/dashboard/forms.py +++ b/amy/dashboard/forms.py @@ -84,6 +84,7 @@ class Meta: "airport", "github", "twitter", + "bluesky", "url", "username", "affiliation", diff --git a/amy/dashboard/tests/test_autoupdate_profile.py b/amy/dashboard/tests/test_autoupdate_profile.py index e520cee33..5c8e6c15d 100644 --- a/amy/dashboard/tests/test_autoupdate_profile.py +++ b/amy/dashboard/tests/test_autoupdate_profile.py @@ -62,6 +62,7 @@ def test_update_profile(self): "airport": self.airport_0_0.pk, "github": "changed", "twitter": "", + "bluesky": "", "url": "", "username": "changed", "affiliation": "", diff --git a/amy/emails/tests/actions/test_ask_for_website_cancel_receiver.py b/amy/emails/tests/actions/test_ask_for_website_cancel_receiver.py index c82fbb16a..95b5064af 100644 --- a/amy/emails/tests/actions/test_ask_for_website_cancel_receiver.py +++ b/amy/emails/tests/actions/test_ask_for_website_cancel_receiver.py @@ -235,6 +235,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", diff --git a/amy/emails/tests/actions/test_ask_for_website_receiver.py b/amy/emails/tests/actions/test_ask_for_website_receiver.py index 7cf7e2832..1ac88af7e 100644 --- a/amy/emails/tests/actions/test_ask_for_website_receiver.py +++ b/amy/emails/tests/actions/test_ask_for_website_receiver.py @@ -223,6 +223,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -240,6 +241,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_ask_for_website_update_receiver.py b/amy/emails/tests/actions/test_ask_for_website_update_receiver.py index 02bca334a..dceb7f584 100644 --- a/amy/emails/tests/actions/test_ask_for_website_update_receiver.py +++ b/amy/emails/tests/actions/test_ask_for_website_update_receiver.py @@ -315,6 +315,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", diff --git a/amy/emails/tests/actions/test_host_instructors_introduction_cancel_receiver.py b/amy/emails/tests/actions/test_host_instructors_introduction_cancel_receiver.py index 812f10276..1dbaae463 100644 --- a/amy/emails/tests/actions/test_host_instructors_introduction_cancel_receiver.py +++ b/amy/emails/tests/actions/test_host_instructors_introduction_cancel_receiver.py @@ -255,6 +255,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -272,6 +273,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_host_instructors_introduction_receiver.py b/amy/emails/tests/actions/test_host_instructors_introduction_receiver.py index b507a5844..0ecf2d1d0 100644 --- a/amy/emails/tests/actions/test_host_instructors_introduction_receiver.py +++ b/amy/emails/tests/actions/test_host_instructors_introduction_receiver.py @@ -253,6 +253,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -270,6 +271,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_host_instructors_introduction_update_receiver.py b/amy/emails/tests/actions/test_host_instructors_introduction_update_receiver.py index 374dd8037..2d96bb474 100644 --- a/amy/emails/tests/actions/test_host_instructors_introduction_update_receiver.py +++ b/amy/emails/tests/actions/test_host_instructors_introduction_update_receiver.py @@ -348,6 +348,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -365,6 +366,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_instructor_badge_awarded_cancel_receiver.py b/amy/emails/tests/actions/test_instructor_badge_awarded_cancel_receiver.py index 218cfea10..1d5450018 100644 --- a/amy/emails/tests/actions/test_instructor_badge_awarded_cancel_receiver.py +++ b/amy/emails/tests/actions/test_instructor_badge_awarded_cancel_receiver.py @@ -207,6 +207,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", diff --git a/amy/emails/tests/actions/test_instructor_badge_awarded_receiver.py b/amy/emails/tests/actions/test_instructor_badge_awarded_receiver.py index 9b2707327..87c983197 100644 --- a/amy/emails/tests/actions/test_instructor_badge_awarded_receiver.py +++ b/amy/emails/tests/actions/test_instructor_badge_awarded_receiver.py @@ -190,6 +190,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", diff --git a/amy/emails/tests/actions/test_instructor_confirmed_for_workshop_cancel_receiver.py b/amy/emails/tests/actions/test_instructor_confirmed_for_workshop_cancel_receiver.py index f104b22e0..6423f7f71 100644 --- a/amy/emails/tests/actions/test_instructor_confirmed_for_workshop_cancel_receiver.py +++ b/amy/emails/tests/actions/test_instructor_confirmed_for_workshop_cancel_receiver.py @@ -251,6 +251,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="", twitter="", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", diff --git a/amy/emails/tests/actions/test_instructor_confirmed_for_workshop_update_receiver.py b/amy/emails/tests/actions/test_instructor_confirmed_for_workshop_update_receiver.py index 89eb8d627..5f7775940 100644 --- a/amy/emails/tests/actions/test_instructor_confirmed_for_workshop_update_receiver.py +++ b/amy/emails/tests/actions/test_instructor_confirmed_for_workshop_update_receiver.py @@ -339,6 +339,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="", twitter="", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", diff --git a/amy/emails/tests/actions/test_instructor_training_approaching_cancel_receiver.py b/amy/emails/tests/actions/test_instructor_training_approaching_cancel_receiver.py index c6ae13e14..39e578a34 100644 --- a/amy/emails/tests/actions/test_instructor_training_approaching_cancel_receiver.py +++ b/amy/emails/tests/actions/test_instructor_training_approaching_cancel_receiver.py @@ -250,6 +250,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -267,6 +268,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_instructor_training_approaching_receiver.py b/amy/emails/tests/actions/test_instructor_training_approaching_receiver.py index 7789a3c3d..610153726 100644 --- a/amy/emails/tests/actions/test_instructor_training_approaching_receiver.py +++ b/amy/emails/tests/actions/test_instructor_training_approaching_receiver.py @@ -244,6 +244,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -261,6 +262,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_instructor_training_approaching_update_receiver.py b/amy/emails/tests/actions/test_instructor_training_approaching_update_receiver.py index efe1517d7..828fe15f3 100644 --- a/amy/emails/tests/actions/test_instructor_training_approaching_update_receiver.py +++ b/amy/emails/tests/actions/test_instructor_training_approaching_update_receiver.py @@ -332,6 +332,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -349,6 +350,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_instructor_training_completed_not_badged_integration.py b/amy/emails/tests/actions/test_instructor_training_completed_not_badged_integration.py index 2ed3a80ab..d84e26615 100644 --- a/amy/emails/tests/actions/test_instructor_training_completed_not_badged_integration.py +++ b/amy/emails/tests/actions/test_instructor_training_completed_not_badged_integration.py @@ -70,6 +70,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -141,6 +142,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -240,6 +242,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", diff --git a/amy/emails/tests/actions/test_persons_merged.py b/amy/emails/tests/actions/test_persons_merged.py index cf737e8e8..17c5ca768 100644 --- a/amy/emails/tests/actions/test_persons_merged.py +++ b/amy/emails/tests/actions/test_persons_merged.py @@ -180,6 +180,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -197,6 +198,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", @@ -218,6 +220,7 @@ def test_integration(self) -> None: "airport": "obj_a", "github": "obj_b", "twitter": "obj_a", + "bluesky": "obj_a", "url": "obj_b", "affiliation": "obj_b", "occupation": "obj_a", diff --git a/amy/emails/tests/actions/test_post_workshop_7days_cancel_receiver.py b/amy/emails/tests/actions/test_post_workshop_7days_cancel_receiver.py index 6c832fd0f..d17041a12 100644 --- a/amy/emails/tests/actions/test_post_workshop_7days_cancel_receiver.py +++ b/amy/emails/tests/actions/test_post_workshop_7days_cancel_receiver.py @@ -246,6 +246,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -263,6 +264,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_post_workshop_7days_receiver.py b/amy/emails/tests/actions/test_post_workshop_7days_receiver.py index ae8c62594..3f5a3fb77 100644 --- a/amy/emails/tests/actions/test_post_workshop_7days_receiver.py +++ b/amy/emails/tests/actions/test_post_workshop_7days_receiver.py @@ -239,6 +239,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -256,6 +257,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_post_workshop_7days_update_receiver.py b/amy/emails/tests/actions/test_post_workshop_7days_update_receiver.py index 282412392..0ef1c58b0 100644 --- a/amy/emails/tests/actions/test_post_workshop_7days_update_receiver.py +++ b/amy/emails/tests/actions/test_post_workshop_7days_update_receiver.py @@ -334,6 +334,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -351,6 +352,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_recruit_helpers_cancel_receiver.py b/amy/emails/tests/actions/test_recruit_helpers_cancel_receiver.py index 66dd21485..c3af005fb 100644 --- a/amy/emails/tests/actions/test_recruit_helpers_cancel_receiver.py +++ b/amy/emails/tests/actions/test_recruit_helpers_cancel_receiver.py @@ -242,6 +242,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -259,6 +260,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_recruit_helpers_receiver.py b/amy/emails/tests/actions/test_recruit_helpers_receiver.py index d5d16b962..8977f6068 100644 --- a/amy/emails/tests/actions/test_recruit_helpers_receiver.py +++ b/amy/emails/tests/actions/test_recruit_helpers_receiver.py @@ -235,6 +235,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -252,6 +253,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/emails/tests/actions/test_recruit_helpers_update_receiver.py b/amy/emails/tests/actions/test_recruit_helpers_update_receiver.py index a4378697f..1dc3d3d17 100644 --- a/amy/emails/tests/actions/test_recruit_helpers_update_receiver.py +++ b/amy/emails/tests/actions/test_recruit_helpers_update_receiver.py @@ -327,6 +327,7 @@ def test_integration(self) -> None: airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -344,6 +345,7 @@ def test_integration(self) -> None: airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", diff --git a/amy/templates/workshops/persons_merge.html b/amy/templates/workshops/persons_merge.html index f91a354b4..389ea5303 100644 --- a/amy/templates/workshops/persons_merge.html +++ b/amy/templates/workshops/persons_merge.html @@ -77,6 +77,11 @@ {{ obj_a.twitter|default:"—" }}{{ obj_b.twitter|default:"—" }} {% include "includes/merge_radio.html" with field=form.twitter %} + + BlueSky + {{ obj_a.bluesky|default:"—" }}{{ obj_b.bluesky|default:"—" }} + {% include "includes/merge_radio.html" with field=form.bluesky %} + URL {{ obj_a.url|default:"—"|urlize_newtab }}{{ obj_b.url|default:"—"|urlize_newtab }} diff --git a/amy/workshops/forms.py b/amy/workshops/forms.py index 6050273d7..6c073aba2 100644 --- a/amy/workshops/forms.py +++ b/amy/workshops/forms.py @@ -383,8 +383,7 @@ class EventForm(forms.ModelForm): sponsor = forms.ModelChoiceField( label="Organiser", required=True, - help_text=Event._meta.get_field("sponsor").help_text - + " Previously called 'Sponsor'.", + help_text=Event._meta.get_field("sponsor").help_text, queryset=Organization.objects.all(), widget=ModelSelect2Widget(data_view="organization-lookup"), ) @@ -675,8 +674,6 @@ class Meta: "event", "person", "role", - "title", - "url", "seat_membership", "seat_public", "seat_open_training", @@ -781,6 +778,7 @@ class Meta: "affiliation", "github", "twitter", + "bluesky", "url", "occupation", "orcid", @@ -961,6 +959,11 @@ class PersonsMergeForm(forms.Form): initial=DEFAULT, widget=forms.RadioSelect, ) + bluesky = forms.ChoiceField( + choices=TWO, + initial=DEFAULT, + widget=forms.RadioSelect, + ) url = forms.ChoiceField( choices=TWO, initial=DEFAULT, diff --git a/amy/workshops/management/commands/fake_database.py b/amy/workshops/management/commands/fake_database.py index b24db005a..45b8b1f5d 100644 --- a/amy/workshops/management/commands/fake_database.py +++ b/amy/workshops/management/commands/fake_database.py @@ -416,6 +416,7 @@ def fake_person(self, *, is_instructor, is_trainer=False): github = social_username twitter = social_username + bluesky = f"@{social_username}.bsky.social" url = self.faker.url() if randbool(0.5) else "" person = Person.objects.create( @@ -426,6 +427,7 @@ def fake_person(self, *, is_instructor, is_trainer=False): gender_other=gender_other, airport=airport, twitter=twitter, + bluesky=bluesky, github=github, url=url, username=username, @@ -619,12 +621,6 @@ def fake_tasks(self, count=120): event=event, person=person, role=role, - title=( - self.faker.sentence(nb_words=4, variable_nb_words=True) - if randbool(0.2) - else "" - ), - url=self.faker.url() if randbool(0.2) else "", ) def fake_unmatched_training_requests(self, count=20): @@ -645,6 +641,7 @@ def fake_duplicated_people(self, count=5): # avoid integrity errors due to unique constraints p.username = create_username(p.personal, p.family) p.twitter = None + p.bluesky = None p.github = None p.email = self.faker.email() diff --git a/amy/workshops/migrations/0272_multiple_changes.py b/amy/workshops/migrations/0272_multiple_changes.py new file mode 100644 index 000000000..bf3b90a50 --- /dev/null +++ b/amy/workshops/migrations/0272_multiple_changes.py @@ -0,0 +1,72 @@ +# Generated by Django 4.2.16 on 2024-12-30 20:50 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("workshops", "0271_alter_workshoprequest_administrative_fee"), + ] + + operations = [ + # #2044 + migrations.AlterField( + model_name="event", + name="host", + field=models.ForeignKey( + help_text="The institution where the workshop is taking place (or would take place for online workshops).", + on_delete=django.db.models.deletion.PROTECT, + related_name="hosted_events", + to="workshops.organization", + ), + ), + migrations.AlterField( + model_name="event", + name="membership", + field=models.ForeignKey( + blank=True, + help_text="The membership this workshop should count towards.", + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="workshops.membership", + ), + ), + migrations.AlterField( + model_name="event", + name="sponsor", + field=models.ForeignKey( + help_text="The institution responsible for organizing and funding the workshop (often the same as Host).", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="sponsored_events", + to="workshops.organization", + ), + ), + # #2094 + migrations.AlterUniqueTogether( + name="task", + unique_together={("event", "person", "role")}, + ), + migrations.RemoveField( + model_name="task", + name="title", + ), + migrations.RemoveField( + model_name="task", + name="url", + ), + # #2726 + migrations.AddField( + model_name="person", + name="bluesky", + field=models.CharField( + blank=True, + max_length=100, + null=True, + unique=True, + verbose_name="BlueSky username", + ), + ), + ] diff --git a/amy/workshops/models.py b/amy/workshops/models.py index 3d4e2b94e..d23752788 100644 --- a/amy/workshops/models.py +++ b/amy/workshops/models.py @@ -809,6 +809,13 @@ class Person( blank=True, verbose_name="Twitter username", ) + bluesky = models.CharField( + max_length=STR_LONG, + unique=True, + null=True, + blank=True, + verbose_name="BlueSky username", + ) url = models.CharField( max_length=STR_LONG, blank=True, @@ -1026,6 +1033,7 @@ def save(self, *args, **kwargs): self.airport = self.airport or None self.github = self.github or None self.twitter = self.twitter or None + self.bluesky = self.bluesky or None super().save(*args, **kwargs) def archive(self) -> None: @@ -1041,6 +1049,7 @@ def archive(self) -> None: self.airport = None self.github = None self.twitter = None + self.bluesky = None self.url = "" self.user_notes = "" self.affiliation = "" @@ -1307,22 +1316,25 @@ class Event(AssignmentMixin, RQJobsMixin, models.Model): null=False, blank=False, related_name="hosted_events", - help_text="Organisation hosting the event.", + help_text="The institution where the workshop is taking place (or would take " + "place for online workshops).", ) + # Currently this is organiser sponsor = models.ForeignKey( Organization, on_delete=models.PROTECT, null=True, blank=False, related_name="sponsored_events", - help_text="Institution that is funding or organising the workshop.", + help_text="The institution responsible for organizing and funding the workshop " + "(often the same as Host).", ) membership = models.ForeignKey( Membership, on_delete=models.PROTECT, null=True, blank=True, - help_text="A membership this event should be counted towards.", + help_text="The membership this workshop should count towards.", ) administrator = models.ForeignKey( Organization, @@ -1674,8 +1686,6 @@ class Task(RQJobsMixin, models.Model): event = models.ForeignKey(Event, on_delete=models.PROTECT) person = models.ForeignKey(Person, on_delete=models.PROTECT) role = models.ForeignKey(Role, on_delete=models.PROTECT) - title = models.CharField(max_length=STR_LONG, blank=True) - url = models.URLField(blank=True, verbose_name="URL") seat_membership = models.ForeignKey( Membership, on_delete=models.PROTECT, @@ -1711,12 +1721,10 @@ class Task(RQJobsMixin, models.Model): objects = TaskManager() class Meta: - unique_together = ("event", "person", "role", "url") + unique_together = ("event", "person", "role") ordering = ("role__name", "event") def __str__(self): - if self.title: - return self.title return "{0}/{1}={2}".format(self.event, self.person, self.role) def get_absolute_url(self): diff --git a/amy/workshops/tests/base.py b/amy/workshops/tests/base.py index efa3afd97..a3b055344 100644 --- a/amy/workshops/tests/base.py +++ b/amy/workshops/tests/base.py @@ -215,6 +215,7 @@ def _setUpInstructors(self): airport=self.airport_0_0, github="herself", twitter="herself", + bluesky="@herself.bsky.social", url="http://hermione.org", username="granger_hermione", country="GB", diff --git a/amy/workshops/tests/test_person.py b/amy/workshops/tests/test_person.py index 717d28c4c..9a7f9a64b 100644 --- a/amy/workshops/tests/test_person.py +++ b/amy/workshops/tests/test_person.py @@ -762,6 +762,7 @@ def setUp(self): airport=self.airport_0_0, github="purdy_kelsi", twitter="purdy_kelsi", + bluesky="@purdy_kelsi.bsky.social", url="http://kelsipurdy.com/", affiliation="University of Arizona", occupation="TA at Biology Department", @@ -858,6 +859,7 @@ def setUp(self): airport=self.airport_0_50, github="deckow_jayden", twitter="deckow_jayden", + bluesky="@deckow_jayden.bsky.social", url="http://jaydendeckow.com/", affiliation="UFlo", occupation="Staff", @@ -947,6 +949,7 @@ def setUp(self): "airport": "obj_a", "github": "obj_b", "twitter": "obj_a", + "bluesky": "obj_a", "url": "obj_b", "affiliation": "obj_b", "occupation": "obj_a", @@ -986,6 +989,7 @@ def test_form_invalid_values(self): "airport": "combine", "github": "combine", "twitter": "combine", + "bluesky": "combine", "url": "combine", "affiliation": "combine", "occupation": "combine", @@ -1049,6 +1053,7 @@ def test_merging_basic_attributes(self): "airport": self.person_a.airport, "github": self.person_b.github, "twitter": self.person_a.twitter, + "bluesky": self.person_a.bluesky, "url": self.person_b.url, "affiliation": self.person_b.affiliation, "occupation": self.person_a.occupation, @@ -1604,6 +1609,7 @@ def _assert_personal_info_removed(self, archived_profile: Person) -> None: self.assertIsNone(archived_profile.airport) self.assertIsNone(archived_profile.github) self.assertIsNone(archived_profile.twitter) + self.assertIsNone(archived_profile.bluesky) self.assertEqual(archived_profile.url, "") self.assertEqual(archived_profile.user_notes, "") self.assertEqual(archived_profile.affiliation, "") diff --git a/amy/workshops/tests/test_tasks.py b/amy/workshops/tests/test_tasks.py index 5f3a40ce3..17843bd36 100644 --- a/amy/workshops/tests/test_tasks.py +++ b/amy/workshops/tests/test_tasks.py @@ -126,65 +126,14 @@ def test_task_detail_view_reachable_from_event_person_and_role_of_task(self): response = self.client.get(reverse("task_details", args=[str(correct_task.id)])) assert response.context["task"].pk == correct_task.pk - def test_add_task_with_correct_url(self): - """Ensure that task can be saved with correct URL field""" - task = self.fixtures["test_task_1"] - payload = { - "event": task.event.pk, - "person": task.person.pk, - "role": task.role.pk, - "title": "Task title", - "url": "http://example.org", - } - response = self.client.post( - reverse("task_edit", kwargs={"task_id": task.pk}), payload, follow=True - ) - self.assertRedirects( - response, reverse("task_details", kwargs={"task_id": task.pk}) - ) - task.refresh_from_db() - self.assertEqual(task.url, "http://example.org") - self.assertEqual(response.context["task"].url, "http://example.org") - - def test_add_task_with_incorrect_url(self): - """Ensure that a task object cannot be saved with incorrect URL field""" - task = self.fixtures["test_task_1"] - payload = { - "event": task.event.pk, - "person": task.person.pk, - "role": task.role.pk, - "title": "Task title", - "url": "htp://example.org", - } - response = self.client.post( - reverse("task_edit", kwargs={"task_id": task.pk}), - payload, - ) - self.assertEqual(response.status_code, 200) - task.refresh_from_db() - self.assertEqual(task.url, "") - def test_add_duplicate_task(self): - """Ensure that duplicate tasks with empty url field cannot exist""" - task_1 = self.fixtures["test_task_1"] - with self.assertRaises(IntegrityError): - Task.objects.create( - event=task_1.event, - person=task_1.person, - role=task_1.role, - ) - - def test_add_duplicate_task_with_url(self): """Ensure that duplicate tasks cannot exist""" task_1 = self.fixtures["test_task_1"] - task_1.url = "http://example.org" - task_1.save() with self.assertRaises(IntegrityError): Task.objects.create( event=task_1.event, person=task_1.person, role=task_1.role, - url=task_1.url, ) def test_task_edit_view_reachable_from_event_person_and_role_of_task(self): diff --git a/amy/workshops/views.py b/amy/workshops/views.py index b2174988e..04196356b 100644 --- a/amy/workshops/views.py +++ b/amy/workshops/views.py @@ -886,6 +886,7 @@ def persons_merge(request): "airport", "github", "twitter", + "bluesky", "url", "affiliation", "occupation", diff --git a/docs/amy_database_structure.md b/docs/amy_database_structure.md index b2edad063..2d36325fb 100644 --- a/docs/amy_database_structure.md +++ b/docs/amy_database_structure.md @@ -51,6 +51,7 @@ The primary tables used in AMY (that will appear in most queries) are those that * `may_contact` A boolean field. We may not contact people if this field is false. This field has been replaced by [new-style consents](#consent) (see also [2021 Consents Project](./design/projects/2021_consents.md)). * `github` Individual's GitHub user id * `twitter` Individual's Twitter user id +* `bluesky` Individual's BlueSky user id * `orcid` Individual's ORCID iD * `url` Link to the individual's personal website * `airport_id` An integer representing the person's self identified nearest. This is linked to the `workshops_airport` table @@ -298,7 +299,6 @@ The primary tables used in AMY (that will appear in most queries) are those that * `seat_membership_id` Used for Instructor Training Learner role only. An integer representing the membership this seat was assigned to. * `seat_public` Used for Instructor Training Learner role only. Determines if the seat counts as public or in-house for the specific membership. * `seat_open_training` Used for Instructor Training Learner role only. Boolean field noting whether this was an open (non-member) training seat. - * `title` and`url` are not used. ### Tags diff --git a/docs/users_guide/community_index.md b/docs/users_guide/community_index.md index 53a7298e5..ba4eb05fe 100644 --- a/docs/users_guide/community_index.md +++ b/docs/users_guide/community_index.md @@ -18,8 +18,9 @@ The Carpentries can maintain the following information about individuals in our * Country * Airport (Airports are used as approximate geographic identifiers for our instructors. Instructors can self-select the airport closest to them or the airport they most frequently use. If your aiport is not in the drop down, please contact so we can add it in.) * Affiliation -* GitHub username +* GitHub username * Twitter username +* BlueSky username * Personal website * Current occupation/career stage * ORCID ID @@ -62,13 +63,13 @@ Carpentries Instructor trainees can [log in to AMY](#logging-in) to view their c ![AMY Training Progress Menu](images/training_progress_menu.png) -You may submit your "Get Involved" step here, to be evaluated by The Carpentries Instructor Training team. The Instructor Training team will also record your status in completing the Teaching Demo and Welcome Session requirements and award your certificate upon successful completion of the Training and all three checkout steps. +You may submit your "Get Involved" step here, to be evaluated by The Carpentries Instructor Training team. The Instructor Training team will also record your status in completing the Teaching Demo and Welcome Session requirements and award your certificate upon successful completion of the Training and all three checkout steps. **Please allow 7-10 days for each of these steps to be evaluated and recorded.** ### Submitting your "Get Involved" step -To submit your "Get Involved" step, click on the blue "Submit a Get Involved Activity" button. +To submit your "Get Involved" step, click on the blue "Submit a Get Involved Activity" button. ![AMY Training Progress Submit](images/training_progress_submit.png) @@ -91,15 +92,15 @@ Once you submit your Get Involved step, your summary page will show your submiss ### Teaching Demonstration -The Trainer leading your Teaching Demonstration will inform the Instructor Training Team whether you passed or were asked to repeat your teaching demo, and your participation will be recorded by our Instructor Training team. +The Trainer leading your Teaching Demonstration will inform the Instructor Training Team whether you passed or were asked to repeat your teaching demo, and your participation will be recorded by our Instructor Training team. ### Welcome Session -If you signed in on the [Welcome Session Etherpad](https://pad.carpentries.org/welcome-sessions-2024), your participation will be recorded by our Instructor Training team. +If you signed in on the [Welcome Session Etherpad](https://pad.carpentries.org/welcome-sessions-2024), your participation will be recorded by our Instructor Training team. ### Certificate -Once you have completed all three steps, your summary page will show your status as complete. The Instructor Training team will award your badge and you will receive an email with a pdf certificate attached. +Once you have completed all three steps, your summary page will show your status as complete. The Instructor Training team will award your badge and you will receive an email with a pdf certificate attached. ![AMY Checkout Complete](images/checkout_complete.png) @@ -114,13 +115,13 @@ The next page will list all upcoming teaching opportunites. This list can be so ![AMY Instructor signup filter view](images/upcoming_teaching_opportunities.png) -Instructors can then register their interest in teaching specific workshop. +Instructors can then register their interest in teaching specific workshop. ![AMY Instructor signup form](images/workshop_intersted_signup.png) A workshop administrator will follow up shortly to confirm or decline each instructor. -### Notes about signing up +### Notes about signing up * Instructors will get a warning if they sign up as interested in concurrent workshops or workshops within two weeks of confirmed workshops. This is to remind Instructors about possible scheduling conflicts and that they may be overextending themsleves. This does not prevent Instructors from signing up. * Instructors will be blocked from signing up for workshops if they are already confirmed to teach a concurrent workshop. This is to prevent actual scheduling conflicts. Instructors may contact if they are interested in teaching concurrent workshops to discuss scheduling options.