prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Add support for multiple local partners
  ### Is your feature request related to a problem? Please describe.
  We really want to be able to have multiple local partners at Thalia. And the website current does not support this.
  
  ### Describe the solution you'd like
  We would like the ability to add multiple local partners.
  
  ### Motivation
  We think it's useful to have multiple local partners so we can show our students what is available in Nijmegen.
  
  ### Describe alternatives you've considered
  Only having one local partner, which does not make sense in the current partner climate.
  
  ### Additional context
  The local partner is also shown in the newsletter.
  
  </issue>
  <code>
  [start of website/newsletters/views.py]
  1 """Views provided by the newsletters package."""
  2 import os
  3 
  4 from django.conf import settings
  5 from django.contrib.admin.views.decorators import staff_member_required
  6 from django.contrib.auth.decorators import permission_required
  7 from django.shortcuts import get_object_or_404, redirect, render
  8 from django.utils.translation import activate, get_language_info
  9 from django_sendfile import sendfile
  10 
  11 from newsletters import services
  12 from newsletters.models import Newsletter
  13 from partners.models import Partner
  14 
  15 
  16 def preview(request, pk, lang=None):
  17     """View that renders the newsletter as HTML.
  18 
  19     :param request: the request object
  20     :param pk: the newsletter's primary key
  21     :param lang: the language of the render
  22     :return: HttpResponse 200 containing the newsletter HTML
  23     """
  24     lang_code = request.LANGUAGE_CODE
  25 
  26     if lang is not None:
  27         try:
  28             get_language_info(lang)
  29             activate(lang)
  30             lang_code = lang
  31         except KeyError:
  32             # Language code not recognised by get_language_info
  33             pass
  34 
  35     # Send cached file, if it exists
  36     file_path = os.path.join(
  37         settings.MEDIA_ROOT, "newsletters", f"{pk}_{lang_code}.html"
  38     )
  39     if os.path.isfile(file_path):
  40         return sendfile(request, file_path)
  41 
  42     newsletter = get_object_or_404(Newsletter, pk=pk)
  43     events = services.get_agenda(newsletter.date) if newsletter.date else None
  44 
  45     return render(
  46         request,
  47         "newsletters/email.html",
  48         {
  49             "newsletter": newsletter,
  50             "agenda_events": events,
  51             "main_partner": Partner.objects.filter(is_main_partner=True).first(),
  52             "local_partner": Partner.objects.filter(is_local_partner=True).first(),
  53             "lang_code": lang_code,
  54         },
  55     )
  56 
  57 
  58 @staff_member_required
  59 @permission_required("newsletters.send_newsletter")
  60 def admin_send(request, pk):
  61     """If this is a GET request this view will render a confirmation page for the administrator.
  62 
  63     If it is a POST request the newsletter will be sent to all recipients.
  64 
  65     :param request: the request object
  66     :param pk: the newsletter's primary key
  67     :return: 302 RedirectResponse if POST else 200 with the
  68              confirmation page HTML
  69     """
  70     newsletter = get_object_or_404(Newsletter, pk=pk)
  71 
  72     if newsletter.sent:
  73         return redirect(newsletter)
  74 
  75     if request.POST:
  76         services.send_newsletter(newsletter)
  77 
  78         return redirect("admin:newsletters_newsletter_changelist")
  79 
  80     return render(
  81         request, "newsletters/admin/send_confirm.html", {"newsletter": newsletter}
  82     )
  83
  [end of website/newsletters/views.py]
  [start of website/newsletters/emails.py]
  1 """The emails defined by the newsletters package."""
  2 import logging
  3 from smtplib import SMTPException
  4 
  5 from django.conf import settings
  6 from django.core import mail
  7 from django.core.mail import EmailMultiAlternatives
  8 from django.template.loader import get_template
  9 from django.utils import translation, timezone
  10 from django.utils.timezone import make_aware
  11 
  12 from newsletters import services
  13 from partners.models import Partner
  14 
  15 logger = logging.getLogger(__name__)
  16 
  17 
  18 def send_newsletter(newsletter):
  19     """Send the newsletter as HTML and plaintext email.
  20 
  21     :param newsletter: the newsletter to be send
  22     """
  23     events = None
  24     if newsletter.date:
  25         datetime = (
  26             make_aware(
  27                 timezone.datetime(
  28                     year=newsletter.date.year,
  29                     month=newsletter.date.month,
  30                     day=newsletter.date.day,
  31                 )
  32             )
  33             if newsletter.date
  34             else None
  35         )
  36         events = services.get_agenda(datetime)
  37 
  38     from_email = settings.NEWSLETTER_FROM_ADDRESS
  39     html_template = get_template("newsletters/email.html")
  40     text_template = get_template("newsletters/email.txt")
  41 
  42     main_partner = Partner.objects.filter(is_main_partner=True).first()
  43     local_partner = Partner.objects.filter(is_local_partner=True).first()
  44 
  45     with mail.get_connection() as connection:
  46         language = ("en", "English")
  47         translation.activate(language[0])
  48 
  49         subject = "[THALIA] " + newsletter.title
  50 
  51         context = {
  52             "newsletter": newsletter,
  53             "agenda_events": events,
  54             "main_partner": main_partner,
  55             "local_partner": local_partner,
  56             "lang_code": language[0],
  57         }
  58 
  59         html_message = html_template.render(context)
  60         text_message = text_template.render(context)
  61 
  62         msg = EmailMultiAlternatives(
  63             subject=subject,
  64             body=text_message,
  65             to=[f"newsletter@{settings.GSUITE_DOMAIN}"],
  66             from_email=from_email,
  67             connection=connection,
  68         )
  69         msg.attach_alternative(html_message, "text/html")
  70 
  71         try:
  72             msg.send()
  73             logger.info("Sent %s newsletter", language[1])
  74         except SMTPException:
  75             logger.exception("Failed to send the %s newsletter", language[1])
  76 
  77         translation.deactivate()
  78
  [end of website/newsletters/emails.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/website/newsletters/emails.py b/website/newsletters/emails.py
  --- a/website/newsletters/emails.py
  +++ b/website/newsletters/emails.py
  @@ -40,7 +40,7 @@
       text_template = get_template("newsletters/email.txt")
   
       main_partner = Partner.objects.filter(is_main_partner=True).first()
  -    local_partner = Partner.objects.filter(is_local_partner=True).first()
  +    local_partners = Partner.objects.filter(is_local_partner=True)
   
       with mail.get_connection() as connection:
           language = ("en", "English")
  @@ -52,7 +52,7 @@
               "newsletter": newsletter,
               "agenda_events": events,
               "main_partner": main_partner,
  -            "local_partner": local_partner,
  +            "local_partners": local_partners,
               "lang_code": language[0],
           }
   
  diff --git a/website/newsletters/views.py b/website/newsletters/views.py
  --- a/website/newsletters/views.py
  +++ b/website/newsletters/views.py
  @@ -49,7 +49,7 @@
               "newsletter": newsletter,
               "agenda_events": events,
               "main_partner": Partner.objects.filter(is_main_partner=True).first(),
  -            "local_partner": Partner.objects.filter(is_local_partner=True).first(),
  +            "local_partners": Partner.objects.filter(is_local_partner=True),
               "lang_code": lang_code,
           },
       )
  
