Merge lp:~adiroiban/launchpad/bug-406477 into lp:launchpad
- bug-406477
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Данило Шеган |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~adiroiban/launchpad/bug-406477 |
Merge into: | lp:launchpad |
Diff against target: |
708 lines (+380/-101) 11 files modified
lib/canonical/launchpad/icing/style-3-0.css (+13/-0) lib/canonical/launchpad/security.py (+74/-33) lib/lp/testing/factory.py (+4/-1) lib/lp/translations/browser/configure.zcml (+1/-1) lib/lp/translations/browser/potemplate.py (+2/-2) lib/lp/translations/configure.zcml (+1/-1) lib/lp/translations/stories/distroseries/xx-distroseries-templates.txt (+72/-15) lib/lp/translations/stories/standalone/xx-potemplate-admin.txt (+42/-2) lib/lp/translations/stories/standalone/xx-potemplate-index.txt (+70/-1) lib/lp/translations/templates/object-templates.pt (+100/-44) lib/lp/translations/templates/potemplate-index.pt (+1/-1) |
To merge this branch: | bzr merge lp:~adiroiban/launchpad/bug-406477 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Данило Шеган (community) | Approve | ||
Review via email: mp+15793@code.launchpad.net |
Commit message
Use launchpad.
Description of the change
Adi Roiban (adiroiban) wrote : | # |
Данило Шеган (danilo) wrote : | # |
Adi, thanks a lot for working on this. In general, there's one major
complaint about how you implemented permissions. There's a number of
narrative/stylistic suggestions as well, though they are obviously of
lower priority (though still important).
If I sound patronising anywhere, please forgive me: I am not sure how
much of our code base or styling guides you have already had a chance to
figure out yourself, so I might be saying things you already know :)
Anyway, this would need further improvements, but is overall a great
step in the right direction!
review needsfixing
У уто, 08. 12 2009. у 03:15 +0000, Adi Roiban пише:
> == Implementation details ==
>
> After asking a pre-implementation review from Danilo, he suggest I
> should use launchpad.
> launchpad.Admin translation.
>
> The previous administration privileges for IPOTemplate was assigned
> only to RosettaAdmins.
> Now it was change to all RosettaAdmin + owner of
> distro.
>
> == Tests ==
>
> There were no test covering the use case of distribution translations
> coordinator admin rights to templates, so this was added to
> distroseries-
>
> Also the previous rosetta-
> administrative links.
FWIW, sometimes we avoid having too many tests in "pagetests" (i.e.
stories), because they are very fragile. Just moving stuff around in
the layout sometimes breaks them, so we do not test for all possible
cases in them.
> ./bin/test -ct "distroseries-
> ./bin/test -ct "rosetta-
FWIW, you can pass -t to bin/test multiple times, eg.
bin/test -vvct distroseries-
(if you really must have colorized output; -vv is basically a standard
verbose mode LP developers use, and -vvv gives you test timings as well)
> == Demo and Q/A ==
>
> Make sure you are a member of Ubuntu Translation Coordinators team
> (ubuntu-
> https:/
>
> Go to the Distro +template page
> https:/
>
> You should see the Administer page for Evolution, disabled-template .
>
> As a member of Ubuntu Translation Coordinators team you should be able
> to administer it, just like any other template from that table.
>
> Login as a normal user, you should not see the administration links
> (only Download), and when trying to manually enter the admin url
> (https:/
While playing with it, I discovered that you see disabled templates even
if you are not logged in, or if you don't have sufficient privileges.
Clicking on it gives you a 'not found' error. It's probably not your
code, but it'd be useful to fix it along the way and show disabled
templates only if someone has TranslationsAdmin privilege on them.
> === modified file 'lib/canonical/
> --- lib/canonical/
> +++ lib/canonical/
> @@ -479,6 +479,28 @@...
Adi Roiban (adiroiban) wrote : | # |
Hi,
Thank you very much for taking the time and reviewing this branch.
It was really ugly. So don't worry, I deserve it :)
I agree that is hard to cover all test paths, is just that right now I don't know what should be tested and what not, and where is the border between a useful test and a bloated test.
Is a test is not needed, feel free to comment and I will delete it.
I'm testing using a single command line, but in MP I put them in different lines to improve readability... stupid thing to do :). For the future I'll put them in a single line.
Disabled templates are only displayed for TranslationsAdmins.
The previous behavior was validated by test stories.
I didn't knew Ubuntu is already a celebrity.
I prefer to keep with Ubuntu, without creating a new distribution. It will just make the story to complicated.
Added a "license=yes" to MakeTranslator , to also sign the translation license.. otherwise that translator has no edit rights.
I'm sorry for failing to write proper stories. Hope I can improve my narrator skills.
Hope the permission are right.
I added stories for testing administration and editing of POTemplate and PoTemplateSubset.
Thank you again for taking the time reviewing this branch.
If there are further issues, have no mercy! :)
It is ok to have these filenames?
xx-potemplate-
xx-potemplate-
xx-rosetta-
xx-rosetta-
I was thinking at removing rosetta from the filename.
Данило Шеган (danilo) wrote : | # |
Hi Adi,
Thanks for all the effort you are putting into this: you are not just
solving the bug, you are helping improve the Launchpad code quality as
well (which is why it's a bit harder than expected :). There's still
some work needed on this branch.
У сре, 09. 12 2009. у 01:03 +0000, Adi Roiban пише:
> Thank you very much for taking the time and reviewing this branch.
> It was really ugly. So don't worry, I deserve it :)
You are most welcome - and it wasn't ugly, it just needed further
polish :)
Btw, it's useful to post an incremental diff (i.e. only the changes
since the last review) so it's easier for a reviewer to only go over
that without going through things they have already approved. This
time it's simple because it's only one revision, but sometimes it's
harder than that and then an incremental diff helps.
> I'm testing using a single command line, but in MP I put them in
> different lines to improve readability... stupid thing to do :). For
> the future I'll put them in a single line.
Thanks!
> Disabled templates are only displayed for TranslationsAdmins.
> The previous behavior was validated by test stories.
Cool, thanks for this improvement!
> I didn't knew Ubuntu is already a celebrity.
> I prefer to keep with Ubuntu, without creating a new
> distribution. It will just make the story to complicated.
Well, "complicated" is a relative term. If you create a new
distribution and at least two new templates (one disabled, another
enabled), you'd have a fully self-contained test. That's means that
extra 5 lines of test set-up, you'll get a story which a reader can
understand fully without resorting to "make run" to see what data is
already there.
However, this branch is already too big: do not worry about this and
keep it as-is. For future work, I do suggest you keep the above in
mind.
> Added a "license=yes" to MakeTranslator , to also sign the
> translation license.. otherwise that translator has no edit rights.
Cool, thanks for doing this.
> I'm sorry for failing to write proper stories. Hope I can improve my
> narrator skills.
Don't worry about it. None of us is great at it, and we've got
years of experience. With every review though, we are always getting
better :)
There are still some suggestions on how to improve it, and some tips
on how to think about it when writing stories inline below.
> Hope the permission are right.
Not yet. I'll comment on the actual code below.
> I added stories for testing administration and editing of POTemplate
> and PoTemplateSubset.
Thanks, they look good.
> Thank you again for taking the time reviewing this branch.
> If there are further issues, have no mercy! :)
This is complicated stuff, so don't feel bad if I have no mercy :)
> It is ok to have these filenames?
> xx-potemplate-
> xx-potemplate-
> xx-rosetta-
> xx-rosetta-
>
> I was thinking at removing rosetta from the filename.
Sure, that'd be great :)
And now, your code with my comments inline:
=== modified file 'lib/canonical/
> --- lib/canonical/
> +++ lib/canonical/
Adi Roiban (adiroiban) wrote : | # |
Here is the diff from the last commit.
I will leave the other tasks for another branch.
I looked for all the other places where factory.
bin/test -m translations looks ok.
=== modified file 'lib/canonical/
--- lib/canonical/
+++ lib/canonical/
@@ -674,6 +674,18 @@
padding: 2px 1em 2px 2px;
}
+/* Templates listing.
+ *
+ * Examples:
+ * https:/
+ * https:/
+ */
+
+.inactive-template td {
+ background-color: #DCDCDC;
+}
+
+
/* Translations statistics and legend.
*
* Examples:
=== modified file 'lib/canonical/
--- lib/canonical/
+++ lib/canonical/
@@ -1123,13 +1123,21 @@
to edit distribution details are able to change translation settings
for a distribution.
"""
- return (
+ # Translation group owner for a distribution is also a
+ # translations administrator for it.
+ translation_group = self.obj.
+ if translation_group and user.inTeam(
+ return True
+ else:
+ return (
-class AdminPOTemplate
+# Please keep AdminPOTemplate
+# know exactly what you are doing.
+class AdminPOTemplate
"""Controls administration of an `IPOTemplate`.
Allow all persons that can also administer the translations to
@@ -1143,16 +1151,17 @@
def checkAuthentica
template = self.obj
if template.
- distro = template.
- translation_group = distro.
- if translation_group and user.inTeam(
- return True
-
+ # Template is on a distribution.
+ distribution = template.
return (
- template.
+ template.
+ user))
- return False
+ else:
+ # Template is on a product.
+ return OnlyRosettaExpe
+ self, user)
class EditPOTemplateD
@@ -1636,7 +1645,11 @@
-class AdminPOTemplate
+# Please keep this in sync with AdminPOTemplate
+# th...
Данило Шеган (danilo) wrote : | # |
У чет, 10. 12 2009. у 12:44 +0000, Adi Roiban пише:
> Here is the diff from the last commit.
> I will leave the other tasks for another branch.
Cool, thanks. We are almost there, only a few bits remaining.
> === modified file 'lib/canonical/
> --- lib/canonical/
> +++ lib/canonical/
> @@ -674,6 +674,18 @@
> padding: 2px 1em 2px 2px;
> }
>
> +/* Templates listing.
> + *
> + * Examples:
> + * https:/
> + * https:/
> + */
> +
> +.inactive-template td {
> + background-color: #DCDCDC;
> +}
> +
> +
I tried it out: this looks great. I've also played with
.inactive-template td {
background-
color: #855;
}
(to give it a slight redish appearance, to indicate something is wrong
with it), but I am not so sure about it. Your call about that, but if
you are in doubt about something, JFDI. :)
> === modified file 'lib/canonical/
> --- lib/canonical/
> +++ lib/canonical/
> @@ -1123,13 +1123,21 @@
> to edit distribution details are able to change translation settings
> for a distribution.
> """
> - return (
> + # Translation group owner for a distribution is also a
> + # translations administrator for it.
> + translation_group = self.obj.
> + if translation_group and user.inTeam(
> + return True
> + else:
> + return (
> OnlyRosettaExpe
> EditDistributio
> self, user))
A minor nitpick: please fix the indentation here as well. In general,
if you are using Emacs, python-mode should do it correctly for you if
you just press Tab key once on each of these lines.
> +# Please keep AdminPOTemplate
> +# know exactly what you are doing.
> +class AdminPOTemplate
> """Controls administration of an `IPOTemplate`.
>
> Allow all persons that can also administer the translations to
> @@ -1143,16 +1151,17 @@
> def checkAuthentica
> template = self.obj
> if template.
> - distro = template.
> - translation_group = distro.
> - if translation_group and
> user.inTeam(
> - return True
> -
> + # Template is on a distribution.
> + distribution = template.
> return (
> AdminDistributi
> -
> template.
> +
> template.
> + user))
Let's replace this `template.d...
Adi Roiban (adiroiban) wrote : | # |
Many thanks for the review... there we a couple of stupid errors :(
For the future I will try to read the whole diff at least twice.
Latest diff.
=== modified file 'lib/canonical/
--- lib/canonical/
+++ lib/canonical/
@@ -682,7 +682,8 @@
*/
.inactive-template td {
- background-color: #DCDCDC;
+ background-color: #fee;
+ color: #855;
}
=== modified file 'lib/canonical/
--- lib/canonical/
+++ lib/canonical/
@@ -1130,9 +1130,9 @@
return True
else:
return (
- OnlyRosettaExpe
- EditDistributio
- self, user))
+ OnlyRosettaExpe
+ EditDistributio
+ self, user))
# Please keep AdminPOTemplate
@@ -1155,8 +1155,7 @@
return (
- template.
- user))
+ distribution)
else:
# Template is on a product.
@@ -1663,16 +1662,13 @@
def checkAuthentica
if template_
- distro = template_
- translation_group = distro.
- if translation_group and user.inTeam(
- return True
-
+ distribution = template_
return (
- template_
-
- return False
+ distribution)
+ else:
+ # Template is on a product.
+ return OnlyRosettaExpe
class AdminDistroSeri
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -1,3 +1,10 @@
+Administering POTemplates
+======
+
+
+Product templates
+-----------------
+
The POTemplate admin page lets us to edit any aspect of that object, that's
why we need to be a Rosetta Expert or a Launchpad admin to use it.
@@ -155,8 +162,29 @@
>>> print admin_browser.url
http://
-
-== Distribution templates ==
+Administrators can disable and t...
Данило Шеган (danilo) wrote : | # |
У пет, 11. 12 2009. у 11:40 +0000, Adi Roiban пише:
> Many thanks for the review... there we a couple of stupid errors :(
> For the future I will try to read the whole diff at least twice.
Great work, thanks again!
review approve
merge approve
Preview Diff
1 | === modified file 'lib/canonical/launchpad/icing/style-3-0.css' |
2 | --- lib/canonical/launchpad/icing/style-3-0.css 2009-12-07 13:53:47 +0000 |
3 | +++ lib/canonical/launchpad/icing/style-3-0.css 2009-12-11 11:37:16 +0000 |
4 | @@ -694,6 +694,19 @@ |
5 | padding: 2px 1em 2px 2px; |
6 | } |
7 | |
8 | +/* Templates listing. |
9 | + * |
10 | + * Examples: |
11 | + * https://translations.launchpad.dev/ubuntu/hoary/+templates |
12 | + * https://translations.launchpad.dev/evolution/trunk/+templates |
13 | + */ |
14 | + |
15 | +.inactive-template td { |
16 | + background-color: #fee; |
17 | + color: #855; |
18 | +} |
19 | + |
20 | + |
21 | /* Translations statistics and legend. |
22 | * |
23 | * Examples: |
24 | |
25 | === modified file 'lib/canonical/launchpad/security.py' |
26 | --- lib/canonical/launchpad/security.py 2009-11-19 15:14:53 +0000 |
27 | +++ lib/canonical/launchpad/security.py 2009-12-11 11:37:16 +0000 |
28 | @@ -479,6 +479,7 @@ |
29 | """Allow Launchpad's admins and Rosetta experts edit all fields.""" |
30 | return is_admin_or_rosetta_expert(user) |
31 | |
32 | + |
33 | class AdminProductTranslations(AuthorizationBase): |
34 | permission = 'launchpad.TranslationsAdmin' |
35 | usedfor = IProduct |
36 | @@ -1103,27 +1104,63 @@ |
37 | usedfor = ICodeImportMachine |
38 | |
39 | |
40 | +class AdminDistributionTranslations(OnlyRosettaExpertsAndAdmins, |
41 | + EditDistributionByDistroOwnersOrAdmins): |
42 | + """Class for deciding who can administer distribution translations. |
43 | + |
44 | + This class is used for `launchpad.TranslationsAdmin` privilege on |
45 | + `IDistribution` and `IDistroSeries` and corresponding `IPOTemplate`s, |
46 | + and limits access to Rosetta experts, Launchpad admins and distribution |
47 | + translation group owner. |
48 | + """ |
49 | + permission = 'launchpad.TranslationsAdmin' |
50 | + usedfor = IDistribution |
51 | + |
52 | + def checkAuthenticated(self, user): |
53 | + """Is the user able to manage `IDistribution` translations settings? |
54 | + |
55 | + Any Launchpad/Launchpad Translations administrator or people allowed |
56 | + to edit distribution details are able to change translation settings |
57 | + for a distribution. |
58 | + """ |
59 | + # Translation group owner for a distribution is also a |
60 | + # translations administrator for it. |
61 | + translation_group = self.obj.translationgroup |
62 | + if translation_group and user.inTeam(translation_group.owner): |
63 | + return True |
64 | + else: |
65 | + return ( |
66 | + OnlyRosettaExpertsAndAdmins.checkAuthenticated(self, user) or |
67 | + EditDistributionByDistroOwnersOrAdmins.checkAuthenticated( |
68 | + self, user)) |
69 | + |
70 | + |
71 | +# Please keep AdminPOTemplateSubset in sync with this, unless you |
72 | +# know exactly what you are doing. |
73 | class AdminPOTemplateDetails(OnlyRosettaExpertsAndAdmins): |
74 | - permission = 'launchpad.Admin' |
75 | + """Controls administration of an `IPOTemplate`. |
76 | + |
77 | + Allow all persons that can also administer the translations to |
78 | + which this template belongs to and also translation group owners. |
79 | + |
80 | + Product owners does not have administrative privileges. |
81 | + """ |
82 | + permission = 'launchpad.TranslationsAdmin' |
83 | usedfor = IPOTemplate |
84 | |
85 | def checkAuthenticated(self, user): |
86 | - """Allow LP/Translations admins, and for distros, owners and |
87 | - translation group owners. |
88 | - """ |
89 | - if OnlyRosettaExpertsAndAdmins.checkAuthenticated(self, user): |
90 | - return True |
91 | - |
92 | template = self.obj |
93 | if template.distroseries is not None: |
94 | - distro = template.distroseries.distribution |
95 | - if user.inTeam(distro.owner): |
96 | - return True |
97 | - translation_group = distro.translationgroup |
98 | - if translation_group and user.inTeam(translation_group.owner): |
99 | - return True |
100 | + # Template is on a distribution. |
101 | + distribution = template.distroseries.distribution |
102 | + return ( |
103 | + AdminDistributionTranslations( |
104 | + distribution).checkAuthenticated(user)) |
105 | |
106 | - return False |
107 | + else: |
108 | + # Template is on a product. |
109 | + return OnlyRosettaExpertsAndAdmins.checkAuthenticated( |
110 | + self, user) |
111 | |
112 | |
113 | class EditPOTemplateDetails(AdminPOTemplateDetails, EditByOwnersOrAdmins): |
114 | @@ -1607,10 +1644,32 @@ |
115 | user.inTeam(celebs.bazaar_experts)) |
116 | |
117 | |
118 | +# Please keep this in sync with AdminPOTemplateDetails. Note that |
119 | +# this permission controls access to browsing into individual |
120 | +# potemplates, but it's on a different object (POTemplateSubset) |
121 | +# from AdminPOTemplateDetails, even though it looks almost identical |
122 | class AdminPOTemplateSubset(OnlyRosettaExpertsAndAdmins): |
123 | - permission = 'launchpad.Admin' |
124 | + """Controls administration of an `IPOTemplateSubset`. |
125 | + |
126 | + Allow all persons that can also administer the translations to |
127 | + which this template belongs to and also translation group owners. |
128 | + |
129 | + Product owners does not have administrative privileges. |
130 | + """ |
131 | + permission = 'launchpad.TranslationsAdmin' |
132 | usedfor = IPOTemplateSubset |
133 | |
134 | + def checkAuthenticated(self, user): |
135 | + template_set = self.obj |
136 | + if template_set.distroseries is not None: |
137 | + distribution = template_set.distroseries.distribution |
138 | + return ( |
139 | + AdminDistributionTranslations( |
140 | + distribution).checkAuthenticated(user)) |
141 | + else: |
142 | + # Template is on a product. |
143 | + return OnlyRosettaExpertsAndAdmins.checkAuthenticated(self, user) |
144 | + |
145 | |
146 | class AdminDistroSeriesLanguage(OnlyRosettaExpertsAndAdmins): |
147 | permission = 'launchpad.Admin' |
148 | @@ -1791,24 +1850,6 @@ |
149 | user.inTeam(self.obj.distribution.language_pack_admin)) |
150 | |
151 | |
152 | -class AdminDistributionTranslations(OnlyRosettaExpertsAndAdmins, |
153 | - EditDistributionByDistroOwnersOrAdmins): |
154 | - permission = 'launchpad.TranslationsAdmin' |
155 | - usedfor = IDistribution |
156 | - |
157 | - def checkAuthenticated(self, user): |
158 | - """Is the user able to manage `IDistribution` translations settings? |
159 | - |
160 | - Any Launchpad/Launchpad Translations administrator or people allowed |
161 | - to edit distribution details are able to change translation settings |
162 | - for a distribution. |
163 | - """ |
164 | - return ( |
165 | - OnlyRosettaExpertsAndAdmins.checkAuthenticated(self, user) or |
166 | - EditDistributionByDistroOwnersOrAdmins.checkAuthenticated( |
167 | - self, user)) |
168 | - |
169 | - |
170 | class AdminLanguagePack(OnlyRosettaExpertsAndAdmins): |
171 | permission = 'launchpad.LanguagePacksAdmin' |
172 | usedfor = ILanguagePack |
173 | |
174 | === modified file 'lib/lp/testing/factory.py' |
175 | --- lib/lp/testing/factory.py 2009-12-10 20:23:49 +0000 |
176 | +++ lib/lp/testing/factory.py 2009-12-11 11:37:16 +0000 |
177 | @@ -76,6 +76,7 @@ |
178 | from lp.translations.interfaces.translationgroup import ( |
179 | ITranslationGroupSet) |
180 | from lp.translations.interfaces.translator import ITranslatorSet |
181 | +from lp.translations.interfaces.translationsperson import ITranslationsPerson |
182 | from canonical.launchpad.ftests._sqlobject import syncUpdate |
183 | from lp.services.mail.signedmessage import SignedMessage |
184 | from lp.services.worlddata.interfaces.country import ICountrySet |
185 | @@ -502,13 +503,15 @@ |
186 | return getUtility(ITranslationGroupSet).new( |
187 | name, title, summary, url, owner) |
188 | |
189 | - def makeTranslator(self, language_code, group=None, person=None): |
190 | + def makeTranslator( |
191 | + self, language_code, group=None, person=None, license=True): |
192 | """Create a new, arbitrary `Translator`.""" |
193 | language = getUtility(ILanguageSet).getLanguageByCode(language_code) |
194 | if group is None: |
195 | group = self.makeTranslationGroup() |
196 | if person is None: |
197 | person = self.makePerson() |
198 | + ITranslationsPerson(person).translations_relicensing_agreement = license |
199 | return getUtility(ITranslatorSet).new(group, language, person) |
200 | |
201 | def makeMilestone( |
202 | |
203 | === modified file 'lib/lp/translations/browser/configure.zcml' |
204 | --- lib/lp/translations/browser/configure.zcml 2009-12-07 18:42:21 +0000 |
205 | +++ lib/lp/translations/browser/configure.zcml 2009-12-11 11:37:16 +0000 |
206 | @@ -420,7 +420,7 @@ |
207 | name="+admin" |
208 | for="lp.translations.interfaces.potemplate.IPOTemplate" |
209 | class="lp.translations.browser.potemplate.POTemplateAdminView" |
210 | - permission="launchpad.Admin" |
211 | + permission="launchpad.TranslationsAdmin" |
212 | template="../../app/templates/generic-edit.pt" |
213 | layer="canonical.launchpad.layers.TranslationsLayer"/> |
214 | <browser:page |
215 | |
216 | === modified file 'lib/lp/translations/browser/potemplate.py' |
217 | --- lib/lp/translations/browser/potemplate.py 2009-11-27 12:50:16 +0000 |
218 | +++ lib/lp/translations/browser/potemplate.py 2009-12-11 11:37:16 +0000 |
219 | @@ -184,7 +184,7 @@ |
220 | text = 'Settings' |
221 | return Link('+edit', text) |
222 | |
223 | - @enabled_with_permission('launchpad.Admin') |
224 | + @enabled_with_permission('launchpad.TranslationsAdmin') |
225 | def administer(self): |
226 | text = 'Administer' |
227 | return Link('+admin', text) |
228 | @@ -688,7 +688,7 @@ |
229 | raise AssertionError('Unknown context for %s' % potemplate.title) |
230 | |
231 | if ((official_rosetta and potemplate.iscurrent) or |
232 | - check_permission('launchpad.Admin', self.context)): |
233 | + check_permission('launchpad.TranslationsAdmin', self.context)): |
234 | # The target is using officially Launchpad Translations and the |
235 | # template is available to be translated, or the user is a is a |
236 | # Launchpad administrator in which case we show everything. |
237 | |
238 | === modified file 'lib/lp/translations/configure.zcml' |
239 | --- lib/lp/translations/configure.zcml 2009-09-26 10:03:31 +0000 |
240 | +++ lib/lp/translations/configure.zcml 2009-12-11 11:37:16 +0000 |
241 | @@ -411,7 +411,7 @@ |
242 | permission="launchpad.Edit" |
243 | set_attributes="owner priority description"/> |
244 | <require |
245 | - permission="launchpad.Admin" |
246 | + permission="launchpad.TranslationsAdmin" |
247 | set_attributes="name translation_domain productseries distroseries sourcepackagename sourcepackageversion binarypackagename languagepack path header iscurrent from_sourcepackagename date_last_updated source_file source_file_format"/> |
248 | </class> |
249 | <adapter |
250 | |
251 | === modified file 'lib/lp/translations/stories/distroseries/xx-distroseries-templates.txt' |
252 | --- lib/lp/translations/stories/distroseries/xx-distroseries-templates.txt 2009-11-30 18:18:08 +0000 |
253 | +++ lib/lp/translations/stories/distroseries/xx-distroseries-templates.txt 2009-12-11 11:37:16 +0000 |
254 | @@ -1,5 +1,3 @@ |
255 | - |
256 | - |
257 | Templates view for DistroSeries |
258 | =============================== |
259 | |
260 | @@ -20,6 +18,7 @@ |
261 | >>> print user_browser.url |
262 | http://translations.launchpad.dev/ubuntu/hoary/+templates |
263 | |
264 | + |
265 | The templates table |
266 | ------------------- |
267 | |
268 | @@ -35,8 +34,7 @@ |
269 | |
270 | >>> table = find_tag_by_id(anon_browser.contents, 'templates_table') |
271 | >>> print extract_text(table) |
272 | - Source package Template name Last update |
273 | - evolution disabled-template 2007-01-05 |
274 | + Source package Template name Last update |
275 | evolution evolution-2.2 2005-05-06 |
276 | evolution man 2006-08-14 |
277 | mozilla pkgconf-mozilla 2005-05-06 |
278 | @@ -44,18 +42,19 @@ |
279 | pmount pmount 2005-05-06 |
280 | |
281 | |
282 | -Logged-in users will see a link from distro series |
283 | +Logged-in users see a link to all the active translation templates |
284 | +on a distribution series translation page. |
285 | >>> user_browser.open( |
286 | ... 'http://translations.launchpad.dev/ubuntu/hoary') |
287 | >>> user_browser.getLink('full list of templates').click() |
288 | |
289 | -Logged-in users can also choose to download all translations for each |
290 | -of the templates. |
291 | +Regular users only see the option to download translations for each of |
292 | +the active templates. |
293 | |
294 | >>> table = find_tag_by_id(user_browser.contents, 'templates_table') |
295 | >>> print extract_text(table) |
296 | Source package Template name Last update Actions |
297 | - evolution disabled-template 2007-01-05 Download |
298 | + evolution evolution-2.2 2005-05-06 Download |
299 | ... |
300 | mozilla pkgconf-mozilla 2005-05-06 Download |
301 | ... |
302 | @@ -70,13 +69,70 @@ |
303 | |
304 | >>> table = find_tag_by_id(admin_browser.contents, 'templates_table') |
305 | >>> print extract_text(table) |
306 | - Source package Template name Last update Actions |
307 | - evolution disabled-template 2007-01-05 Edit Upload Download Administer |
308 | - evolution evolution-2.2 2005-05-06 Edit Upload Download Administer |
309 | - evolution man 2006-08-14 Edit Upload Download Administer |
310 | - mozilla pkgconf-mozilla 2005-05-06 Edit Upload Download Administer |
311 | - pmount man 2006-08-14 Edit Upload Download Administer |
312 | - pmount pmount 2005-05-06 Edit Upload Download Administer |
313 | + Source package Template name Last update Actions |
314 | + evolution disabled-template (inactive) 2007-01-05 Edit Upload Download Administer |
315 | + evolution evolution-2.2 2005-05-06 Edit Upload Download Administer |
316 | + evolution man 2006-08-14 Edit Upload Download Administer |
317 | + mozilla pkgconf-mozilla 2005-05-06 Edit Upload Download Administer |
318 | + pmount man 2006-08-14 Edit Upload Download Administer |
319 | + pmount pmount 2005-05-06 Edit Upload Download Administer |
320 | + |
321 | +Ubuntu Translations Coordinator can administer all templates, including |
322 | +those that are currently disabled. |
323 | + |
324 | +New user is made an owner of an Ubuntu translation group, thus being |
325 | +considered a translations administrator for Ubuntu. |
326 | + |
327 | + >>> from zope.component import getUtility |
328 | + >>> from canonical.launchpad.ftests import login, logout |
329 | + >>> from canonical.launchpad.interfaces import ( |
330 | + ... IDistributionSet, IPersonSet, ILaunchpadCelebrities) |
331 | + >>> login('foo.bar@canonical.com') |
332 | + >>> a_person = factory.makePerson(email='utc-member@example.com', |
333 | + ... name='utc-member', password='test', displayname='Some Guy') |
334 | + >>> utc_member = factory.makeTranslator('ro', person=a_person) |
335 | + >>> utc_team = factory.makeTeam(owner=a_person) |
336 | + >>> utg = factory.makeTranslationGroup(owner=utc_team, |
337 | + ... name="Ubuntu Translation Group") |
338 | + >>> ubuntu = getUtility(ILaunchpadCelebrities).ubuntu |
339 | + >>> ubuntu.translationgroup = utg |
340 | + >>> # Log out so we can go back to using test browsers. |
341 | + >>> logout() |
342 | + |
343 | +Visiting the Ubuntu Hoary templates page, translation administrators |
344 | +will see "Edit" and "Administer" links for all templates. |
345 | + |
346 | +Trying to edit/administer enabled templates brings them to the |
347 | +appropriate page. |
348 | + |
349 | + >>> utc_browser = setupBrowser(auth='Basic utc-member@example.com:test') |
350 | + >>> utc_browser.open( |
351 | + ... 'http://translations.launchpad.dev/ubuntu/hoary/+templates') |
352 | + >>> utc_browser.getLink(url='ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+edit').click() |
353 | + >>> print utc_browser.url |
354 | + http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+edit |
355 | + |
356 | + >>> utc_browser.open( |
357 | + ... 'http://translations.launchpad.dev/ubuntu/hoary/+templates') |
358 | + >>> utc_browser.getLink(url='/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+admin').click() |
359 | + >>> print utc_browser.url |
360 | + http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+admin |
361 | + |
362 | +Trying to edit/administer disabled templates brings them to the |
363 | +appropriate page. |
364 | + |
365 | + >>> utc_browser = setupBrowser(auth='Basic utc-member@example.com:test') |
366 | + >>> utc_browser.open( |
367 | + ... 'http://translations.launchpad.dev/ubuntu/hoary/+templates') |
368 | + >>> utc_browser.getLink(url='ubuntu/hoary/+source/evolution/+pots/disabled-template/+edit').click() |
369 | + >>> print utc_browser.url |
370 | + http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/disabled-template/+edit |
371 | + |
372 | + >>> utc_browser.open( |
373 | + ... 'http://translations.launchpad.dev/ubuntu/hoary/+templates') |
374 | + >>> utc_browser.getLink(url='/ubuntu/hoary/+source/evolution/+pots/disabled-template/+admin').click() |
375 | + >>> print utc_browser.url |
376 | + http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/disabled-template/+admin |
377 | |
378 | |
379 | Links to the templates |
380 | @@ -97,3 +153,4 @@ |
381 | >>> admin_browser.getLink('Edit').click() |
382 | >>> print admin_browser.url |
383 | http://translations.../evolution/+pots/disabled-template/+edit |
384 | + |
385 | |
386 | === renamed file 'lib/lp/translations/stories/standalone/xx-rosetta-pofile-export.txt' => 'lib/lp/translations/stories/standalone/xx-pofile-export.txt' |
387 | === modified file 'lib/lp/translations/stories/standalone/xx-potemplate-admin.txt' |
388 | --- lib/lp/translations/stories/standalone/xx-potemplate-admin.txt 2009-08-12 05:09:36 +0000 |
389 | +++ lib/lp/translations/stories/standalone/xx-potemplate-admin.txt 2009-12-11 11:37:16 +0000 |
390 | @@ -1,3 +1,10 @@ |
391 | +Administering POTemplates |
392 | +========================= |
393 | + |
394 | + |
395 | +Product templates |
396 | +----------------- |
397 | + |
398 | The POTemplate admin page lets us to edit any aspect of that object, that's |
399 | why we need to be a Rosetta Expert or a Launchpad admin to use it. |
400 | |
401 | @@ -155,8 +162,29 @@ |
402 | >>> print admin_browser.url |
403 | http://translations.launchpad.dev/evolution/trunk/+pots/evolution-renamed |
404 | |
405 | - |
406 | -== Distribution templates == |
407 | +Administrators can disable and then make changes to a disabled template. |
408 | + |
409 | + >>> admin_browser.open( |
410 | + ... 'http://translations.launchpad.dev/evolution/trunk/+pots/' |
411 | + ... 'evolution-renamed/+admin') |
412 | + >>> admin_browser.getControl(name='field.iscurrent').value = False |
413 | + >>> admin_browser.getControl('Change').click() |
414 | + >>> print admin_browser.url |
415 | + http://translations.launchpad.dev/evolution/trunk/+pots/evolution-renamed |
416 | + |
417 | +Now we will reenable the template. |
418 | + |
419 | + >>> admin_browser.open( |
420 | + ... 'http://translations.launchpad.dev/evolution/trunk/+pots/' |
421 | + ... 'evolution-renamed/+admin') |
422 | + >>> admin_browser.getControl(name='field.iscurrent').value = True |
423 | + >>> admin_browser.getControl('Change').click() |
424 | + >>> print admin_browser.url |
425 | + http://translations.launchpad.dev/evolution/trunk/+pots/evolution-renamed |
426 | + |
427 | + |
428 | +Distribution templates |
429 | +---------------------- |
430 | |
431 | Distributions get slightly wider permissions to manage their templates |
432 | autonomously. |
433 | @@ -214,3 +242,15 @@ |
434 | |
435 | >>> print template.path |
436 | splat.pot |
437 | + |
438 | +Distribution translation coordinators can disable and manage disabled |
439 | +templates. |
440 | + |
441 | + >>> group_owner_browser.open(template_admin_url) |
442 | + >>> group_owner_browser.getControl(name='field.iscurrent').value = False |
443 | + >>> group_owner_browser.getControl('Change').click() |
444 | + >>> group_owner_browser.open(template_admin_url) |
445 | + >>> group_owner_browser.getControl(name='field.iscurrent').value = True |
446 | + >>> group_owner_browser.getControl('Change').click() |
447 | + |
448 | + |
449 | |
450 | === renamed file 'lib/lp/translations/stories/standalone/xx-rosetta-potemplate-export.txt' => 'lib/lp/translations/stories/standalone/xx-potemplate-export.txt' |
451 | === renamed file 'lib/lp/translations/stories/standalone/xx-rosetta-potemplate-index.txt' => 'lib/lp/translations/stories/standalone/xx-potemplate-index.txt' |
452 | --- lib/lp/translations/stories/standalone/xx-rosetta-potemplate-index.txt 2009-11-09 17:08:21 +0000 |
453 | +++ lib/lp/translations/stories/standalone/xx-potemplate-index.txt 2009-12-11 11:37:16 +0000 |
454 | @@ -1,4 +1,9 @@ |
455 | -= POTemplate index page = |
456 | +POTemplate index page |
457 | +===================== |
458 | + |
459 | + |
460 | +DistoSeries |
461 | +----------- |
462 | |
463 | The index page for a POTemplate lists all available translations |
464 | for a source package. No Privileges Person visits the |
465 | @@ -74,6 +79,10 @@ |
466 | Dutch ... ... ... ... Luk Claes |
467 | Finnish ... ... ... ... P\xf6ll\xe4 |
468 | |
469 | + |
470 | +DistroSeries and ProductSeries links to related templates |
471 | +--------------------------------------------------------- |
472 | + |
473 | We are presented not only with links to alternate templates from the same |
474 | source, but also with links to the same template in (other) distroseries. |
475 | |
476 | @@ -95,3 +104,63 @@ |
477 | >>> print alternate_notice |
478 | <p...<a href="/evolution/trunk/+pots/evolution-2.2"... |
479 | |
480 | + |
481 | +Administering templates |
482 | +----------------------- |
483 | + |
484 | +Anonymous visitors see only a list of all existing templates, with no |
485 | +administration or download/upload links. |
486 | + |
487 | + >>> anon_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
488 | + >>> anon_browser.getLink('upload') |
489 | + Traceback (most recent call last): |
490 | + ... |
491 | + LinkNotFoundError |
492 | + |
493 | + >>> anon_browser.getLink('download').click() |
494 | + Traceback (most recent call last): |
495 | + ... |
496 | + LinkNotFoundError |
497 | + |
498 | +As an authenticated user, you should see the download link, |
499 | +but not the one for uploading file to this potemplate. |
500 | + |
501 | + >>> user_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
502 | + >>> user_browser.getLink('upload') |
503 | + Traceback (most recent call last): |
504 | + ... |
505 | + LinkNotFoundError |
506 | + |
507 | + >>> user_browser.getLink('download').click() |
508 | + >>> print user_browser.url |
509 | + http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+export |
510 | + |
511 | +Translation administrators will see both download and upload links. |
512 | +Beside administering this template, "Change permissions" |
513 | +and "Change details" should be also accessible. |
514 | + |
515 | + >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
516 | + >>> admin_browser.getLink('upload').click() |
517 | + >>> print admin_browser.url |
518 | + http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+upload |
519 | + |
520 | + >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
521 | + >>> admin_browser.getLink('download').click() |
522 | + >>> print admin_browser.url |
523 | + http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+export |
524 | + |
525 | + >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
526 | + >>> admin_browser.getLink('Administer this template').click() |
527 | + >>> print admin_browser.url |
528 | + http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+admin |
529 | + |
530 | + >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
531 | + >>> admin_browser.getLink('Change details').click() |
532 | + >>> print admin_browser.url |
533 | + http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/+edit |
534 | + |
535 | + >>> admin_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
536 | + >>> admin_browser.getLink('Change permissions').click() |
537 | + >>> print admin_browser.url |
538 | + http://translations.launchpad.dev/ubuntu/+settings |
539 | + |
540 | |
541 | === modified file 'lib/lp/translations/templates/object-templates.pt' |
542 | --- lib/lp/translations/templates/object-templates.pt 2009-12-07 14:19:02 +0000 |
543 | +++ lib/lp/translations/templates/object-templates.pt 2009-12-11 11:37:16 +0000 |
544 | @@ -82,51 +82,107 @@ |
545 | </tr> |
546 | </thead> |
547 | <tbody> |
548 | - <tr tal:repeat="template view/iter_templates" class="template_row"> |
549 | - <td tal:condition="view/is_distroseries" |
550 | - tal:content="template/sourcepackagename/name" |
551 | - class="sourcepackage_column">Source package |
552 | - </td> |
553 | - <td class="template_column"><a tal:attributes="href template/fmt:url" |
554 | - tal:content="template/name">Template name</a></td> |
555 | - <td class="lastupdate_column"> |
556 | - <span class="sortkey" |
557 | - tal:condition="template/date_last_updated" |
558 | - tal:content="template/date_last_updated/fmt:datetime"> |
559 | - time sort key |
560 | - </span> |
561 | - <span class="lastupdate_column" |
562 | - tal:condition="template/date_last_updated" |
563 | - tal:attributes=" |
564 | - title template/date_last_updated/fmt:datetime" |
565 | - tal:content=" |
566 | - template/date_last_updated/fmt:approximatedate" |
567 | - > |
568 | - 2009-09-23 |
569 | - </span> |
570 | - </td> |
571 | - <td class="actions_column" |
572 | - tal:condition="context/required:launchpad.AnyPerson"> |
573 | - <div class="template_links"> |
574 | - <tal:maintainer condition="template/required:launchpad.Edit"> |
575 | - <a tal:attributes="href string:${template/fmt:url}/+edit; |
576 | - title string:Edit ${template/name}'s details"> |
577 | - <img src="/@@/edit" /> Edit</a> |
578 | - <a tal:attributes="href string:${template/fmt:url}/+upload; |
579 | - title string:Upload translations to ${template/name}"> |
580 | - <img src="/@@/add" /> Upload</a> |
581 | - </tal:maintainer> |
582 | - <a tal:attributes="href string:${template/fmt:url}/+export; |
583 | - title string:Download translations from ${template/name}"> |
584 | - <img src="/@@/download" /> Download</a> |
585 | - <tal:admin condition="template/required:launchpad.Admin"> |
586 | - <a tal:attributes="href string:${template/fmt:url}/+admin; |
587 | - title string:Administer ${template/name}"> |
588 | - <img src="/@@/edit" /> Administer</a> |
589 | + <tal:templates repeat="template view/iter_templates"> |
590 | + <tal:not-current condition="not: template/iscurrent"> |
591 | + <tal:admin condition="template/required:launchpad.TranslationsAdmin"> |
592 | + <tr class="template_row inactive-template"> |
593 | + <td tal:condition="view/is_distroseries" |
594 | + tal:content="template/sourcepackagename/name" |
595 | + class="sourcepackage_column">Source package |
596 | + </td> |
597 | + <td class="template_column"> |
598 | + <a tal:attributes="href template/fmt:url"> |
599 | + <span tal:content="template/name">Template name</span> |
600 | + </a> (inactive) |
601 | + </td> |
602 | + <td class="lastupdate_column"> |
603 | + <span class="sortkey" |
604 | + tal:condition="template/date_last_updated" |
605 | + tal:content="template/date_last_updated/fmt:datetime"> |
606 | + time sort key |
607 | + </span> |
608 | + <span class="lastupdate_column" |
609 | + tal:condition="template/date_last_updated" |
610 | + tal:attributes=" |
611 | + title template/date_last_updated/fmt:datetime" |
612 | + tal:content=" |
613 | + template/date_last_updated/fmt:approximatedate" |
614 | + > |
615 | + 2009-09-23 |
616 | + </span> |
617 | + </td> |
618 | + <td class="actions_column" |
619 | + tal:condition="context/required:launchpad.AnyPerson"> |
620 | + <div class="template_links"> |
621 | + <tal:maintainer condition="template/required:launchpad.Edit"> |
622 | + <a tal:attributes="href string:${template/fmt:url}/+edit; |
623 | + title string:Edit ${template/name}'s details"> |
624 | + <img src="/@@/edit" /> Edit</a> |
625 | + <a tal:attributes="href string:${template/fmt:url}/+upload; |
626 | + title string:Upload translations to ${template/name}"> |
627 | + <img src="/@@/add" /> Upload</a> |
628 | + </tal:maintainer> |
629 | + <a tal:attributes="href string:${template/fmt:url}/+export; |
630 | + title string:Download translations from ${template/name}"> |
631 | + <img src="/@@/download" /> Download</a> |
632 | + <tal:admin condition="template/required:launchpad.TranslationsAdmin"> |
633 | + <a tal:attributes="href string:${template/fmt:url}/+admin; |
634 | + title string:Administer ${template/name}"> |
635 | + <img src="/@@/edit" /> Administer</a> |
636 | + </tal:admin> |
637 | + </div> |
638 | + </td> |
639 | + </tr> |
640 | </tal:admin> |
641 | - </div> |
642 | - </td> |
643 | - </tr> |
644 | + </tal:not-current> |
645 | + <tal:current condition="template/iscurrent"> |
646 | + <tr class="template_row"> |
647 | + <td tal:condition="view/is_distroseries" |
648 | + tal:content="template/sourcepackagename/name" |
649 | + class="sourcepackage_column">Source package |
650 | + </td> |
651 | + <td class="template_column"><a tal:attributes="href template/fmt:url" |
652 | + tal:content="template/name">Template name</a></td> |
653 | + <td class="lastupdate_column"> |
654 | + <span class="sortkey" |
655 | + tal:condition="template/date_last_updated" |
656 | + tal:content="template/date_last_updated/fmt:datetime"> |
657 | + time sort key |
658 | + </span> |
659 | + <span class="lastupdate_column" |
660 | + tal:condition="template/date_last_updated" |
661 | + tal:attributes=" |
662 | + title template/date_last_updated/fmt:datetime" |
663 | + tal:content=" |
664 | + template/date_last_updated/fmt:approximatedate" |
665 | + > |
666 | + 2009-09-23 |
667 | + </span> |
668 | + </td> |
669 | + <td class="actions_column" |
670 | + tal:condition="context/required:launchpad.AnyPerson"> |
671 | + <div class="template_links"> |
672 | + <tal:maintainer condition="template/required:launchpad.Edit"> |
673 | + <a tal:attributes="href string:${template/fmt:url}/+edit; |
674 | + title string:Edit ${template/name}'s details"> |
675 | + <img src="/@@/edit" /> Edit</a> |
676 | + <a tal:attributes="href string:${template/fmt:url}/+upload; |
677 | + title string:Upload translations to ${template/name}"> |
678 | + <img src="/@@/add" /> Upload</a> |
679 | + </tal:maintainer> |
680 | + <a tal:attributes="href string:${template/fmt:url}/+export; |
681 | + title string:Download translations from ${template/name}"> |
682 | + <img src="/@@/download" /> Download</a> |
683 | + <tal:admin condition="template/required:launchpad.TranslationsAdmin"> |
684 | + <a tal:attributes="href string:${template/fmt:url}/+admin; |
685 | + title string:Administer ${template/name}"> |
686 | + <img src="/@@/edit" /> Administer</a> |
687 | + </tal:admin> |
688 | + </div> |
689 | + </td> |
690 | + </tr> |
691 | + </tal:current> |
692 | + </tal:templates> |
693 | </tbody> |
694 | </table> |
695 | </div> |
696 | |
697 | === modified file 'lib/lp/translations/templates/potemplate-index.pt' |
698 | --- lib/lp/translations/templates/potemplate-index.pt 2009-10-15 14:04:48 +0000 |
699 | +++ lib/lp/translations/templates/potemplate-index.pt 2009-12-11 11:37:16 +0000 |
700 | @@ -115,7 +115,7 @@ |
701 | class="download sprite">download</a> |
702 | translation tarballs. |
703 | </p> |
704 | - <div tal:condition="context/required:launchpad.Admin"> |
705 | + <div tal:condition="context/required:launchpad.TranslationsAdmin"> |
706 | <a tal:attributes="href |
707 | context/menu:navigation/administer/url" |
708 | class="edit sprite"> |
= Bug 406477 =
Members of the ubuntu- translations- coordinators team can edit templates through the +admin pages.
However, once a template has been disabled, the +admin page is no longer accessible to them, which stops them from e.g. enabling the template again in case of a mistake.
== Implementation details ==
After asking a pre-implementation review from Danilo, he suggest I should use launchpad. TranslationsAdm in, instead of the more generic launchpad.Admin translation.
The previous administration privileges for IPOTemplate was assigned only to RosettaAdmins. translationgrou p
Now it was change to all RosettaAdmin + owner of distro.
== Tests ==
There were no test covering the use case of distribution translations coordinator admin rights to templates, so this was added to distroseries- templates
Also the previous rosetta- potemplate- index was not checking the administrative links.
./bin/test -ct "distroseries- templates" potemplate- index"
./bin/test -ct "rosetta-
== Demo and Q/A ==
Make sure you are a member of Ubuntu Translation Coordinators team (ubuntu- l10n-coordinato r). /launchpad. dev/~ubuntu- l10n-coordinato r
https:/
Go to the Distro +template page /translations. launchpad. dev/ubuntu/ hoary/+ templates
https:/
You should see the Administer page for Evolution, disabled-template .
As a member of Ubuntu Translation Coordinators team you should be able to administer it, just like any other template from that table.
Login as a normal user, you should not see the administration links (only Download), and when trying to manually enter the admin url (https:/ /translations. launchpad. dev/ubuntu/ hoary/+ source/ evolution/ +pots/disabled- template/ +admin) you should see an access denied page.
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: /launchpad/ security. py translations/ browser/ configure. zcml translations/ browser/ potemplate. py translations/ stories/ distroseries/ xx-distroseries -templates. txt translations/ stories/ standalone/ xx-rosetta- potemplate- index.txt translations/ templates/ object- templates. pt translations/ templates/ potemplate- index.pt
lib/canonical
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/