prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  rss-feeds should have more speaking titles
  eg.: https://bodhi.fedoraproject.org/rss/updates/?releases=F24
  the feed is named "updates"
  maybe it should be renamed to "Fedora XX Released Updates" where XX would be 24,...
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `bodhi/server/renderers.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 # Copyright © 2014-2017 Red Hat, Inc.
  3 #
  4 # This file is part of Bodhi.
  5 #
  6 # This program is free software; you can redistribute it and/or
  7 # modify it under the terms of the GNU General Public License
  8 # as published by the Free Software Foundation; either version 2
  9 # of the License, or (at your option) any later version.
  10 #
  11 # This program is distributed in the hope that it will be useful,
  12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 # GNU General Public License for more details.
  15 #
  16 # You should have received a copy of the GNU General Public License
  17 # along with this program; if not, write to the Free Software
  18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  19 """Define special view renderers, such as RSS and jpeg."""
  20 import io
  21 import operator
  22 
  23 from pytz import utc
  24 from feedgen.feed import FeedGenerator
  25 
  26 
  27 def rss(info):
  28     """
  29     Return a RSS renderer.
  30 
  31     Args:
  32         info (pyramid.renderers.RendererHelper): Unused.
  33     Returns:
  34         function: A function that can be used to render a RSS view.
  35     """
  36     def render(data, system):
  37         """
  38         Render the given data as an RSS view.
  39 
  40         If the request's content type is set to the default, this function will change it to
  41         application/rss+xml.
  42 
  43         Args:
  44             data (dict): A dictionary describing the information to be rendered. The information can
  45                 be different types of objects, such as updates, users, comments, or overrides.
  46             system (pyramid.events.BeforeRender): Used to get the current request.
  47         Returns:
  48             basestring: An RSS document representing the given data.
  49         """
  50         request = system.get('request')
  51         if request is not None:
  52             response = request.response
  53             ct = response.content_type
  54             if ct == response.default_content_type:
  55                 response.content_type = 'application/rss+xml'
  56 
  57         if 'updates' in data:
  58             key = 'updates'
  59         elif 'users' in data:
  60             key = 'users'
  61         elif 'comments' in data:
  62             key = 'comments'
  63         elif 'overrides' in data:
  64             key = 'overrides'
  65 
  66         feed = FeedGenerator()
  67         feed.title(key)
  68         feed.link(href=request.url, rel='self')
  69         feed.description(key)
  70         feed.language(u'en')
  71 
  72         def linker(route, param, key):
  73             def link_dict(obj):
  74                 return dict(href=request.route_url(route, **{param: obj[key]}))
  75             return link_dict
  76 
  77         getters = {
  78             'updates': {
  79                 'title': operator.itemgetter('title'),
  80                 'link': linker('update', 'id', 'title'),
  81                 'description': operator.itemgetter('notes'),
  82                 'pubdate': lambda obj: utc.localize(obj['date_submitted']),
  83             },
  84             'users': {
  85                 'title': operator.itemgetter('name'),
  86                 'link': linker('user', 'name', 'name'),
  87                 'description': operator.itemgetter('name'),
  88             },
  89             'comments': {
  90                 'title': operator.itemgetter('rss_title'),
  91                 'link': linker('comment', 'id', 'id'),
  92                 'description': operator.itemgetter('text'),
  93                 'pubdate': lambda obj: utc.localize(obj['timestamp']),
  94             },
  95             'overrides': {
  96                 'title': operator.itemgetter('nvr'),
  97                 'link': linker('override', 'nvr', 'nvr'),
  98                 'description': operator.itemgetter('notes'),
  99                 'pubdate': lambda obj: utc.localize(obj['submission_date']),
  100             },
  101         }
  102 
  103         for value in data[key]:
  104             feed_item = feed.add_item()
  105             for name, getter in getters[key].items():
  106                 # Because we have to use methods to fill feed entry attributes,
  107                 # it's done by getting methods by name and calling them
  108                 # on the same line.
  109                 getattr(feed_item, name)(getter(value))
  110 
  111         return feed.rss_str()
  112 
  113     return render
  114 
  115 
  116 def jpeg(info):
  117     """
  118     Return a JPEG renderer.
  119 
  120     Args:
  121         info (pyramid.renderers.RendererHelper): Unused.
  122     Returns:
  123         function: A function that can be used to render a jpeg view.
  124     """
  125     def render(data, system):
  126         """
  127         Render the given image as a request response.
  128 
  129         This function will also set the content type to image/jpeg if it is the default type.
  130 
  131         Args:
  132             data (PIL.Image.Image): The jpeg that should be sent back as a response.
  133             system (pyramid.events.BeforeRender): Used to get the current request.
  134         Returns:
  135             str: The raw jpeg bytes of the given image.
  136         """
  137         request = system.get('request')
  138         if request is not None:
  139             response = request.response
  140             ct = response.content_type
  141             if ct == response.default_content_type:
  142                 response.content_type = 'image/jpeg'
  143 
  144         b = io.BytesIO()
  145         data.save(b, 'jpeg')
  146         return b.getvalue()
  147     return render
  148
  ```
  --- 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/bodhi/server/renderers.py b/bodhi/server/renderers.py
  --- a/bodhi/server/renderers.py
  +++ b/bodhi/server/renderers.py
  @@ -56,17 +56,29 @@
   
           if 'updates' in data:
               key = 'updates'
  +            feed_title = 'Released updates'
           elif 'users' in data:
               key = 'users'
  +            feed_title = 'Bodhi users'
           elif 'comments' in data:
               key = 'comments'
  +            feed_title = 'User comments'
           elif 'overrides' in data:
               key = 'overrides'
  +            feed_title = 'Update overrides'
  +
  +        feed_description_list = []
  +        for k in request.GET.keys():
  +            feed_description_list.append('%s(%s)' % (k, request.GET[k]))
  +        if feed_description_list:
  +            feed_description = 'Filtered on: ' + ', '.join(feed_description_list)
  +        else:
  +            feed_description = "All %s" % (key)
   
           feed = FeedGenerator()
  -        feed.title(key)
  +        feed.title(feed_title)
           feed.link(href=request.url, rel='self')
  -        feed.description(key)
  +        feed.description(feed_description)
           feed.language(u'en')
   
           def linker(route, param, key):
  