verification_info: {"golden_diff": "diff --git a/website/newsletters/emails.py b/website/newsletters/emails.py\n--- a/website/newsletters/emails.py\n+++ b/website/newsletters/emails.py\n@@ -40,7 +40,7 @@\n     text_template = get_template(\"newsletters/email.txt\")\n \n     main_partner = Partner.objects.filter(is_main_partner=True).first()\n-    local_partner = Partner.objects.filter(is_local_partner=True).first()\n+    local_partners = Partner.objects.filter(is_local_partner=True)\n \n     with mail.get_connection() as connection:\n         language = (\"en\", \"English\")\n@@ -52,7 +52,7 @@\n             \"newsletter\": newsletter,\n             \"agenda_events\": events,\n             \"main_partner\": main_partner,\n-            \"local_partner\": local_partner,\n+            \"local_partners\": local_partners,\n             \"lang_code\": language[0],\n         }\n \ndiff --git a/website/newsletters/views.py b/website/newsletters/views.py\n--- a/website/newsletters/views.py\n+++ b/website/newsletters/views.py\n@@ -49,7 +49,7 @@\n             \"newsletter\": newsletter,\n             \"agenda_events\": events,\n             \"main_partner\": Partner.objects.filter(is_main_partner=True).first(),\n-            \"local_partner\": Partner.objects.filter(is_local_partner=True).first(),\n+            \"local_partners\": Partner.objects.filter(is_local_partner=True),\n             \"lang_code\": lang_code,\n         },\n     )\n", "issue": "Add support for multiple local partners\n### Is your feature request related to a problem? Please describe.\r\nWe really want to be able to have multiple local partners at Thalia. And the website current does not support this.\r\n\r\n### Describe the solution you'd like\r\nWe would like the ability to add multiple local partners.\r\n\r\n### Motivation\r\nWe think it's useful to have multiple local partners so we can show our students what is available in Nijmegen.\r\n\r\n### Describe alternatives you've considered\r\nOnly having one local partner, which does not make sense in the current partner climate.\r\n\r\n### Additional context\r\nThe local partner is also shown in the newsletter.\n", "before_files": [{"content": "\"\"\"Views provided by the newsletters package.\"\"\"\nimport os\n\nfrom django.conf import settings\nfrom django.contrib.admin.views.decorators import staff_member_required\nfrom django.contrib.auth.decorators import permission_required\nfrom django.shortcuts import get_object_or_404, redirect, render\nfrom django.utils.translation import activate, get_language_info\nfrom django_sendfile import sendfile\n\nfrom newsletters import services\nfrom newsletters.models import Newsletter\nfrom partners.models import Partner\n\n\ndef preview(request, pk, lang=None):\n    \"\"\"View that renders the newsletter as HTML.\n\n    :param request: the request object\n    :param pk: the newsletter's primary key\n    :param lang: the language of the render\n    :return: HttpResponse 200 containing the newsletter HTML\n    \"\"\"\n    lang_code = request.LANGUAGE_CODE\n\n    if lang is not None:\n        try:\n            get_language_info(lang)\n            activate(lang)\n            lang_code = lang\n        except KeyError:\n            # Language code not recognised by get_language_info\n            pass\n\n    # Send cached file, if it exists\n    file_path = os.path.join(\n        settings.MEDIA_ROOT, \"newsletters\", f\"{pk}_{lang_code}.html\"\n    )\n    if os.path.isfile(file_path):\n        return sendfile(request, file_path)\n\n    newsletter = get_object_or_404(Newsletter, pk=pk)\n    events = services.get_agenda(newsletter.date) if newsletter.date else None\n\n    return render(\n        request,\n        \"newsletters/email.html\",\n        {\n            \"newsletter\": newsletter,\n            \"agenda_events\": events,\n            \"main_partner\": Partner.objects.filter(is_main_partner=True).first(),\n            \"local_partner\": Partner.objects.filter(is_local_partner=True).first(),\n            \"lang_code\": lang_code,\n        },\n    )\n\n\n@staff_member_required\n@permission_required(\"newsletters.send_newsletter\")\ndef admin_send(request, pk):\n    \"\"\"If this is a GET request this view will render a confirmation page for the administrator.\n\n    If it is a POST request the newsletter will be sent to all recipients.\n\n    :param request: the request object\n    :param pk: the newsletter's primary key\n    :return: 302 RedirectResponse if POST else 200 with the\n             confirmation page HTML\n    \"\"\"\n    newsletter = get_object_or_404(Newsletter, pk=pk)\n\n    if newsletter.sent:\n        return redirect(newsletter)\n\n    if request.POST:\n        services.send_newsletter(newsletter)\n\n        return redirect(\"admin:newsletters_newsletter_changelist\")\n\n    return render(\n        request, \"newsletters/admin/send_confirm.html\", {\"newsletter\": newsletter}\n    )\n", "path": "website/newsletters/views.py"}, {"content": "\"\"\"The emails defined by the newsletters package.\"\"\"\nimport logging\nfrom smtplib import SMTPException\n\nfrom django.conf import settings\nfrom django.core import mail\nfrom django.core.mail import EmailMultiAlternatives\nfrom django.template.loader import get_template\nfrom django.utils import translation, timezone\nfrom django.utils.timezone import make_aware\n\nfrom newsletters import services\nfrom partners.models import Partner\n\nlogger = logging.getLogger(__name__)\n\n\ndef send_newsletter(newsletter):\n    \"\"\"Send the newsletter as HTML and plaintext email.\n\n    :param newsletter: the newsletter to be send\n    \"\"\"\n    events = None\n    if newsletter.date:\n        datetime = (\n            make_aware(\n                timezone.datetime(\n                    year=newsletter.date.year,\n                    month=newsletter.date.month,\n                    day=newsletter.date.day,\n                )\n            )\n            if newsletter.date\n            else None\n        )\n        events = services.get_agenda(datetime)\n\n    from_email = settings.NEWSLETTER_FROM_ADDRESS\n    html_template = get_template(\"newsletters/email.html\")\n    text_template = get_template(\"newsletters/email.txt\")\n\n    main_partner = Partner.objects.filter(is_main_partner=True).first()\n    local_partner = Partner.objects.filter(is_local_partner=True).first()\n\n    with mail.get_connection() as connection:\n        language = (\"en\", \"English\")\n        translation.activate(language[0])\n\n        subject = \"[THALIA] \" + newsletter.title\n\n        context = {\n            \"newsletter\": newsletter,\n            \"agenda_events\": events,\n            \"main_partner\": main_partner,\n            \"local_partner\": local_partner,\n            \"lang_code\": language[0],\n        }\n\n        html_message = html_template.render(context)\n        text_message = text_template.render(context)\n\n        msg = EmailMultiAlternatives(\n            subject=subject,\n            body=text_message,\n            to=[f\"newsletter@{settings.GSUITE_DOMAIN}\"],\n            from_email=from_email,\n            connection=connection,\n        )\n        msg.attach_alternative(html_message, \"text/html\")\n\n        try:\n            msg.send()\n            logger.info(\"Sent %s newsletter\", language[1])\n        except SMTPException:\n            logger.exception(\"Failed to send the %s newsletter\", language[1])\n\n        translation.deactivate()\n", "path": "website/newsletters/emails.py"}]}