Merge lp:~barry/launchpad/430065-person into lp:launchpad
- 430065-person
- Merge into devel
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~barry/launchpad/430065-person |
Merge into: | lp:launchpad |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~barry/launchpad/430065-person |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brad Crittenden (community) | code | Approve | |
Curtis Hovey | code | Pending | |
Review via email: mp+11935@code.launchpad.net |
Commit message
Description of the change
Barry Warsaw (barry) wrote : | # |
Brad Crittenden (bac) wrote : | # |
Hi Barry,
The changes look good. Thanks for taking the time to make a lot of drive-by fixes.
I've got a few questions below.
--Brad
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -4086,6 +4086,8 @@
> custom_
> LaunchpadRadioW
>
> + label = 'Change your e-mail settings'
> +
> def initialize(self):
> if self.context.
> # +editemails is not available on teams.
> @@ -4191,13 +4193,11 @@
> which the user is subscribed to this mailing list.
> """
> subscription = mailing_
> - if subscription is not None:
> - if subscription.
> - return "Preferred address"
> - else:
> - return subscription.
> - else:
> + if subscription is None:
> return "Don't subscribe"
> + if subscription.
Hmm, I'd have used an elif.
> + return 'Preferred address'
> + return subscription.
>
> def _mailing_
> """Creates a field for each mailing list the user can subscribe to.
> @@ -4233,8 +4235,22 @@
> @property
> def mailing_
> """Return all the mailing list subscription widgets."""
> - return [widget for widget in self.widgets
> - if 'field.
> + mailing_list_set = getUtility(
> + widgets = []
> + for widget in self.widgets:
> + if 'field.
Why not use 'startswith'? Can it really be anywhere in the name?
> + team_name = widget.label
> + mailing_list = mailing_
> + assert mailing_list is not None, 'Missing mailing list'
> + widget_dict = dict(
> + team=mailing_
> + widget=widget,
> + )
> + widgets.
> + # We'll put the label in the first column, so don't include it
> + # in the second column.
> + widget.
> + return widgets
>
> def _validate_
> """A generic validator for this view's actions.
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -1,11 +1,14 @@
> -= A person's contact email address =
> +======
> +A person's contact email address
> +======
Thanks for converting this test.
> === modified file 'lib/lp/
> --- lib/lp/
Barry Warsaw (barry) wrote : | # |
On Sep 16, 2009, at 10:24 PM, Brad Crittenden wrote:
>The changes look good. Thanks for taking the time to make a lot of drive-by fixes.
>
>I've got a few questions below.
Thanks for the review Brad!
>> === modified file 'lib/lp/
>> --- lib/lp/
>> +++ lib/lp/
>> @@ -4086,6 +4086,8 @@
>> custom_
>> LaunchpadRadioW
>>
>> + label = 'Change your e-mail settings'
>> +
>> def initialize(self):
>> if self.context.
>> # +editemails is not available on teams.
>> @@ -4191,13 +4193,11 @@
>> which the user is subscribed to this mailing list.
>> """
>> subscription = mailing_
>> - if subscription is not None:
>> - if subscription.
>> - return "Preferred address"
>> - else:
>> - return subscription.
>> - else:
>> + if subscription is None:
>> return "Don't subscribe"
>> + if subscription.
>
>Hmm, I'd have used an elif.
Changed.
>
>> + return 'Preferred address'
>> + return subscription.
>>
>> def _mailing_
>> """Creates a field for each mailing list the user can subscribe to.
>> @@ -4233,8 +4235,22 @@
>> @property
>> def mailing_
>> """Return all the mailing list subscription widgets."""
>> - return [widget for widget in self.widgets
>> - if 'field.
>> + mailing_list_set = getUtility(
>> + widgets = []
>> + for widget in self.widgets:
>> + if 'field.
>
>Why not use 'startswith'? Can it really be anywhere in the name?
Good call. This was cut-and-pasted from the original code, but .startswith()
is better, so I changed this.
>> @@ -87,24 +77,21 @@
>> lists. You can subscribe to a team's mailing list using any of
>> your verified email addresses.</p>
>>
>> - <table class="form">
>> + <table class="listing" style="width: 45em;">
>> <thead>
>> - <th style="
>> - <td><strong>
>> + <th style="
>
>Missing semi-colon
Cut-and-paste, but good catch! Changed. Here's the incremental.
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -4195,9 +4195,10 @@
if subscription is None:
return "Don't subscribe"
- if subscription.
+ elif subscription.
return 'Preferred address'
- return subscription.ema...
Preview Diff
1 | === modified file 'lib/canonical/launchpad/browser/launchpad.py' |
2 | --- lib/canonical/launchpad/browser/launchpad.py 2009-09-08 22:42:42 +0000 |
3 | +++ lib/canonical/launchpad/browser/launchpad.py 2009-09-16 19:56:45 +0000 |
4 | @@ -250,7 +250,7 @@ |
5 | if extra_breadcrumb is not None: |
6 | breadcrumbs.insert(idx + 1, extra_breadcrumb) |
7 | break |
8 | - if len(breadcrumbs): |
9 | + if len(breadcrumbs) > 0: |
10 | page_crumb = self.makeBreadcrumbForRequestedPage() |
11 | if page_crumb: |
12 | breadcrumbs.append(page_crumb) |
13 | |
14 | === modified file 'lib/canonical/launchpad/pagetitles.py' |
15 | --- lib/canonical/launchpad/pagetitles.py 2009-09-16 17:07:14 +0000 |
16 | +++ lib/canonical/launchpad/pagetitles.py 2009-09-16 21:27:18 +0000 |
17 | @@ -657,15 +657,8 @@ |
18 | person_answer_contact_for = ContextDisplayName( |
19 | 'Projects for which %s is an answer contact') |
20 | |
21 | -person_changepassword = 'Change your password' |
22 | - |
23 | -person_codesofconduct = ContextDisplayName( |
24 | - smartquote("%s's code of conduct signatures")) |
25 | - |
26 | person_edit = ContextDisplayName(smartquote("%s's details")) |
27 | |
28 | -person_editemails = ContextDisplayName(smartquote("%s's e-mail addresses")) |
29 | - |
30 | # person_foaf is an rdf file |
31 | |
32 | person_hwdb_submissions = ContextDisplayName( |
33 | |
34 | === modified file 'lib/lp/registry/browser/configure.zcml' |
35 | --- lib/lp/registry/browser/configure.zcml 2009-09-16 17:07:14 +0000 |
36 | +++ lib/lp/registry/browser/configure.zcml 2009-09-16 21:19:47 +0000 |
37 | @@ -801,7 +801,7 @@ |
38 | for="lp.registry.interfaces.person.IPerson" |
39 | class="lp.registry.browser.person.PersonChangePasswordView" |
40 | permission="launchpad.Edit" |
41 | - template="../templates/person-changepassword.pt"/> |
42 | + template="../../app/templates/generic-edit.pt"/> |
43 | <browser:page |
44 | name="+editlanguages" |
45 | for="lp.registry.interfaces.person.IPerson" |
46 | |
47 | === modified file 'lib/lp/registry/browser/person.py' |
48 | --- lib/lp/registry/browser/person.py 2009-09-16 17:07:14 +0000 |
49 | +++ lib/lp/registry/browser/person.py 2009-09-16 21:19:47 +0000 |
50 | @@ -4086,6 +4086,8 @@ |
51 | custom_widget('mailing_list_auto_subscribe_policy', |
52 | LaunchpadRadioWidgetWithDescription) |
53 | |
54 | + label = 'Change your e-mail settings' |
55 | + |
56 | def initialize(self): |
57 | if self.context.is_team: |
58 | # +editemails is not available on teams. |
59 | @@ -4191,13 +4193,11 @@ |
60 | which the user is subscribed to this mailing list. |
61 | """ |
62 | subscription = mailing_list.getSubscription(self.context) |
63 | - if subscription is not None: |
64 | - if subscription.email_address is None: |
65 | - return "Preferred address" |
66 | - else: |
67 | - return subscription.email_address |
68 | - else: |
69 | + if subscription is None: |
70 | return "Don't subscribe" |
71 | + if subscription.email_address is None: |
72 | + return 'Preferred address' |
73 | + return subscription.email_address |
74 | |
75 | def _mailing_list_fields(self): |
76 | """Creates a field for each mailing list the user can subscribe to. |
77 | @@ -4207,10 +4207,12 @@ |
78 | """ |
79 | mailing_list_set = getUtility(IMailingListSet) |
80 | fields = [] |
81 | - terms = [SimpleTerm("Preferred address"), |
82 | - SimpleTerm("Don't subscribe")] |
83 | - terms += [SimpleTerm(email, email.email) |
84 | - for email in self.validated_addresses] |
85 | + terms = [ |
86 | + SimpleTerm("Preferred address"), |
87 | + SimpleTerm("Don't subscribe"), |
88 | + ] |
89 | + for email in self.validated_addresses: |
90 | + terms.append(SimpleTerm(email, email.email)) |
91 | for team in self.context.teams_participated_in: |
92 | mailing_list = mailing_list_set.get(team.name) |
93 | if mailing_list is not None and mailing_list.is_usable: |
94 | @@ -4233,8 +4235,22 @@ |
95 | @property |
96 | def mailing_list_widgets(self): |
97 | """Return all the mailing list subscription widgets.""" |
98 | - return [widget for widget in self.widgets |
99 | - if 'field.subscription.' in widget.name] |
100 | + mailing_list_set = getUtility(IMailingListSet) |
101 | + widgets = [] |
102 | + for widget in self.widgets: |
103 | + if 'field.subscription.' in widget.name: |
104 | + team_name = widget.label |
105 | + mailing_list = mailing_list_set.get(team_name) |
106 | + assert mailing_list is not None, 'Missing mailing list' |
107 | + widget_dict = dict( |
108 | + team=mailing_list.team, |
109 | + widget=widget, |
110 | + ) |
111 | + widgets.append(widget_dict) |
112 | + # We'll put the label in the first column, so don't include it |
113 | + # in the second column. |
114 | + widget.display_label = False |
115 | + return widgets |
116 | |
117 | def _validate_selected_address(self, data, field='VALIDATED_SELECTED'): |
118 | """A generic validator for this view's actions. |
119 | @@ -4479,7 +4495,8 @@ |
120 | Valid addresses are the ones presented as options for the mailing |
121 | list widgets. |
122 | """ |
123 | - names = [w.context.getName() for w in self.mailing_list_widgets] |
124 | + names = [widget_dict['widget'].context.getName() |
125 | + for widget_dict in self.mailing_list_widgets] |
126 | self.validate_widgets(data, names) |
127 | return self.errors |
128 | |
129 | @@ -4490,7 +4507,8 @@ |
130 | mailing_list_set = getUtility(IMailingListSet) |
131 | dirty = False |
132 | prefix_length = len('subscription.') |
133 | - for widget in self.mailing_list_widgets: |
134 | + for widget_dict in self.mailing_list_widgets: |
135 | + widget = widget_dict['widget'] |
136 | mailing_list_name = widget.context.getName()[prefix_length:] |
137 | mailing_list = mailing_list_set.get(mailing_list_name) |
138 | new_value = data[widget.context.getName()] |
139 | |
140 | === modified file 'lib/lp/registry/stories/foaf/xx-setpreferredemail.txt' |
141 | --- lib/lp/registry/stories/foaf/xx-setpreferredemail.txt 2008-09-08 13:35:16 +0000 |
142 | +++ lib/lp/registry/stories/foaf/xx-setpreferredemail.txt 2009-09-16 21:00:11 +0000 |
143 | @@ -1,11 +1,14 @@ |
144 | -= A person's contact email address = |
145 | +================================ |
146 | +A person's contact email address |
147 | +================================ |
148 | |
149 | A person may have many confirmed email address which he may use to |
150 | login with, but only one email address will be the contact email |
151 | address. |
152 | |
153 | |
154 | -== Setting the contact email address == |
155 | +Setting the contact email address |
156 | +================================= |
157 | |
158 | Sample Person chooses to change his contact email address to the |
159 | address he prefers to login with. |
160 | @@ -14,10 +17,10 @@ |
161 | >>> browser.open('http://launchpad.dev/~name12') |
162 | >>> browser.getLink('Change details').click() |
163 | >>> browser.getLink('E-mail Settings').click() |
164 | - >>> browser.url |
165 | - 'http://launchpad.dev/~name12/+editemails' |
166 | - >>> browser.title |
167 | - "Sample Person's e-mail addresses" |
168 | + >>> print browser.url |
169 | + http://launchpad.dev/~name12/+editemails |
170 | + >>> print browser.title |
171 | + +editemails : Sample Person |
172 | |
173 | Sample Person has a second browser open to the same page; maybe he is |
174 | absent minded. |
175 | @@ -62,13 +65,14 @@ |
176 | testing@canonical.com is already set as your contact address. |
177 | |
178 | |
179 | -== Unclaimed users == |
180 | +Unclaimed users |
181 | +=============== |
182 | |
183 | An unclaimed user will probably have no contact email address. |
184 | |
185 | >>> admin_browser.open('http://launchpad.dev/~matsubara') |
186 | - >>> admin_browser.title |
187 | - 'Diogo Matsubara does not use Launchpad' |
188 | + >>> print admin_browser.title |
189 | + Diogo Matsubara does not use Launchpad |
190 | >>> admin_browser.getLink('Change e-mail settings').click() |
191 | >>> print find_tag_by_id(admin_browser.contents, |
192 | ... 'no-contact-address').string |
193 | |
194 | === modified file 'lib/lp/registry/stories/foaf/xx-validate-email.txt' |
195 | --- lib/lp/registry/stories/foaf/xx-validate-email.txt 2009-09-10 23:58:31 +0000 |
196 | +++ lib/lp/registry/stories/foaf/xx-validate-email.txt 2009-09-16 21:00:11 +0000 |
197 | @@ -1,4 +1,6 @@ |
198 | -= Validating an email address = |
199 | +=========================== |
200 | +Validating an email address |
201 | +=========================== |
202 | |
203 | The user 'salgado' has an unvalidated email address that was probably |
204 | added by gina. Now he wants to validate it. |
205 | @@ -10,7 +12,7 @@ |
206 | >>> browser = setupBrowser(auth='Basic salgado@ubuntu.com:zeca') |
207 | >>> browser.open('http://launchpad.dev/~salgado/+editemails') |
208 | >>> print browser.title |
209 | - Guilherme Salgado's e-mail addresses |
210 | + +editemails : Guilherme Salgado |
211 | |
212 | >>> browser.getControl(name="field.UNVALIDATED_SELECTED").getControl( |
213 | ... value='salgado@ubuntu.com').selected = True |
214 | @@ -79,7 +81,8 @@ |
215 | An e-mail message was sent to 'salgado@example.com'... |
216 | |
217 | |
218 | -== Validating the email address string == |
219 | +Validating the email address string |
220 | +=================================== |
221 | |
222 | Leaving the email address field blank and hitting the 'Add' button |
223 | should display an error message. |
224 | @@ -88,8 +91,8 @@ |
225 | '' |
226 | |
227 | >>> browser.getControl('Add', index=1).click() |
228 | - >>> browser.title |
229 | - "Guilherme Salgado's e-mail addresses" |
230 | + >>> print browser.title |
231 | + +editemails : Guilherme Salgado |
232 | |
233 | >>> for msg in get_feedback_messages(browser.contents): |
234 | ... print msg |
235 | @@ -99,13 +102,13 @@ |
236 | Entering a string that does not look like an email address causes an |
237 | error to be displayed. |
238 | |
239 | - >>> browser.title |
240 | - "Guilherme Salgado's e-mail addresses" |
241 | + >>> print browser.title |
242 | + +editemails : Guilherme Salgado |
243 | |
244 | >>> browser.getControl('Add a new address').value = 'foo' |
245 | >>> browser.getControl('Add', index=1).click() |
246 | - >>> browser.title |
247 | - "Guilherme Salgado's e-mail addresses" |
248 | + >>> print browser.title |
249 | + +editemails : Guilherme Salgado |
250 | |
251 | >>> for msg in get_feedback_messages(browser.contents): |
252 | ... print msg |
253 | @@ -117,8 +120,8 @@ |
254 | will not run. A malicious hacker cannot use a XSS vulnerability to gain |
255 | information about Launchpad users. |
256 | |
257 | - >>> browser.title |
258 | - "Guilherme Salgado's e-mail addresses" |
259 | + >>> print browser.title |
260 | + +editemails : Guilherme Salgado |
261 | |
262 | >>> browser.getControl('Add a new address').value = ( |
263 | ... "salgado@example.com<br/><script>window.alert('XSS')</script>") |
264 | @@ -130,7 +133,8 @@ |
265 | doesn't seem to be a valid email address. |
266 | |
267 | |
268 | -== +editemails for teams == |
269 | ++editemails for teams |
270 | +===================== |
271 | |
272 | Because people and teams share the same namespace, it used to be possible to |
273 | hack the url to get to a team's +editemails page. This makes no sense, and |
274 | |
275 | === modified file 'lib/lp/registry/stories/mailinglists/subscriptions.txt' |
276 | --- lib/lp/registry/stories/mailinglists/subscriptions.txt 2009-09-14 01:28:41 +0000 |
277 | +++ lib/lp/registry/stories/mailinglists/subscriptions.txt 2009-09-16 21:00:11 +0000 |
278 | @@ -85,8 +85,10 @@ |
279 | >>> browser.open('http://launchpad.dev/~carlos') |
280 | >>> browser.getLink("Change details").click() |
281 | >>> browser.getLink("E-mail Settings").click() |
282 | - >>> browser.title |
283 | - "Carlos Perell\xc3\xb3 Mar\xc3\xadn's e-mail addresses" |
284 | + |
285 | + >>> from canonical.launchpad.helpers import backslashreplace |
286 | + >>> print backslashreplace(browser.title) |
287 | + +editemails : Carlos Perell\xf3 Mar\xedn |
288 | |
289 | >>> admins = browser.getControl(name='field.subscription.admins') |
290 | >>> rosetta_admins = browser.getControl( |
291 | @@ -211,8 +213,8 @@ |
292 | >>> browser.open('http://launchpad.dev/~carlos') |
293 | >>> browser.getLink("Change details").click() |
294 | >>> browser.getLink("E-mail Settings").click() |
295 | - >>> browser.title |
296 | - "Carlos Perell\xc3\xb3 Mar\xc3\xadn's e-mail addresses" |
297 | + >>> print backslashreplace(browser.title) |
298 | + +editemails : Carlos Perell\xf3 Mar\xedn |
299 | |
300 | >>> rosetta_admins = browser.getControl( |
301 | ... name='field.subscription.rosetta-admins') |
302 | @@ -245,8 +247,8 @@ |
303 | >>> browser.open('http://launchpad.dev/~jdub') |
304 | >>> browser.getLink("Change details").click() |
305 | >>> browser.getLink("E-mail Settings").click() |
306 | - >>> browser.title |
307 | - "Jeff Waugh's e-mail addresses" |
308 | + >>> print browser.title |
309 | + +editemails : Jeff Waugh |
310 | |
311 | >>> browser.getControl( |
312 | ... name='field.subscription.rosetta-admins') |
313 | @@ -270,8 +272,8 @@ |
314 | >>> browser.open('http://launchpad.dev/~jdub') |
315 | >>> browser.getLink("Change details").click() |
316 | >>> browser.getLink("E-mail Settings").click() |
317 | - >>> browser.title |
318 | - "Jeff Waugh's e-mail addresses" |
319 | + >>> print browser.title |
320 | + +editemails : Jeff Waugh |
321 | |
322 | >>> rosetta_team = browser.getControl( |
323 | ... name='field.subscription.rosetta-admins') |
324 | @@ -472,8 +474,8 @@ |
325 | >>> browser.open('http://launchpad.dev/~carlos') |
326 | >>> browser.getLink("Change details").click() |
327 | >>> browser.getLink("E-mail Settings").click() |
328 | - >>> browser.title |
329 | - "Carlos Perell\xc3\xb3 Mar\xc3\xadn's e-mail addresses" |
330 | + >>> print backslashreplace(browser.title) |
331 | + +editemails : Carlos Perell\xf3 Mar\xedn |
332 | |
333 | Carlos's default setting, 'Ask me when I join a team', is still in place. |
334 | |
335 | |
336 | === removed file 'lib/lp/registry/templates/person-changepassword.pt' |
337 | --- lib/lp/registry/templates/person-changepassword.pt 2009-07-18 00:05:49 +0000 |
338 | +++ lib/lp/registry/templates/person-changepassword.pt 1970-01-01 00:00:00 +0000 |
339 | @@ -1,32 +0,0 @@ |
340 | -<html |
341 | - xmlns="http://www.w3.org/1999/xhtml" |
342 | - xmlns:tal="http://xml.zope.org/namespaces/tal" |
343 | - xmlns:metal="http://xml.zope.org/namespaces/metal" |
344 | - xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
345 | - xml:lang="en" |
346 | - lang="en" |
347 | - dir="ltr" |
348 | - metal:use-macro="view/macro:page/onecolumn" |
349 | - i18n:domain="launchpad" |
350 | -> |
351 | - <body> |
352 | - |
353 | - <metal:style fill-slot="head_epilogue"> |
354 | - <style type="text/css"> |
355 | - #launchpad-form-widgets th { |
356 | - width: 12em; |
357 | - } |
358 | - </style> |
359 | - </metal:style> |
360 | - |
361 | - |
362 | - <div metal:fill-slot="main"> |
363 | - |
364 | - <div metal:use-macro="context/@@launchpad_form/form"> |
365 | - |
366 | - </div> |
367 | - |
368 | - </div> |
369 | - |
370 | -</body> |
371 | -</html> |
372 | |
373 | === modified file 'lib/lp/registry/templates/person-editemails.pt' |
374 | --- lib/lp/registry/templates/person-editemails.pt 2009-07-17 17:59:07 +0000 |
375 | +++ lib/lp/registry/templates/person-editemails.pt 2009-09-16 21:00:11 +0000 |
376 | @@ -3,35 +3,25 @@ |
377 | xmlns:tal="http://xml.zope.org/namespaces/tal" |
378 | xmlns:metal="http://xml.zope.org/namespaces/metal" |
379 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
380 | - xml:lang="en" |
381 | - lang="en" |
382 | - dir="ltr" |
383 | - metal:use-macro="view/macro:page/onecolumn" |
384 | + metal:use-macro="view/macro:page/main_only" |
385 | i18n:domain="launchpad" |
386 | > |
387 | <body> |
388 | <div metal:fill-slot="main"> |
389 | <div metal:use-macro="context/@@launchpad_form/form"> |
390 | <metal:extra-info fill-slot="extra_info"> |
391 | - <h1>Change your e-mail settings</h1> |
392 | <h2>Your e-mail addresses</h2> |
393 | - <tal:block condition="context/preferredemail"> |
394 | - <p>Your preferred contact address for all Launchpad e-mail is:</p> |
395 | - <ul id="preferred-email"> |
396 | - <li class="mail"><b tal:content="context/preferredemail/email" /></li> |
397 | - </ul> |
398 | - </tal:block> |
399 | - |
400 | - <tal:block tal:condition="not: context/preferredemail"> |
401 | - <p id="no-contact-address"> |
402 | - Currently you don't have a contact address in |
403 | - Launchpad. |
404 | - </p> |
405 | - </tal:block> |
406 | + <p tal:condition="context/preferredemail"> |
407 | + Your preferred contact address for all Launchpad e-mail is: |
408 | + <b tal:content="context/preferredemail/email" /> |
409 | + </p> |
410 | + <p tal:condition="not: context/preferredemail" |
411 | + id="no-contact-address"> |
412 | + Currently you don't have a contact address in Launchpad. |
413 | + </p> |
414 | </metal:extra-info> |
415 | |
416 | <metal:widgets fill-slot="widgets"> |
417 | - |
418 | <table class="form"> |
419 | <tal:validated tal:condition="view/validated_addresses"> |
420 | <tal:widget define="widget nocall:view/widgets/VALIDATED_SELECTED"> |
421 | @@ -87,24 +77,21 @@ |
422 | lists. You can subscribe to a team's mailing list using any of |
423 | your verified email addresses.</p> |
424 | |
425 | - <table class="form"> |
426 | + <table class="listing" style="width: 45em;"> |
427 | <thead> |
428 | - <th style="white-space:nowrap">For this mailing list...</th> |
429 | - <td><strong>Subscribe with this address</strong></td> |
430 | + <th style="white-space:nowrap">For mailing list</th> |
431 | + <th>Subscribe with</th> |
432 | </thead> |
433 | <tbody> |
434 | - <metal:block tal:repeat="widget view/mailing_list_widgets"> |
435 | - <metal:block use-macro="context/@@launchpad_form/widget_row" /> |
436 | - </metal:block> |
437 | - <tr> |
438 | - <td></td> |
439 | - <td> |
440 | - <input tal:replace="structure |
441 | - view/action_update_subscriptions/render" /> |
442 | - </td> |
443 | - </tr> |
444 | + <tr tal:repeat="widget view/mailing_list_widgets"> |
445 | + <td tal:content="structure widget/team/fmt:link">Team</td> |
446 | + <td tal:content="structure widget/widget">Widget</td> |
447 | + </tr> |
448 | </tbody> |
449 | </table> |
450 | + <div style="padding-top: 1em; padding-bottom: 1em;"> |
451 | + <input tal:replace="structure view/action_update_subscriptions/render" /> |
452 | + </div> |
453 | </form> |
454 | |
455 | <form action="" |
456 | @@ -128,7 +115,7 @@ |
457 | <th style="white-space:nowrap; text-align:left;"> |
458 | <div style="margin-bottom: 1em;"> |
459 | <label tal:attributes="for widget/name" |
460 | - tal:content="structure widget/label" /> |
461 | + tal:content="structure widget/label" /> |
462 | </div> |
463 | </th> |
464 | <td></td> |
465 | @@ -140,8 +127,8 @@ |
466 | <tr> |
467 | <td> |
468 | <input |
469 | - tal:replace="structure |
470 | - view/action_update_autosubscribe_policy/render" /> |
471 | + tal:replace="structure |
472 | + view/action_update_autosubscribe_policy/render" /> |
473 | </td> |
474 | <td></td> |
475 | </tr> |
476 | @@ -152,37 +139,5 @@ |
477 | </form> |
478 | |
479 | </div> |
480 | - |
481 | -<div metal:fill-slot="help"> |
482 | - <p> |
483 | - This page displays all the email addresses associated with your |
484 | - Launchpad account. Some of these addresses are verified (known to |
485 | - be associated with you), but some may need confirmation before you |
486 | - can use them in Launchpad. |
487 | - </p> |
488 | - |
489 | - <p> |
490 | - When you confirm that an address is yours, Launchpad will send a |
491 | - verification email to that address. To complete the verification |
492 | - process, simply visit the URL contained in the email. |
493 | - </p> |
494 | - |
495 | - <p> |
496 | - You may choose one of your verified addresses to be your |
497 | - preferred email address. Email from Launchpad will be sent to |
498 | - this address. |
499 | - </p> |
500 | - |
501 | - <p id="mailing-list-help" tal:condition="view/mailing_list_widgets"> |
502 | - This page also displays mailing lists for all of your |
503 | - teams that have them. You can subscribe to a list using any of |
504 | - your verified email addresses, or you can choose to have messages |
505 | - delivered to your preferred address. That way, if you change your |
506 | - preferred address, you won't have to change all your subscriptions |
507 | - to use the new address. |
508 | - </p> |
509 | - |
510 | -</div> |
511 | - |
512 | </body> |
513 | </html> |
= Summary =
This branch fixes bug 430065 which converts the ~person/+editemails and +changepassword pages to UI 3.0. Along the way, I was able to close
~person/
an old bug 180349 which adds some useful links to the mailing list
subscription section on the +editemails page.
== Proposed fix ==
Update the templates and views, fix tests, and do a minimal redesign on the
+editemails page. That page is actually pretty horrendous, but time boxing
only allows for a moderate redesign and improvement. In particular, on the
+editemails page it would be nice to move the Add button to next to the "Add a
new address" text box, but given the way the form is laid out, this isn't
possible.
The ui has been approved by rockstar and edwin.
== Pre-implementation notes ==
None really. By now, conversions are pretty straightforward.
== Implementation details ==
Changes in this branch:
* Get rid of the person- changepassword. pt template altogether, substituting
generic-edit.pt for it.
* Removed some pagetitles that are no longer necessary.
* Fixed a stylistic nit in launchpad.py Hierarchy class.
* Cleaned up the PersonEditEmail sView implementation. Also, change the list_widgets property implementation to return a dictionary instead
mailing_
of the widgets directly. This allowed me to fix bug 180349.
* Update a bunch of doctests.
== Tests ==
% bin/test -vv -t mailinglist -t stories/foaf -t stories/gpg-coc -t conduct
== Demo and Q/A ==
For a person with no preferred email address and no mailing list
subscriptions:
http:// launchpad. dev/~matsubara/ +editemails
For a person with a preferred email address but no mailing list subscriptions:
http:// launchpad. dev/~no- priv/+editemail s
For a person with several validated email addresses and a mailing list
subscription:
http:// launchpad. dev/~name16/ +editemails
To see the change password page:
http:// launchpad. dev/~no- priv/+changepas sword
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: registry/ browser/ configure. zcml registry/ stories/ mailinglists/ subscriptions. txt /launchpad/ pagetitles. py registry/ stories/ foaf/xx- validate- email.txt registry/ templates/ person- editemails. pt /launchpad/ browser/ launchpad. py registry/ stories/ foaf/xx- setpreferredema il.txt registry/ browser/ person. py
lib/lp/
lib/lp/
lib/canonical
lib/lp/
lib/lp/
lib/canonical
lib/lp/
lib/lp/
== Pylint notices ==
lib/lp/ registry/ browser/ person. py interface' (No module named restful)
117: [F0401] Unable to import 'lazr.delegates' (No module named delegates)
118: [F0401] Unable to import 'lazr.config' (No module named config)
119: [F0401] Unable to import 'lazr.restful.