verification_info: {"golden_diff": "diff --git a/bodhi/server/renderers.py b/bodhi/server/renderers.py\n--- a/bodhi/server/renderers.py\n+++ b/bodhi/server/renderers.py\n@@ -56,17 +56,29 @@\n \n         if 'updates' in data:\n             key = 'updates'\n+            feed_title = 'Released updates'\n         elif 'users' in data:\n             key = 'users'\n+            feed_title = 'Bodhi users'\n         elif 'comments' in data:\n             key = 'comments'\n+            feed_title = 'User comments'\n         elif 'overrides' in data:\n             key = 'overrides'\n+            feed_title = 'Update overrides'\n+\n+        feed_description_list = []\n+        for k in request.GET.keys():\n+            feed_description_list.append('%s(%s)' % (k, request.GET[k]))\n+        if feed_description_list:\n+            feed_description = 'Filtered on: ' + ', '.join(feed_description_list)\n+        else:\n+            feed_description = \"All %s\" % (key)\n \n         feed = FeedGenerator()\n-        feed.title(key)\n+        feed.title(feed_title)\n         feed.link(href=request.url, rel='self')\n-        feed.description(key)\n+        feed.description(feed_description)\n         feed.language(u'en')\n \n         def linker(route, param, key):\n", "issue": "rss-feeds should have more speaking titles\neg.: https://bodhi.fedoraproject.org/rss/updates/?releases=F24\r\nthe feed is named \"updates\"\r\nmaybe it should be renamed to \"Fedora XX Released Updates\" where XX would be 24,...\r\n\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright \u00a9 2014-2017 Red Hat, Inc.\n#\n# This file is part of Bodhi.\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n\"\"\"Define special view renderers, such as RSS and jpeg.\"\"\"\nimport io\nimport operator\n\nfrom pytz import utc\nfrom feedgen.feed import FeedGenerator\n\n\ndef rss(info):\n    \"\"\"\n    Return a RSS renderer.\n\n    Args:\n        info (pyramid.renderers.RendererHelper): Unused.\n    Returns:\n        function: A function that can be used to render a RSS view.\n    \"\"\"\n    def render(data, system):\n        \"\"\"\n        Render the given data as an RSS view.\n\n        If the request's content type is set to the default, this function will change it to\n        application/rss+xml.\n\n        Args:\n            data (dict): A dictionary describing the information to be rendered. The information can\n                be different types of objects, such as updates, users, comments, or overrides.\n            system (pyramid.events.BeforeRender): Used to get the current request.\n        Returns:\n            basestring: An RSS document representing the given data.\n        \"\"\"\n        request = system.get('request')\n        if request is not None:\n            response = request.response\n            ct = response.content_type\n            if ct == response.default_content_type:\n                response.content_type = 'application/rss+xml'\n\n        if 'updates' in data:\n            key = 'updates'\n        elif 'users' in data:\n            key = 'users'\n        elif 'comments' in data:\n            key = 'comments'\n        elif 'overrides' in data:\n            key = 'overrides'\n\n        feed = FeedGenerator()\n        feed.title(key)\n        feed.link(href=request.url, rel='self')\n        feed.description(key)\n        feed.language(u'en')\n\n        def linker(route, param, key):\n            def link_dict(obj):\n                return dict(href=request.route_url(route, **{param: obj[key]}))\n            return link_dict\n\n        getters = {\n            'updates': {\n                'title': operator.itemgetter('title'),\n                'link': linker('update', 'id', 'title'),\n                'description': operator.itemgetter('notes'),\n                'pubdate': lambda obj: utc.localize(obj['date_submitted']),\n            },\n            'users': {\n                'title': operator.itemgetter('name'),\n                'link': linker('user', 'name', 'name'),\n                'description': operator.itemgetter('name'),\n            },\n            'comments': {\n                'title': operator.itemgetter('rss_title'),\n                'link': linker('comment', 'id', 'id'),\n                'description': operator.itemgetter('text'),\n                'pubdate': lambda obj: utc.localize(obj['timestamp']),\n            },\n            'overrides': {\n                'title': operator.itemgetter('nvr'),\n                'link': linker('override', 'nvr', 'nvr'),\n                'description': operator.itemgetter('notes'),\n                'pubdate': lambda obj: utc.localize(obj['submission_date']),\n            },\n        }\n\n        for value in data[key]:\n            feed_item = feed.add_item()\n            for name, getter in getters[key].items():\n                # Because we have to use methods to fill feed entry attributes,\n                # it's done by getting methods by name and calling them\n                # on the same line.\n                getattr(feed_item, name)(getter(value))\n\n        return feed.rss_str()\n\n    return render\n\n\ndef jpeg(info):\n    \"\"\"\n    Return a JPEG renderer.\n\n    Args:\n        info (pyramid.renderers.RendererHelper): Unused.\n    Returns:\n        function: A function that can be used to render a jpeg view.\n    \"\"\"\n    def render(data, system):\n        \"\"\"\n        Render the given image as a request response.\n\n        This function will also set the content type to image/jpeg if it is the default type.\n\n        Args:\n            data (PIL.Image.Image): The jpeg that should be sent back as a response.\n            system (pyramid.events.BeforeRender): Used to get the current request.\n        Returns:\n            str: The raw jpeg bytes of the given image.\n        \"\"\"\n        request = system.get('request')\n        if request is not None:\n            response = request.response\n            ct = response.content_type\n            if ct == response.default_content_type:\n                response.content_type = 'image/jpeg'\n\n        b = io.BytesIO()\n        data.save(b, 'jpeg')\n        return b.getvalue()\n    return render\n", "path": "bodhi/server/renderers.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright \u00a9 2014-2017 Red Hat, Inc.\n#\n# This file is part of Bodhi.\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n\"\"\"Define special view renderers, such as RSS and jpeg.\"\"\"\nimport io\nimport operator\n\nfrom pytz import utc\nfrom feedgen.feed import FeedGenerator\n\n\ndef rss(info):\n    \"\"\"\n    Return a RSS renderer.\n\n    Args:\n        info (pyramid.renderers.RendererHelper): Unused.\n    Returns:\n        function: A function that can be used to render a RSS view.\n    \"\"\"\n    def render(data, system):\n        \"\"\"\n        Render the given data as an RSS view.\n\n        If the request's content type is set to the default, this function will change it to\n        application/rss+xml.\n\n        Args:\n            data (dict): A dictionary describing the information to be rendered. The information can\n                be different types of objects, such as updates, users, comments, or overrides.\n            system (pyramid.events.BeforeRender): Used to get the current request.\n        Returns:\n            basestring: An RSS document representing the given data.\n        \"\"\"\n        request = system.get('request')\n        if request is not None:\n            response = request.response\n            ct = response.content_type\n            if ct == response.default_content_type:\n                response.content_type = 'application/rss+xml'\n\n        if 'updates' in data:\n            key = 'updates'\n            feed_title = 'Released updates'\n        elif 'users' in data:\n            key = 'users'\n            feed_title = 'Bodhi users'\n        elif 'comments' in data:\n            key = 'comments'\n            feed_title = 'User comments'\n        elif 'overrides' in data:\n            key = 'overrides'\n            feed_title = 'Update overrides'\n\n        feed_description_list = []\n        for k in request.GET.keys():\n            feed_description_list.append('%s(%s)' % (k, request.GET[k]))\n        if feed_description_list:\n            feed_description = 'Filtered on: ' + ', '.join(feed_description_list)\n        else:\n            feed_description = \"All %s\" % (key)\n\n        feed = FeedGenerator()\n        feed.title(feed_title)\n        feed.link(href=request.url, rel='self')\n        feed.description(feed_description)\n        feed.language(u'en')\n\n        def linker(route, param, key):\n            def link_dict(obj):\n                return dict(href=request.route_url(route, **{param: obj[key]}))\n            return link_dict\n\n        getters = {\n            'updates': {\n                'title': operator.itemgetter('title'),\n                'link': linker('update', 'id', 'title'),\n                'description': operator.itemgetter('notes'),\n                'pubdate': lambda obj: utc.localize(obj['date_submitted']),\n            },\n            'users': {\n                'title': operator.itemgetter('name'),\n                'link': linker('user', 'name', 'name'),\n                'description': operator.itemgetter('name'),\n            },\n            'comments': {\n                'title': operator.itemgetter('rss_title'),\n                'link': linker('comment', 'id', 'id'),\n                'description': operator.itemgetter('text'),\n                'pubdate': lambda obj: utc.localize(obj['timestamp']),\n            },\n            'overrides': {\n                'title': operator.itemgetter('nvr'),\n                'link': linker('override', 'nvr', 'nvr'),\n                'description': operator.itemgetter('notes'),\n                'pubdate': lambda obj: utc.localize(obj['submission_date']),\n            },\n        }\n\n        for value in data[key]:\n            feed_item = feed.add_item()\n            for name, getter in getters[key].items():\n                # Because we have to use methods to fill feed entry attributes,\n                # it's done by getting methods by name and calling them\n                # on the same line.\n                getattr(feed_item, name)(getter(value))\n\n        return feed.rss_str()\n\n    return render\n\n\ndef jpeg(info):\n    \"\"\"\n    Return a JPEG renderer.\n\n    Args:\n        info (pyramid.renderers.RendererHelper): Unused.\n    Returns:\n        function: A function that can be used to render a jpeg view.\n    \"\"\"\n    def render(data, system):\n        \"\"\"\n        Render the given image as a request response.\n\n        This function will also set the content type to image/jpeg if it is the default type.\n\n        Args:\n            data (PIL.Image.Image): The jpeg that should be sent back as a response.\n            system (pyramid.events.BeforeRender): Used to get the current request.\n        Returns:\n            str: The raw jpeg bytes of the given image.\n        \"\"\"\n        request = system.get('request')\n        if request is not None:\n            response = request.response\n            ct = response.content_type\n            if ct == response.default_content_type:\n                response.content_type = 'image/jpeg'\n\n        b = io.BytesIO()\n        data.save(b, 'jpeg')\n        return b.getvalue()\n    return render\n", "path": "bodhi/server/renderers.py"}]}