internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: svthalia/concrexit

Issue:
Edit information field in admin gives error page
### Describe the bug
The site gives the 500 error page when you try to edit information fields of registered users

### How to reproduce
Go to an event on the admin and press change on a user's registration. At "Fields:" press the "Edit Information Fields" button and the bug happens (found at parents day, Tim Kersten)

### Expected behaviour
I'd expect the appropriate page for editing a user's information fields.



Discussion:
Confirmed, corresponding sentry log: https://thalia.sentry.io/issues/3905837977/?project=1463433&query=is%3Aunresolved&referrer=issue-stream
Thats a very simple issue, probably solved by removing a sinlge `s` 😆 
But kinda surprising to see it's been there for 2+ years without anyone noticing.

Resolving patch:
diff --git a/website/events/admin/views.py b/website/events/admin/views.py
--- a/website/events/admin/views.py
+++ b/website/events/admin/views.py
@@ -66,7 +66,7 @@ def get_context_data(self, **kwargs):
                 "change": True,
                 "has_view_permission": True,
                 "has_add_permission": False,
-                "has_change_permission": self.request.user.has_perms(
+                "has_change_permission": self.request.user.has_perm(
                     "events.change_eventregistration"
                 ),
                 "has_delete_permission": False,
@@ -143,7 +143,7 @@ def get_context_data(self, **kwargs):
                 "change": True,
                 "has_view_permission": True,
                 "has_add_permission": False,
-                "has_change_permission": self.request.user.has_perms(
+                "has_change_permission": self.request.user.has_perm(
                     "events.change_event"
                 ),
                 "has_delete_permission": False,


Test patch:
Repository: svthalia/concrexit

Issue:
Model Relation Diagram generation with GraphViz
### Is your feature request related to a problem? Please describe.
Generate a diagram from the model layer in the pipeline

### Motivation
Automatic Documentation is good

### Describe alternatives you've considered
Manual labor

### Additional context
I will implement this feature

`python manage.py graph_models -a -g -o models.png` requires: https://graphviz.org/download/
https://django-extensions.readthedocs.io/en/latest/graph_models.html


Discussion:
Nice, curious to see the result

Resolving patch:
diff --git a/website/thaliawebsite/settings.py b/website/thaliawebsite/settings.py
--- a/website/thaliawebsite/settings.py
+++ b/website/thaliawebsite/settings.py
@@ -440,6 +440,7 @@ def from_env(
 ###############################################################################
 # (Mostly) static settings
 INSTALLED_APPS = [
+    "django_extensions",
     "django.contrib.auth",
     "django.contrib.contenttypes",
     "django.contrib.sessions",
@@ -895,3 +896,31 @@ def from_env(
 
 # Make sure the locations in django.po files don't include line nrs.
 makemessages.Command.xgettext_options.append("--add-location=file")
+
+GRAPH_MODELS = {
+    "all_applications": False,
+    "group_models": True,
+    "app_labels": [
+        "events",
+        "photos",
+        "merchandise",
+        "thabloid",
+        "partners",
+        "newsletters",
+        "shortlinks",
+        "promotion",
+        "documents",
+        "pizzas",
+        "announcements",
+        "sales",
+        "registrations",
+        "mailinglists",
+        "payments",
+        "members",
+        "admin",
+        "pushnotifications",
+        "activemembers",
+        "education",
+        "auth",
+    ],
+}


Test patch:
Repository: svthalia/concrexit

Issue:
Send promo requests overview to promocie
<!--

Please add the appropriate label for what change should be made:
docs: changes to the documentation)
refactor: refactoring production code, eg. renaming a variable or rewriting a function
test: adding missing tests, refactoring tests; no production code change
chore: updating poetry etc; no production code change

-->

### Describe the change
Since the splitting of paparazcie and promocie, promo mails should go to promocie, not paparazcie.

### Additional context
There's a default var in settings.py.


Discussion:

Resolving patch:
diff --git a/website/thaliawebsite/settings.py b/website/thaliawebsite/settings.py
--- a/website/thaliawebsite/settings.py
+++ b/website/thaliawebsite/settings.py
@@ -157,7 +157,7 @@ def from_env(
     f"{os.environ.get('ADDRESS_EDUCATION', 'educacie')}@{SITE_DOMAIN}"
 )
 PROMO_REQUEST_NOTIFICATION_ADDRESS = (
-    f"{os.environ.get('ADDRESS_PROMOREQUESTS', 'paparazcie')}@{SITE_DOMAIN}"
+    f"{os.environ.get('ADDRESS_PROMOREQUESTS', 'promocie')}@{SITE_DOMAIN}"
 )
 PROMO_PUBLISH_DATE_TIMEDELTA = timezone.timedelta(weeks=1)
 


Test patch:
Repository: svthalia/concrexit

Issue:
Moving files to S3 should be idempotent
### Is your feature request related to a problem? Please describe.
Moving files to S3 will always upload the file, even if it already exists.

### Describe the solution you'd like
Check if it already exists

### Motivation

### Describe alternatives you've considered

### Additional context



Discussion:

Resolving patch:
diff --git a/website/thaliawebsite/management/commands/migratemedia.py b/website/thaliawebsite/management/commands/migratemedia.py
--- a/website/thaliawebsite/management/commands/migratemedia.py
+++ b/website/thaliawebsite/management/commands/migratemedia.py
@@ -24,8 +24,25 @@ def handle(self, *args, **options):
 
         # process migrate local media files to s3
         for full_path in self._get_all_media_file():
+            upload_path = self._split_path_to_upload(full_path)
             try:
-                upload_path = self._split_path_to_upload(full_path)
+                try:
+                    remote_file = s3_client.head_object(
+                        Bucket=settings.AWS_STORAGE_BUCKET_NAME, Key=upload_path
+                    )
+                except ClientError as e:
+                    if e.response["Error"]["Code"] == "404":
+                        remote_file = None
+                    else:
+                        raise e
+
+                if remote_file:
+                    # file already exists
+                    # note that this will not check if the file contents are the same
+                    print(f"file already exists {upload_path}")
+                    logging.info(f"file already exists {upload_path}")
+                    continue
+
                 s3_client.upload_file(
                     full_path, settings.AWS_STORAGE_BUCKET_NAME, upload_path
                 )


Test patch:
Repository: svthalia/concrexit

Issue:
Preserve order of uploaded photos
### Is your feature request related to a problem? Please describe.
Since filepond, uploaded photos are ordered 'randomly'. (Says tim reijneveld)

### Describe the solution you'd like
Photos are ordered according to the name (?) of the uploaded files.

### Motivation
Sometimes a certain ordering makes sense within an album.


Discussion:
Looking at the code, it seems like photos are ordered based on their filename in the zip that is uploaded. So this shouldn't be a problem I think...
We could also take a look at EXIF data if we want.
Stijn just texted me about it. Looks like the ordering in the admin makes sense somehow but it's a frontend thing? 
Specifically, image number 16 of wine tasting (the cover) is filename 0045. 

Resolving patch:
diff --git a/website/photos/migrations/0021_alter_photo_options.py b/website/photos/migrations/0021_alter_photo_options.py
new file mode 100644
--- /dev/null
+++ b/website/photos/migrations/0021_alter_photo_options.py
@@ -0,0 +1,16 @@
+# Generated by Django 4.1.7 on 2023-03-22 17:48
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("photos", "0020_remove_album_new_album_notification"),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name="photo",
+            options={"ordering": ("pk",)},
+        ),
+    ]
diff --git a/website/photos/models.py b/website/photos/models.py
--- a/website/photos/models.py
+++ b/website/photos/models.py
@@ -84,7 +84,8 @@ def delete(self, using=None, keep_parents=False):
     class Meta:
         """Meta class for Photo."""
 
-        ordering = ("file",)
+        # Photos are created in order of their filename.
+        ordering = ("pk",)
 
 
 class Like(models.Model):


Test patch:
Repository: svthalia/concrexit

Issue:
Move from Nix to docker only
None of use can work with Nix, and the current state of stuff doesn't really seem to allow us to even release a new version (i.e. we could probably manage to replace the docker image but not the nginx configs).

We should change our server stuff such that anyone can understand and maintain it: docker compose on a simple linux instance. I'm not entirely sure about the details but I'm thinking:

- Terraform config staying mostly the same but: not NixOS but just e.g. debian/ubuntu server. We can probably also switch to a t4g instance.
- On that instance just install docker and run a docker compose thing. deploying = updating the docker compose file (and optionally a .env) to pull new images. CI can build and push (concrexit-web and concrexit-nginx) images, perhaps to githubs registry?

So the steps to do so I think are:

- [ ] Add a Dockerfile for nginx
- [ ] Create a working docker compose file for production
- [ ] Run cronjobs within the concrexit web container
- [ ] Update terraform config
- [ ] Figure out how exactly to install stuff on a fresh ec2 instance. Ideally this would be pretty much automatic. I guess we can make an install script 
- [ ] Add/update workflows to build and deploy
- [ ] Document all of this so that anyone can use it




Discussion:

Resolving patch:
diff --git a/website/thaliawebsite/settings.py b/website/thaliawebsite/settings.py
--- a/website/thaliawebsite/settings.py
+++ b/website/thaliawebsite/settings.py
@@ -238,22 +238,18 @@ def from_env(
     ],
 }
 
+# https://docs.djangoproject.com/en/dev/ref/settings/#media-url
+MEDIA_URL = "/media/private/"
+# https://docs.djangoproject.com/en/dev/ref/settings/#media-root
+MEDIA_ROOT = from_env("MEDIA_ROOT", development=os.path.join(BASE_DIR, "media"))
+
 SENDFILE_BACKEND = setting(
     development="django_sendfile.backends.development",
     production="django_sendfile.backends.nginx",
 )
 # https://github.com/johnsensible/django-sendfile#nginx-backend
 SENDFILE_URL = "/media/sendfile/"
-SENDFILE_ROOT = from_env(
-    "SENDFILE_ROOT",
-    production="/concrexit/media/",
-    development=os.path.join(BASE_DIR, "media"),
-)
-
-# https://docs.djangoproject.com/en/dev/ref/settings/#media-url
-MEDIA_URL = "/media/private/"
-# https://docs.djangoproject.com/en/dev/ref/settings/#media-root
-MEDIA_ROOT = from_env("MEDIA_ROOT", development=os.path.join(BASE_DIR, "media"))
+SENDFILE_ROOT = MEDIA_ROOT
 
 PRIVATE_MEDIA_LOCATION = ""
 PUBLIC_MEDIA_LOCATION = "public"


Test patch:
Repository: svthalia/concrexit

Issue:
Add organisers back to event admin list
### Is your feature request related to a problem? Please describe.
The organiser column was removed #2459. 

### Describe the solution you'd like
A comma-separated list of organisers, optionally as links to the organiser's admin pages.

### Motivation
Then you get a nice overview of who does which events.

### Describe alternatives you've considered
Leave it.



Discussion:

Resolving patch:
diff --git a/website/events/admin/event.py b/website/events/admin/event.py
--- a/website/events/admin/event.py
+++ b/website/events/admin/event.py
@@ -40,6 +40,7 @@ class EventAdmin(DoNextModelAdmin):
         "event_date",
         "registration_date",
         "num_participants",
+        "get_organisers",
         "category",
         "published",
         "edit_link",
@@ -108,7 +109,12 @@ class EventAdmin(DoNextModelAdmin):
     )
 
     def get_queryset(self, request):
