internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: carpentries/amy

Issue:
Support event tags in email template for Email Automation
Add event tag values to email template context for easier access by users:

```django
{% if "online" in tags %}
...
{% endif %}
```


Discussion:

Resolving patch:
diff --git a/amy/autoemails/actions.py b/amy/autoemails/actions.py
--- a/amy/autoemails/actions.py
+++ b/amy/autoemails/actions.py
@@ -291,6 +291,7 @@ def get_additional_context(self, objects, *args, **kwargs):
         context["assignee"] = (
             event.assigned_to.full_name if event.assigned_to else "Regional Coordinator"
         )
+        context["tags"] = list(event.tags.values_list("name", flat=True))
 
         return context
 
@@ -443,6 +444,7 @@ def get_additional_context(self, objects, *args, **kwargs):
         )
 
         context["reports_link"] = reports_link(event.slug)
+        context["tags"] = list(event.tags.values_list("name", flat=True))
 
         return context
 
@@ -558,5 +560,6 @@ def get_additional_context(self, objects, *args, **kwargs):
         context["assignee"] = (
             event.assigned_to.full_name if event.assigned_to else "Regional Coordinator"
         )
+        context["tags"] = list(event.tags.values_list("name", flat=True))
 
         return context


Test patch:
diff --git a/amy/autoemails/tests/test_newinstructoraction.py b/amy/autoemails/tests/test_newinstructoraction.py
--- a/amy/autoemails/tests/test_newinstructoraction.py
+++ b/amy/autoemails/tests/test_newinstructoraction.py
@@ -181,6 +181,7 @@ def testContext(self):
                 role=r,
                 task=t,
                 assignee="Regional Coordinator",
+                tags=['SWC'],
             ),
         )
 
diff --git a/amy/autoemails/tests/test_postworkshopaction.py b/amy/autoemails/tests/test_postworkshopaction.py
--- a/amy/autoemails/tests/test_postworkshopaction.py
+++ b/amy/autoemails/tests/test_postworkshopaction.py
@@ -204,6 +204,7 @@ def testContext(self):
                 all_emails=["hg@magic.uk", "hp@magic.uk"],
                 assignee="Regional Coordinator",
                 reports_link="https://workshop-reports.carpentries.org/?key=e18dd84d093be5cd6c6ccaf63d38a8477ca126f4&slug=test-event",
+                tags=['SWC', 'TTT'],
             ),
         )
 
diff --git a/amy/autoemails/tests/test_selforganisedrequestaction.py b/amy/autoemails/tests/test_selforganisedrequestaction.py
--- a/amy/autoemails/tests/test_selforganisedrequestaction.py
+++ b/amy/autoemails/tests/test_selforganisedrequestaction.py
@@ -180,6 +180,7 @@ def testContext(self):
                 short_notice=True,
                 all_emails=["harry@hogwarts.edu", "hg@magic.uk", "rw@magic.uk"],
                 assignee="Regional Coordinator",
+                tags=['LC', 'automated-email', 'Circuits'],
             ),
         )
Repository: carpentries/amy

Issue:
What is the purpose of git_version.py?
What is the purpose of this file? 

https://github.com/carpentries/amy/blob/develop/amy/workshops/git_version.py

It gets updated regularly on my local repo but I have been ignoring it locally as it has been unchanged in the repo in the past two years.


