Merge lp:~andrea.corbellini/launchpad/bug-630302 into lp:launchpad

Proposed by Andrea Corbellini
Status: Work in progress
Proposed branch: lp:~andrea.corbellini/launchpad/bug-630302
Merge into: lp:launchpad
Diff against target: 92 lines (+39/-0)
3 files modified
lib/lp/registry/browser/person.py (+22/-0)
lib/lp/registry/stories/person/xx-person-home.txt (+12/-0)
lib/lp/registry/templates/person-portlet-contact-details.pt (+5/-0)
To merge this branch: bzr merge lp:~andrea.corbellini/launchpad/bug-630302
Reviewer Review Type Date Requested Status
Robert Collins (community) Needs Fixing
Curtis Hovey (community) Needs Information
Review via email: mp+44061@code.launchpad.net

Description of the change

This is my attempt to fix bug #630302. I've set up a new URL: lp.net/people/+id/<person-id> that redirects to the person's homepage (e.g. lp.net/~name). <person-id> is the hexadecimal representation of the ID of the person.

The permalink is shown on the person's homepage, under "User information".

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

I am not certain of this approach. Who advised it? I think Bug #630302 is a dupe of bug #655565 which cites several issues regarding the use of Person.id.

review: Needs Information
Revision history for this message
Andrea Corbellini (andrea.corbellini) wrote :

Hi. I though this was an easy fix, so I didn't have a pre-imp chat with anybody. Thank you for having pointed me to bug #655565: it shows many important use cases for this feature.

About the issues regarding Person.id, I can't find them. I have no problems to add a new database column "public_id" if needed, but I'd like to know the nature of such issues, just to be sure to avoid them.

Solved the Person.id problem, here's what I'm willing to do with this branch, if you agree:

* Expand my work to the API: adding the redirect, creating a new method "people.getById()" (or similar), adding a new attribute "person.id".
* Remove the "Permalink" <dl> from people pages.

Revision history for this message
Curtis Hovey (sinzui) wrote :

I think people.getById() should return if Person.merged is None. Otherwise, it needs to enter a recursive call to get an unmerged person.
    if person.merged is None:
        return person
    else:
        return people.getById(person.merged)

Suspension and deactivation are not permanent. This case is ambiguous and I do not think it should block this branch.

I wonder if this should return None of the person is a team? Teams are deleted by merging them with ~registry. There are hundreds of deleted teams that will ultimately return ~registry.

Supporting the merge case is probably all we needs to do to close this bug.

Revision history for this message
Robert Collins (lifeless) wrote :

This branch has a functional defect:
 - the redirect will OOPS if the resulting url is unusable for any reason (e.g. merged, suspended, deactivated).

Stylistically I think that showing the permalink in the homepage is cruft and irrelevant for most people.

So I propose the following to make it landable:
 - add tests that getting the permalink *as a normal unprivileged user* returns a 404 for the following cases:
  - private teams/persons
  - suspended users
  - deactivated users
  - deleted teams
  - deleted persons
 - add tests that getting the permalink as a user which can see a private team returns the current ~foo url in a redirect (302)
 - Add tests that getting the permalink as a normal unprivileged user returns the current ~foo url in a 302 when the (person,team) has been merged.

There may be data model limits making deleted teams impossible to handle (because that is implemented as a merge) - if so thats fine, lets make sure there is a bug about that and ignore it for this branch.

Secondly, export the permalink attribute on the API in the 'devel' version. You can choose to export more, but with its removal from the users homepage we need to supply some way to access it.

Lastly please remove it from the users homepage for now (unless Curtis or Huw jump in and say I'm wrong about this aspect).

I'm going to put this back in WIP for now, but I think the things I'm asking for here are a pretty small amount of work, and will prevent us having critical bugs shortly after landing this.

review: Needs Fixing

Unmerged revisions

12092. By Andrea Corbellini

Add the tests.

12091. By Andrea Corbellini

Show the permalink on the person homepage.

12090. By Andrea Corbellini

Handle the people/+id/123 redirect.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/browser/person.py'
2--- lib/lp/registry/browser/person.py 2010-12-17 15:01:53 +0000
3+++ lib/lp/registry/browser/person.py 2010-12-17 15:36:18 +0000
4@@ -204,6 +204,8 @@
5 from canonical.launchpad.webapp.login import logoutPerson
6 from canonical.launchpad.webapp.menu import get_current_view
7 from canonical.launchpad.webapp.publisher import LaunchpadView
8+from canonical.launchpad.webapp.url import urlappend
9+from canonical.launchpad.webapp.vhosts import allvhosts
10 from canonical.lazr.utils import smartquote
11 from canonical.widgets import (
12 LaunchpadDropdownWidget,
13@@ -306,6 +308,7 @@
14 Milestone,
15 milestone_sort_key,
16 )
17+from lp.registry.model.person import Person
18 from lp.services.fields import LocationField
19 from lp.services.geoip.interfaces import IRequestPreferredLanguages
20 from lp.services.openid.adapters.openid import CurrentOpenIDEndPoint
21@@ -778,6 +781,18 @@
22 return self.redirectSubTree(
23 canonical_url(person, request=self.request))
24
25+ @stepthrough('+id')
26+ def redirect_id(self, person_id_hex):
27+ """Redirect to the canonical_url of the person with the given ID."""
28+ try:
29+ person_id = int(person_id_hex, 16)
30+ except ValueError:
31+ raise NotFoundError
32+ person = Person.selectOne(Person.q.id == person_id)
33+ if person:
34+ return self.redirectSubTree(canonical_url(person))
35+ raise NotFoundError
36+
37 @stepto('+me')
38 def me(self):
39 me = getUtility(ILaunchBag).user
40@@ -2863,6 +2878,13 @@
41 return formatter(content).text_to_html()
42
43 @cachedproperty
44+ def permalink(self):
45+ """Return the permalink that points to this account."""
46+ rooturl = allvhosts.configs['mainsite'].rooturl
47+ link = 'people/+id/%x' % self.context.id
48+ return urlappend(rooturl, link)
49+
50+ @cachedproperty
51 def recently_approved_members(self):
52 members = self.context.getMembersByStatus(
53 TeamMembershipStatus.APPROVED,
54
55=== modified file 'lib/lp/registry/stories/person/xx-person-home.txt'
56--- lib/lp/registry/stories/person/xx-person-home.txt 2010-08-27 22:40:36 +0000
57+++ lib/lp/registry/stories/person/xx-person-home.txt 2010-12-17 15:36:18 +0000
58@@ -138,6 +138,18 @@
59 English
60
61
62+Permalink
63+---------
64+
65+Each person has a permalink, which is shown on the homepage and is
66+visible by everybody:
67+
68+ >>> browser.open('http://launchpad.dev/~name16')
69+ >>> print extract_text(find_tag_by_id(browser.contents, 'permalink'))
70+ Permalink:
71+ http://launchpad.dev/people/+id/10
72+
73+
74 Summary Pagelets
75 ----------------
76
77
78=== modified file 'lib/lp/registry/templates/person-portlet-contact-details.pt'
79--- lib/lp/registry/templates/person-portlet-contact-details.pt 2010-12-01 22:05:51 +0000
80+++ lib/lp/registry/templates/person-portlet-contact-details.pt 2010-12-17 15:36:18 +0000
81@@ -200,6 +200,11 @@
82 tal:content="context/karma">342</a>
83 </dd>
84 </dl>
85+
86+ <dl id="permalink">
87+ <dt>Permalink:</dt>
88+ <dd tal:content="view/permalink">None</dd>
89+ </dl>
90 </div>
91
92 </div>