-        return super().get_queryset(request).select_properties("participant_count")
+        return (
+            super()
+            .get_queryset(request)
+            .select_properties("participant_count")
+            .prefetch_related("organisers")
+        )
 
     def get_form(self, request, obj=None, change=False, **kwargs):
         form = super().get_form(request, obj, change, **kwargs)
@@ -161,6 +167,11 @@ def num_participants(self, obj):
 
     num_participants.short_description = _("Number of participants")
 
+    def get_organisers(self, obj):
+        return ", ".join(str(o) for o in obj.organisers.all())
+
+    get_organisers.short_description = _("Organisers")
+
     def make_published(self, request, queryset):
         """Change the status of the event to published."""
         self._change_published(request, queryset, True)


Test patch:
Repository: svthalia/concrexit

Issue:
Add API endpoint for event slugs
### Is your feature request related to a problem? Please describe.
For the app we want to get events based on their slug, this is currently not possible.

### Describe the solution you'd like
Add an API endpoint for event slugs.



Discussion:

Resolving patch:
diff --git a/website/events/api/v2/serializers/event.py b/website/events/api/v2/serializers/event.py
--- a/website/events/api/v2/serializers/event.py
+++ b/website/events/api/v2/serializers/event.py
@@ -1,4 +1,5 @@
 from rest_framework import serializers
