We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
overrides auto-search shows f21 candidates twice
![overrides](https://cloud.githubusercontent.com/assets/671366/9627790/2a11b728-5184-11e5-8834-b30c5c7341c8.png)
You can see that f21 candidate appearing twice. I also checked few other f21 packages and they are listed twice.

Please fix to show them once.


--- 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/views/generic.py`
Content:
```
1 # This program is free software; you can redistribute it and/or
2 # modify it under the terms of the GNU General Public License
3 # as published by the Free Software Foundation; either version 2
4 # of the License, or (at your option) any later version.
5 #
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9 # GNU General Public License for more details.
10 #
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14 
15 import datetime
16 import sqlalchemy as sa
17 
18 from pyramid.security import authenticated_userid
19 from pyramid.settings import asbool
20 from pyramid.view import view_config, notfound_view_config
21 from pyramid.exceptions import HTTPNotFound, HTTPForbidden
22 
23 from bodhi import log
24 import bodhi.models
25 import bodhi.util
26 
27 
28 @notfound_view_config(append_slash=True)
29 def notfound_view(context, request):
30     """ Automatically redirects to slash-appended routes.
31 
32     http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/urldispatch.html#redirecting-to-slash-appended-rou
33     """
34     return HTTPNotFound()
35 
36 
37 def get_top_testers(request):
38     db = request.db
39     blacklist = request.registry.settings.get('stats_blacklist').split()
40     days = int(request.registry.settings.get('top_testers_timeframe', 7))
41     start_time = datetime.datetime.utcnow() - datetime.timedelta(days=days)
42 
43     query = db.query(
44         bodhi.models.User,
45         sa.func.count(bodhi.models.User.comments).label('count_1')
46     ).join(bodhi.models.Comment)
47     query = query\
48         .order_by('count_1 desc')\
49         .filter(bodhi.models.Comment.timestamp > start_time)
50 
51     for user in blacklist:
52         query = query.filter(bodhi.models.User.name != user)
53 
54     return query\
55         .group_by(bodhi.models.User)\
56         .limit(5)\
57         .all()
58 
59 
60 def get_latest_updates(request, critpath, security):
61     db = request.db
62     query = db.query(bodhi.models.Update)
63 
64     if critpath:
65         query = query.filter(
66             bodhi.models.Update.critpath==True)
67     if security:
68         query = query.filter(
69             bodhi.models.Update.type==bodhi.models.UpdateType.security)
70 
71     query = query.filter(
72         bodhi.models.Update.status==bodhi.models.UpdateStatus.testing)
73 
74     query = query.order_by(bodhi.models.Update.date_submitted.desc())
75     return query.limit(5).all()
76 
77 
78 @view_config(route_name='home', renderer='home.html')
79 def home(request):
80     """ Returns data for the frontpage """
81     r = request
82 
83     @request.cache.cache_on_arguments()
84     def work():
85         top_testers = get_top_testers(request)
86         critpath_updates = get_latest_updates(request, True, False)
87         security_updates = get_latest_updates(request, False, True)
88 
89         return {
90             "top_testers": [(obj.__json__(r), n) for obj, n in top_testers],
91             "critpath_updates": [obj.__json__(r) for obj in critpath_updates],
92             "security_updates": [obj.__json__(r) for obj in security_updates],
93         }
94 
95     return work()
96 
97 
98 @view_config(route_name='new_update', renderer='new_update.html')
99 def new_update(request):
100     """ Returns the new update form """
101     user = authenticated_userid(request)
102     if not user:
103         raise HTTPForbidden("You must be logged in.")
104     return dict(
105         update=None,
106         types=reversed(bodhi.models.UpdateType.values()),
107         severities=reversed(bodhi.models.UpdateSeverity.values()),
108         suggestions=reversed(bodhi.models.UpdateSuggestion.values()),
109     )
110 
111 
112 @view_config(route_name='latest_candidates', renderer='json')
113 def latest_candidates(request):
114     """
115     For a given `package`, this method returns the most recent builds tagged
116     into the Release.candidate_tag for all Releases.
117     """
118     koji = request.koji
119     db = request.db
120 
121     @request.cache.cache_on_arguments()
122     def work(pkg, testing):
123         result = []
124         koji.multicall = True
125 
126         releases = db.query(bodhi.models.Release) \
127                      .filter(
128                          bodhi.models.Release.state.in_(
129                              (bodhi.models.ReleaseState.pending,
130                               bodhi.models.ReleaseState.current)))
131 
132         kwargs = dict(package=pkg, latest=True)
133         for release in releases:
134             koji.listTagged(release.candidate_tag, **kwargs)
135             if testing:
136                 koji.listTagged(release.testing_tag, **kwargs)
137                 koji.listTagged(release.pending_testing_tag, **kwargs)
138 
139         builds = koji.multiCall() or []  # Protect against None
140 
141         for build in builds:
142             if isinstance(build, dict):
143                 continue
144             if build and build[0] and build[0][0]:
145                 result.append({
146                     'nvr': build[0][0]['nvr'],
147                     'id': build[0][0]['id'],
148                 })
149         return result
150 
151 
152     pkg = request.params.get('package')
153     testing = asbool(request.params.get('testing'))
154     log.debug('latest_candidate(%r, %r)' % (pkg, testing))
155 
156     if not pkg:
157         return []
158 
159     result = work(pkg, testing)
160 
161     log.debug(result)
162     return result
163 
164 
165 @view_config(route_name='latest_builds', renderer='json')
166 def latest_builds(request):
167     """ Get a list of the latest builds for a given package.
168 
169     Returns a dictionary of the release dist tag to the latest build.
170     """
171     builds = {}
172     koji = request.koji
173     package = request.params.get('package')
174     for tag_type, tags in bodhi.models.Release.get_tags()[0].iteritems():
175         for tag in tags:
176             try:
177                 for build in koji.getLatestBuilds(tag, package=package):
178                     builds[tag] = build['nvr']
179             except:  # Things like EPEL don't have pending tags
180                 pass
181     return builds
182 
183 
184 @view_config(route_name='new_override', renderer='override.html')
185 def new_override(request):
186     """ Returns the new buildroot override form """
187     user = authenticated_userid(request)
188     if not user:
189         raise HTTPForbidden("You must be logged in.")
190     return dict()
191 
192 
193 @view_config(route_name='api_version', renderer='json')
194 def api_version(request):
195     """ Returns the Bodhi API version """
196     return dict(version=bodhi.util.version())
197
```
--- 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/bodhi/views/generic.py b/bodhi/views/generic.py
--- a/bodhi/views/generic.py
+++ b/bodhi/views/generic.py
@@ -142,10 +142,14 @@
             if isinstance(build, dict):
                 continue
             if build and build[0] and build[0][0]:
-                result.append({
+                item = {
                     'nvr': build[0][0]['nvr'],
                     'id': build[0][0]['id'],
-                })
+                }
+                # Prune duplicates
+                # https://github.com/fedora-infra/bodhi/issues/450
+                if item not in result:
+                    result.append(item)
         return result

{"golden_diff": "diff --git a/bodhi/views/generic.py b/bodhi/views/generic.py\n--- a/bodhi/views/generic.py\n+++ b/bodhi/views/generic.py\n@@ -142,10 +142,14 @@\n             if isinstance(build, dict):\n                 continue\n             if build and build[0] and build[0][0]:\n-                result.append({\n+                item = {\n                     'nvr': build[0][0]['nvr'],\n                     'id': build[0][0]['id'],\n-                })\n+                }\n+                # Prune duplicates\n+                # https://github.com/fedora-infra/bodhi/issues/450\n+                if item not in result:\n+                    result.append(item)\n         return result\n", "issue": "overrides auto-search shows f21 candidates twice\n![overrides](https://cloud.githubusercontent.com/assets/671366/9627790/2a11b728-5184-11e5-8834-b30c5c7341c8.png)\nYou can see that f21 candidate appearing twice. I also checked few other f21 packages and they are listed twice.\n\nPlease fix to show them once.\n\n", "before_files": [{"content": "# 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\nimport datetime\nimport sqlalchemy as sa\n\nfrom pyramid.security import authenticated_userid\nfrom pyramid.settings import asbool\nfrom pyramid.view import view_config, notfound_view_config\nfrom pyramid.exceptions import HTTPNotFound, HTTPForbidden\n\nfrom bodhi import log\nimport bodhi.models\nimport bodhi.util\n\n\n@notfound_view_config(append_slash=True)\ndef notfound_view(context, request):\n    \"\"\" Automatically redirects to slash-appended routes.\n\n    http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/urldispatch.html#redirecting-to-slash-appended-rou\n    \"\"\"\n    return HTTPNotFound()\n\n\ndef get_top_testers(request):\n    db = request.db\n    blacklist = request.registry.settings.get('stats_blacklist').split()\n    days = int(request.registry.settings.get('top_testers_timeframe', 7))\n    start_time = datetime.datetime.utcnow() - datetime.timedelta(days=days)\n\n    query = db.query(\n        bodhi.models.User,\n        sa.func.count(bodhi.models.User.comments).label('count_1')\n    ).join(bodhi.models.Comment)\n    query = query\\\n        .order_by('count_1 desc')\\\n        .filter(bodhi.models.Comment.timestamp > start_time)\n\n    for user in blacklist:\n        query = query.filter(bodhi.models.User.name != user)\n\n    return query\\\n        .group_by(bodhi.models.User)\\\n        .limit(5)\\\n        .all()\n\n\ndef get_latest_updates(request, critpath, security):\n    db = request.db\n    query = db.query(bodhi.models.Update)\n\n    if critpath:\n        query = query.filter(\n            bodhi.models.Update.critpath==True)\n    if security:\n        query = query.filter(\n            bodhi.models.Update.type==bodhi.models.UpdateType.security)\n\n    query = query.filter(\n        bodhi.models.Update.status==bodhi.models.UpdateStatus.testing)\n\n    query = query.order_by(bodhi.models.Update.date_submitted.desc())\n    return query.limit(5).all()\n\n\n@view_config(route_name='home', renderer='home.html')\ndef home(request):\n    \"\"\" Returns data for the frontpage \"\"\"\n    r = request\n\n    @request.cache.cache_on_arguments()\n    def work():\n        top_testers = get_top_testers(request)\n        critpath_updates = get_latest_updates(request, True, False)\n        security_updates = get_latest_updates(request, False, True)\n\n        return {\n            \"top_testers\": [(obj.__json__(r), n) for obj, n in top_testers],\n            \"critpath_updates\": [obj.__json__(r) for obj in critpath_updates],\n            \"security_updates\": [obj.__json__(r) for obj in security_updates],\n        }\n\n    return work()\n\n\n@view_config(route_name='new_update', renderer='new_update.html')\ndef new_update(request):\n    \"\"\" Returns the new update form \"\"\"\n    user = authenticated_userid(request)\n    if not user:\n        raise HTTPForbidden(\"You must be logged in.\")\n    return dict(\n        update=None,\n        types=reversed(bodhi.models.UpdateType.values()),\n        severities=reversed(bodhi.models.UpdateSeverity.values()),\n        suggestions=reversed(bodhi.models.UpdateSuggestion.values()),\n    )\n\n\n@view_config(route_name='latest_candidates', renderer='json')\ndef latest_candidates(request):\n    \"\"\"\n    For a given `package`, this method returns the most recent builds tagged\n    into the Release.candidate_tag for all Releases.\n    \"\"\"\n    koji = request.koji\n    db = request.db\n\n    @request.cache.cache_on_arguments()\n    def work(pkg, testing):\n        result = []\n        koji.multicall = True\n\n        releases = db.query(bodhi.models.Release) \\\n                     .filter(\n                         bodhi.models.Release.state.in_(\n                             (bodhi.models.ReleaseState.pending,\n                              bodhi.models.ReleaseState.current)))\n\n        kwargs = dict(package=pkg, latest=True)\n        for release in releases:\n            koji.listTagged(release.candidate_tag, **kwargs)\n            if testing:\n                koji.listTagged(release.testing_tag, **kwargs)\n                koji.listTagged(release.pending_testing_tag, **kwargs)\n\n        builds = koji.multiCall() or []  # Protect against None\n\n        for build in builds:\n            if isinstance(build, dict):\n                continue\n            if build and build[0] and build[0][0]:\n                result.append({\n                    'nvr': build[0][0]['nvr'],\n                    'id': build[0][0]['id'],\n                })\n        return result\n\n\n    pkg = request.params.get('package')\n    testing = asbool(request.params.get('testing'))\n    log.debug('latest_candidate(%r, %r)' % (pkg, testing))\n\n    if not pkg:\n        return []\n\n    result = work(pkg, testing)\n\n    log.debug(result)\n    return result\n\n\n@view_config(route_name='latest_builds', renderer='json')\ndef latest_builds(request):\n    \"\"\" Get a list of the latest builds for a given package.\n\n    Returns a dictionary of the release dist tag to the latest build.\n    \"\"\"\n    builds = {}\n    koji = request.koji\n    package = request.params.get('package')\n    for tag_type, tags in bodhi.models.Release.get_tags()[0].iteritems():\n        for tag in tags:\n            try:\n                for build in koji.getLatestBuilds(tag, package=package):\n                    builds[tag] = build['nvr']\n            except:  # Things like EPEL don't have pending tags\n                pass\n    return builds\n\n\n@view_config(route_name='new_override', renderer='override.html')\ndef new_override(request):\n    \"\"\" Returns the new buildroot override form \"\"\"\n    user = authenticated_userid(request)\n    if not user:\n        raise HTTPForbidden(\"You must be logged in.\")\n    return dict()\n\n\n@view_config(route_name='api_version', renderer='json')\ndef api_version(request):\n    \"\"\" Returns the Bodhi API version \"\"\"\n    return dict(version=bodhi.util.version())\n", "path": "bodhi/views/generic.py"}], "after_files": [{"content": "# 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\nimport datetime\nimport sqlalchemy as sa\n\nfrom pyramid.security import authenticated_userid\nfrom pyramid.settings import asbool\nfrom pyramid.view import view_config, notfound_view_config\nfrom pyramid.exceptions import HTTPNotFound, HTTPForbidden\n\nfrom bodhi import log\nimport bodhi.models\nimport bodhi.util\n\n\n@notfound_view_config(append_slash=True)\ndef notfound_view(context, request):\n    \"\"\" Automatically redirects to slash-appended routes.\n\n    http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/urldispatch.html#redirecting-to-slash-appended-rou\n    \"\"\"\n    return HTTPNotFound()\n\n\ndef get_top_testers(request):\n    db = request.db\n    blacklist = request.registry.settings.get('stats_blacklist').split()\n    days = int(request.registry.settings.get('top_testers_timeframe', 7))\n    start_time = datetime.datetime.utcnow() - datetime.timedelta(days=days)\n\n    query = db.query(\n        bodhi.models.User,\n        sa.func.count(bodhi.models.User.comments).label('count_1')\n    ).join(bodhi.models.Comment)\n    query = query\\\n        .order_by('count_1 desc')\\\n        .filter(bodhi.models.Comment.timestamp > start_time)\n\n    for user in blacklist:\n        query = query.filter(bodhi.models.User.name != user)\n\n    return query\\\n        .group_by(bodhi.models.User)\\\n        .limit(5)\\\n        .all()\n\n\ndef get_latest_updates(request, critpath, security):\n    db = request.db\n    query = db.query(bodhi.models.Update)\n\n    if critpath:\n        query = query.filter(\n            bodhi.models.Update.critpath==True)\n    if security:\n        query = query.filter(\n            bodhi.models.Update.type==bodhi.models.UpdateType.security)\n\n    query = query.filter(\n        bodhi.models.Update.status==bodhi.models.UpdateStatus.testing)\n\n    query = query.order_by(bodhi.models.Update.date_submitted.desc())\n    return query.limit(5).all()\n\n\n@view_config(route_name='home', renderer='home.html')\ndef home(request):\n    \"\"\" Returns data for the frontpage \"\"\"\n    r = request\n\n    @request.cache.cache_on_arguments()\n    def work():\n        top_testers = get_top_testers(request)\n        critpath_updates = get_latest_updates(request, True, False)\n        security_updates = get_latest_updates(request, False, True)\n\n        return {\n            \"top_testers\": [(obj.__json__(r), n) for obj, n in top_testers],\n            \"critpath_updates\": [obj.__json__(r) for obj in critpath_updates],\n            \"security_updates\": [obj.__json__(r) for obj in security_updates],\n        }\n\n    return work()\n\n\n@view_config(route_name='new_update', renderer='new_update.html')\ndef new_update(request):\n    \"\"\" Returns the new update form \"\"\"\n    user = authenticated_userid(request)\n    if not user:\n        raise HTTPForbidden(\"You must be logged in.\")\n    return dict(\n        update=None,\n        types=reversed(bodhi.models.UpdateType.values()),\n        severities=reversed(bodhi.models.UpdateSeverity.values()),\n        suggestions=reversed(bodhi.models.UpdateSuggestion.values()),\n    )\n\n\n@view_config(route_name='latest_candidates', renderer='json')\ndef latest_candidates(request):\n    \"\"\"\n    For a given `package`, this method returns the most recent builds tagged\n    into the Release.candidate_tag for all Releases.\n    \"\"\"\n    koji = request.koji\n    db = request.db\n\n    @request.cache.cache_on_arguments()\n    def work(pkg, testing):\n        result = []\n        koji.multicall = True\n\n        releases = db.query(bodhi.models.Release) \\\n                     .filter(\n                         bodhi.models.Release.state.in_(\n                             (bodhi.models.ReleaseState.pending,\n                              bodhi.models.ReleaseState.current)))\n\n        kwargs = dict(package=pkg, latest=True)\n        for release in releases:\n            koji.listTagged(release.candidate_tag, **kwargs)\n            if testing:\n                koji.listTagged(release.testing_tag, **kwargs)\n                koji.listTagged(release.pending_testing_tag, **kwargs)\n\n        builds = koji.multiCall() or []  # Protect against None\n\n        for build in builds:\n            if isinstance(build, dict):\n                continue\n            if build and build[0] and build[0][0]:\n                item = {\n                    'nvr': build[0][0]['nvr'],\n                    'id': build[0][0]['id'],\n                }\n                # Prune duplicates\n                # https://github.com/fedora-infra/bodhi/issues/450\n                if item not in result:\n                    result.append(item)\n        return result\n\n\n    pkg = request.params.get('package')\n    testing = asbool(request.params.get('testing'))\n    log.debug('latest_candidate(%r, %r)' % (pkg, testing))\n\n    if not pkg:\n        return []\n\n    result = work(pkg, testing)\n\n    log.debug(result)\n    return result\n\n\n@view_config(route_name='latest_builds', renderer='json')\ndef latest_builds(request):\n    \"\"\" Get a list of the latest builds for a given package.\n\n    Returns a dictionary of the release dist tag to the latest build.\n    \"\"\"\n    builds = {}\n    koji = request.koji\n    package = request.params.get('package')\n    for tag_type, tags in bodhi.models.Release.get_tags()[0].iteritems():\n        for tag in tags:\n            try:\n                for build in koji.getLatestBuilds(tag, package=package):\n                    builds[tag] = build['nvr']\n            except:  # Things like EPEL don't have pending tags\n                pass\n    return builds\n\n\n@view_config(route_name='new_override', renderer='override.html')\ndef new_override(request):\n    \"\"\" Returns the new buildroot override form \"\"\"\n    user = authenticated_userid(request)\n    if not user:\n        raise HTTPForbidden(\"You must be logged in.\")\n    return dict()\n\n\n@view_config(route_name='api_version', renderer='json')\ndef api_version(request):\n    \"\"\" Returns the Bodhi API version \"\"\"\n    return dict(version=bodhi.util.version())\n", "path": "bodhi/views/generic.py"}]}