We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Notification Mails detected as SPAM
**Describe the bug**
This is likely specific to the exact email setup users have but in my case, the notification mails in my case are caught by the SpamAssassin rule `TO_NO_BRKTS_HTML_IMG` which is discussed [here](https://stackoverflow.com/questions/40082594/meaning-of-to-no-brkts-html-img-in-spamassassin). As a fix for this, it would be useful if ephios used the configured first and last name to properly address the users in the `To:` field of the email.   

**To Reproduce**
Make ephios send a notification email.

**Expected behavior**
Emails should arrive in my inbox without being detected as SPAM. This could be done by modifying the `To:` field. 

**Screenshots**
\-

**Environment**
An email SPAM filter using SpamAssassin

**Additional context**
\-


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ephios/core/services/notifications/backends.py`
Content:
```
1 import logging
2 import smtplib
3 import traceback
4 
5 from django.conf import settings
6 from django.core.mail import mail_admins
7 from django.utils.translation import gettext_lazy as _
8 from webpush import send_user_notification
9 
10 from ephios.core.models.users import Notification
11 from ephios.core.services.mail.send import send_mail
12 
13 logger = logging.getLogger(__name__)
14 
15 
16 def installed_notification_backends():
17     from ephios.core.signals import register_notification_backends
18 
19     for _, backends in register_notification_backends.send_to_all_plugins(None):
20         yield from (b() for b in backends)
21 
22 
23 def enabled_notification_backends():
24     from ephios.core.signals import register_notification_backends
25 
26     for _, backends in register_notification_backends.send(None):
27         yield from (b() for b in backends)
28 
29 
30 def send_all_notifications():
31     for backend in installed_notification_backends():
32         for notification in Notification.objects.filter(failed=False):
33             if backend.can_send(notification) and backend.user_prefers_sending(notification):
34                 try:
35                     backend.send(notification)
36                 except Exception as e:  # pylint: disable=broad-except
37                     if settings.DEBUG:
38                         raise e
39                     notification.failed = True
40                     notification.save()
41                     try:
42                         mail_admins(
43                             "Notification sending failed",
44                             f"Notification: {notification}\nException: {e}\n{traceback.format_exc()}",
45                         )
46                     except smtplib.SMTPConnectError:
47                         pass  # if the mail backend threw this, mail admin will probably throw this as well
48                     logger.warning(
49                         f"Notification sending failed for notification object #{notification.pk} ({notification}) for backend {backend} with {e}"
50                     )
51     Notification.objects.filter(failed=False).delete()
52 
53 
54 class AbstractNotificationBackend:
55     @property
56     def slug(self):
57         return NotImplementedError
58 
59     @property
60     def title(self):
61         return NotImplementedError
62 
63     @classmethod
64     def can_send(cls, notification):
65         return notification.user is not None
66 
67     @classmethod
68     def user_prefers_sending(cls, notification):
69         if notification.notification_type.unsubscribe_allowed and notification.user is not None:
70             if not notification.user.is_active:
71                 return False
72             backends = notification.user.preferences["notifications__notifications"].get(
73                 notification.slug
74             )
75             if backends is not None:
76                 return cls.slug in backends
77         return True
78 
79     @classmethod
80     def send(cls, notification: Notification):
81         raise NotImplementedError
82 
83 
84 class EmailNotificationBackend(AbstractNotificationBackend):
85     slug = "ephios_backend_email"
86     title = _("via email")
87 
88     @classmethod
89     def can_send(cls, notification):
90         return notification.user is not None or "email" in notification.data
91 
92     @classmethod
93     def _get_mailaddress(cls, notification):
94         return notification.user.email if notification.user else notification.data.get("email")
95 
96     @classmethod
97     def send(cls, notification):
98         send_mail(
99             to=[cls._get_mailaddress(notification)],
100             subject=notification.subject,
101             plaintext=notification.as_plaintext(),
102             html=notification.as_html(),
103             is_autogenerated=True,
104         )
105 
106 
107 class WebPushNotificationBackend(AbstractNotificationBackend):
108     slug = "ephios_backend_webpush"
109     title = _("via push notification")
110 
111     @classmethod
112     def send(cls, notification):
113         payload = {
114             "head": str(notification.subject),
115             "body": notification.body,
116             "icon": "/static/ephios/img/ephios-symbol-red.svg",
117         }
118         if actions := notification.get_actions():
119             payload["url"] = actions[0][1]
120         send_user_notification(user=notification.user, payload=payload, ttl=1000)
121 
122 
123 CORE_NOTIFICATION_BACKENDS = [EmailNotificationBackend, WebPushNotificationBackend]
124
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ephios/core/services/notifications/backends.py b/ephios/core/services/notifications/backends.py
--- a/ephios/core/services/notifications/backends.py
+++ b/ephios/core/services/notifications/backends.py
@@ -91,7 +91,9 @@
 
     @classmethod
     def _get_mailaddress(cls, notification):
-        return notification.user.email if notification.user else notification.data.get("email")
+        if notification.user:
+            return f"{notification.user.get_full_name()} <{notification.user.email}>"
+        return notification.data.get("email")
 
     @classmethod
     def send(cls, notification):

{"golden_diff": "diff --git a/ephios/core/services/notifications/backends.py b/ephios/core/services/notifications/backends.py\n--- a/ephios/core/services/notifications/backends.py\n+++ b/ephios/core/services/notifications/backends.py\n@@ -91,7 +91,9 @@\n \n     @classmethod\n     def _get_mailaddress(cls, notification):\n-        return notification.user.email if notification.user else notification.data.get(\"email\")\n+        if notification.user:\n+            return f\"{notification.user.get_full_name()} <{notification.user.email}>\"\n+        return notification.data.get(\"email\")\n \n     @classmethod\n     def send(cls, notification):\n", "issue": "Notification Mails detected as SPAM\n**Describe the bug**\r\nThis is likely specific to the exact email setup users have but in my case, the notification mails in my case are caught by the SpamAssassin rule `TO_NO_BRKTS_HTML_IMG` which is discussed [here](https://stackoverflow.com/questions/40082594/meaning-of-to-no-brkts-html-img-in-spamassassin). As a fix for this, it would be useful if ephios used the configured first and last name to properly address the users in the `To:` field of the email.   \r\n\r\n**To Reproduce**\r\nMake ephios send a notification email.\r\n\r\n**Expected behavior**\r\nEmails should arrive in my inbox without being detected as SPAM. This could be done by modifying the `To:` field. \r\n\r\n**Screenshots**\r\n\\-\r\n\r\n**Environment**\r\nAn email SPAM filter using SpamAssassin\r\n\r\n**Additional context**\r\n\\-\r\n\n", "before_files": [{"content": "import logging\nimport smtplib\nimport traceback\n\nfrom django.conf import settings\nfrom django.core.mail import mail_admins\nfrom django.utils.translation import gettext_lazy as _\nfrom webpush import send_user_notification\n\nfrom ephios.core.models.users import Notification\nfrom ephios.core.services.mail.send import send_mail\n\nlogger = logging.getLogger(__name__)\n\n\ndef installed_notification_backends():\n    from ephios.core.signals import register_notification_backends\n\n    for _, backends in register_notification_backends.send_to_all_plugins(None):\n        yield from (b() for b in backends)\n\n\ndef enabled_notification_backends():\n    from ephios.core.signals import register_notification_backends\n\n    for _, backends in register_notification_backends.send(None):\n        yield from (b() for b in backends)\n\n\ndef send_all_notifications():\n    for backend in installed_notification_backends():\n        for notification in Notification.objects.filter(failed=False):\n            if backend.can_send(notification) and backend.user_prefers_sending(notification):\n                try:\n                    backend.send(notification)\n                except Exception as e:  # pylint: disable=broad-except\n                    if settings.DEBUG:\n                        raise e\n                    notification.failed = True\n                    notification.save()\n                    try:\n                        mail_admins(\n                            \"Notification sending failed\",\n                            f\"Notification: {notification}\\nException: {e}\\n{traceback.format_exc()}\",\n                        )\n                    except smtplib.SMTPConnectError:\n                        pass  # if the mail backend threw this, mail admin will probably throw this as well\n                    logger.warning(\n                        f\"Notification sending failed for notification object #{notification.pk} ({notification}) for backend {backend} with {e}\"\n                    )\n    Notification.objects.filter(failed=False).delete()\n\n\nclass AbstractNotificationBackend:\n    @property\n    def slug(self):\n        return NotImplementedError\n\n    @property\n    def title(self):\n        return NotImplementedError\n\n    @classmethod\n    def can_send(cls, notification):\n        return notification.user is not None\n\n    @classmethod\n    def user_prefers_sending(cls, notification):\n        if notification.notification_type.unsubscribe_allowed and notification.user is not None:\n            if not notification.user.is_active:\n                return False\n            backends = notification.user.preferences[\"notifications__notifications\"].get(\n                notification.slug\n            )\n            if backends is not None:\n                return cls.slug in backends\n        return True\n\n    @classmethod\n    def send(cls, notification: Notification):\n        raise NotImplementedError\n\n\nclass EmailNotificationBackend(AbstractNotificationBackend):\n    slug = \"ephios_backend_email\"\n    title = _(\"via email\")\n\n    @classmethod\n    def can_send(cls, notification):\n        return notification.user is not None or \"email\" in notification.data\n\n    @classmethod\n    def _get_mailaddress(cls, notification):\n        return notification.user.email if notification.user else notification.data.get(\"email\")\n\n    @classmethod\n    def send(cls, notification):\n        send_mail(\n            to=[cls._get_mailaddress(notification)],\n            subject=notification.subject,\n            plaintext=notification.as_plaintext(),\n            html=notification.as_html(),\n            is_autogenerated=True,\n        )\n\n\nclass WebPushNotificationBackend(AbstractNotificationBackend):\n    slug = \"ephios_backend_webpush\"\n    title = _(\"via push notification\")\n\n    @classmethod\n    def send(cls, notification):\n        payload = {\n            \"head\": str(notification.subject),\n            \"body\": notification.body,\n            \"icon\": \"/static/ephios/img/ephios-symbol-red.svg\",\n        }\n        if actions := notification.get_actions():\n            payload[\"url\"] = actions[0][1]\n        send_user_notification(user=notification.user, payload=payload, ttl=1000)\n\n\nCORE_NOTIFICATION_BACKENDS = [EmailNotificationBackend, WebPushNotificationBackend]\n", "path": "ephios/core/services/notifications/backends.py"}], "after_files": [{"content": "import logging\nimport smtplib\nimport traceback\n\nfrom django.conf import settings\nfrom django.core.mail import mail_admins\nfrom django.utils.translation import gettext_lazy as _\nfrom webpush import send_user_notification\n\nfrom ephios.core.models.users import Notification\nfrom ephios.core.services.mail.send import send_mail\n\nlogger = logging.getLogger(__name__)\n\n\ndef installed_notification_backends():\n    from ephios.core.signals import register_notification_backends\n\n    for _, backends in register_notification_backends.send_to_all_plugins(None):\n        yield from (b() for b in backends)\n\n\ndef enabled_notification_backends():\n    from ephios.core.signals import register_notification_backends\n\n    for _, backends in register_notification_backends.send(None):\n        yield from (b() for b in backends)\n\n\ndef send_all_notifications():\n    for backend in installed_notification_backends():\n        for notification in Notification.objects.filter(failed=False):\n            if backend.can_send(notification) and backend.user_prefers_sending(notification):\n                try:\n                    backend.send(notification)\n                except Exception as e:  # pylint: disable=broad-except\n                    if settings.DEBUG:\n                        raise e\n                    notification.failed = True\n                    notification.save()\n                    try:\n                        mail_admins(\n                            \"Notification sending failed\",\n                            f\"Notification: {notification}\\nException: {e}\\n{traceback.format_exc()}\",\n                        )\n                    except smtplib.SMTPConnectError:\n                        pass  # if the mail backend threw this, mail admin will probably throw this as well\n                    logger.warning(\n                        f\"Notification sending failed for notification object #{notification.pk} ({notification}) for backend {backend} with {e}\"\n                    )\n    Notification.objects.filter(failed=False).delete()\n\n\nclass AbstractNotificationBackend:\n    @property\n    def slug(self):\n        return NotImplementedError\n\n    @property\n    def title(self):\n        return NotImplementedError\n\n    @classmethod\n    def can_send(cls, notification):\n        return notification.user is not None\n\n    @classmethod\n    def user_prefers_sending(cls, notification):\n        if notification.notification_type.unsubscribe_allowed and notification.user is not None:\n            if not notification.user.is_active:\n                return False\n            backends = notification.user.preferences[\"notifications__notifications\"].get(\n                notification.slug\n            )\n            if backends is not None:\n                return cls.slug in backends\n        return True\n\n    @classmethod\n    def send(cls, notification: Notification):\n        raise NotImplementedError\n\n\nclass EmailNotificationBackend(AbstractNotificationBackend):\n    slug = \"ephios_backend_email\"\n    title = _(\"via email\")\n\n    @classmethod\n    def can_send(cls, notification):\n        return notification.user is not None or \"email\" in notification.data\n\n    @classmethod\n    def _get_mailaddress(cls, notification):\n        if notification.user:\n            return f\"{notification.user.get_full_name()} <{notification.user.email}>\"\n        return notification.data.get(\"email\")\n\n    @classmethod\n    def send(cls, notification):\n        send_mail(\n            to=[cls._get_mailaddress(notification)],\n            subject=notification.subject,\n            plaintext=notification.as_plaintext(),\n            html=notification.as_html(),\n            is_autogenerated=True,\n        )\n\n\nclass WebPushNotificationBackend(AbstractNotificationBackend):\n    slug = \"ephios_backend_webpush\"\n    title = _(\"via push notification\")\n\n    @classmethod\n    def send(cls, notification):\n        payload = {\n            \"head\": str(notification.subject),\n            \"body\": notification.body,\n            \"icon\": \"/static/ephios/img/ephios-symbol-red.svg\",\n        }\n        if actions := notification.get_actions():\n            payload[\"url\"] = actions[0][1]\n        send_user_notification(user=notification.user, payload=payload, ttl=1000)\n\n\nCORE_NOTIFICATION_BACKENDS = [EmailNotificationBackend, WebPushNotificationBackend]\n", "path": "ephios/core/services/notifications/backends.py"}]}