← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wallyworld/launchpad/person-related-artifact-counts-206917 into lp:launchpad

 

Ian Booth has proposed merging lp:~wallyworld/launchpad/person-related-artifact-counts-206917 into lp:launchpad with lp:~wallyworld/launchpad/person-related-software-timeout-735972 as a prerequisite.

Commit message:
Replace bug/question/blueprint counts with icons on the person related software page; remove the related project info from the page.

Requested reviews:
  Curtis Hovey (sinzui)
Related bugs:
  Bug #206917 in Launchpad itself: "Bugs/Blueprints/Questions counts are odd on "related projects" page"
  https://bugs.launchpad.net/launchpad/+bug/206917
  Bug #253977 in Launchpad itself: "Related software page includes things that aren't software"
  https://bugs.launchpad.net/launchpad/+bug/253977

For more details, see:
https://code.launchpad.net/~wallyworld/launchpad/person-related-artifact-counts-206917/+merge/130934

== Implementation ==

Two issues are addressed to reduce the SQL needed to load the person related software page:
- remove the related projects table from the related software page; there is now a link on the person index page to get to it and there's also still the link on the related projects page
- the bug/question/blueprint links are rendered as icons rather than counts (which are somewhat meaningless)

See the 2 linked bugs for justification.

The above almost halves the query count to populate the related software page.

== Demo and QA ==

Screenshots of selected new related software pages:

http://people.canonical.com/~ianb/related-software.png
http://people.canonical.com/~ianb/uploaded-packages.png

== Tests ==

Existing tests were tweaked to account for the new page content.

== Lint ==

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/registry/browser/configure.zcml
  lib/lp/registry/browser/person.py
  lib/lp/registry/browser/tests/test_person.py
  lib/lp/registry/stories/person/xx-person-projects.txt
  lib/lp/registry/templates/person-index.pt
  lib/lp/registry/templates/person-macros.pt
  lib/lp/registry/templates/person-related-projects.pt
  lib/lp/registry/templates/person-related-software.pt
  lib/lp/soyuz/stories/soyuz/xx-person-packages.txt


-- 
https://code.launchpad.net/~wallyworld/launchpad/person-related-artifact-counts-206917/+merge/130934
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.
=== modified file 'lib/lp/registry/browser/configure.zcml'
--- lib/lp/registry/browser/configure.zcml	2012-10-16 15:12:09 +0000
+++ lib/lp/registry/browser/configure.zcml	2012-10-23 07:41:26 +0000
@@ -930,7 +930,7 @@
         <browser:renamed-page
             for="lp.registry.interfaces.person.IPerson"
             name="+projects"
-            new_name="+related-software"/>
+            new_name="+related-projects"/>
         <browser:pages
             for="lp.registry.interfaces.person.IPerson"
             permission="zope.Public"

=== modified file 'lib/lp/registry/browser/person.py'
--- lib/lp/registry/browser/person.py	2012-10-23 07:41:26 +0000
+++ lib/lp/registry/browser/person.py	2012-10-23 07:41:26 +0000
@@ -113,7 +113,6 @@
 from lp import _
 from lp.answers.browser.questiontarget import SearchQuestionsView
 from lp.answers.enums import QuestionParticipation
