Merge lp:~deryck/launchpad/hot-bugtasks-to-hot-bugs-442170 into lp:launchpad/db-devel
- hot-bugtasks-to-hot-bugs-442170
- Merge into db-devel
Status: | Merged |
---|---|
Approved by: | Eleanor Berger |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~deryck/launchpad/hot-bugtasks-to-hot-bugs-442170 |
Merge into: | lp:launchpad/db-devel |
Diff against target: |
186 lines (+72/-30) 4 files modified
lib/lp/bugs/browser/bugtarget.py (+21/-0) lib/lp/bugs/browser/bugtask.py (+0/-9) lib/lp/bugs/stories/bugs/xx-product-bugs-page.txt (+48/-18) lib/lp/bugs/templates/bugtarget-bugs.pt (+3/-3) |
To merge this branch: | bzr merge lp:~deryck/launchpad/hot-bugtasks-to-hot-bugs-442170 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eleanor Berger (community) | Approve | ||
Review via email: mp+17826@code.launchpad.net |
Commit message
Make the method getting a hot bugs list get bugs by heat rather than recently touched bugtasks.
Description of the change
Deryck Hodge (deryck) wrote : | # |
Eleanor Berger (intellectronica) wrote : | # |
At last, real hot bugs!!!
We've discussed a few minor changes:
1. Exiting from the loop instead of returning twice in hot_bugs.
2. Accessing bug/prop instead of bug/default_
Everything else looks great.
Eleanor Berger (intellectronica) wrote : | # |
On further discussion, we realised that there's a subtle problem with using the default_bugtask, since it isn't necessarily a task on the same bugtarget we're viewing. Instead of returning bugs, we should return the task we got back from searchTasks. That does complicate the loop in hot_bugs a bit.
Deryck Hodge (deryck) wrote : | # |
I believe I've fixed everything now. Latest incremental diff:
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -1264,12 +1264,13 @@
hot_bugs = []
count = 0
for task in bugtasks:
- if task.bug not in hot_bugs:
+ # Ensure we only represent a bug once in the list.
+ if task.bug not in [hot_task.bug for hot_task in hot_bugs]:
if count < 10:
- hot_bugs.
+ hot_bugs.
- elif count == 10:
- return hot_bugs
+ else:
+ break
return hot_bugs
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -1257,7 +1257,7 @@
- "heat": "Bug.hotness",
+ "heat": "Bug.heat",
}
_open_
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -203,8 +203,8 @@
#21 Summary for new bug 6 New Undecided ...
-Fix released bugs are not shown. We demonstrate this by setting the bugtask
-for bug 18 to be "Fix released".
+Fix Released bugs are not shown. We demonstrate this by setting the bugtask
+for bug 18 to be "Fix Released".
>>> from lp.bugs.
>>> from lp.registry.
@@ -215,7 +215,7 @@
... BugTaskStatus.
>>> logout()
-And then reloading the page. The Fix released bug, bug 18, is no longer shown.
+And then reloading the page. The Fix Released bug, bug 18, is no longer shown.
>>> anon_browser.
>>> print extract_text(
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -113,23 +113,23 @@
</tr>
</thead>
<tbody>
- <tr tal:repeat="bug view/hot_bugs">
+ <tr tal:repeat="bugtask view/hot_bugs">
<td class="icon left">
<img alt="" src="/@@/bug" />
</td>
<td style="text-align: right">
- #<span tal:replace=
+ #<span tal:replace=
</td>
<td>
- <a tal:attributes=
- tal:content=
+ <a tal:attributes=
+ tal:content=
...
Eleanor Berger (intellectronica) : | # |
Preview Diff
1 | === modified file 'lib/lp/bugs/browser/bugtarget.py' | |||
2 | --- lib/lp/bugs/browser/bugtarget.py 2010-01-07 05:41:58 +0000 | |||
3 | +++ lib/lp/bugs/browser/bugtarget.py 2010-01-22 16:41:25 +0000 | |||
4 | @@ -40,6 +40,7 @@ | |||
5 | 40 | from canonical.config import config | 40 | from canonical.config import config |
6 | 41 | from lp.bugs.browser.bugtask import BugTaskSearchListingView | 41 | from lp.bugs.browser.bugtask import BugTaskSearchListingView |
7 | 42 | from lp.bugs.interfaces.bug import IBug | 42 | from lp.bugs.interfaces.bug import IBug |
8 | 43 | from lp.bugs.interfaces.bugtask import BugTaskSearchParams | ||
9 | 43 | from canonical.launchpad.browser.feeds import ( | 44 | from canonical.launchpad.browser.feeds import ( |
10 | 44 | BugFeedLink, BugTargetLatestBugsFeedLink, FeedsMixin, | 45 | BugFeedLink, BugTargetLatestBugsFeedLink, FeedsMixin, |
11 | 45 | PersonLatestBugsFeedLink) | 46 | PersonLatestBugsFeedLink) |
12 | @@ -55,6 +56,7 @@ | |||
13 | 55 | from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities | 56 | from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities |
14 | 56 | from canonical.launchpad.interfaces.temporaryblobstorage import ( | 57 | from canonical.launchpad.interfaces.temporaryblobstorage import ( |
15 | 57 | ITemporaryStorageManager) | 58 | ITemporaryStorageManager) |
16 | 59 | from canonical.launchpad.searchbuilder import any | ||
17 | 58 | from canonical.launchpad.webapp import urlappend | 60 | from canonical.launchpad.webapp import urlappend |
18 | 59 | from canonical.launchpad.webapp.breadcrumb import Breadcrumb | 61 | from canonical.launchpad.webapp.breadcrumb import Breadcrumb |
19 | 60 | from canonical.launchpad.webapp.interfaces import ILaunchBag, NotFoundError | 62 | from canonical.launchpad.webapp.interfaces import ILaunchBag, NotFoundError |
20 | @@ -1252,6 +1254,25 @@ | |||
21 | 1252 | else: | 1254 | else: |
22 | 1253 | return 'None specified' | 1255 | return 'None specified' |
23 | 1254 | 1256 | ||
24 | 1257 | @property | ||
25 | 1258 | def hot_bugs(self): | ||
26 | 1259 | """Return the 10 hotest bugs according to IBug.heat.""" | ||
27 | 1260 | params = BugTaskSearchParams( | ||
28 | 1261 | orderby=['-heat', '-date_last_updated'], omit_dupes=True, | ||
29 | 1262 | user=self.user, status=any(*UNRESOLVED_BUGTASK_STATUSES)) | ||
30 | 1263 | bugtasks = self.context.searchTasks(params) | ||
31 | 1264 | hot_bugs = [] | ||
32 | 1265 | count = 0 | ||
33 | 1266 | for task in bugtasks: | ||
34 | 1267 | # Ensure we only represent a bug once in the list. | ||
35 | 1268 | if task.bug not in [hot_task.bug for hot_task in hot_bugs]: | ||
36 | 1269 | if count < 10: | ||
37 | 1270 | hot_bugs.append(task) | ||
38 | 1271 | count += 1 | ||
39 | 1272 | else: | ||
40 | 1273 | break | ||
41 | 1274 | return hot_bugs | ||
42 | 1275 | |||
43 | 1255 | 1276 | ||
44 | 1256 | class BugTargetBugTagsView(LaunchpadView): | 1277 | class BugTargetBugTagsView(LaunchpadView): |
45 | 1257 | """Helper methods for rendering the bug tags portlet.""" | 1278 | """Helper methods for rendering the bug tags portlet.""" |
46 | 1258 | 1279 | ||
47 | === modified file 'lib/lp/bugs/browser/bugtask.py' | |||
48 | --- lib/lp/bugs/browser/bugtask.py 2010-01-19 16:43:20 +0000 | |||
49 | +++ lib/lp/bugs/browser/bugtask.py 2010-01-22 16:41:25 +0000 | |||
50 | @@ -2726,15 +2726,6 @@ | |||
51 | 2726 | return IDistributionSourcePackage(self.context, None) | 2726 | return IDistributionSourcePackage(self.context, None) |
52 | 2727 | 2727 | ||
53 | 2728 | @property | 2728 | @property |
54 | 2729 | def hot_bugtasks(self): | ||
55 | 2730 | """Return the 10 most recently updated bugtasks for this target.""" | ||
56 | 2731 | params = BugTaskSearchParams( | ||
57 | 2732 | orderby="-date_last_updated", omit_dupes=True, user=self.user, | ||
58 | 2733 | status=any(*UNRESOLVED_BUGTASK_STATUSES)) | ||
59 | 2734 | search = self.context.searchTasks(params) | ||
60 | 2735 | return list(search[:10]) | ||
61 | 2736 | |||
62 | 2737 | @property | ||
63 | 2738 | def addquestion_url(self): | 2729 | def addquestion_url(self): |
64 | 2739 | """Return the URL for the +addquestion view for the context.""" | 2730 | """Return the URL for the +addquestion view for the context.""" |
65 | 2740 | if IQuestionTarget.providedBy(self.context): | 2731 | if IQuestionTarget.providedBy(self.context): |
66 | 2741 | 2732 | ||
67 | === modified file 'lib/lp/bugs/stories/bugs/xx-product-bugs-page.txt' | |||
68 | --- lib/lp/bugs/stories/bugs/xx-product-bugs-page.txt 2010-01-18 18:27:32 +0000 | |||
69 | +++ lib/lp/bugs/stories/bugs/xx-product-bugs-page.txt 2010-01-22 16:41:25 +0000 | |||
70 | @@ -131,38 +131,68 @@ | |||
71 | 131 | 131 | ||
72 | 132 | == Hot Bugs == | 132 | == Hot Bugs == |
73 | 133 | 133 | ||
76 | 134 | A listing of the 10 'hottest' bugs (currently simply the bugs most | 134 | A listing of the 10 'hottest' bugs is displayed to allow a quick |
77 | 135 | recently touched) is displayed to allow a quick overview of the project. | 135 | overview of the project. |
78 | 136 | |||
79 | 137 | To demonstrate this, we create 10 bugs and adjust their heat values manually. | ||
80 | 138 | |||
81 | 139 | >>> from zope.component import getUtility | ||
82 | 140 | >>> from canonical.launchpad.ftests import login, logout | ||
83 | 141 | >>> from lp.registry.interfaces.product import IProductSet | ||
84 | 142 | >>> import transaction | ||
85 | 143 | >>> login('foo.bar@canonical.com') | ||
86 | 144 | >>> firefox = getUtility(IProductSet).getByName("firefox") | ||
87 | 145 | >>> heat_values = [0, 400, 200, 600, 100, 50, 50, 50, 50, 50, 50, 50] | ||
88 | 146 | >>> for count in range(1, 11): | ||
89 | 147 | ... summary = 'Summary for new bug %d' % count | ||
90 | 148 | ... bug = factory.makeBug(title=summary, product=firefox) | ||
91 | 149 | ... bug.setHeat(heat_values[count]) | ||
92 | 150 | >>> transaction.commit() | ||
93 | 151 | >>> logout() | ||
94 | 152 | |||
95 | 136 | For each bug we have the number, title, status, importance and the time | 153 | For each bug we have the number, title, status, importance and the time |
96 | 137 | since the last update. | 154 | since the last update. |
97 | 138 | 155 | ||
98 | 139 | >>> anon_browser.open('http://bugs.launchpad.dev/firefox') | 156 | >>> anon_browser.open('http://bugs.launchpad.dev/firefox') |
99 | 140 | >>> print extract_text( | 157 | >>> print extract_text( |
100 | 141 | ... find_tag_by_id(anon_browser.contents, 'hot-bugs')) | 158 | ... find_tag_by_id(anon_browser.contents, 'hot-bugs')) |
111 | 142 | Summary Status Importance Last changed | 159 | Summary Status Importance Last changed |
112 | 143 | #5 Firefox install... New Critical on 2006-07-14 | 160 | #18 Summary for new bug 3 New Undecided ... |
113 | 144 | #4 Reflow problems... New Medium on 2006-07-14 | 161 | #16 Summary for new bug 1 New Undecided ... |
114 | 145 | #1 Firefox does no... New Low on 2006-05-19 | 162 | #17 Summary for new bug 2 New Undecided ... |
115 | 146 | 163 | #19 Summary for new bug 4 New Undecided ... | |
116 | 147 | 164 | #25 Summary for new bug 10 New Undecided ... | |
117 | 148 | Fix released bugs are not shown. We demonstrate this by setting the bugtask | 165 | #22 Summary for new bug 7 New Undecided ... |
118 | 149 | for bug 4 to be "Fix released". | 166 | #23 Summary for new bug 8 New Undecided ... |
119 | 150 | 167 | #24 Summary for new bug 9 New Undecided ... | |
120 | 151 | >>> from zope.component import getUtility | 168 | #20 Summary for new bug 5 New Undecided ... |
121 | 169 | #21 Summary for new bug 6 New Undecided ... | ||
122 | 170 | |||
123 | 171 | |||
124 | 172 | Fix Released bugs are not shown. We demonstrate this by setting the bugtask | ||
125 | 173 | for bug 18 to be "Fix Released". | ||
126 | 174 | |||
127 | 152 | >>> from lp.bugs.interfaces.bug import BugTaskStatus, IBugSet | 175 | >>> from lp.bugs.interfaces.bug import BugTaskStatus, IBugSet |
128 | 153 | >>> from lp.registry.interfaces.person import IPersonSet | 176 | >>> from lp.registry.interfaces.person import IPersonSet |
129 | 154 | >>> login('foo.bar@canonical.com') | 177 | >>> login('foo.bar@canonical.com') |
131 | 155 | >>> bug_4 = getUtility(IBugSet).get(4) | 178 | >>> bug_18 = getUtility(IBugSet).get(18) |
132 | 156 | >>> project_owner = getUtility(IPersonSet).getByName('name12') | 179 | >>> project_owner = getUtility(IPersonSet).getByName('name12') |
134 | 157 | >>> bug_4.bugtasks[0].transitionToStatus( | 180 | >>> bug_18.bugtasks[0].transitionToStatus( |
135 | 158 | ... BugTaskStatus.FIXRELEASED, project_owner) | 181 | ... BugTaskStatus.FIXRELEASED, project_owner) |
136 | 159 | >>> logout() | 182 | >>> logout() |
137 | 160 | 183 | ||
139 | 161 | And then reloading the page. The Fix released bug, bug 4, is no longer shown. | 184 | And then reloading the page. The Fix Released bug, bug 18, is no longer shown. |
140 | 162 | 185 | ||
141 | 163 | >>> anon_browser.reload() | 186 | >>> anon_browser.reload() |
142 | 164 | >>> print extract_text( | 187 | >>> print extract_text( |
143 | 165 | ... find_tag_by_id(anon_browser.contents, 'hot-bugs')) | 188 | ... find_tag_by_id(anon_browser.contents, 'hot-bugs')) |
147 | 166 | Summary Status Importance Last changed | 189 | Summary Status Importance Last changed |
148 | 167 | #5 Firefox install... New Critical on 2006-07-14 | 190 | #16 Summary for new bug 1 New Undecided ... |
149 | 168 | #1 Firefox does no... New Low on 2006-05-19 | 191 | #17 Summary for new bug 2 New Undecided ... |
150 | 192 | #19 Summary for new bug 4 New Undecided ... | ||
151 | 193 | #25 Summary for new bug 10 New Undecided ... | ||
152 | 194 | #22 Summary for new bug 7 New Undecided ... | ||
153 | 195 | #23 Summary for new bug 8 New Undecided ... | ||
154 | 196 | #24 Summary for new bug 9 New Undecided ... | ||
155 | 197 | #20 Summary for new bug 5 New Undecided ... | ||
156 | 198 | #21 Summary for new bug 6 New Undecided ... | ||
157 | 169 | 199 | ||
158 | === modified file 'lib/lp/bugs/templates/bugtarget-bugs.pt' | |||
159 | --- lib/lp/bugs/templates/bugtarget-bugs.pt 2010-01-20 17:26:54 +0000 | |||
160 | +++ lib/lp/bugs/templates/bugtarget-bugs.pt 2010-01-22 16:41:25 +0000 | |||
161 | @@ -95,7 +95,7 @@ | |||
162 | 95 | </ul> | 95 | </ul> |
163 | 96 | </div> | 96 | </div> |
164 | 97 | 97 | ||
166 | 98 | <tal:has_hot_bugs condition="view/hot_bugtasks"> | 98 | <tal:has_hot_bugs condition="view/hot_bugs"> |
167 | 99 | <div class="search-box"> | 99 | <div class="search-box"> |
168 | 100 | <metal:search | 100 | <metal:search |
169 | 101 | use-macro="context/@@+bugtarget-macros-search/simple-search-form" | 101 | use-macro="context/@@+bugtarget-macros-search/simple-search-form" |
170 | @@ -123,7 +123,7 @@ | |||
171 | 123 | </tr> | 123 | </tr> |
172 | 124 | </thead> | 124 | </thead> |
173 | 125 | <tbody> | 125 | <tbody> |
175 | 126 | <tr tal:repeat="bugtask view/hot_bugtasks"> | 126 | <tr tal:repeat="bugtask view/hot_bugs"> |
176 | 127 | <td class="icon left"> | 127 | <td class="icon left"> |
177 | 128 | <span tal:replace="structure bugtask/image:icon" /> | 128 | <span tal:replace="structure bugtask/image:icon" /> |
178 | 129 | </td> | 129 | </td> |
179 | @@ -148,7 +148,7 @@ | |||
180 | 148 | </table> | 148 | </table> |
181 | 149 | </tal:has_hot_bugs> | 149 | </tal:has_hot_bugs> |
182 | 150 | 150 | ||
184 | 151 | <tal:no_hot_bugs condition="not: view/hot_bugtasks"> | 151 | <tal:no_hot_bugs condition="not: view/hot_bugs"> |
185 | 152 | <p id="no-bugs-filed"><strong>There are currently no bugs filed against | 152 | <p id="no-bugs-filed"><strong>There are currently no bugs filed against |
186 | 153 | <tal:project_title replace="context/title" />.</strong></p> | 153 | <tal:project_title replace="context/title" />.</strong></p> |
187 | 154 | 154 |
This branch moves the hot_bugtasks method from the bug listing view to a hot_bugs method on a bug target view, which changes the behavior to return 10 bugs according to heat rather than recently touched bug tasks.
This change also allows us to fix Bug #442170, since the code ensures the same bug isn't shown twice. The code uses default_bugtask for display.
The "hot bugs" test in stories/ bugs/xx- product- bugs-page. txt has been updated to use factory data, rather than sample data, and to test that bugs are listed by heat.
The branch builds on a branch from Tom/Brian M. that allows sorting by heat, so the diff for my changes is pasted:
http:// pastebin. ubuntu. com/360139/