+from rest_framework.reverse import reverse
 
 from activemembers.api.v2.serializers.member_group import MemberGroupSerializer
 from documents.api.v2.serializers.document import DocumentSerializer
@@ -20,6 +21,8 @@ class Meta:
         model = Event
         fields = (
             "pk",
+            "slug",
+            "url",
             "title",
             "description",
             "caption",
@@ -57,6 +60,7 @@ class Meta:
     fine = PaymentAmountSerializer()
     documents = DocumentSerializer(many=True)
     user_permissions = serializers.SerializerMethodField("_user_permissions")
+    url = serializers.SerializerMethodField("_url")
 
     def _user_registration(self, instance: Event):
         if self.context["request"].member and len(instance.member_registration) > 0:
@@ -101,5 +105,18 @@ def _user_permissions(self, instance):
         member = self.context["request"].member
         return services.event_permissions(member, instance, registration_prefetch=True)
 
+    def _url(self, instance: Event):
+        if instance.slug is None:
+            return reverse(
+                "events:event",
+                kwargs={"pk": instance.pk},
+                request=self.context["request"],
+            )
+        return reverse(
+            "events:event",
+            kwargs={"slug": instance.slug},
+            request=self.context["request"],
+        )
+
     def _maps_url(self, instance):
         return create_google_maps_url(instance.map_location, zoom=13, size="450x250")
diff --git a/website/events/api/v2/urls.py b/website/events/api/v2/urls.py
--- a/website/events/api/v2/urls.py
+++ b/website/events/api/v2/urls.py
@@ -21,6 +21,11 @@
         EventDetailView.as_view(),
         name="event-detail",
     ),