-from lp.answers.interfaces.questioncollection import IQuestionSet
 from lp.answers.interfaces.questionsperson import IQuestionsPerson
 from lp.app.browser.launchpadform import (
     action,
@@ -3423,11 +3422,8 @@
     failed_builds = None
     needs_building = None
 
-    def __init__(self, object, open_bugs, open_questions,
-                 failed_builds, needs_building):
+    def __init__(self, object, failed_builds, needs_building):
         self.context = object
-        self.open_bugs = open_bugs
-        self.open_questions = open_questions
         self.failed_builds = failed_builds
         self.needs_building = needs_building
 
@@ -3668,28 +3664,12 @@
 
     def _addStatsToPackages(self, package_releases):
         """Add stats to the given package releases, and return them."""
-        distro_packages = [
-            package_release.distrosourcepackage
-            for package_release in package_releases]
-        package_bug_counts = getUtility(IBugTaskSet).getBugCountsForPackages(
-            self.user, distro_packages)
-        open_bugs = {}
-        for bug_count in package_bug_counts:
-            distro_package = bug_count['package']
-            open_bugs[distro_package] = bug_count['open']
-
-        question_set = getUtility(IQuestionSet)
-        package_question_counts = question_set.getOpenQuestionCountByPackages(
-            distro_packages)
-
         builds_by_package, needs_build_by_package = self._calculateBuildStats(
             package_releases)
 
         return [
             SourcePackageReleaseWithStats(
-                package, open_bugs[package.distrosourcepackage],
-                package_question_counts[package.distrosourcepackage],
-                builds_by_package[package],
+                package, builds_by_package[package],
                 needs_build_by_package[package])
             for package in package_releases]
 
@@ -3698,30 +3678,12 @@
         filtered_spphs = [
             spph for spph in publishings if
             check_permission('launchpad.View', spph)]
-        distro_packages = [
-            spph.meta_sourcepackage.distribution_sourcepackage
-            for spph in filtered_spphs]
-        package_bug_counts = getUtility(IBugTaskSet).getBugCountsForPackages(
-            self.user, distro_packages)
-        open_bugs = {}
-        for bug_count in package_bug_counts:
-            distro_package = bug_count['package']
-            open_bugs[distro_package] = bug_count['open']
-
-        question_set = getUtility(IQuestionSet)
-        package_question_counts = question_set.getOpenQuestionCountByPackages(
-            distro_packages)
-
         builds_by_package, needs_build_by_package = self._calculateBuildStats(
             [spph.sourcepackagerelease for spph in filtered_spphs])
 
         return [
             SourcePackagePublishingHistoryWithStats(
-                spph,
-                open_bugs[spph.meta_sourcepackage.distribution_sourcepackage],
-                package_question_counts[
-                    spph.meta_sourcepackage.distribution_sourcepackage],
-                builds_by_package[spph.sourcepackagerelease],
+                spph, builds_by_package[spph.sourcepackagerelease],
                 needs_build_by_package[spph.sourcepackagerelease])
             for spph in filtered_spphs]
 

=== modified file 'lib/lp/registry/browser/tests/test_person.py'
--- lib/lp/registry/browser/tests/test_person.py	2012-09-06 00:01:38 +0000
+++ lib/lp/registry/browser/tests/test_person.py	2012-10-23 07:41:26 +0000
@@ -73,7 +73,7 @@
 from lp.testing.pages import (
     extract_text,
     setupBrowserForUser,
-    )
+    find_tags_by_class)
 from lp.testing.views import (
     create_initialized_view,
     create_view,
@@ -924,8 +924,12 @@
         expected_base = '/%s/+source/%s' % (
             self.spph.distroseries.distribution.name,
             self.spph.source_package_name)
-        self.assertIn('<a href="%s/+bugs">' % expected_base, html)
-        self.assertIn('<a href="%s/+questions">' % expected_base, html)
+        bugs_link = find_tags_by_class(html, 'sprite bug action-icon', True)
+        self.assertEqual('%s/+bugs' % expected_base, bugs_link.get('href'))
+        questions_link = find_tags_by_class(
+            html, 'sprite question action-icon', True)
+        self.assertEqual(
+            '%s/+questions' % expected_base, questions_link.get('href'))
 
 
 class TestPersonPPAPackagesView(TestCaseWithFactory):

=== modified file 'lib/lp/registry/stories/person/xx-person-projects.txt'
--- lib/lp/registry/stories/person/xx-person-projects.txt	2010-08-13 14:00:31 +0000
+++ lib/lp/registry/stories/person/xx-person-projects.txt	2012-10-23 07:41:26 +0000
@@ -18,24 +18,23 @@
 
     >>> anon_browser.getLink('Show related projects').click()
     >>> print anon_browser.title
-    Related software : ...Ubuntu Team... team
+    Related projects : ...Ubuntu Team... team
 
     >>> related_projects = find_tag_by_id(
     ...     anon_browser.contents, 'related-projects')
     >>> print extract_text(related_projects)
     Name            Bugs    Blueprints  Questions
-    Ubuntu Linux    4       1           8
-    Ubuntu Test     0       0           0
-    Tomcat          1       0           0
+    Ubuntu Linux
+    Ubuntu Test
+    Tomcat
 
-    >>> print anon_browser.getLink('4').url
+    >>> bugs_links = find_tags_by_class(
+    ...     anon_browser.contents, 'sprite bug action-icon')
+    >>> for b in bugs_links:
+    ...     print b.get('href')
     http://launchpad.dev/ubuntu/+bugs
-
-    >>> print anon_browser.getLink('1').url
-    http://launchpad.dev/ubuntu/+specs
-
-    >>> print anon_browser.getLink('8').url
-    http://launchpad.dev/ubuntu/+questions
+    http://launchpad.dev/ubuntutest/+bugs
+    http://launchpad.dev/tomcat/+bugs
 
 A person's projects are listed on the 'Related software' page,
 accessible through the main navigation menu.
@@ -47,23 +46,44 @@
     >>> print anon_browser.title
     Related software : Mark Shuttleworth
 
-In the case of a person that owns/drives more than
-config.launchpad.default_batch_size, a message is displayed and the
-table contains only that many projects. This is done to handle the
-Registry Admins case which owns lots of projects and the page would
-become a performance nightmare. In 99% of the cases, people won't reach
-the config.launchpad.default_batch_size threshold.
-
-    >>> print extract_text(
-    ...     find_tag_by_id(anon_browser.contents, 'limit-encountered'))
-    Displaying first 5 projects out of 7 total
-
+    >>> anon_browser.open('http://launchpad.dev/~mark')
+    >>> anon_browser.getLink('Related projects').click()
     >>> related_projects = find_tag_by_id(
     ...     anon_browser.contents, 'related-projects')
     >>> print extract_text(related_projects)
     Name                            Bugs    Blueprints  Questions
-    Debian GNU/Linux                3       0           0
-    The Gentoo Linux                0       0           0
-    Kubuntu - Free KDE-based Linux  0       4           0
-    Redhat Advanced Server          0       0           0
-    Apache                          1       0           0
+    Debian GNU/Linux
+    The Gentoo Linux
+    Kubuntu - Free KDE-based Linux
+    Redhat Advanced Server
+    Apache
+
+    >>> bugs_links = find_tags_by_class(
+    ...     anon_browser.contents, 'sprite bug action-icon')
+    >>> for b in bugs_links:
+    ...     print b.get('href')
+    http://launchpad.dev/debian/+bugs
+    http://launchpad.dev/gentoo/+bugs
+    http://launchpad.dev/kubuntu/+bugs
+    http://launchpad.dev/redhat/+bugs
+    http://launchpad.dev/apache/+bugs
+
+    >>> question_links = find_tags_by_class(
+    ...     anon_browser.contents, 'sprite question action-icon')
+    >>> for q in question_links:
+    ...     print q.get('href')
+    http://launchpad.dev/debian/+questions
+    http://launchpad.dev/gentoo/+questions
+    http://launchpad.dev/kubuntu/+questions
+    http://launchpad.dev/redhat/+questions
+    http://launchpad.dev/apache/+questions
+
+    >>> spec_links = find_tags_by_class(
+    ...     anon_browser.contents, 'sprite blueprint action-icon')
+    >>> for s in spec_links:
+    ...     print s.get('href')
+    http://launchpad.dev/debian/+specs
+    http://launchpad.dev/gentoo/+specs
+    http://launchpad.dev/kubuntu/+specs
+    http://launchpad.dev/redhat/+specs
+    http://launchpad.dev/apache/+specs

=== modified file 'lib/lp/registry/templates/person-index.pt'
--- lib/lp/registry/templates/person-index.pt	2012-08-14 23:19:36 +0000
+++ lib/lp/registry/templates/person-index.pt	2012-10-23 07:41:26 +0000
@@ -72,6 +72,13 @@
         </a>
       </li>
       <li
+        tal:define="link context/menu:overview/projects"
+        tal:condition="link/enabled">
+        <a class="sprite info" tal:attributes="href link/fmt:url">
+          Related projects
+        </a>
+      </li>
+      <li
         tal:define="link context/menu:overview/oauth_tokens"
         tal:condition="link/enabled"
         tal:content="structure link/fmt:link" />

=== modified file 'lib/lp/registry/templates/person-macros.pt'
--- lib/lp/registry/templates/person-macros.pt	2012-08-13 20:07:00 +0000
+++ lib/lp/registry/templates/person-macros.pt	2012-10-23 07:41:26 +0000
@@ -167,14 +167,14 @@
           </tal:not_failed>
       </tal:built>
     </td>
-    <td style="text-align: right">
+    <td>
       <a tal:attributes="href string:${spr/distrosourcepackage/fmt:url}/+bugs"
-         tal:content="spr/open_bugs">
+         class="sprite bug action-icon">
       </a>
     </td>
-    <td style="text-align: right">
+    <td>
       <a tal:attributes="href string:${spr/distrosourcepackage/fmt:url}/+questions"
-         tal:content="spr/open_questions">
+         class="sprite question action-icon">
       </a>
     </td>
   </tal:define>
@@ -228,14 +228,14 @@
           </tal:not_failed>
       </tal:built>
     </td>
-    <td style="text-align: right">
+    <td>
       <a tal:attributes="href string:${spph/meta_sourcepackage/distribution_sourcepackage/fmt:url}/+bugs"
-         tal:content="spph/open_bugs">
+         class="sprite bugs action-icon">
       </a>
     </td>
-    <td style="text-align: right">
+    <td>
       <a tal:attributes="href string:${spph/meta_sourcepackage/distribution_sourcepackage/fmt:url}/+questions"
-         tal:content="spph/open_questions">
+         class="sprite question action-icon">
       </a>
     </td>
   </tal:define>

=== modified file 'lib/lp/registry/templates/person-related-projects.pt'
--- lib/lp/registry/templates/person-related-projects.pt	2012-06-11 00:47:38 +0000
+++ lib/lp/registry/templates/person-related-projects.pt	2012-10-23 07:41:26 +0000
@@ -46,19 +46,19 @@
                tal:content="project/title">
             </a>
           </td>
-          <td style="text-align: right">
+          <td>
             <a tal:attributes="href string:${project/url}/+bugs"
-               tal:content="project/bug_count">
+               class="sprite bug action-icon">
             </a>
           </td>
-          <td style="text-align: right">
+          <td>
             <a tal:attributes="href string:${project/url}/+specs"
-               tal:content="project/spec_count">
+               class="sprite blueprint action-icon">
             </a>
           </td>
-          <td style="text-align: right">
+          <td>
             <a tal:attributes="href string:${project/url}/+questions"
-               tal:content="project/question_count">
+               class="sprite question action-icon">
             </a>
           </td>
         </tr>

=== modified file 'lib/lp/registry/templates/person-related-software.pt'
--- lib/lp/registry/templates/person-related-software.pt	2011-09-23 07:49:54 +0000
+++ lib/lp/registry/templates/person-related-software.pt	2012-10-23 07:41:26 +0000
@@ -89,8 +89,6 @@
         <th>Version</th>
         <th>When</th>
         <th>Failures</th>
-        <th>Bugs</th>
-        <th>Questions</th>
       </tr>
     </thead>
 
@@ -127,55 +125,6 @@
 
   </div><!--id packages-->
 
-  <div id="projects" class="top-portlet">
-    <a name="projects" />
-    <h2>Related projects</h2>
-
-    <span id="limit-encountered"
-          tal:content="view/projects_header_message" />
-    <table tal:define="projects view/related_projects"
-           tal:condition="projects"
-           class="listing"
-           id="related-projects">
-      <thead>
-        <tr>
-          <th>Name</th>
-          <th>Bugs</th>
-          <th>Blueprints</th>
-          <th>Questions</th>
-        </tr>
-      </thead>
-
-      <tbody>
-        <tr tal:repeat="project projects">
-          <td>
-            <a tal:attributes="href project/url"
-               tal:content="project/title">
-            </a>
-          </td>
-          <td style="text-align: right">
-            <a tal:attributes="href string:${project/url}/+bugs"
-               tal:content="project/bug_count">
-            </a>
-          </td>
-          <td style="text-align: right">
-            <a tal:attributes="href string:${project/url}/+specs"
-               tal:content="project/spec_count">
-            </a>
-          </td>
-          <td style="text-align: right">
-            <a tal:attributes="href string:${project/url}/+questions"
-               tal:content="project/question_count">
-            </a>
-          </td>
-        </tr>
-      </tbody>
-    </table>
-    <p tal:condition="not: view/related_projects">
-      <span tal:replace="context/title">Foo Bar</span>
-      doesn't own or drive any projects.
-    </p>
-  </div>
 </div>
 
 <metal:macros fill-slot="bogus">
@@ -219,8 +168,6 @@
           </tal:block>
       </tal:block>
     </td>
-    <td style="text-align: right">-</td>
-    <td style="text-align: right">-</td>
   </tal:block>
   </tr>
 </metal:macro>

=== modified file 'lib/lp/soyuz/stories/soyuz/xx-person-packages.txt'
--- lib/lp/soyuz/stories/soyuz/xx-person-packages.txt	2012-08-19 00:32:32 +0000
+++ lib/lp/soyuz/stories/soyuz/xx-person-packages.txt	2012-10-23 07:41:26 +0000
@@ -96,9 +96,20 @@
     1...5 of 7 results
     ...
     Name        Uploaded to  Version   When        Failures   Bugs  Questions
-    alsa-utils  Debian Sid   1.0.9a-4  2005-07-01  None       0     0
+    alsa-utils  Debian Sid   1.0.9a-4  2005-07-01  None
     ...
 
+    >>> bug_link = find_tags_by_class(
+    ...     browser.contents, 'sprite bug action-icon', True)
+    >>> print bug_link.get('href')
+    /debian/+source/alsa-utils/+bugs
+
+    >>> question_link = find_tags_by_class(
+    ...     browser.contents, 'sprite question action-icon', True)
+    >>> print question_link.get('href')
+    /debian/+source/alsa-utils/+questions
+
+
 The Maintained packages page only has data if the person or team has
 maintained packages to show. No-priv does not maintain packages.
 
@@ -121,9 +132,20 @@
     1...5 of 6 results
     ...
     Name    Uploaded to          Version When        Failures  Bugs Questions
-    foobar  Ubuntu Breezy-autotest  1.0  2006-12-01  i386      0    0
+    foobar  Ubuntu Breezy-autotest  1.0  2006-12-01  i386
     ...
 
+    >>> bug_link = find_tags_by_class(
+    ...     browser.contents, 'sprite bug action-icon', True)
+    >>> print bug_link.get('href')
+    /ubuntu/+source/foobar/+bugs
+
+    >>> question_link = find_tags_by_class(
+    ...     browser.contents, 'sprite question action-icon', True)
+    >>> print question_link.get('href')
+    /ubuntu/+source/foobar/+questions
+
+
 The navigation link to "PPA packages" takes the user to the
 page that lists PPA packages in batches.
 
@@ -221,14 +243,14 @@
     >>> user_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(user_browser)
     source1 PPA for Celso Providelo - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
 The not logged-in (anonymous) user's case:
 
     >>> anon_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(anon_browser)
     source1 PPA for Celso Providelo - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
 However no-priv himself and any Launchpad Administrator can still see
 both packages:
@@ -237,16 +259,16 @@
     >>> nopriv_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(nopriv_browser)
     source1 PPA for Celso Providelo - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
     source2 PPA named p3a for No Priv... Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
     >>> admin_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(admin_browser)
     source1 PPA for Celso Providelo - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
     source2 PPA named p3a for No Priv... Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
 Let's move the publication of source1 from mark's public archive to his
 private one and the view the page again.
@@ -261,12 +283,12 @@
     >>> user_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(user_browser)
     source1 PPA for Celso Providelo - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
     >>> anon_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(anon_browser)
     source1 PPA for Celso Providelo - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
 Notice that the source1 package is still appearing because it is also
 published in some non-private archives, which override the private nature
@@ -309,12 +331,12 @@
     >>> user_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(user_browser)
     source1 PPA named p3a for Celso... - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
     >>> anon_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(anon_browser)
     source1 PPA named p3a for Celso... - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
 Even after the package is superseded, the package remains visibile in
 the listings.
@@ -327,12 +349,12 @@
     >>> user_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(user_browser)
     source1 PPA named p3a for Celso... - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
     >>> anon_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(anon_browser)
     source1 PPA named p3a for Celso... - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
 
 Packages deleted from a PPA
@@ -348,9 +370,9 @@
     >>> admin_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(admin_browser)
     source1 PPA named p3a for Celso... - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
     source2 PPA named p3a for No Priv... - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
 Then delete the 'source2' package.
 
@@ -384,9 +406,9 @@
     >>> admin_browser.open("http://launchpad.dev/~cprov/+related-software";)
     >>> print_ppa_rows(admin_browser)
     source1 PPA named p3a for Celso... - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
     source2 PPA named p3a for No Priv... - Ubuntutest Breezy-autotest 666
-        ...ago None - -
+        ...ago None
 
 Please note also that disabled archives are not viewable by anonymous users.
 


Follow ups