prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Non-closable site announcements can secretly be closed if you send the right cookie
  ### Describe the bug
  Non-closable site announcements can secretly be closed if you send the right cookie
  
  ### How to reproduce
  Steps to reproduce the behaviour:
  1. Have an announcement that is closable
  2. Close it on your machine
  3. Change the announcement to be non-closable
  4. It still isn't there because you already closed it.
  
  The `closable` field just controls whether the close button appears or not, but it doesn't influence the actual logic
  
  ### Expected behaviour
  Always show non-closable announcements
  
  ### Screenshots
  
  ### 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: `website/announcements/context_processors.py`
  Content:
  ```
  1 """These context processors can be used to expand the context provided to admin views."""
  2 from .models import Announcement
  3 
  4 
  5 def announcements(request):
  6     """Get a list of announcements.
  7 
  8     Filters out announcements that have been closed already.
  9 
  10     :param request: the request object
  11     :return: a dict containing the list announcements
  12     :rtype: dict
  13     """
  14     closed_announcements = request.session.get("closed_announcements", [])
  15     announcements_list = [
  16         a
  17         for a in Announcement.objects.all()
  18         if a.is_visible and a.pk not in closed_announcements
  19     ]
  20 
  21     # Announcements set by AnnouncementMiddleware.
  22     persistent_announcements = getattr(request, "_announcements", [])
  23     return {
  24         "announcements": announcements_list,
  25         "persistent_announcements": persistent_announcements,
  26     }
  27
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/website/announcements/context_processors.py b/website/announcements/context_processors.py
  --- a/website/announcements/context_processors.py
  +++ b/website/announcements/context_processors.py
  @@ -15,7 +15,7 @@
       announcements_list = [
           a
           for a in Announcement.objects.all()
  -        if a.is_visible and a.pk not in closed_announcements
  +        if a.is_visible and (not a.closeable or a.pk not in closed_announcements)
       ]
   
       # Announcements set by AnnouncementMiddleware.
  
verification_info: {"golden_diff": "diff --git a/website/announcements/context_processors.py b/website/announcements/context_processors.py\n--- a/website/announcements/context_processors.py\n+++ b/website/announcements/context_processors.py\n@@ -15,7 +15,7 @@\n     announcements_list = [\n         a\n         for a in Announcement.objects.all()\n-        if a.is_visible and a.pk not in closed_announcements\n+        if a.is_visible and (not a.closeable or a.pk not in closed_announcements)\n     ]\n \n     # Announcements set by AnnouncementMiddleware.\n", "issue": "Non-closable site announcements can secretly be closed if you send the right cookie\n### Describe the bug\r\nNon-closable site announcements can secretly be closed if you send the right cookie\r\n\r\n### How to reproduce\r\nSteps to reproduce the behaviour:\r\n1. Have an announcement that is closable\r\n2. Close it on your machine\r\n3. Change the announcement to be non-closable\r\n4. It still isn't there because you already closed it.\r\n\r\nThe `closable` field just controls whether the close button appears or not, but it doesn't influence the actual logic\r\n\r\n### Expected behaviour\r\nAlways show non-closable announcements\r\n\r\n### Screenshots\r\n\r\n### Additional context\r\n\n", "before_files": [{"content": "\"\"\"These context processors can be used to expand the context provided to admin views.\"\"\"\nfrom .models import Announcement\n\n\ndef announcements(request):\n    \"\"\"Get a list of announcements.\n\n    Filters out announcements that have been closed already.\n\n    :param request: the request object\n    :return: a dict containing the list announcements\n    :rtype: dict\n    \"\"\"\n    closed_announcements = request.session.get(\"closed_announcements\", [])\n    announcements_list = [\n        a\n        for a in Announcement.objects.all()\n        if a.is_visible and a.pk not in closed_announcements\n    ]\n\n    # Announcements set by AnnouncementMiddleware.\n    persistent_announcements = getattr(request, \"_announcements\", [])\n    return {\n        \"announcements\": announcements_list,\n        \"persistent_announcements\": persistent_announcements,\n    }\n", "path": "website/announcements/context_processors.py"}], "after_files": [{"content": "\"\"\"These context processors can be used to expand the context provided to admin views.\"\"\"\nfrom .models import Announcement\n\n\ndef announcements(request):\n    \"\"\"Get a list of announcements.\n\n    Filters out announcements that have been closed already.\n\n    :param request: the request object\n    :return: a dict containing the list announcements\n    :rtype: dict\n    \"\"\"\n    closed_announcements = request.session.get(\"closed_announcements\", [])\n    announcements_list = [\n        a\n        for a in Announcement.objects.all()\n        if a.is_visible and (not a.closeable or a.pk not in closed_announcements)\n    ]\n\n    # Announcements set by AnnouncementMiddleware.\n    persistent_announcements = getattr(request, \"_announcements\", [])\n    return {\n        \"announcements\": announcements_list,\n        \"persistent_announcements\": persistent_announcements,\n    }\n", "path": "website/announcements/context_processors.py"}]}