+    path(
+        "events/<slug:slug>/",
+        EventDetailView.as_view(lookup_field="slug"),
+        name="event-detail",
+    ),
     path(
         "events/<int:pk>/registrations/",
         EventRegistrationsView.as_view(),


Test patch:
Repository: svthalia/concrexit

Issue:
Fix escaped HTML in promorequest email remarks field
### Describe the bug
![image](https://user-images.githubusercontent.com/41264528/229277977-1b5293d7-4962-4eea-8358-9f70ec001512.png)


Discussion:

Resolving patch:
diff --git a/website/promotion/emails.py b/website/promotion/emails.py
--- a/website/promotion/emails.py
+++ b/website/promotion/emails.py
@@ -16,8 +16,8 @@ def send_weekly_overview():
     send_email(
         to=[settings.PROMO_REQUEST_NOTIFICATION_ADDRESS],
         subject="[PROMO] Weekly request overview",
-        txt_template="requests/weekly_overview.txt",
-        html_template="requests/weekly_overview.html",
+        txt_template="promotion/email/weekly_overview.txt",
+        html_template="promotion/email/weekly_overview.html",
         context={
             "new_requests": new_requests,
             "upcoming_requests": upcoming_requests,


Test patch:
Repository: svthalia/concrexit

Issue:
Education Exam/Summary count incorrect.
### Describe the bug
For some courses it says there are >500 documents. That's clearly not correct. Something seems to be wrong here: https://github.com/svthalia/concrexit/blob/ce784be158c2e26afa9d389d67065db1cb1a716c/website/education/views.py#L48-L58

### How to reproduce
Go to https://thalia.nu/education/courses/



Discussion:

Resolving patch:
diff --git a/website/education/views.py b/website/education/views.py
--- a/website/education/views.py
+++ b/website/education/views.py
@@ -5,7 +5,6 @@
 from django.contrib.auth.decorators import login_required
 from django.contrib.messages.views import SuccessMessageMixin
 from django.core.exceptions import PermissionDenied
-from django.db.models import Count
 from django.http import HttpResponse
 from django.shortcuts import redirect
 from django.urls import reverse_lazy
@@ -25,11 +24,8 @@
 class CourseIndexView(ListView):
     """Render an overview of the courses."""
 
-    queryset = (
-        Course.objects.filter(until=None)
-        .prefetch_related("categories", "old_courses")
-        .annotate(summary_count=Count("summary"))
-        .annotate(exam_count=Count("exam"))
+    queryset = Course.objects.filter(until=None).prefetch_related(
+        "categories", "old_courses"
     )
     template_name = "education/courses.html"
 
@@ -40,15 +36,15 @@ def get_context_data(self, **kwargs) -> dict:
         context = super().get_context_data(**kwargs)
         context.update(
             {
-                "courses": (
+                "courses": [
                     {
                         "course_code": x.course_code,
                         "name": x.name,
                         "categories": x.categories.all(),
                         "document_count": sum(
                             [
-                                x.summary_count,
-                                x.exam_count,
+                                x.summary_set.filter(accepted=True).count(),
+                                x.exam_set.filter(accepted=True).count(),
                             ]
                             + [
                                 c.summary_set.filter(accepted=True).count()
@@ -59,7 +55,7 @@ def get_context_data(self, **kwargs) -> dict:
                         "url": x.get_absolute_url(),
                     }
                     for x in context["object_list"]
-                ),
+                ],
                 "categories": Category.objects.all(),
             }
         )


Test patch:
Repository: svthalia/concrexit

Issue:
AttributeError: 'Profile' object has no attribute 'is_minimised'
Sentry Issue: [CONCREXIT-P2](https://thalia.sentry.io/issues/4038068631/?referrer=github_integration)

```
AttributeError: 'Profile' object has no attribute 'is_minimised'
(3 additional frame(s) were not displayed)
...
  File "registrations/views.py", line 238, in get_context_data
    ) and self.request.member.profile.is_minimised:
```


Discussion:

Resolving patch:
diff --git a/website/registrations/views.py b/website/registrations/views.py
--- a/website/registrations/views.py
+++ b/website/registrations/views.py
@@ -235,7 +235,7 @@ def get_context_data(self, **kwargs):
         if (
             self.request.member.latest_membership
             and not self.request.member.latest_membership.is_active()
-        ) and self.request.member.profile.is_minimised:
+        ) and self.request.member.profile.is_minimized:
             messages.warning(
                 self.request,
                 _(


Test patch:
Repository: svthalia/concrexit

Issue:
Expand/improve document part of event endpoint
<!--

Please add the appropriate label for what change should be made:
docs: changes to the documentation)
refactor: refactoring production code, eg. renaming a variable or rewriting a function
test: adding missing tests, refactoring tests; no production code change
chore: updating poetry etc; no production code change

-->

### Describe the change
Change the current URL or add a URL to a link to the actual document (that is, one that ends with `/[name].pdf`).

### Motivation
It's very nice for the app to be able to just fetch files directly.
Also, I don't think the current URL is even necessary because you also have the PK with which you can create the URL.

### Current implementation
There is a URL that leads to the file, but only after a redirect to `cdn`.


Discussion:

Resolving patch:
diff --git a/website/documents/api/v2/serializers/document.py b/website/documents/api/v2/serializers/document.py
--- a/website/documents/api/v2/serializers/document.py
+++ b/website/documents/api/v2/serializers/document.py
@@ -1,10 +1,10 @@
 from rest_framework.fields import SerializerMethodField
-from rest_framework.reverse import reverse
 
 from documents.models import Document
 from thaliawebsite.api.v2.serializers.cleaned_model_serializer import (
     CleanedModelSerializer,
 )
+from utils.media.services import get_media_url
 
 
 class DocumentSerializer(CleanedModelSerializer):
@@ -15,6 +15,10 @@ class Meta:
     url = SerializerMethodField("_url")
 
     def _url(self, instance):
-        return self.context["request"].build_absolute_uri(
-            reverse("documents:document", kwargs={"pk": instance.pk})
-        )
+        if instance.members_only and (
+            not self.request.user.is_authenticated
+            or not self.request.member.has_active_membership()
+        ):
+            return self.request.build_absolute_uri(instance.get_absolute_url())
+
+        return get_media_url(instance.file, absolute_url=True)


Test patch:
Repository: svthalia/concrexit

Issue:
Expand/improve document part of event endpoint
<!--

Please add the appropriate label for what change should be made:
docs: changes to the documentation)
refactor: refactoring production code, eg. renaming a variable or rewriting a function
test: adding missing tests, refactoring tests; no production code change
chore: updating poetry etc; no production code change

-->

### Describe the change
Change the current URL or add a URL to a link to the actual document (that is, one that ends with `/[name].pdf`).

### Motivation
It's very nice for the app to be able to just fetch files directly.
Also, I don't think the current URL is even necessary because you also have the PK with which you can create the URL.

### Current implementation
There is a URL that leads to the file, but only after a redirect to `cdn`.


Discussion:

Resolving patch:
diff --git a/website/documents/api/v2/serializers/document.py b/website/documents/api/v2/serializers/document.py
--- a/website/documents/api/v2/serializers/document.py
+++ b/website/documents/api/v2/serializers/document.py
@@ -1,10 +1,10 @@
 from rest_framework.fields import SerializerMethodField
-from rest_framework.reverse import reverse
 
 from documents.models import Document
 from thaliawebsite.api.v2.serializers.cleaned_model_serializer import (
     CleanedModelSerializer,
 )
+from utils.media.services import get_media_url
 
 
 class DocumentSerializer(CleanedModelSerializer):
@@ -15,6 +15,12 @@ class Meta:
     url = SerializerMethodField("_url")
 
     def _url(self, instance):
-        return self.context["request"].build_absolute_uri(
-            reverse("documents:document", kwargs={"pk": instance.pk})
-        )
+        if instance.members_only and (
+            not self.context["request"].user.is_authenticated
+            or not self.context["request"].member.has_active_membership()
+        ):
+            return self.context["request"].build_absolute_uri(
+                instance.get_absolute_url()
+            )
+
+        return get_media_url(instance.file, absolute_url=True)


Test patch: