prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Legacy and Warehouse RSS feeds differ
  @andrew asked in https://github.com/librariesio/libraries.io/issues/2024#issuecomment-372638824 about Warehouse's RSS feeds:
  
  > * https://pypi.org/rss/updates.xml
  > * https://pypi.org/rss/packages.xml
  
  > Which I expected the contents to match the old ones but currently don't:
  
  > * https://pypi.python.org/pypi?%3Aaction=rss
  > * https://pypi.python.org/pypi?%3Aaction=packages_rss
  
  I've verified through visual inspection that the data in the legacy RSS feed and the data in the Warehouse RSS feeds differ.
  
  This is a bug in the feeds or a bug in the docs. Currently our [feeds documentation](https://warehouse.readthedocs.io/api-reference/feeds/) and [Warehouse migration guide](https://warehouse.readthedocs.io/api-reference/integration-guide/) don't say anything about deliberate differences between the legacy and Warehouse RSS feeds. We can update the docs if there's a deliberate reason for the difference.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `warehouse/rss/views.py`
  Content:
  ```
  1 # Licensed under the Apache License, Version 2.0 (the "License");
  2 # you may not use this file except in compliance with the License.
  3 # You may obtain a copy of the License at
  4 #
  5 # http://www.apache.org/licenses/LICENSE-2.0
  6 #
  7 # Unless required by applicable law or agreed to in writing, software
  8 # distributed under the License is distributed on an "AS IS" BASIS,
  9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10 # See the License for the specific language governing permissions and
  11 # limitations under the License.
  12 
  13 from pyramid.view import view_config
  14 from sqlalchemy.orm import joinedload
  15 
  16 from warehouse.cache.origin import origin_cache
  17 from warehouse.packaging.models import Project, Release
  18 from warehouse.xml import XML_CSP
  19 
  20 
  21 @view_config(
  22     route_name="rss.updates",
  23     renderer="rss/updates.xml",
  24     decorator=[
  25         origin_cache(
  26             1 * 24 * 60 * 60,                         # 1 day
  27             stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day
  28             stale_if_error=5 * 24 * 60 * 60,          # 5 days
  29         ),
  30     ],
  31 )
  32 def rss_updates(request):
  33     request.response.content_type = "text/xml"
  34 
  35     request.find_service(name="csp").merge(XML_CSP)
  36 
  37     latest_releases = (
  38         request.db.query(Release)
  39                   .options(joinedload(Release.project))
  40                   .order_by(Release.created.desc())
  41                   .limit(40)
  42                   .all()
  43     )
  44 
  45     return {"latest_releases": latest_releases}
  46 
  47 
  48 @view_config(
  49     route_name="rss.packages",
  50     renderer="rss/packages.xml",
  51     decorator=[
  52         origin_cache(
  53             1 * 24 * 60 * 60,                         # 1 day
  54             stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day
  55             stale_if_error=5 * 24 * 60 * 60,          # 5 days
  56         ),
  57     ],
  58 )
  59 def rss_packages(request):
  60     request.response.content_type = "text/xml"
  61 
  62     request.find_service(name="csp").merge(XML_CSP)
  63 
  64     newest_projects = (
  65         request.db.query(Project)
  66                   .options(joinedload(Project.releases, innerjoin=True))
  67                   .order_by(Project.created.desc())
  68                   .limit(40)
  69                   .all()
  70     )
  71 
  72     return {"newest_projects": newest_projects}
  73
  ```
  --- 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/warehouse/rss/views.py b/warehouse/rss/views.py
  --- a/warehouse/rss/views.py
  +++ b/warehouse/rss/views.py
  @@ -26,6 +26,7 @@
               1 * 24 * 60 * 60,                         # 1 day
               stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day
               stale_if_error=5 * 24 * 60 * 60,          # 5 days
  +            keys=["all-projects"],
           ),
       ],
   )
  @@ -53,6 +54,7 @@
               1 * 24 * 60 * 60,                         # 1 day
               stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day
               stale_if_error=5 * 24 * 60 * 60,          # 5 days
  +            keys=["all-projects"],
           ),
       ],
   )
  
verification_info: {"golden_diff": "diff --git a/warehouse/rss/views.py b/warehouse/rss/views.py\n--- a/warehouse/rss/views.py\n+++ b/warehouse/rss/views.py\n@@ -26,6 +26,7 @@\n             1 * 24 * 60 * 60,                         # 1 day\n             stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day\n             stale_if_error=5 * 24 * 60 * 60,          # 5 days\n+            keys=[\"all-projects\"],\n         ),\n     ],\n )\n@@ -53,6 +54,7 @@\n             1 * 24 * 60 * 60,                         # 1 day\n             stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day\n             stale_if_error=5 * 24 * 60 * 60,          # 5 days\n+            keys=[\"all-projects\"],\n         ),\n     ],\n )\n", "issue": "Legacy and Warehouse RSS feeds differ\n@andrew asked in https://github.com/librariesio/libraries.io/issues/2024#issuecomment-372638824 about Warehouse's RSS feeds:\r\n\r\n> * https://pypi.org/rss/updates.xml\r\n> * https://pypi.org/rss/packages.xml\r\n\r\n> Which I expected the contents to match the old ones but currently don't:\r\n\r\n> * https://pypi.python.org/pypi?%3Aaction=rss\r\n> * https://pypi.python.org/pypi?%3Aaction=packages_rss\r\n\r\nI've verified through visual inspection that the data in the legacy RSS feed and the data in the Warehouse RSS feeds differ.\r\n\r\nThis is a bug in the feeds or a bug in the docs. Currently our [feeds documentation](https://warehouse.readthedocs.io/api-reference/feeds/) and [Warehouse migration guide](https://warehouse.readthedocs.io/api-reference/integration-guide/) don't say anything about deliberate differences between the legacy and Warehouse RSS feeds. We can update the docs if there's a deliberate reason for the difference.\n", "before_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom pyramid.view import view_config\nfrom sqlalchemy.orm import joinedload\n\nfrom warehouse.cache.origin import origin_cache\nfrom warehouse.packaging.models import Project, Release\nfrom warehouse.xml import XML_CSP\n\n\n@view_config(\n    route_name=\"rss.updates\",\n    renderer=\"rss/updates.xml\",\n    decorator=[\n        origin_cache(\n            1 * 24 * 60 * 60,                         # 1 day\n            stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day\n            stale_if_error=5 * 24 * 60 * 60,          # 5 days\n        ),\n    ],\n)\ndef rss_updates(request):\n    request.response.content_type = \"text/xml\"\n\n    request.find_service(name=\"csp\").merge(XML_CSP)\n\n    latest_releases = (\n        request.db.query(Release)\n                  .options(joinedload(Release.project))\n                  .order_by(Release.created.desc())\n                  .limit(40)\n                  .all()\n    )\n\n    return {\"latest_releases\": latest_releases}\n\n\n@view_config(\n    route_name=\"rss.packages\",\n    renderer=\"rss/packages.xml\",\n    decorator=[\n        origin_cache(\n            1 * 24 * 60 * 60,                         # 1 day\n            stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day\n            stale_if_error=5 * 24 * 60 * 60,          # 5 days\n        ),\n    ],\n)\ndef rss_packages(request):\n    request.response.content_type = \"text/xml\"\n\n    request.find_service(name=\"csp\").merge(XML_CSP)\n\n    newest_projects = (\n        request.db.query(Project)\n                  .options(joinedload(Project.releases, innerjoin=True))\n                  .order_by(Project.created.desc())\n                  .limit(40)\n                  .all()\n    )\n\n    return {\"newest_projects\": newest_projects}\n", "path": "warehouse/rss/views.py"}], "after_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom pyramid.view import view_config\nfrom sqlalchemy.orm import joinedload\n\nfrom warehouse.cache.origin import origin_cache\nfrom warehouse.packaging.models import Project, Release\nfrom warehouse.xml import XML_CSP\n\n\n@view_config(\n    route_name=\"rss.updates\",\n    renderer=\"rss/updates.xml\",\n    decorator=[\n        origin_cache(\n            1 * 24 * 60 * 60,                         # 1 day\n            stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day\n            stale_if_error=5 * 24 * 60 * 60,          # 5 days\n            keys=[\"all-projects\"],\n        ),\n    ],\n)\ndef rss_updates(request):\n    request.response.content_type = \"text/xml\"\n\n    request.find_service(name=\"csp\").merge(XML_CSP)\n\n    latest_releases = (\n        request.db.query(Release)\n                  .options(joinedload(Release.project))\n                  .order_by(Release.created.desc())\n                  .limit(40)\n                  .all()\n    )\n\n    return {\"latest_releases\": latest_releases}\n\n\n@view_config(\n    route_name=\"rss.packages\",\n    renderer=\"rss/packages.xml\",\n    decorator=[\n        origin_cache(\n            1 * 24 * 60 * 60,                         # 1 day\n            stale_while_revalidate=1 * 24 * 60 * 60,  # 1 day\n            stale_if_error=5 * 24 * 60 * 60,          # 5 days\n            keys=[\"all-projects\"],\n        ),\n    ],\n)\ndef rss_packages(request):\n    request.response.content_type = \"text/xml\"\n\n    request.find_service(name=\"csp\").merge(XML_CSP)\n\n    newest_projects = (\n        request.db.query(Project)\n                  .options(joinedload(Project.releases, innerjoin=True))\n                  .order_by(Project.created.desc())\n                  .limit(40)\n                  .all()\n    )\n\n    return {\"newest_projects\": newest_projects}\n", "path": "warehouse/rss/views.py"}]}