Merge lp:~edwin-grubbs/launchpad/bug-230801-renewing-membership into lp:launchpad/db-devel

Proposed by Edwin Grubbs
Status: Merged
Approved by: Edwin Grubbs
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~edwin-grubbs/launchpad/bug-230801-renewing-membership
Merge into: lp:launchpad/db-devel
Diff against target: 949 lines (+296/-79)
39 files modified
lib/lp/archiveuploader/nascentuploadfile.py (+1/-1)
lib/lp/archiveuploader/tests/nascentuploadfile.txt (+71/-0)
lib/lp/bugs/templates/bug-portlet-subscribers.pt (+1/-1)
lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt (+1/-1)
lib/lp/bugs/templates/bugtarget-portlet-bugfilters.pt (+1/-1)
lib/lp/bugs/templates/bugtarget-portlet-bugtags.pt (+1/-1)
lib/lp/bugs/templates/bugtask-index.pt (+3/-3)
lib/lp/bugs/templates/bugtask-tasks-and-nominations-table-row.pt (+1/-1)
lib/lp/bugs/templates/bugtasks-and-nominations-table.pt (+1/-1)
lib/lp/bugs/templates/official-bug-target-manage-tags.pt (+1/-1)
lib/lp/code/templates/branch-import-details.pt (+1/-1)
lib/lp/code/templates/branch-index.pt (+1/-1)
lib/lp/code/templates/branch-listing.pt (+1/-1)
lib/lp/code/templates/branch-portlet-subscribers.pt (+1/-1)
lib/lp/code/templates/branch-related-bugs-specs.pt (+1/-1)
lib/lp/code/templates/branchmergeproposal-generic-listing.pt (+1/-1)
lib/lp/registry/browser/person.py (+4/-1)
lib/lp/registry/browser/tests/productrelease-views.txt (+1/-1)
lib/lp/registry/templates/object-timeline-graph.pt (+1/-1)
lib/lp/registry/templates/person-macros.pt (+1/-1)
lib/lp/registry/templates/product-new.pt (+1/-1)
lib/lp/registry/templates/productrelease-add-from-series.pt (+1/-1)
lib/lp/registry/templates/teammembership-index.pt (+1/-1)
lib/lp/registry/templates/timeline-macros.pt (+1/-1)
lib/lp/soyuz/templates/archive-edit-dependencies.pt (+1/-1)
lib/lp/soyuz/templates/archive-macros.pt (+1/-1)
lib/lp/soyuz/templates/archive-packages.pt (+1/-1)
lib/lp/soyuz/templates/archive-subscribers.pt (+1/-1)
lib/lp/translations/browser/language.py (+8/-0)
lib/lp/translations/stories/distroseries/xx-distroseries-templates.txt (+56/-13)
lib/lp/translations/stories/productseries/xx-productseries-templates.txt (+27/-18)
lib/lp/translations/stories/standalone/xx-language.txt (+68/-7)
lib/lp/translations/templates/language-index.pt (+9/-4)
lib/lp/translations/templates/object-templates.pt (+20/-3)
lib/lp/translations/templates/pofile-export.pt (+1/-1)
lib/lp/translations/templates/pofile-translate.pt (+1/-1)
lib/lp/translations/templates/translation-import-queue-macros.pt (+1/-1)
lib/lp/translations/templates/translationimportqueueentry-index.pt (+1/-1)
lib/lp/translations/templates/translationmessage-translate.pt (+1/-1)
To merge this branch: bzr merge lp:~edwin-grubbs/launchpad/bug-230801-renewing-membership
Reviewer Review Type Date Requested Status
Michael Nelson (community) code Approve
Review via email: mp+15610@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

Summary
-------

This branch fixes an oops caused by the user double clicking
on the /~$user/+expiringmembership/$team form's submit button.

The view class now checks if the membership can be renewed
before calling the method in the model that raises the exception.

The view still displays the message saying that the membership has been
renewed, because it is very unlikely that the user would be able to try to
renew an unrenewable membership without double clicking, since the form will
not show up on the page if the membership will not be expiring within seven
days.

Tests
-----

./bin/test -vvt 'xx-member-renewed-membership.txt|teammembership-email-notification.txt'

Demo and Q/A
------------

* Log in as <email address hidden>
* Open http://launchpad.dev/~guadamen/+members
  * Edit Foo Bar's membership.
  * Set the expiration within 7 days in the future.
    (Surprisingly, you can set the team's admin's membership to expire, and
     before this fix the admin would get the same exception when double
     clicking to renew the membership.)
* Open http://launchpad.dev/~name16/+expiringmembership/guadamen
  * Double click on the Renew button.
  * Instead of an OOPS, you should the person index page with a notice
    that the membership has been renewed to some time next year.

Revision history for this message
Michael Nelson (michael.nelson) wrote :

> Demo and Q/A
> ------------
>
> * Log in as <email address hidden>
> * Open http://launchpad.dev/~guadamen/+members
> * Edit Foo Bar's membership.
> * Set the expiration within 7 days in the future.
> (Surprisingly, you can set the team's admin's membership to expire, and
> before this fix the admin would get the same exception when double
> clicking to renew the membership.)
> * Open http://launchpad.dev/~name16/+expiringmembership/guadamen
> * Double click on the Renew button.

In addition, I had to first set the "invite them to renew their own membership" option on the group before I could renew.

> * Instead of an OOPS, you should the person index page with a notice
> that the membership has been renewed to some time next year.

Nice - I couldn't actually reproduce the problem with Chromium (double-click protection? ;-) , but with Firefox I could.

Not worth worrying about at all, but if you click really really quickly (or perhaps it has to do with the number of clicks and overloading the dev server) you can get more than one notification.

Great! Thanks Edwin.

<EdwinGrubbs> noodles775, al-maisan: can one of you review my tiny branch? https://code.edge.launchpad.net/~edwin-grubbs/launchpad/bug-230801-renewing-membership/+merge/15610
* beuno is now known as beuno-lunch
<noodles775> EdwinGrubbs: sure!
* noodles775 is loving the 4 or 5 liners :)
<noodles775> EdwinGrubbs: is this targeted to db-devel for a reason? (or are you planning on landing it on devel?)
<EdwinGrubbs> noodles775: I'm planning on landing it on devel after pqm opens, and I wanted to prevent merge conflicts later, since devel still didn't have some of the revisions when I started the branch.
* stub has quit ("Leaving.")
<noodles775> k

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/archiveuploader/nascentuploadfile.py'
--- lib/lp/archiveuploader/nascentuploadfile.py 2009-11-10 13:09:26 +0000
+++ lib/lp/archiveuploader/nascentuploadfile.py 2009-12-07 23:15:25 +0000
@@ -690,7 +690,7 @@
690 tar_checker.ancient_files[first_file])690 tar_checker.ancient_files[first_file])
691 yield UploadError(691 yield UploadError(
692 "%s: has %s file(s) with a time stamp too "692 "%s: has %s file(s) with a time stamp too "
693 "far into the future (e.g. %s [%s])."693 "far in the past (e.g. %s [%s])."
694 % (self.filename, len(ancient_files), first_file,694 % (self.filename, len(ancient_files), first_file,
695 timestamp))695 timestamp))
696 return696 return
697697
=== modified file 'lib/lp/archiveuploader/tests/nascentuploadfile.txt'
--- lib/lp/archiveuploader/tests/nascentuploadfile.txt 2009-07-08 08:38:05 +0000
+++ lib/lp/archiveuploader/tests/nascentuploadfile.txt 2009-12-07 23:15:25 +0000
@@ -539,6 +539,77 @@
539539
540== DebBinaryUploadFile ==540== DebBinaryUploadFile ==
541541
542DebBinaryUploadFile models a binary .deb file.
543
544 >>> from lp.archiveuploader.nascentuploadfile import (
545 ... DebBinaryUploadFile)
546 >>> ed_deb_path = datadir('ed_0.2-20_i386.deb')
547 >>> ed_binary_deb = DebBinaryUploadFile(ed_deb_path,
548 ... 'e31eeb0b6b3b87e1ea79378df864ffff',
549 ... 15, 'main/editors', 'important', 'foo', '1.2',
550 ... ed_mixed_changes, modified_insecure_policy,
551 ... mock_logger_quiet)
552
553Like the other files it can be verified:
554
555 >>> list(ed_binary_deb.verify())
556 []
557
558Verification checks that the specified section matches the section in the
559changes file:
560
561 >>> ed_binary_deb = DebBinaryUploadFile(ed_deb_path,
562 ... 'e31eeb0b6b3b87e1ea79378df864ffff',
563 ... 15, 'main/net', 'important', 'foo', '1.2',
564 ... ed_mixed_changes, modified_insecure_policy,
565 ... mock_logger_quiet)
566 >>> list(ed_binary_deb.verify())
567 [UploadError('ed_0.2-20_i386.deb control file lists section as
568 main/editors but changes file has main/net.',)]
569
570It also checks the priority against the changes file:
571
572 >>> ed_binary_deb = DebBinaryUploadFile(ed_deb_path,
573 ... 'e31eeb0b6b3b87e1ea79378df864ffff',
574 ... 15, 'main/editors', 'extra', 'foo', '1.2',
575 ... ed_mixed_changes, modified_insecure_policy,
576 ... mock_logger_quiet)
577 >>> list(ed_binary_deb.verify())
578 [UploadError('ed_0.2-20_i386.deb control file lists priority as important
579 but changes file has extra.',)]
580
581The timestamp of the files in the .deb are tested against the policy for being
582too new:
583
584 >>> old_only_policy = getPolicy(
585 ... name='insecure', distro='ubuntu', distroseries='hoary')
586 >>> old_only_policy.can_upload_binaries = True
587 >>> old_only_policy.future_time_grace = -5 * 365 * 24 * 60 * 60
588
589 >>> ed_binary_deb = DebBinaryUploadFile(ed_deb_path,
590 ... 'e31eeb0b6b3b87e1ea79378df864ffff',
591 ... 15, 'main/editors', 'important', 'foo', '1.2',
592 ... ed_mixed_changes, old_only_policy,
593 ... mock_logger_quiet)
594 >>> list(ed_binary_deb.verifyDebTimestamp())
595 [UploadError('ed_0.2-20_i386.deb: has 26 file(s) with a time stamp too
596 far into the future (e.g. control [Thu Jan 3 19:29:01 2008]).',)]
597
598... as well as for being too old:
599
600 >>> new_only_policy = getPolicy(
601 ... name='insecure', distro='ubuntu', distroseries='hoary')
602 >>> new_only_policy.can_upload_binaries = True
603 >>> new_only_policy.earliest_year = 2010
604 >>> ed_binary_deb = DebBinaryUploadFile(ed_deb_path,
605 ... 'e31eeb0b6b3b87e1ea79378df864ffff',
606 ... 15, 'main/editors', 'important', 'foo', '1.2',
607 ... ed_mixed_changes, new_only_policy,
608 ... mock_logger_quiet)
609 >>> list(ed_binary_deb.verify())
610 [UploadError('ed_0.2-20_i386.deb: has 26 file(s) with a time stamp too
611 far in the past (e.g. control [Thu Jan 3 19:29:01 2008]).',)]
612
542613
543== UDebBinaryUploadFile ==614== UDebBinaryUploadFile ==
544615
545616
=== modified file 'lib/lp/bugs/templates/bug-portlet-subscribers.pt'
--- lib/lp/bugs/templates/bug-portlet-subscribers.pt 2009-11-26 03:13:32 +0000
+++ lib/lp/bugs/templates/bug-portlet-subscribers.pt 2009-12-07 23:15:25 +0000
@@ -25,7 +25,7 @@
25 <img src="/@@/spinner" />25 <img src="/@@/spinner" />
26 </div>26 </div>
27 <script type="text/javascript">27 <script type="text/javascript">
28 YUI().use('io-base', 'node', 'bugs.bugtask_index', function(Y) {28 LPS.use('io-base', 'node', 'bugs.bugtask_index', function(Y) {
29 // Must be done inline here to ensure the load event fires.29 // Must be done inline here to ensure the load event fires.
30 // This is a work around for a YUI3 issue with event handling.30 // This is a work around for a YUI3 issue with event handling.
31 var subscription_link = Y.one('.menu-link-subscription');31 var subscription_link = Y.one('.menu-link-subscription');
3232
=== modified file 'lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt'
--- lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt 2009-10-01 12:09:37 +0000
+++ lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt 2009-12-07 23:15:25 +0000
@@ -14,7 +14,7 @@
14 tal:define="lp_js string:${icingroot}/build"14 tal:define="lp_js string:${icingroot}/build"
15 tal:attributes="src string:${lp_js}/bugs/filebug-dupefinder.js"></script>15 tal:attributes="src string:${lp_js}/bugs/filebug-dupefinder.js"></script>
16 <script type="text/javascript">16 <script type="text/javascript">
17 YUI().use('base', 'node', 'oop', 'event', 'bugs.dupe_finder', function(Y) {17 LPS.use('base', 'node', 'oop', 'event', 'bugs.dupe_finder', function(Y) {
18 Y.bugs.setup_dupe_finder();18 Y.bugs.setup_dupe_finder();
19 });19 });
20 </script>20 </script>
2121
=== modified file 'lib/lp/bugs/templates/bugtarget-portlet-bugfilters.pt'
--- lib/lp/bugs/templates/bugtarget-portlet-bugfilters.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/bugs/templates/bugtarget-portlet-bugfilters.pt 2009-12-07 23:15:25 +0000
@@ -12,7 +12,7 @@
12 <img src="/@@/spinner" />12 <img src="/@@/spinner" />
13 </div>13 </div>
14 <script type="text/javascript">14 <script type="text/javascript">
15 YUI().use('io-base', 'node', function(Y) {15 LPS.use('io-base', 'node', function(Y) {
16 Y.on('domready', function() {16 Y.on('domready', function() {
17 var portlet = Y.one('#portlet-bugfilters');17 var portlet = Y.one('#portlet-bugfilters');
18 Y.one('#bugfilters-portlet-spinner').setStyle('display', 'block');18 Y.one('#bugfilters-portlet-spinner').setStyle('display', 'block');
1919
=== modified file 'lib/lp/bugs/templates/bugtarget-portlet-bugtags.pt'
--- lib/lp/bugs/templates/bugtarget-portlet-bugtags.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/bugs/templates/bugtarget-portlet-bugtags.pt 2009-12-07 23:15:25 +0000
@@ -9,7 +9,7 @@
9 <a id="tags-content-link"9 <a id="tags-content-link"
10 tal:attributes="href context/fmt:url/+bugtarget-portlet-tags-content"></a>10 tal:attributes="href context/fmt:url/+bugtarget-portlet-tags-content"></a>
11 <script type="text/javascript">11 <script type="text/javascript">
12 YUI().use('io-base', 'node', function(Y) {12 LPS.use('io-base', 'node', function(Y) {
13 Y.on('domready', function() {13 Y.on('domready', function() {
14 Y.one('#tags-portlet-spinner').setStyle('display', 'block');14 Y.one('#tags-portlet-spinner').setStyle('display', 'block');
1515
1616
=== modified file 'lib/lp/bugs/templates/bugtask-index.pt'
--- lib/lp/bugs/templates/bugtask-index.pt 2009-11-30 17:57:15 +0000
+++ lib/lp/bugs/templates/bugtask-index.pt 2009-12-07 23:15:25 +0000
@@ -37,7 +37,7 @@
37 </script>37 </script>
38 </tal:devmode>38 </tal:devmode>
39 <script type="text/javascript">39 <script type="text/javascript">
40 YUI().use('base', 'node', 'oop', 'event', 'bugs.bugtask_index',40 LPS.use('base', 'node', 'oop', 'event', 'bugs.bugtask_index',
41 'code.branchmergeproposal.popupdiff', function(Y) {41 'code.branchmergeproposal.popupdiff', function(Y) {
42 Y.bugs.setup_bugtask_index();42 Y.bugs.setup_bugtask_index();
43 Y.on('load', function(e) {43 Y.on('load', function(e) {
@@ -155,7 +155,7 @@
155 <img src="/@@/spinner" id="tags-edit-spinner" style="display: none" />155 <img src="/@@/spinner" id="tags-edit-spinner" style="display: none" />
156 <a href="+edit" title="Edit tags" id="edit-tags-trigger" class="sprite edit"></a>156 <a href="+edit" title="Edit tags" id="edit-tags-trigger" class="sprite edit"></a>
157 <script type="text/javascript">157 <script type="text/javascript">
158 YUI().use('event', 'node', 'bugs.bug_tags_entry', function(Y) {158 LPS.use('event', 'node', 'bugs.bug_tags_entry', function(Y) {
159 // XXX intellectronica 2009-04-16 bug #362309:159 // XXX intellectronica 2009-04-16 bug #362309:
160 // The load event fires very late on bug pages that take a160 // The load event fires very late on bug pages that take a
161 // long time to render, but we prefer to use it since the161 // long time to render, but we prefer to use it since the
@@ -295,7 +295,7 @@
295 button.style.display = 'none';295 button.style.display = 'none';
296 </script>296 </script>
297 <script type="text/javascript">297 <script type="text/javascript">
298 YUI().use('lp.comment', function(Y) {298 LPS.use('lp.comment', function(Y) {
299 var comment = new Y.lp.Comment();299 var comment = new Y.lp.Comment();
300 comment.render();300 comment.render();
301 });301 });
302302
=== modified file 'lib/lp/bugs/templates/bugtask-tasks-and-nominations-table-row.pt'
--- lib/lp/bugs/templates/bugtask-tasks-and-nominations-table-row.pt 2009-11-03 15:32:31 +0000
+++ lib/lp/bugs/templates/bugtask-tasks-and-nominations-table-row.pt 2009-12-07 23:15:25 +0000
@@ -185,7 +185,7 @@
185 class="bugtasks-table-row-init-script"185 class="bugtasks-table-row-init-script"
186 tal:condition="not:view/many_bugtasks"186 tal:condition="not:view/many_bugtasks"
187 tal:content="string:187 tal:content="string:
188 YUI().use('event', 'bugs.bugtask_index', function(Y) {188 LPS.use('event', 'bugs.bugtask_index', function(Y) {
189 Y.on('load',189 Y.on('load',
190 function(e) {190 function(e) {
191 Y.bugs.setup_bugtask_row(${view/js_config});191 Y.bugs.setup_bugtask_row(${view/js_config});
192192
=== modified file 'lib/lp/bugs/templates/bugtasks-and-nominations-table.pt'
--- lib/lp/bugs/templates/bugtasks-and-nominations-table.pt 2009-09-02 22:13:06 +0000
+++ lib/lp/bugs/templates/bugtasks-and-nominations-table.pt 2009-12-07 23:15:25 +0000
@@ -88,7 +88,7 @@
88 </span>88 </span>
8989
90 <script type="text/javascript" tal:content="string:90 <script type="text/javascript" tal:content="string:
91 YUI().use('event', 'bugs.bugtask_index', function(Y) {91 LPS.use('event', 'bugs.bugtask_index', function(Y) {
92 Y.on('load', function(e) {92 Y.on('load', function(e) {
93 Y.bugs.setup_me_too(${view/current_user_affected_js_status});93 Y.bugs.setup_me_too(${view/current_user_affected_js_status});
94 }, window);94 }, window);
9595
=== modified file 'lib/lp/bugs/templates/official-bug-target-manage-tags.pt'
--- lib/lp/bugs/templates/official-bug-target-manage-tags.pt 2009-09-04 17:03:00 +0000
+++ lib/lp/bugs/templates/official-bug-target-manage-tags.pt 2009-12-07 23:15:25 +0000
@@ -31,7 +31,7 @@
31 </script>31 </script>
32 <script tal:replace="structure view/tags_js_data" />32 <script tal:replace="structure view/tags_js_data" />
33 <script type="text/javascript">33 <script type="text/javascript">
34 YUI().use('event', 'bugs.official_bug_tag_management', function(Y) {34 LPS.use('event', 'bugs.official_bug_tag_management', function(Y) {
35 Y.on('domready', function(e) {35 Y.on('domready', function(e) {
36 Y.bugs.setup_official_bug_tag_management();36 Y.bugs.setup_official_bug_tag_management();
37 });37 });
3838
=== modified file 'lib/lp/code/templates/branch-import-details.pt'
--- lib/lp/code/templates/branch-import-details.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/code/templates/branch-import-details.pt 2009-12-07 23:15:25 +0000
@@ -32,7 +32,7 @@
32 Try again32 Try again
33 </a>33 </a>
34 <script type="text/javascript">34 <script type="text/javascript">
35 YUI().use('event', 'node', function(Y) {35 LPS.use('event', 'node', function(Y) {
36 Y.on("domready", function () { Y.one('#tryagainlink').setStyle('display', 'inline') });36 Y.on("domready", function () { Y.one('#tryagainlink').setStyle('display', 'inline') });
37 });37 });
38 </script>38 </script>
3939
=== modified file 'lib/lp/code/templates/branch-index.pt'
--- lib/lp/code/templates/branch-index.pt 2009-11-17 05:07:41 +0000
+++ lib/lp/code/templates/branch-index.pt 2009-12-07 23:15:25 +0000
@@ -47,7 +47,7 @@
47 </tal:devmode>47 </tal:devmode>
48 <script type="text/javascript"48 <script type="text/javascript"
49 tal:content="string:49 tal:content="string:
50 YUI().use('node', 'event', 'widget', 'plugin', 'overlay',50 LPS.use('node', 'event', 'widget', 'plugin', 'overlay',
51 'lazr.choiceedit', 'code.branchstatus',51 'lazr.choiceedit', 'code.branchstatus',
52 'code.branchmergeproposal.popupdiff',52 'code.branchmergeproposal.popupdiff',
53 function(Y) {53 function(Y) {
5454
=== modified file 'lib/lp/code/templates/branch-listing.pt'
--- lib/lp/code/templates/branch-listing.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/code/templates/branch-listing.pt 2009-12-07 23:15:25 +0000
@@ -41,7 +41,7 @@
41}41}
42registerLaunchpadFunction(hookUpFilterSubmission);42registerLaunchpadFunction(hookUpFilterSubmission);
4343
44YUI().use('io-base', 'node', 'json-parse', function(Y) {44LPS.use('io-base', 'node', 'json-parse', function(Y) {
4545
46function doUpdate(transaction_id, response, args) {46function doUpdate(transaction_id, response, args) {
47 json_values = Y.JSON.parse(response.responseText);47 json_values = Y.JSON.parse(response.responseText);
4848
=== modified file 'lib/lp/code/templates/branch-portlet-subscribers.pt'
--- lib/lp/code/templates/branch-portlet-subscribers.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/code/templates/branch-portlet-subscribers.pt 2009-12-07 23:15:25 +0000
@@ -41,7 +41,7 @@
41 string:&lt;script id='milestone-script' type='text/javascript'&gt;" />41 string:&lt;script id='milestone-script' type='text/javascript'&gt;" />
42 <!--42 <!--
4343
44 YUI().use('io-base', 'node', 'code.branchsubscription', function(Y) {44 LPS.use('io-base', 'node', 'code.branchsubscription', function(Y) {
4545
46 if(Y.UA.ie) {46 if(Y.UA.ie) {
47 Y.one('#subscriber-list').set('innerHTML',47 Y.one('#subscriber-list').set('innerHTML',
4848
=== modified file 'lib/lp/code/templates/branch-related-bugs-specs.pt'
--- lib/lp/code/templates/branch-related-bugs-specs.pt 2009-09-08 21:42:45 +0000
+++ lib/lp/code/templates/branch-related-bugs-specs.pt 2009-12-07 23:15:25 +0000
@@ -42,7 +42,7 @@
42 string:&lt;script id='branchlink-script' type='text/javascript'&gt;" />42 string:&lt;script id='branchlink-script' type='text/javascript'&gt;" />
43 <!--43 <!--
4444
45 YUI().use('io-base', 'code.branchlinks', function(Y) {45 LPS.use('io-base', 'code.branchlinks', function(Y) {
4646
47 if(Y.UA.ie) {47 if(Y.UA.ie) {
48 return;48 return;
4949
=== modified file 'lib/lp/code/templates/branchmergeproposal-generic-listing.pt'
--- lib/lp/code/templates/branchmergeproposal-generic-listing.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/code/templates/branchmergeproposal-generic-listing.pt 2009-12-07 23:15:25 +0000
@@ -24,7 +24,7 @@
24 </form>24 </form>
25<script type="text/javascript">25<script type="text/javascript">
2626
27YUI().use('node', function(Y) {27LPS.use('node', function(Y) {
2828
29 function submit_filter() {29 function submit_filter() {
30 Y.one('#filter_form').submit();30 Y.one('#filter_form').submit();
3131
=== modified file 'lib/lp/registry/browser/person.py'
--- lib/lp/registry/browser/person.py 2009-11-21 14:45:26 +0000
+++ lib/lp/registry/browser/person.py 2009-12-07 23:15:25 +0000
@@ -548,7 +548,10 @@
548 @action(_("Renew"), name="renew")548 @action(_("Renew"), name="renew")
549 def renew_action(self, action, data):549 def renew_action(self, action, data):
550 member = self.context.person550 member = self.context.person
551 member.renewTeamMembership(self.context.team)551 # This if-statement prevents an exception if the user
552 # double clicks on the submit button.
553 if self.context.canBeRenewedByMember():
554 member.renewTeamMembership(self.context.team)
552 self.request.response.addInfoNotification(555 self.request.response.addInfoNotification(
553 _("Membership renewed until ${date}.", mapping=dict(556 _("Membership renewed until ${date}.", mapping=dict(
554 date=self.context.dateexpires.strftime('%Y-%m-%d'))))557 date=self.context.dateexpires.strftime('%Y-%m-%d'))))
555558
=== modified file 'lib/lp/registry/browser/tests/productrelease-views.txt'
--- lib/lp/registry/browser/tests/productrelease-views.txt 2009-09-11 16:00:24 +0000
+++ lib/lp/registry/browser/tests/productrelease-views.txt 2009-12-07 23:15:25 +0000
@@ -130,7 +130,7 @@
130 >>> script = find_tag_by_id(view.render(), 'milestone-script')130 >>> script = find_tag_by_id(view.render(), 'milestone-script')
131 >>> print script131 >>> print script
132 <script id="milestone-script" type="text/javascript">132 <script id="milestone-script" type="text/javascript">
133 YUI().use(... 'lp.milestoneoverlay'...133 LPS.use(... 'lp.milestoneoverlay'...
134 var milestone_form_uri = '.../app/simple/+addmilestone/++form++';134 var milestone_form_uri = '.../app/simple/+addmilestone/++form++';
135 var series_uri = '/app/simple';135 var series_uri = '/app/simple';
136 ...136 ...
137137
=== modified file 'lib/lp/registry/templates/object-timeline-graph.pt'
--- lib/lp/registry/templates/object-timeline-graph.pt 2009-11-24 09:30:01 +0000
+++ lib/lp/registry/templates/object-timeline-graph.pt 2009-12-07 23:15:25 +0000
@@ -32,7 +32,7 @@
32 include_inactive = false;32 include_inactive = false;
33 }33 }
3434
35 YUI().use('registry.timeline', 'node', function(Y) {35 LPS.use('registry.timeline', 'node', function(Y) {
36 Y.on('domready', function(e) {36 Y.on('domready', function(e) {
37 if (Y.UA.ie) {37 if (Y.UA.ie) {
38 return;38 return;
3939
=== modified file 'lib/lp/registry/templates/person-macros.pt'
--- lib/lp/registry/templates/person-macros.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/registry/templates/person-macros.pt 2009-12-07 23:15:25 +0000
@@ -190,7 +190,7 @@
190 condition="private_prefix">190 condition="private_prefix">
191 <script type="text/javascript"191 <script type="text/javascript"
192 tal:content="string:192 tal:content="string:
193 YUI().use('node', 'event', function(Y) {193 LPS.use('node', 'event', function(Y) {
194 // Prepend/remove 'private-' from team name based on visibility194 // Prepend/remove 'private-' from team name based on visibility
195 // setting. User can choose to edit it back out, if they wish.195 // setting. User can choose to edit it back out, if they wish.
196 function visibility_on_change(e) {196 function visibility_on_change(e) {
197197
=== modified file 'lib/lp/registry/templates/product-new.pt'
--- lib/lp/registry/templates/product-new.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/registry/templates/product-new.pt 2009-12-07 23:15:25 +0000
@@ -14,7 +14,7 @@
14 * details widgets until the user states that the project they are14 * details widgets until the user states that the project they are
15 * registering is not a duplicate.15 * registering is not a duplicate.
16 */16 */
17YUI().use('node', 'lazr.effects', function(Y) {17LPS.use('node', 'lazr.effects', function(Y) {
18 Y.on('domready', function() {18 Y.on('domready', function() {
19 /* These two regexps serve slightly different purposes. The first19 /* These two regexps serve slightly different purposes. The first
20 * finds the leftmost run of valid url characters for the autofill20 * finds the leftmost run of valid url characters for the autofill
2121
=== modified file 'lib/lp/registry/templates/productrelease-add-from-series.pt'
--- lib/lp/registry/templates/productrelease-add-from-series.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/registry/templates/productrelease-add-from-series.pt 2009-12-07 23:15:25 +0000
@@ -14,7 +14,7 @@
14 <tal:script14 <tal:script
15 replace="structure15 replace="structure
16 string:&lt;script id='milestone-script' type='text/javascript'&gt;" />16 string:&lt;script id='milestone-script' type='text/javascript'&gt;" />
17 YUI().use('node', 'lp.milestoneoverlay', function (Y) {17 LPS.use('node', 'lp.milestoneoverlay', function (Y) {
1818
19 // This is a value for the SELECT OPTION which is passed with19 // This is a value for the SELECT OPTION which is passed with
20 // the SELECT's "change" event. It includes some symbols that are not20 // the SELECT's "change" event. It includes some symbols that are not
2121
=== modified file 'lib/lp/registry/templates/teammembership-index.pt'
--- lib/lp/registry/templates/teammembership-index.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/registry/templates/teammembership-index.pt 2009-12-07 23:15:25 +0000
@@ -20,7 +20,7 @@
20 use-macro="context/@@launchpad_widget_macros/yui2calendar-dependencies" />20 use-macro="context/@@launchpad_widget_macros/yui2calendar-dependencies" />
2121
22 <script type="text/javascript">22 <script type="text/javascript">
23 YUI().use('node', 'lp.calendar', function(Y) {23 LPS.use('node', 'lp.calendar', function(Y) {
24 // Ensure that when the picker is used the radio button switches24 // Ensure that when the picker is used the radio button switches
25 // from 'Never' to 'On' and the expiry field is enabled.25 // from 'Never' to 'On' and the expiry field is enabled.
26 Y.on("available", function(e) {26 Y.on("available", function(e) {
2727
=== modified file 'lib/lp/registry/templates/timeline-macros.pt'
--- lib/lp/registry/templates/timeline-macros.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/registry/templates/timeline-macros.pt 2009-12-07 23:15:25 +0000
@@ -35,7 +35,7 @@
35 if (auto_resize == 'true') {35 if (auto_resize == 'true') {
36 timeline_url += 'resize_frame=timeline-iframe&';36 timeline_url += 'resize_frame=timeline-iframe&';
37 }37 }
38 YUI().use('node', function(Y) {38 LPS.use('node', function(Y) {
39 if (Y.UA.ie) {39 if (Y.UA.ie) {
40 return;40 return;
41 }41 }
4242
=== modified file 'lib/lp/soyuz/templates/archive-edit-dependencies.pt'
--- lib/lp/soyuz/templates/archive-edit-dependencies.pt 2009-11-12 17:26:17 +0000
+++ lib/lp/soyuz/templates/archive-edit-dependencies.pt 2009-12-07 23:15:25 +0000
@@ -62,7 +62,7 @@
62 </div> <!-- launchpad_form -->62 </div> <!-- launchpad_form -->
6363
64<script type="text/javascript">64<script type="text/javascript">
65 YUI().use("node", function(Y) {65 LPS.use("node", function(Y) {
6666
67 // Highlight (setting bold font-weight) the label for the67 // Highlight (setting bold font-weight) the label for the
68 // selected option in a given NodesList. Assumes the input is68 // selected option in a given NodesList. Assumes the input is
6969
=== modified file 'lib/lp/soyuz/templates/archive-macros.pt'
--- lib/lp/soyuz/templates/archive-macros.pt 2009-11-04 19:59:16 +0000
+++ lib/lp/soyuz/templates/archive-macros.pt 2009-12-07 23:15:25 +0000
@@ -10,7 +10,7 @@
10 </tal:comment>10 </tal:comment>
1111
12<script type="text/javascript">12<script type="text/javascript">
13YUI().use('node', 'io-base', 'lazr.anim', 'soyuz-base', function(Y) {13LPS.use('node', 'io-base', 'lazr.anim', 'soyuz-base', function(Y) {
1414
1515
16/*16/*
1717
=== modified file 'lib/lp/soyuz/templates/archive-packages.pt'
--- lib/lp/soyuz/templates/archive-packages.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/soyuz/templates/archive-packages.pt 2009-12-07 23:15:25 +0000
@@ -23,7 +23,7 @@
23 </tal:devmode>23 </tal:devmode>
24 <script type="text/javascript" id="repository-size-update"24 <script type="text/javascript" id="repository-size-update"
25 tal:condition="view/archive_url">25 tal:condition="view/archive_url">
26YUI().use('io-base', 'lazr.anim', 'node', 'soyuz-base',26LPS.use('io-base', 'lazr.anim', 'node', 'soyuz-base',
27 'soyuz.update_archive_build_statuses', function(Y) {27 'soyuz.update_archive_build_statuses', function(Y) {
2828
2929
3030
=== modified file 'lib/lp/soyuz/templates/archive-subscribers.pt'
--- lib/lp/soyuz/templates/archive-subscribers.pt 2009-09-29 07:21:40 +0000
+++ lib/lp/soyuz/templates/archive-subscribers.pt 2009-12-07 23:15:25 +0000
@@ -98,7 +98,7 @@
98 </form>98 </form>
99 </div><!-- class="portlet" -->99 </div><!-- class="portlet" -->
100 <script type="text/javascript" id="setup-archivesubscribers-index">100 <script type="text/javascript" id="setup-archivesubscribers-index">
101 YUI().use('soyuz.archivesubscribers_index', function(Y) {101 LPS.use('soyuz.archivesubscribers_index', function(Y) {
102 Y.soyuz.setup_archivesubscribers_index();102 Y.soyuz.setup_archivesubscribers_index();
103 });103 });
104 </script>104 </script>
105105
=== modified file 'lib/lp/translations/browser/language.py'
--- lib/lp/translations/browser/language.py 2009-10-31 11:06:44 +0000
+++ lib/lp/translations/browser/language.py 2009-12-07 23:15:25 +0000
@@ -29,6 +29,7 @@
29 enabled_with_permission, GetitemNavigation, LaunchpadEditFormView,29 enabled_with_permission, GetitemNavigation, LaunchpadEditFormView,
30 LaunchpadFormView, LaunchpadView, Link, NavigationMenu)30 LaunchpadFormView, LaunchpadView, Link, NavigationMenu)
31from lp.translations.utilities.pluralforms import make_friendly_plural_forms31from lp.translations.utilities.pluralforms import make_friendly_plural_forms
32from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
3233
33from canonical.widgets import LabeledMultiCheckBoxWidget34from canonical.widgets import LabeledMultiCheckBoxWidget
3435
@@ -202,6 +203,13 @@
202203
203 return pluralforms_list204 return pluralforms_list
204205
206 @property
207 def add_question_url(self):
208 rosetta = getUtility(ILaunchpadCelebrities).lp_translations
209 return canonical_url(
210 rosetta,
211 view_name='+addquestion',
212 rootsite='answers')
205213
206class LanguageAdminView(LaunchpadEditFormView):214class LanguageAdminView(LaunchpadEditFormView):
207 """Handle an admin form submission."""215 """Handle an admin form submission."""
208216
=== modified file 'lib/lp/translations/stories/distroseries/xx-distroseries-templates.txt'
--- lib/lp/translations/stories/distroseries/xx-distroseries-templates.txt 2009-10-30 10:09:17 +0000
+++ lib/lp/translations/stories/distroseries/xx-distroseries-templates.txt 2009-12-07 23:15:25 +0000
@@ -1,11 +1,15 @@
1= Templates view for DistroSeries =1
2
3Templates view for DistroSeries
4===============================
25
3The +templates view for DistroSeries gives an overview of the translation6The +templates view for DistroSeries gives an overview of the translation
4templates in this series and provides easy access to the various subpages of7templates in this series and provides easy access to the various subpages of
5each template.8each template.
69
710
8== Getting there ==11Getting there
12-------------
913
10To get to the listing of all templates, one needs to use the link14To get to the listing of all templates, one needs to use the link
11from the distribution series translations page.15from the distribution series translations page.
@@ -16,7 +20,45 @@
16 >>> print user_browser.url20 >>> print user_browser.url
17 http://translations.launchpad.dev/ubuntu/hoary/+templates21 http://translations.launchpad.dev/ubuntu/hoary/+templates
1822
19== The templates table ==23The templates table
24-------------------
25
26Full template listing for a distribution series is reached by following
27a link from the distribution series translations page.
28
29 >>> anon_browser.open(
30 ... 'http://translations.launchpad.dev/ubuntu/hoary')
31 >>> anon_browser.getLink('full list of templates').click()
32
33Full listing of templates shows source package name, template name and
34the date of last update for this distribution series.
35
36 >>> table = find_tag_by_id(anon_browser.contents, 'templates_table')
37 >>> print extract_text(table)
38 Source package Template name Last update
39 evolution disabled-template 2007-01-05
40 evolution evolution-2.2 2005-05-06
41 evolution man 2006-08-14
42 mozilla pkgconf-mozilla 2005-05-06
43 pmount man 2006-08-14
44 pmount pmount 2005-05-06
45
46
47Logged-in users will see a link from distro series
48 >>> user_browser.open(
49 ... 'http://translations.launchpad.dev/ubuntu/hoary')
50 >>> user_browser.getLink('full list of templates').click()
51
52Logged-in users can also choose to download all translations for each
53of the templates.
54
55 >>> table = find_tag_by_id(user_browser.contents, 'templates_table')
56 >>> print extract_text(table)
57 Source package Template name Last update Actions
58 evolution disabled-template 2007-01-05 Download
59 ...
60 mozilla pkgconf-mozilla 2005-05-06 Download
61 ...
2062
21Administrator can see all editing options.63Administrator can see all editing options.
2264
@@ -28,16 +70,17 @@
2870
29 >>> table = find_tag_by_id(admin_browser.contents, 'templates_table')71 >>> table = find_tag_by_id(admin_browser.contents, 'templates_table')
30 >>> print extract_text(table)72 >>> print extract_text(table)
31 Source package Template name Actions73 Source package Template name Last update Actions
32 evolution disabled-template Edit Upload Download Administer74 evolution disabled-template 2007-01-05 Edit Upload Download Administer
33 evolution evolution-2.2 Edit Upload Download Administer75 evolution evolution-2.2 2005-05-06 Edit Upload Download Administer
34 evolution man Edit Upload Download Administer76 evolution man 2006-08-14 Edit Upload Download Administer
35 mozilla pkgconf-mozilla Edit Upload Download Administer77 mozilla pkgconf-mozilla 2005-05-06 Edit Upload Download Administer
36 pmount man Edit Upload Download Administer78 pmount man 2006-08-14 Edit Upload Download Administer
37 pmount pmount Edit Upload Download Administer79 pmount pmount 2005-05-06 Edit Upload Download Administer
3880
3981
40== Links to the templates ==82Links to the templates
83----------------------
4184
42Clicking on a template name will take the user to that template's overview85Clicking on a template name will take the user to that template's overview
43page.86page.
4487
=== modified file 'lib/lp/translations/stories/productseries/xx-productseries-templates.txt'
--- lib/lp/translations/stories/productseries/xx-productseries-templates.txt 2009-10-30 10:09:17 +0000
+++ lib/lp/translations/stories/productseries/xx-productseries-templates.txt 2009-12-07 23:15:25 +0000
@@ -1,13 +1,18 @@
1= Templates view for ProductSeries =1
2
3Templates view for ProductSeries
4================================
25
3The +templates view for ProductSeries gives an overview of the translation6The +templates view for ProductSeries gives an overview of the translation
4templates in this series and provides easy access to the various subpages of7templates in this series and provides easy access to the various subpages of
5each template.8each template.
69
7== Preparation ==10
811Preparation
9To test the ordering of templates in the listing, we need another template12-----------
10that is new but must appear at the top of the list.13
14To test the ordering of templates in the listing, we need another
15template that is new but must appear at the top of the list.
1116
12 >>> login('foo.bar@canonical.com')17 >>> login('foo.bar@canonical.com')
13 >>> from zope.component import getUtility18 >>> from zope.component import getUtility
@@ -18,7 +23,9 @@
18 ... name='at-the-top')23 ... name='at-the-top')
19 >>> logout()24 >>> logout()
2025
21== Getting there ==26
27Getting there
28-------------
2229
23To get to the listing of all templates, one needs to use the link30To get to the listing of all templates, one needs to use the link
24from the product series translations page.31from the product series translations page.
@@ -30,16 +37,17 @@
30 http://translations.launchpad.dev/evolution/trunk/+templates37 http://translations.launchpad.dev/evolution/trunk/+templates
3138
3239
33== The templates table ==40The templates table
41-------------------
3442
35The page shows a table of all templates and links to their subpages.43The page shows a table of all templates and links to their subpages.
3644
37 >>> table = find_tag_by_id(user_browser.contents, 'templates_table')45 >>> table = find_tag_by_id(user_browser.contents, 'templates_table')
38 >>> print extract_text(table)46 >>> print extract_text(table)
39 Template name Actions47 Template name Last update Actions
40 at-the-top Download48 at-the-top ... Download
41 evolution-2.2 Download49 evolution-2.2 2005-08-25 Download
42 evolution-2.2-test Download50 evolution-2.2-test 2006-12-13 Download
4351
44If an administrator views this page, links to the templates admin page are52If an administrator views this page, links to the templates admin page are
45shown, too.53shown, too.
@@ -48,13 +56,14 @@
48 ... 'http://translations.launchpad.dev/evolution/trunk/+templates')56 ... 'http://translations.launchpad.dev/evolution/trunk/+templates')
49 >>> table = find_tag_by_id(admin_browser.contents, 'templates_table')57 >>> table = find_tag_by_id(admin_browser.contents, 'templates_table')
50 >>> print extract_text(table)58 >>> print extract_text(table)
51 Template name Actions59 Template name Last update Actions
52 at-the-top Edit Upload Download Administer60 at-the-top ... Edit Upload Download Administer
53 evolution-2.2 Edit Upload Download Administer61 evolution-2.2 2005-08-25 Edit Upload Download Administer
54 evolution-2.2-test Edit Upload Download Administer62 evolution-2.2-test 2006-12-13 Edit Upload Download Administer
5563
5664
57== Links to the templates ==65Links to the templates
66----------------------
5867
59Clicking on a template name will take the user to that template's overview68Clicking on a template name will take the user to that template's overview
60page.69page.
6170
=== modified file 'lib/lp/translations/stories/standalone/xx-language.txt'
--- lib/lp/translations/stories/standalone/xx-language.txt 2009-10-31 11:06:44 +0000
+++ lib/lp/translations/stories/standalone/xx-language.txt 2009-12-07 23:15:25 +0000
@@ -1,6 +1,15 @@
1
2
3Languages view
4==============
5
1Here is the tale of languages. We will see how to create, find and edit6Here is the tale of languages. We will see how to create, find and edit
2them.7them.
38
9
10Getting there
11-------------
12
4Launchpad Translations has a main page.13Launchpad Translations has a main page.
514
6 >>> admin_browser.open('http://translations.launchpad.dev/')15 >>> admin_browser.open('http://translations.launchpad.dev/')
@@ -11,7 +20,12 @@
11 >>> print admin_browser.url20 >>> print admin_browser.url
12 http://translations.launchpad.dev/+languages21 http://translations.launchpad.dev/+languages
1322
14Following the link, there is a form to add new languages.23
24Adding new languages
25--------------------
26
27Following the link from the translations main page, there is a form to
28add new languages.
1529
16 >>> admin_browser.getLink('Add new language').click()30 >>> admin_browser.getLink('Add new language').click()
17 >>> print admin_browser.url31 >>> print admin_browser.url
@@ -65,11 +79,16 @@
65 ...79 ...
66 LinkNotFoundError80 LinkNotFoundError
6781
68 >>> user_browser.open('http://translations.launchpad.dev/+languages/+add')82 >>> user_browser.open(
83 ... 'http://translations.launchpad.dev/+languages/+add')
69 Traceback (most recent call last):84 Traceback (most recent call last):
70 ...85 ...
71 Unauthorized:...86 Unauthorized:...
7287
88
89Searching for a language
90------------------------
91
73From the top languages page, anyone can find languages.92From the top languages page, anyone can find languages.
7493
75 >>> browser.open('http://translations.launchpad.dev/+languages')94 >>> browser.open('http://translations.launchpad.dev/+languages')
@@ -82,7 +101,11 @@
82 >>> print browser.url101 >>> print browser.url
83 http://translations.launchpad.dev/+languages/+index?find=Spanish102 http://translations.launchpad.dev/+languages/+index?find=Spanish
84103
85And following one of the found languages, we can see a brief information104
105Read language information
106-------------------------
107
108Following one of the found languages, we can see a brief information
86about the selected language.109about the selected language.
87110
88 >>> browser.getLink('Spanish').click()111 >>> browser.getLink('Spanish').click()
@@ -128,14 +151,50 @@
128 ...Uruguay...151 ...Uruguay...
129 ...Venezuela...152 ...Venezuela...
130153
131 >>> topcontributors_portlet = find_portlet(browser.contents, 'Top contributors')154 >>> topcontributors_portlet = find_portlet(
155 ... browser.contents, 'Top contributors')
132 >>> print topcontributors_portlet156 >>> print topcontributors_portlet
133 <...157 <...
134 ...Carlos Perelló Marín...158 ...Carlos Perelló Marín...
135159
160Our test sample data does not know about plural forms of
161Abkhazian and about countries where this language is spoken.
162
163We will see a note about missing plural forms and a link to Rosetta
164add question page for informing Rosetta admin about the right plural
165form.
166
167 >>> browser.open('http://translations.launchpad.dev/+languages/ab')
168 >>> print extract_text(find_portlet(browser.contents, 'Plural forms'
169 ... ).renderContents())
170 Plural forms
171 Unfortunately, Launchpad doesn't know the plural
172 form information for this language...
173
174 >>> print browser.getLink(id='plural_question').url
175 http://answers.launchpad.dev/rosetta/+addquestion
176
177We will see a note that Launchpad does not know in which countries
178this language is spoken and a link to add question page for informing
179Rosetta admin about the countries where this page is officially spoken.
180
181 >>> countries_portlet = find_portlet(browser.contents, 'Countries')
182 >>> print countries_portlet
183 <...
184 Abkhazian is not registered as being spoken in any
185 country...
186
187 >>> print browser.getLink(id='country_question').url
188 http://answers.launchpad.dev/rosetta/+addquestion
189
190
191Edit language information
192-------------------------
193
136Finally, there is the edit form to change language basic information.194Finally, there is the edit form to change language basic information.
137195
138 >>> user_browser.open('http://translations.launchpad.dev/+languages/es')196 >>> user_browser.open(
197 ... 'http://translations.launchpad.dev/+languages/es')
139 >>> print user_browser.url198 >>> print user_browser.url
140 http://translations.launchpad.dev/+languages/es199 http://translations.launchpad.dev/+languages/es
141200
@@ -146,7 +205,8 @@
146 ...205 ...
147 LinkNotFoundError206 LinkNotFoundError
148207
149 >>> user_browser.open('http://translations.launchpad.dev/+languages/es/+admin')208 >>> user_browser.open(
209 ... 'http://translations.launchpad.dev/+languages/es/+admin')
150 Traceback (most recent call last):210 Traceback (most recent call last):
151 ...211 ...
152 Unauthorized:...212 Unauthorized:...
@@ -155,7 +215,8 @@
155215
156 >>> from canonical.launchpad.testing.pages import strip_label216 >>> from canonical.launchpad.testing.pages import strip_label
157217
158 >>> admin_browser.open('http://translations.launchpad.dev/+languages/es')218 >>> admin_browser.open(
219 ... 'http://translations.launchpad.dev/+languages/es')
159 >>> print admin_browser.url220 >>> print admin_browser.url
160 http://translations.launchpad.dev/+languages/es221 http://translations.launchpad.dev/+languages/es
161222
162223
=== modified file 'lib/lp/translations/templates/language-index.pt'
--- lib/lp/translations/templates/language-index.pt 2009-09-17 14:45:59 +0000
+++ lib/lp/translations/templates/language-index.pt 2009-12-07 23:15:25 +0000
@@ -43,8 +43,10 @@
43 <p class="helpwanted">43 <p class="helpwanted">
44 Unfortunately, Launchpad doesn't know the plural form44 Unfortunately, Launchpad doesn't know the plural form
45 information for this language. If you know it, please open a45 information for this language. If you know it, please open a
46 <a href="/rosetta/+addticket">ticket</a> with that information,46 <a id='plural_question'
47 so we can add it to Launchpad.47 tal:attributes="href view/add_question_url"
48 >question</a>
49 with that information, so we can add it to Launchpad.
48 </p>50 </p>
49 </tal:has_not_pluralforms>51 </tal:has_not_pluralforms>
50 </div>52 </div>
@@ -124,8 +126,11 @@
124 </tal:language>126 </tal:language>
125 is not registered as being spoken in any country. If you know127 is not registered as being spoken in any country. If you know
126 about a country that officially speaks this language, please128 about a country that officially speaks this language, please
127 open a <a href="/rosetta/+addticket">ticket</a> with that129 open a
128 information, so we can add it to Launchpad.130 <a id='country_question'
131 tal:attributes="href view/add_question_url"
132 >question</a>
133 with that information, so we can add it to Launchpad.
129 </p>134 </p>
130 </tal:has_not_countries>135 </tal:has_not_countries>
131 </div>136 </div>
132137
=== modified file 'lib/lp/translations/templates/object-templates.pt'
--- lib/lp/translations/templates/object-templates.pt 2009-11-24 19:23:52 +0000
+++ lib/lp/translations/templates/object-templates.pt 2009-12-07 23:15:25 +0000
@@ -26,16 +26,16 @@
26 </style>26 </style>
27 <style tal:condition="view/is_distroseries" type="text/css">27 <style tal:condition="view/is_distroseries" type="text/css">
28 #templates_table {28 #templates_table {
29 width: 72em;29 width: 79em;
30 }30 }
31 </style>31 </style>
32 <style tal:condition="not:view/is_distroseries" type="text/css">32 <style tal:condition="not:view/is_distroseries" type="text/css">
33 #templates_table {33 #templates_table {
34 width: 50em;34 width: 58em;
35 }35 }
36 </style>36 </style>
37 <script language="JavaScript" type="text/javascript">37 <script language="JavaScript" type="text/javascript">
38 YUI().use('node-base', 'event-delegate', function(Y) {38 LPS.use('node-base', 'event-delegate', function(Y) {
39 Y.on('domready', function(e) {39 Y.on('domready', function(e) {
40 Y.all('#templates_table .template_links').addClass(40 Y.all('#templates_table .template_links').addClass(
41 'inactive_links');41 'inactive_links');
@@ -75,6 +75,7 @@
75 <th tal:condition="view/is_distroseries"75 <th tal:condition="view/is_distroseries"
76 class="sourcepackage_column">Source package</th>76 class="sourcepackage_column">Source package</th>
77 <th class="template_column">Template name</th>77 <th class="template_column">Template name</th>
78 <th class="lastupdate_column">Last update</th>
78 <th class="actions_column"79 <th class="actions_column"
79 tal:condition="context/required:launchpad.AnyPerson">80 tal:condition="context/required:launchpad.AnyPerson">
80 Actions</th>81 Actions</th>
@@ -88,6 +89,22 @@
88 </td>89 </td>
89 <td class="template_column"><a tal:attributes="href template/fmt:url"90 <td class="template_column"><a tal:attributes="href template/fmt:url"
90 tal:content="template/name">Template name</a></td>91 tal:content="template/name">Template name</a></td>
92 <td class="lastupdate_column">
93 <span class="sortkey"
94 tal:condition="template/date_last_updated"
95 tal:content="template/date_last_updated/fmt:datetime">
96 time sort key
97 </span>
98 <span class="lastupdate_column"
99 tal:condition="template/date_last_updated"
100 tal:attributes="
101 title template/date_last_updated/fmt:datetime"
102 tal:content="
103 template/date_last_updated/fmt:approximatedate"
104 >
105 2009-09-23
106 </span>
107 </td>
91 <td class="actions_column"108 <td class="actions_column"
92 tal:condition="context/required:launchpad.AnyPerson">109 tal:condition="context/required:launchpad.AnyPerson">
93 <div class="template_links">110 <div class="template_links">
94111
=== modified file 'lib/lp/translations/templates/pofile-export.pt'
--- lib/lp/translations/templates/pofile-export.pt 2009-11-10 21:04:19 +0000
+++ lib/lp/translations/templates/pofile-export.pt 2009-12-07 23:15:25 +0000
@@ -13,7 +13,7 @@
13 }13 }
14 </style>14 </style>
15 <script type="text/javascript">15 <script type="text/javascript">
16 YUI().use('node', 'event', function(Y){16 LPS.use('node', 'event', function(Y){
17 Y.on('domready', function(){17 Y.on('domready', function(){
18 // The pochanged option is only available for the PO format.18 // The pochanged option is only available for the PO format.
19 var formatlist = Y.one('#div_format select');19 var formatlist = Y.one('#div_format select');
2020
=== modified file 'lib/lp/translations/templates/pofile-translate.pt'
--- lib/lp/translations/templates/pofile-translate.pt 2009-11-04 19:59:16 +0000
+++ lib/lp/translations/templates/pofile-translate.pt 2009-12-07 23:15:25 +0000
@@ -20,7 +20,7 @@
20 <script type="text/javascript">20 <script type="text/javascript">
21 registerLaunchpadFunction(insertAllExpansionButtons);21 registerLaunchpadFunction(insertAllExpansionButtons);
2222
23 YUI().use('node', 'cookie', 'anim', 'lp.pofile', function(Y) {23 LPS.use('node', 'cookie', 'anim', 'lp.pofile', function(Y) {
2424
25 var hide_notification = function(node) {25 var hide_notification = function(node) {
26 var hide_anim = new Y.Anim({26 var hide_anim = new Y.Anim({
2727
=== modified file 'lib/lp/translations/templates/translation-import-queue-macros.pt'
--- lib/lp/translations/templates/translation-import-queue-macros.pt 2009-11-20 14:15:34 +0000
+++ lib/lp/translations/templates/translation-import-queue-macros.pt 2009-12-07 23:15:25 +0000
@@ -18,7 +18,7 @@
18 </script>18 </script>
1919
20 <script type="text/javascript">20 <script type="text/javascript">
21 YUI().use( 'translations', 'event', function(Y) {21 LPS.use( 'translations', 'event', function(Y) {
22 Y.on('domready', function(e) {22 Y.on('domready', function(e) {
23 Y.translations.initialize_import_queue_page(Y);23 Y.translations.initialize_import_queue_page(Y);
24 });24 });
2525
=== modified file 'lib/lp/translations/templates/translationimportqueueentry-index.pt'
--- lib/lp/translations/templates/translationimportqueueentry-index.pt 2009-11-04 13:56:17 +0000
+++ lib/lp/translations/templates/translationimportqueueentry-index.pt 2009-12-07 23:15:25 +0000
@@ -14,7 +14,7 @@
14 }14 }
15 </style>15 </style>
16 <script type="text/javascript">16 <script type="text/javascript">
17 YUI().use('node', 'lazr.anim', function(Y) {17 LPS.use('node', 'lazr.anim', function(Y) {
18 var fields = {'POT':18 var fields = {'POT':
19 ['field.name', 'field.translation_domain',19 ['field.name', 'field.translation_domain',
20 'field.languagepack'],20 'field.languagepack'],
2121
=== modified file 'lib/lp/translations/templates/translationmessage-translate.pt'
--- lib/lp/translations/templates/translationmessage-translate.pt 2009-09-17 07:28:30 +0000
+++ lib/lp/translations/templates/translationmessage-translate.pt 2009-12-07 23:15:25 +0000
@@ -18,7 +18,7 @@
18 tal:define="lp_js string:${icingroot}/build"18 tal:define="lp_js string:${icingroot}/build"
19 tal:attributes="src string:${lp_js}/translations/pofile.js"></script>19 tal:attributes="src string:${lp_js}/translations/pofile.js"></script>
20 <script type="text/javascript">20 <script type="text/javascript">
21 YUI().use('node', 'lp.pofile', function(Y) {21 LPS.use('node', 'lp.pofile', function(Y) {
22 Y.on('domready', Y.lp.pofile.setupSuggestionDismissal);22 Y.on('domready', Y.lp.pofile.setupSuggestionDismissal);
23 });23 });
24 </script>24 </script>

Subscribers

People subscribed via source and target branches

to status/vote changes: