Hi Abel, Thanks for this branch. It looks good to me except for a couple of questions. Please do have a UI review too. --Brad > === modified file 'lib/lp/bugs/browser/bugtask.py' --- lib/lp/bugs/browser/bugtask.py 2010-02-03 21:11:53 +0000 > +++ lib/lp/bugs/browser/bugtask.py 2010-02-16 16:16:26 +0000 > @@ -1858,7 +1858,8 @@ > > > def get_buglisting_search_filter_url( > - assignee=None, importance=None, status=None, status_upstream=None): > + assignee=None, importance=None, status=None, status_upstream=None, > + has_patches=None): > """Return the given URL with the search parameters specified.""" > search_params = [] > > @@ -1870,6 +1871,8 @@ > search_params.append(('field.status', status)) > if status_upstream is not None: > search_params.append(('field.status_upstream', status_upstream)) > + if has_patches is not None: > + search_params.append(('field.has_patch', 'on')) > > query_string = urllib.urlencode(search_params, doseq=True) > > === modified file 'lib/lp/bugs/browser/distribution_upstream_bug_report.py' > --- lib/lp/bugs/browser/distribution_upstream_bug_report.py 2009-06-25 00:40:31 +0000 > +++ lib/lp/bugs/browser/distribution_upstream_bug_report.py 2010-02-16 16:16:26 +0000 > @@ -60,11 +60,12 @@ > BAD_THRESHOLD = 20 > > def __init__(self, open_bugs=0, triaged_bugs=0, upstream_bugs=0, > - watched_bugs=0): > + watched_bugs=0, bugs_with_upstream_patches=0): > self.open_bugs = open_bugs > self.triaged_bugs = triaged_bugs > self.upstream_bugs = upstream_bugs > self.watched_bugs = watched_bugs > + self.bugs_with_upstream_patches = bugs_with_upstream_patches > > @property > def triaged_bugs_percentage(self): > @@ -148,9 +149,9 @@ > - *_url: convenience URLs > """ > def __init__(self, dsp, dssp, product, open_bugs, triaged_bugs, > - upstream_bugs, watched_bugs): > + upstream_bugs, watched_bugs, bugs_with_upstream_patches): > BugReportData.__init__(self, open_bugs, triaged_bugs, upstream_bugs, > - watched_bugs) > + watched_bugs, bugs_with_upstream_patches) > self.dsp = dsp > self.dssp = dssp > self.product = product > @@ -235,6 +236,14 @@ > self.watched_bugs_delta_url = urlappend( > dsp_bugs_url, unwatched_bugs_search_filter_url) > > + # The bugs with upstream patches URL links to all open upstream > + # bugs that don't have a bugwatch but have patches attached. > + bugs_with_upstream_patches_filter_url = ( > + get_buglisting_search_filter_url( > + status_upstream='pending_bugwatch', has_patches=True)) > + self.bugs_with_upstream_patches_url = urlappend( > + dsp_bugs_url, bugs_with_upstream_patches_filter_url) > + > > class DistributionUpstreamBugReport(LaunchpadView): > """Implements the actual upstream bug report. > @@ -248,6 +257,7 @@ > valid_sort_keys = [ > 'bugtracker_name', > 'bug_supervisor_name', > + 'bugs_with_upstream_patches', > 'dsp', > 'open_bugs', > 'product', > @@ -344,7 +354,8 @@ > packages_to_exclude = self.context.upstream_report_excluded_packages > counts = self.context.getPackagesAndPublicUpstreamBugCounts( > limit=self.LIMIT, exclude_packages=packages_to_exclude) > - for (dsp, product, open, triaged, upstream, watched) in counts: > + for (dsp, product, open, triaged, upstream, watched, > + bugs_with_upstream_patches) in counts: > # The +edit-packaging page is only available for > # IDistributionSeriesSourcepackages, so deduce one here. If > # the distribution doesn't have series we can't offer a link > @@ -360,6 +371,7 @@ > self.total.watched_bugs += watched > > item = PackageBugReportData( > - dsp, dssp, product, open, triaged, upstream, watched) > + dsp, dssp, product, open, triaged, upstream, watched, > + bugs_with_upstream_patches) > self._data.append(item) > > === modified file 'lib/lp/bugs/doc/distribution-upstream-bug-report.txt' > --- lib/lp/bugs/doc/distribution-upstream-bug-report.txt 2009-10-16 20:33:56 +0000 > +++ lib/lp/bugs/doc/distribution-upstream-bug-report.txt 2010-02-16 16:16:26 +0000 > @@ -131,20 +131,56 @@ > >>> task = getUtility(IBugTaskSet).createTask(bug, name12, product=pmount) > >>> Store.of(task).flush() > >>> print_report(ubuntu.getPackagesAndPublicUpstreamBugCounts(limit=3)) > - pmount pmount 2 2 1 0 > - linux-source-2.6.15 None 1 0 0 0 > - mozilla-firefox firefox 1 1 1 1 > - > -Linking that task to a bugwatch makes the watch counts update: > + pmount pmount 2 2 1 0 0 > + linux-source-2.6.15 None 1 0 0 0 0 > + mozilla-firefox firefox 1 1 1 1 0 > + > +The last column counts those bugs with upstream tasks that have patches > +attached but which don't have an upstream bugwatch. If we add a ordinary > +attachment to our pmount bug, the value of the last column does not > +change... > + > + >>> attachment = factory.makeBugAttachment(bug) > + >>> print_report(ubuntu.getPackagesAndPublicUpstreamBugCounts(limit=3)) > + pmount pmount 2 2 1 0 0 > + linux-source-2.6.15 None 1 0 0 0 0 > + mozilla-firefox firefox 1 1 1 1 0 > + > +...but when we make this attachment a patch, the value of the column > +increases. > + > + >>> from lp.bugs.interfaces.bugattachment import BugAttachmentType > + >>> attachment.type = BugAttachmentType.PATCH > + >>> Store.of(attachment).flush() > + >>> print_report(ubuntu.getPackagesAndPublicUpstreamBugCounts(limit=3)) > + pmount pmount 2 2 1 0 1 > + linux-source-2.6.15 None 1 0 0 0 0 > + mozilla-firefox firefox 1 1 1 1 0 > + > +Note that we count only bugs with patches for products that do not > +use Malone officially. > + > + >>> pmount.official_malone = True > + >>> Store.of(pmount).flush() > + >>> print_report(ubuntu.getPackagesAndPublicUpstreamBugCounts(limit=3)) > + pmount pmount 2 2 1 1 0 > + linux-source-2.6.15 None 1 0 0 0 0 > + mozilla-firefox firefox 1 1 1 1 0 I find having a '0' to be misleading. Would not using a '-' or some other indicator to show the data are not relevant be more appropriate? > + >>> pmount.official_malone = False > + >>> Store.of(pmount).flush() > + > +Linking that task to a bugwatch increases the watch counts and decreases > +the count of bugs having patches but no bug watch. > > >>> url = "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666" > >>> [watch] = getUtility(IBugWatchSet).fromText(url, bug, name12) > >>> task.bugwatch = watch > >>> sync(task) > >>> print_report(ubuntu.getPackagesAndPublicUpstreamBugCounts(limit=3)) > - pmount pmount 2 2 1 1 > - linux-source-2.6.15 None 1 0 0 0 > - mozilla-firefox firefox 1 1 1 1 > + pmount pmount 2 2 1 1 0 > + linux-source-2.6.15 None 1 0 0 0 0 > + mozilla-firefox firefox 1 1 1 1 0 > > > Properties of BugReportData > @@ -488,6 +524,7 @@ > > >>> print_sort_order_links(view) > bug_supervisor_name http://...?sort_by=bug_supervisor_name > + bugs_with_upstream_patches http:...?sort_by=bugs_with_upstream_patches > bugtracker_name http://...?sort_by=bugtracker_name > dsp http://...?sort_by=dsp > open_bugs http://...?sort_by=open_bugs > @@ -517,6 +554,7 @@ > > >>> print_sort_order_links(view) > bug_supervisor_name http://...?sort_by=-bug_supervisor_name > + bugs_with_upstream_patches http:...?sort_by=bugs_with_upstream_patches > bugtracker_name http://...?sort_by=bugtracker_name... > > Each sort_order_links dict has an 'arrow' key. This is the URL of the > @@ -524,6 +562,7 @@ > > >>> print_sort_order_links(view, 'arrow') > bug_supervisor_name /@@/arrowUp > + bugs_with_upstream_patches /@@/arrowBlank > bugtracker_name /@@/arrowBlank > dsp /@@/arrowBlank > open_bugs /@@/arrowBlank > @@ -552,6 +591,7 @@ > > >>> print_sort_order_links(view, 'arrow') > bug_supervisor_name /@@/arrowDown > + bugs_with_upstream_patches /@@/arrowBlank > bugtracker_name /@@/arrowBlank... > > >>> form = {'sort_by': '-bugtracker_name'} > @@ -562,6 +602,7 @@ > > >>> print_sort_order_links(view, 'arrow') > bug_supervisor_name /@@/arrowBlank > + bugs_with_upstream_patches /@@/arrowBlank > bugtracker_name /@@/arrowDown... > > PS: This page is actually browser-tested in pagetests.distribution- > === modified file 'lib/lp/bugs/stories/distribution/xx-distribution-upstream-bug-report.txt' > --- lib/lp/bugs/stories/distribution/xx-distribution-upstream-bug-report.txt 2010-01-23 14:17:49 +0000 > +++ lib/lp/bugs/stories/distribution/xx-distribution-upstream-bug-report.txt 2010-02-16 16:16:26 +0000 > @@ -43,11 +43,11 @@ > >>> table = find_tag_by_id(browser.contents, 'upstream-report-content') > >>> print extract_text(table, True) > linux-source-2.6.15 Missing corresponding project. (find) (link) > - 2 2 100.00 0 2 100.00 0 1 50.00 1 > + 2 2 100.00 0 2 100.00 0 1 50.00 1 0 > mozilla-firefox Mozilla Firefox Launchpad Unspecified > 1 1 100.00 0 1 100.00 0 > thunderbird Missing corresponding project. (find) (link) > - 1 1 100.00 0 1 100.00 0 1 100.00 0 > + 1 1 100.00 0 1 100.00 0 1 100.00 0 0 > > XXX kiko 2008-02-01 bug=188020: One thing to note from the counts above > is that while the linux-source/tomcat task is counted as pending a > @@ -58,7 +58,7 @@ > > >>> table = find_tag_by_id(browser.contents, 'upstream-report-totals') > >>> print extract_text(table) > - Totals: 4 4 100.00 0 4 100.00 0 3 75.00 1 > + Totals: 4 4 100.00 0 4 100.00 0 3 75.00 1 0 > > This 3 in the watched column is caused by a problem similar to the > above; if you do a count of the values in the cells it would be 2, of > @@ -254,11 +254,27 @@ > >>> table = find_tag_by_id(browser.contents, 'upstream-report-content') > >>> print extract_text(table, True) > linux-source-2.6.15 Missing corresponding project. (find) (link) > - 2 2 100.00 0 2 100.00 0 0 0.00 2 > - mozilla-firefox Mozilla Firefox The Mozilla.org Bug Tracker Unspecified > - 1 1 100.00 0 1 100.00 0 0 0.00 1 > - thunderbird Missing corresponding project. (find) (link) > - 1 1 100.00 0 1 100.00 0 1 100.00 0 > + 2 2 100.00 0 2 100.00 0 0 0.00 2 0 > + mozilla-firefox Mozilla Firefox The Mozilla.org Bug Tracker Unspecified > + 1 1 100.00 0 1 100.00 0 0 0.00 1 0 > + thunderbird Missing corresponding project. (find) (link) > + 1 1 100.00 0 1 100.00 0 1 100.00 0 0 > + > +If we now add an attachment to the bug we created earlier, the number > +of bugs with patches for upstream increases for linux-source-2.6.15. > + > + >>> login('