Discussion:
This file is used for displaying the current git commit hash in the AMY footer:
![obraz](https://user-images.githubusercontent.com/72821/81503527-55542c80-92e4-11ea-9e1d-6d4273fcd263.png)

I agree it's a bit cumbersome to use it properly, as it requires regenerating through `make` and some sort of git magic for ignoring changes to this file. (We do regenerate it on the production, though!)

@maneesha if you feel like it, it'd be good to have this file removed from AMY.

Can we put it in `.gitignore` ? 
It's not enough. `.gitignore` works for files by preventing them being added to the index, while we have to use `git update-index --skip-worktree <file>` command.

I'd propose to get rid of it as it's not super extra useful.

Resolving patch:
diff --git a/amy/workshops/context_processors.py b/amy/workshops/context_processors.py
--- a/amy/workshops/context_processors.py
+++ b/amy/workshops/context_processors.py
@@ -1,17 +1,6 @@
-from workshops import __version__
-try:
-    from workshops import git_version
-except ImportError:
-    git_version = None
+from . import __version__
 
 
 def version(request):
-    data = {'workshops_version': __version__}
-    if git_version:
-        data.update({
-            'workshops_git_hash': git_version.HASH,
-            'workshops_git_short_hash': git_version.SHORT_HASH,
-            'workshops_git_date': git_version.DATE,
-            'workshops_git_dirty': git_version.DIRTY,
-        })
+    data = {'amy_version': __version__}
     return data
diff --git a/amy/workshops/git_version.py b/amy/workshops/git_version.py
deleted file mode 100644
--- a/amy/workshops/git_version.py
+++ /dev/null
@@ -1,5 +0,0 @@
-HASH = '114193ac5dc04c6894dcc3a82903fee5b81990b8'
-SHORT_HASH = '114193a'
-DATE = '2018-09-28'
-
-DIRTY = True


Test patch:
Repository: carpentries/amy

Issue:
Wrong name of permissions to accept & create event for Workshop Inquiry and Self-Organised Submission
Permissions for accepting `WorkshopInquiryRequest` and `SelfOrganisedSubmission` where prefixed with `workshops.` app name, while they should be prefixed with `extrequests`.


Discussion:

Resolving patch:
diff --git a/amy/extrequests/views.py b/amy/extrequests/views.py
--- a/amy/extrequests/views.py
+++ b/amy/extrequests/views.py
@@ -279,7 +279,7 @@ class WorkshopInquirySetState(OnlyForAdminsMixin, ChangeRequestStateView):
 
 class WorkshopInquiryAcceptEvent(OnlyForAdminsMixin, PermissionRequiredMixin,
                                  AMYCreateAndFetchObjectView):
-    permission_required = ['workshops.change_workshopinquiryrequest',
+    permission_required = ['extrequests.change_workshopinquiryrequest',
                            'workshops.add_event']
     model = Event
     form_class = EventCreateForm
@@ -400,7 +400,7 @@ class SelfOrganisedSubmissionSetState(OnlyForAdminsMixin,
 class SelfOrganisedSubmissionAcceptEvent(OnlyForAdminsMixin,
                                          PermissionRequiredMixin,
                                          AMYCreateAndFetchObjectView):
-    permission_required = ['workshops.change_selforganisedsubmission',
+    permission_required = ['extrequests.change_selforganisedsubmission',
                            'workshops.add_event']
     model = Event
     form_class = EventCreateForm


Test patch:
Repository: carpentries/amy

Issue:
Update search matching to include secondary email
I just searched for an individual using an email address and AMY did not find a match.  After searching with the first/last name, I was able to find that the person did indeed have an AMY profile. Additionally, the email that I used to search was the secondary email listed in the person's profile.

Can we update the search so that it also looks at secondary emails for matching?


Discussion:

Resolving patch:
diff --git a/amy/workshops/views.py b/amy/workshops/views.py
--- a/amy/workshops/views.py
+++ b/amy/workshops/views.py
@@ -1947,6 +1947,7 @@ def search(request):
                         (Q(personal__icontains=name1) & Q(family__icontains=name2))
                         | (Q(personal__icontains=name2) & Q(family__icontains=name1))
                         | Q(email__icontains=term)
+                        | Q(secondary_email__icontains=term)
                         | Q(github__icontains=term)
                     )
                     persons = Person.objects.filter(complex_q)
@@ -1955,6 +1956,7 @@ def search(request):
                         Q(personal__icontains=term)
                         | Q(family__icontains=term)
                         | Q(email__icontains=term)
+                        | Q(secondary_email__icontains=term)
                         | Q(github__icontains=term)
                     ).order_by("family")
                 results += list(persons)


Test patch:
diff --git a/amy/workshops/tests/test_search.py b/amy/workshops/tests/test_search.py
--- a/amy/workshops/tests/test_search.py
+++ b/amy/workshops/tests/test_search.py
@@ -89,6 +89,26 @@ def test_search_for_people_by_personal_family_names(self):
         self.assertIn(org, response.context['organizations'])
         self.assertIn(self.hermione, response.context['persons'])
 
+    def test_search_for_people_by_secondary_email(self):
+        """Test if searching by secondary email yields people correctly."""
+        # Let's add Hermione Granger email as some organisation's name.
+        # This is required because of redirection if only 1 person matches.
+        org = Organization.objects.create(fullname='hermione2@granger.co.uk',
+                                          domain='hgr.com')
+
+        # make sure Hermione has individual secondary email
+        self.hermione.secondary_email = 'hermione2@granger.co.uk'
+        self.hermione.save()
+
+        response = self.search_for(
+            'hermione2@granger.co.uk', in_organizations=True, in_persons=True)
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(len(response.context['persons'])
+                         + len(response.context['organizations']),
+                         2, 'Expected two search results')
+        self.assertIn(org, response.context['organizations'])
+        self.assertIn(self.hermione, response.context['persons'])
+
     def test_search_for_training_requests(self):
         """Make sure that finding training requests works."""
Repository: carpentries/amy

Issue:
Workshops "Update from URL" not updating
When I try to update the workshop website in AMY it doesn't do anything. It isn't providing me with a new "Comment Box" showing me the updated instructors/helpers. 

I get the message: **Success: 2020-04-28-genentech was updated successfully** but nothing happens


Discussion:
@sheraaronhurt I went to 2020-04-genentech event in AMY and tried updating it by clicking "Update from URL" and then "Update" in the modal window.

The result was that comment box at the bottom was filled with instructor and helper names from that website.

I highly suggest forcing refresh of the website cache. When on event edit page, hit one of [the shortcuts Wikipedia lists](https://en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache) (for me CTRL+F5 or CMD+SHIFT+R works), then try again updating from URL.

Feel free to reach out to me on Slack if you need some assistance with diagnosing this issue.
I did this and nothing happened. It changed the date that I did something but it didn't provide me with a new comment box.... 

Normally, even it nothing changed, when I click the update url it would provide a new box with the date/time and names. 
Same. I tried this and it is still not working. I also tried clearing the cache from the settings menu and no change. I haven't been able to pull info from the workshop website for any of the workshops I've been working on so its definitely system wide.

Resolving patch:
diff --git a/amy/workshops/views.py b/amy/workshops/views.py
--- a/amy/workshops/views.py
+++ b/amy/workshops/views.py
@@ -1067,7 +1067,7 @@ def get_context_data(self, **kwargs):
         return context
 
     def get_form_class(self):
-        return partial(EventForm, show_lessons=True, add_comment=False)
+        return partial(EventForm, show_lessons=True, add_comment=True)
 
     def get_logger(self):
         return logger


Test patch:
Repository: carpentries/amy

Issue:
Remove "Lessons Covered" from Self Organized Submission accept view
Currently when "Mix and Match" is selected on the self organized workshop form, a list of lessons is also displayed when the submission is being accepted:

![image](https://user-images.githubusercontent.com/829690/81445109-4cc5ef80-9146-11ea-812c-f2645891a9de.png)

We do not use this list, so it should not be displayed on this form.  The **Curricula taught at the workshop** should still be displayed.


Discussion:

Resolving patch:
diff --git a/amy/extrequests/views.py b/amy/extrequests/views.py
--- a/amy/extrequests/views.py
+++ b/amy/extrequests/views.py
@@ -416,7 +416,9 @@ def get_form_kwargs(self):
             self.other_object.workshop_types.filter(mix_match=True).exists()
         )
 
-        kwargs['show_lessons'] = mix_match
+        # no matter what, don't show "lessons" field; previously they were shown
+        # when mix&match was selected
+        kwargs['show_lessons'] = False
 
         url = self.other_object.workshop_url.strip()
         data = {


Test patch:
diff --git a/amy/extrequests/tests/test_selforganised_submissions.py b/amy/extrequests/tests/test_selforganised_submissions.py
--- a/amy/extrequests/tests/test_selforganised_submissions.py
+++ b/amy/extrequests/tests/test_selforganised_submissions.py
@@ -478,19 +478,18 @@ def test_host_task_created(self):
         Task.objects.get(person=self.harry, event=event,
                          role=Role.objects.get(name="host"))
 
-    def test_lessons_shown_in_event_create_form(self):
-        """Ensure Mix&Match triggers "lessons" field on EventCreateForm."""
-        # self.sos1 has Mix&Match workshop type, so it should display "lessons"
+    def test_lessons_hidden_in_event_create_form(self):
+        """Ensure Mix&Match doesn't trigger "lessons" field on EventCreateForm."""
+        # self.sos1 has Mix&Match workshop type, so it should hide "lessons"
         # field in Event form
         rv = self.client.get(self.url)
         self.assertEqual(rv.status_code, 200)
         self.assertIn(Curriculum.objects.get(mix_match=True),
                       self.sos1.workshop_types.all())
-        self.assertIn("lessons", rv.context["form"].fields.keys())
+        self.assertNotIn("lessons", rv.context["form"].fields.keys())
 
-        # self.sos2 doesn't have Mix&Match workshop type, so it can't show
-        # "lessons" field in Event form
-        # but for tests we need a different status for that submission
+        # self.sos2 doesn't have Mix&Match workshop type, and the "lessons" field
+        # should remain hidden in Event form
         self.sos2.state = "p"
         self.sos2.save()
         rv = self.client.get(self.url2)
Repository: carpentries/amy

Issue:
Workshops with tag "circuits" don't trigger the 7 days post-workshop email
example: https://amy.carpentries.org/workshops/event/2020-07-21-nmcsa-online/
cc: @Talishask 


Discussion:
The reason why Circuits events are omitted is that "LC" /  "DC" / "SWC" is expected. I can extend the list to cover Circuits as well, however please confirm what should show in the email subject (the template is `Completed {DC, SWC, LC} workshop at {site} on {dates}`).

Resolving patch:
diff --git a/amy/autoemails/actions.py b/amy/autoemails/actions.py
--- a/amy/autoemails/actions.py
+++ b/amy/autoemails/actions.py
@@ -466,7 +466,7 @@ def check(event: Event):
             # must have "automated-email" tag
             and event.tags.filter(name__icontains="automated-email")
             # must have LC, DC, or SWC tags
-            and event.tags.filter(name__in=["LC", "DC", "SWC"])
+            and event.tags.filter(name__in=["LC", "DC", "SWC", "Circuits"])
             # must not be self-organized or instructor training
             # 2020-02-11: only for workshops administered by other than
             #             Instructor Training


Test patch:
diff --git a/amy/autoemails/tests/test_postworkshopaction.py b/amy/autoemails/tests/test_postworkshopaction.py
--- a/amy/autoemails/tests/test_postworkshopaction.py
+++ b/amy/autoemails/tests/test_postworkshopaction.py
@@ -143,6 +143,29 @@ def testCheckConditions(self):
         e.administrator = Organization.objects.get(domain="librarycarpentry.org")
         self.assertEqual(PostWorkshopAction.check(e), True)
 
+    def testCheckConditionsCircuits(self):
+        """Make sure `check` works for "Circuits" workshops too."""
+        e = Event.objects.create(
+            slug="test-event",
+            host=Organization.objects.first(),
+            administrator=Organization.objects.get(domain="librarycarpentry.org"),
+            start=date.today() + timedelta(days=7),
+            end=date.today() + timedelta(days=8),
+        )
+        e.tags.set(Tag.objects.filter(name__in=["automated-email"]))
+        p = Person.objects.create(
+            personal="Harry", family="Potter", email="hp@magic.uk"
+        )
+        r = Role.objects.create(name="host")
+        Task.objects.create(event=e, person=p, role=r)
+
+        # 1st case: fail
+        self.assertEqual(PostWorkshopAction.check(e), False)
+
+        # 2nd case: success
+        e.tags.add(Tag.objects.get(name="Circuits"))
+        self.assertEqual(PostWorkshopAction.check(e), True)
+
     def testContext(self):
         """Make sure `get_additional_context` works correctly."""
         a = PostWorkshopAction(
Repository: carpentries/amy

Issue:
Add instructor training registration code to membership
For each membership term for a given organization, we give them a code that is used to register on Eventbrite. This code is required to unlock registration on Eventbrite.  Currently we store this in a separate spreadsheet, but ideally we'd want it stored here so we are not looking in another place for this.  Each organization's membership term will have a unique code that is valid for that term only.  They get a new code when their membership renews.

For now, this can be a simple text field so that we are not keeping data in two separate places.  Ideally moving ahead we'd like to use it to integrate with Eventbrite's API allowing us to match up Eventbrite registration with our applications (related to #1614). 


Discussion:

Resolving patch:
diff --git a/amy/fiscal/forms.py b/amy/fiscal/forms.py
--- a/amy/fiscal/forms.py
+++ b/amy/fiscal/forms.py
@@ -87,7 +87,7 @@ class Meta:
         model = Membership
         fields = [
             'organization', 'variant', 'agreement_start', 'agreement_end',
-            'contribution_type', 'workshops_without_admin_fee_per_agreement',
+            'contribution_type', 'registration_code', 'workshops_without_admin_fee_per_agreement',
             'self_organized_workshops_per_agreement',
             'seats_instructor_training',
             'additional_instructor_training_seats',
diff --git a/amy/workshops/migrations/0218_membership_registration_code.py b/amy/workshops/migrations/0218_membership_registration_code.py
new file mode 100644
--- /dev/null
+++ b/amy/workshops/migrations/0218_membership_registration_code.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.13 on 2020-08-18 20:14
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('workshops', '0217_auto_20200615_1436'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='membership',
+            name='registration_code',
+            field=models.CharField(blank=True, help_text='Unique registration code used for Eventbrite and trainee application.', max_length=40, null=True, unique=True, verbose_name='Registration Code'),
+        ),
+    ]
diff --git a/amy/workshops/models.py b/amy/workshops/models.py
--- a/amy/workshops/models.py
+++ b/amy/workshops/models.py
@@ -152,6 +152,17 @@ class Membership(models.Model):
         Organization, null=False, blank=False, on_delete=models.PROTECT
     )
 
+    registration_code = models.CharField(
+        max_length=STR_MED,
+        null=True,
+        blank=True,
+        unique=True,
+        verbose_name="Registration Code",
+        help_text="Unique registration code used for Eventbrite and trainee application."
+        )
+
+
+
     def __str__(self):
         from workshops.util import human_daterange
 


Test patch:
Repository: carpentries/amy

Issue:
Include "Supporting Instructor" role in Person role count
The "Person" page has a list of roles with a count by roles:

![image](https://user-images.githubusercontent.com/829690/94966054-9da9fc00-04ca-11eb-9279-742d6cacfc6c.png)

This should also include a count for the role "Supporting Instructor." 




Discussion:

Resolving patch:
diff --git a/amy/workshops/views.py b/amy/workshops/views.py
--- a/amy/workshops/views.py
+++ b/amy/workshops/views.py
@@ -247,6 +247,13 @@ class PersonDetails(OnlyForAdminsMixin, AMYDetailView):
                     output_field=IntegerField(),
                 )
             ),
+
+            num_supporting=Count(
+                Case(
+                    When(task__role__name="supporting-instructor", then=Value(1)),
+                    output_field=IntegerField(),
+                )
+            ),
         )
         .prefetch_related(
             "award_set__badge",


Test patch:
Repository: carpentries/amy

Issue:
Note whether workshop is public or private
There should be a new field in `workshops_event` to note whether the workshop is public or private.  This should not be a boolean -- public or private should be explicitly checked.  This field should be required.


Discussion:
Default: public

Resolving patch:
diff --git a/amy/workshops/forms.py b/amy/workshops/forms.py
--- a/amy/workshops/forms.py
+++ b/amy/workshops/forms.py
@@ -443,6 +443,7 @@ class Meta:
             "open_TTT_applications",
             "curricula",
             "lessons",
+            "public_status",
             "comment",
         ]
         widgets = {
@@ -486,6 +487,7 @@ def __init__(self, *args, **kwargs):
             "reg_key",
             "manual_attendance",
             "contact",
+            "public_status",
             Div(
                 Div(HTML("Location details"), css_class="card-header"),
                 Div(
diff --git a/amy/workshops/migrations/0220_event_public_status.py b/amy/workshops/migrations/0220_event_public_status.py
new file mode 100644
--- /dev/null
+++ b/amy/workshops/migrations/0220_event_public_status.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.13 on 2020-10-18 16:57
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('workshops', '0219_workshoprequest_online_inperson'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='event',
+            name='public_status',
+            field=models.CharField(choices=[('public', 'Public'), ('private', 'Private')], default='public', blank=True, max_length=10, verbose_name='Is this workshop public?', help_text='Public workshops will show up in public Carpentries feeds.'),
+        ),
+    ]
diff --git a/amy/workshops/models.py b/amy/workshops/models.py
--- a/amy/workshops/models.py
+++ b/amy/workshops/models.py
@@ -1212,6 +1212,20 @@ class Event(AssignmentMixin, RQJobsMixin, models.Model):
         help_text="Specific lessons covered during the event",
     )
 
+    # indicate that the workshop is either private or public
+    PUBLIC_STATUS_CHOICES = [
+        ("public", "Public"),
+        ("private", "Private"),
+    ]
+    public_status = models.CharField(
+        max_length=10,
+        choices=PUBLIC_STATUS_CHOICES,
+        default="public",
+        blank=True,
+        verbose_name="Is this workshop public?",
+        help_text="Public workshops will show up in public Carpentries feeds.",
+    )
+
     objects = EventQuerySet.as_manager()
 
     class Meta:


Test patch:
Repository: carpentries/amy

Issue:
Move position of "Is this workshop public" question
The question about "Is this workshop public" should be moved to be directly below the "Host" field on the event view and edit pages.


Discussion:

Resolving patch:
diff --git a/amy/workshops/forms.py b/amy/workshops/forms.py
--- a/amy/workshops/forms.py
+++ b/amy/workshops/forms.py
@@ -477,6 +477,7 @@ def __init__(self, *args, **kwargs):
             Field("start", placeholder="YYYY-MM-DD"),
             Field("end", placeholder="YYYY-MM-DD"),
             "host",
+            "public_status",
             "administrator",
             "assigned_to",
             "tags",
@@ -487,7 +488,6 @@ def __init__(self, *args, **kwargs):
             "reg_key",
             "manual_attendance",
             "contact",
-            "public_status",
             Div(
                 Div(HTML("Location details"), css_class="card-header"),
                 Div(


Test patch: