Code review comment for lp:~jcsackett/launchpad/unknown-translations-service-643545-0
- unknown-translations-service-643545-0
- Merge into devel
Revision history for this message
j.c.sackett (jcsackett) wrote : | # |
1 | === modified file 'lib/canonical/launchpad/webapp/configure.zcml' |
2 | --- lib/canonical/launchpad/webapp/configure.zcml 2010-09-20 00:36:24 +0000 |
3 | +++ lib/canonical/launchpad/webapp/configure.zcml 2010-09-23 01:16:03 +0000 |
4 | @@ -493,12 +493,6 @@ |
5 | name="fmt" |
6 | /> |
7 | <adapter |
8 | - for="lp.registry.interfaces.sourcepackage.ISourcePackage" |
9 | - provides="zope.traversing.interfaces.IPathAdapter" |
10 | - factory="canonical.launchpad.webapp.tales.SourcePackageFormatterAPI" |
11 | - name="fmt" |
12 | - /> |
13 | - <adapter |
14 | for="lp.soyuz.interfaces.sourcepackagerelease.ISourcePackageRelease" |
15 | provides="zope.traversing.interfaces.IPathAdapter" |
16 | factory="canonical.launchpad.webapp.tales.SourcePackageReleaseFormatterAPI" |
17 | |
18 | === modified file 'lib/canonical/launchpad/webapp/tales.py' |
19 | --- lib/canonical/launchpad/webapp/tales.py 2010-08-30 11:46:44 +0000 |
20 | +++ lib/canonical/launchpad/webapp/tales.py 2010-09-23 14:21:46 +0000 |
21 | @@ -26,10 +26,11 @@ |
22 | from zope.component import adapts, getUtility, queryAdapter, getMultiAdapter |
23 | from zope.app import zapi |
24 | from zope.publisher.browser import BrowserView |
25 | -from zope.publisher.interfaces import IApplicationRequest |
26 | -from zope.publisher.interfaces.browser import IBrowserApplicationRequest |
27 | from zope.traversing.interfaces import ( |
28 | - ITraversable, IPathAdapter, TraversalError) |
29 | + ITraversable, |
30 | + IPathAdapter, |
31 | + TraversalError, |
32 | + ) |
33 | from zope.security.interfaces import Unauthorized |
34 | from zope.security.proxy import isinstance as zope_isinstance |
35 | from zope.schema import TextLine |
36 | @@ -242,6 +243,7 @@ |
37 | This is available for all objects. Individual operations may fail for |
38 | objects that do not support them. |
39 | """ |
40 | + |
41 | def __init__(self, context): |
42 | self._context = context |
43 | |
44 | @@ -310,6 +312,7 @@ |
45 | else: |
46 | return None |
47 | |
48 | + |
49 | def htmlmatch(formvalue, value): |
50 | value = str(value) |
51 | if isinstance(formvalue, list): |
52 | @@ -317,6 +320,7 @@ |
53 | else: |
54 | return formvalue == value |
55 | |
56 | + |
57 | class HTMLFormOperation: |
58 | |
59 | implements(ITraversable) |
60 | @@ -835,13 +839,11 @@ |
61 | """Return whether the bug has a patch.""" |
62 | return self._context.bug.has_patches |
63 | |
64 | - |
65 | def badges(self): |
66 | - |
67 | badges = [] |
68 | if self._context.bug.private: |
69 | badges.append(self.icon_template % ( |
70 | - "private", "Private","sprite private")) |
71 | + "private", "Private", "sprite private")) |
72 | |
73 | if self._hasMentoringOffer(): |
74 | badges.append(self.icon_template % ( |
75 | @@ -859,7 +861,7 @@ |
76 | milestone_text = "milestone %s" % self._context.milestone.name |
77 | badges.append(self.linked_icon_template % ( |
78 | canonical_url(self._context.milestone), |
79 | - milestone_text , "Linked to %s" % milestone_text, |
80 | + milestone_text, "Linked to %s" % milestone_text, |
81 | "sprite milestone")) |
82 | |
83 | if self._hasPatch(): |
84 | @@ -981,7 +983,6 @@ |
85 | '<img width="%(width)s" height="14" alt="%(alt)s" ' |
86 | 'title="%(title)s" src="%(src)s" />') |
87 | |
88 | - |
89 | def icon(self): |
90 | """Return the appropriate <img> tag for the build icon.""" |
91 | icon_map = { |
92 | @@ -989,7 +990,7 @@ |
93 | BuildStatus.FULLYBUILT: {'src': "/@@/build-success"}, |
94 | BuildStatus.FAILEDTOBUILD: { |
95 | 'src': "/@@/build-failed", |
96 | - 'width': '16' |
97 | + 'width': '16', |
98 | }, |
99 | BuildStatus.MANUALDEPWAIT: {'src': "/@@/build-depwait"}, |
100 | BuildStatus.CHROOTWAIT: {'src': "/@@/build-chrootwait"}, |
101 | @@ -1185,6 +1186,7 @@ |
102 | return self.hidden |
103 | return super(TeamFormatterAPI, self).unique_displayname(view_name) |
104 | |
105 | + |
106 | class CustomizableFormatter(ObjectFormatterAPI): |
107 | """A ObjectFormatterAPI that is easy to customize. |
108 | |
109 | @@ -1322,16 +1324,6 @@ |
110 | return {'displayname': displayname} |
111 | |
112 | |
113 | -class SourcePackageFormatterAPI(CustomizableFormatter): |
114 | - """Adapter for ISourcePackage objects to a formatted string.""" |
115 | - |
116 | - _link_summary_template = '%(displayname)s' |
117 | - |
118 | - def _link_summary_values(self): |
119 | - displayname = self._context.displayname |
120 | - return {'displayname': displayname} |
121 | - |
122 | - |
123 | class SourcePackageReleaseFormatterAPI(CustomizableFormatter): |
124 | |
125 | """Adapter for ISourcePackageRelease objects to a formatted string.""" |
126 | @@ -1415,7 +1407,7 @@ |
127 | 'bzr_identity': branch.bzr_identity, |
128 | 'display_name': cgi.escape(branch.displayname), |
129 | 'name': branch.name, |
130 | - 'unique_name' : branch.unique_name, |
131 | + 'unique_name': branch.unique_name, |
132 | 'url': self.url(view_name), |
133 | } |
134 | |
135 | @@ -1527,6 +1519,7 @@ |
136 | |
137 | class PackageBuildFormatterAPI(ObjectFormatterAPI): |
138 | """Adapter providing fmt support for `IPackageBuild` objects.""" |
139 | + |
140 | def _composeArchiveReference(self, archive): |
141 | if archive.is_ppa: |
142 | return " [%s/%s]" % ( |
143 | @@ -1553,7 +1546,7 @@ |
144 | |
145 | def _link_summary_values(self): |
146 | """See CustomizableFormatter._link_summary_values.""" |
147 | - return {'hostname': self._context.hostname,} |
148 | + return {'hostname': self._context.hostname} |
149 | |
150 | |
151 | class MilestoneFormatterAPI(CustomizableFormatter): |
152 | @@ -2464,7 +2457,6 @@ |
153 | """See `ObjectFormatterAPI`.""" |
154 | return super(LanguageFormatterAPI, self).url(view_name, rootsite) |
155 | |
156 | - |
157 | def link(self, view_name, rootsite='translations'): |
158 | """See `ObjectFormatterAPI`.""" |
159 | url = self.url(view_name, rootsite) |
160 | @@ -2501,6 +2493,7 @@ |
161 | |
162 | |
163 | class PackageDiffFormatterAPI(ObjectFormatterAPI): |
164 | + |
165 | def link(self, view_name, rootsite=None): |
166 | diff = self._context |
167 | if not diff.date_fulfilled: |
168 | |
169 | === modified file 'lib/lp/registry/browser/configure.zcml' |
170 | --- lib/lp/registry/browser/configure.zcml 2010-09-21 03:30:43 +0000 |
171 | +++ lib/lp/registry/browser/configure.zcml 2010-09-23 13:36:13 +0000 |
172 | @@ -482,6 +482,12 @@ |
173 | factory="lp.registry.browser.distributionsourcepackage.DistributionSourcePackageFormatterAPI" |
174 | name="fmt" |
175 | /> |
176 | + <adapter |
177 | + for="lp.registry.interfaces.sourcepackage.ISourcePackage" |
178 | + provides="zope.traversing.interfaces.IPathAdapter" |
179 | + factory="lp.registry.browser.sourcepackage.SourcePackageFormatterAPI" |
180 | + name="fmt" |
181 | + /> |
182 | <browser:url |
183 | for="lp.registry.interfaces.commercialsubscription.ICommercialSubscription" |
184 | path_expression="string:+commercialsubscription/${id}" |
185 | |
186 | === modified file 'lib/lp/registry/browser/distribution.py' |
187 | --- lib/lp/registry/browser/distribution.py 2010-09-15 16:03:14 +0000 |
188 | +++ lib/lp/registry/browser/distribution.py 2010-09-23 14:23:31 +0000 |
189 | @@ -343,6 +343,7 @@ |
190 | 'ppas', |
191 | 'configure_answers', |
192 | 'configure_blueprints', |
193 | + 'configure_translations', |
194 | ] |
195 | |
196 | @enabled_with_permission('launchpad.Edit') |
197 | @@ -457,7 +458,13 @@ |
198 | @enabled_with_permission('launchpad.Edit') |
199 | def configure_blueprints(self): |
200 | text = 'Configure blueprints' |
201 | - summary = 'Enable tracking of feature planning.' |
202 | + summary = 'Enable tracking of feature planning.' |
203 | + return Link('+edit', text, summary, icon='edit') |
204 | + |
205 | + @enabled_with_permission('launchpad.Edit') |
206 | + def configure_translations(self): |
207 | + text = 'Configure translations' |
208 | + summary = 'Allow users to provide translations for this project.' |
209 | return Link('+edit', text, summary, icon='edit') |
210 | |
211 | |
212 | @@ -771,7 +778,7 @@ |
213 | "members", |
214 | "official_malone", |
215 | "official_blueprints", |
216 | - "official_rosetta", |
217 | + "translations_usage", |
218 | "official_answers", |
219 | ] |
220 | |
221 | @@ -817,7 +824,7 @@ |
222 | 'official_malone', |
223 | 'enable_bug_expiration', |
224 | 'official_blueprints', |
225 | - 'official_rosetta', |
226 | + 'translations_usage', |
227 | 'official_answers', |
228 | 'translation_focus', |
229 | ] |
230 | |
231 | === modified file 'lib/lp/registry/browser/sourcepackage.py' |
232 | --- lib/lp/registry/browser/sourcepackage.py 2010-09-03 06:06:40 +0000 |
233 | +++ lib/lp/registry/browser/sourcepackage.py 2010-09-23 14:23:54 +0000 |
234 | @@ -46,6 +46,7 @@ |
235 | _, |
236 | helpers, |
237 | ) |
238 | +from canonical.launchpad.webapp.tales import CustomizableFormatter |
239 | from canonical.launchpad.browser.multistep import ( |
240 | MultiStepView, |
241 | StepView, |
242 | @@ -122,6 +123,18 @@ |
243 | return '/projects/+new?%s' % query_string |
244 | |
245 | |
246 | +class SourcePackageFormatterAPI(CustomizableFormatter): |
247 | + """Adapter for ISourcePackage objects to a formatted string.""" |
248 | + |
249 | + _link_permission = 'zope.Public' |
250 | + |
251 | + _link_summary_template = '%(displayname)s' |
252 | + |
253 | + def _link_summary_values(self): |
254 | + displayname = self._context.displayname |
255 | + return {'displayname': displayname} |
256 | + |
257 | + |
258 | class SourcePackageNavigation(GetitemNavigation, BugTargetTraversalMixin): |
259 | |
260 | usedfor = ISourcePackage |
261 | @@ -338,7 +351,7 @@ |
262 | next_url = None |
263 | |
264 | main_action_label = u'Change' |
265 | - |
266 | + |
267 | def main_action(self, data): |
268 | productseries = data['productseries'] |
269 | # Because it is part of a multistep view, the next_url can't |
270 | |
271 | === modified file 'lib/lp/translations/browser/configure.zcml' |
272 | --- lib/lp/translations/browser/configure.zcml 2010-07-23 09:41:07 +0000 |
273 | +++ lib/lp/translations/browser/configure.zcml 2010-09-23 04:44:03 +0000 |
274 | @@ -645,6 +645,15 @@ |
275 | name="+languages" |
276 | template="../templates/productseries-translations-languages.pt" |
277 | /> |
278 | + <browser:page |
279 | + name="+portlet-not-using-launchpad" |
280 | + template="../templates/translations-portlet-not-using-launchpad.pt"/> |
281 | + <browser:page |
282 | + name="+portlet-configuration" |
283 | + template="../templates/translations-portlet-configuration.pt"/> |
284 | + <browser:page |
285 | + name="+portlet-not-using-launchpad-extra" |
286 | + template="../templates/translations-portlet-not-using-launchpad-extra.pt"/> |
287 | </browser:pages> |
288 | <browser:pages |
289 | for="lp.registry.interfaces.productseries.IProductSeries" |
290 | @@ -822,7 +831,13 @@ |
291 | template="../templates/product-portlet-obsolete-translatables.pt"/> |
292 | <browser:page |
293 | name="+portlet-not-using-launchpad" |
294 | - template="../templates/product-portlet-not-using-launchpad.pt"/> |
295 | + template="../templates/translations-portlet-not-using-launchpad.pt"/> |
296 | + <browser:page |
297 | + name="+portlet-configuration" |
298 | + template="../templates/translations-portlet-configuration.pt"/> |
299 | + <browser:page |
300 | + name="+portlet-not-using-launchpad-extra" |
301 | + template="../templates/translations-portlet-not-using-launchpad-extra.pt"/> |
302 | </browser:pages> |
303 | |
304 | <!-- ProjectGroup views --> |
305 | @@ -915,7 +930,24 @@ |
306 | permission="launchpad.View" |
307 | template="../templates/distribution-language-pack-admin-info.pt" |
308 | layer="lp.translations.publisher.TranslationsLayer"/> |
309 | - |
310 | + <browser:page |
311 | + name="+portlet-not-using-launchpad" |
312 | + for="lp.registry.interfaces.distribution.IDistribution" |
313 | + permission="zope.Public" |
314 | + template="../templates/translations-portlet-not-using-launchpad.pt" |
315 | + layer="lp.translations.publisher.TranslationsLayer"/> |
316 | + <browser:page |
317 | + name="+portlet-not-using-launchpad-extra" |
318 | + for="lp.registry.interfaces.distribution.IDistribution" |
319 | + permission="zope.Public" |
320 | + template="../templates/translations-portlet-not-using-launchpad-extra.pt" |
321 | + layer="lp.translations.publisher.TranslationsLayer"/> |
322 | + <browser:page |
323 | + name="+portlet-configuration" |
324 | + for="lp.registry.interfaces.distribution.IDistribution" |
325 | + permission="zope.Public" |
326 | + template="../templates/translations-portlet-configuration.pt" |
327 | + layer="lp.translations.publisher.TranslationsLayer"/> |
328 | <!-- DistroSeries --> |
329 | |
330 | <browser:defaultView |
331 | @@ -943,6 +975,15 @@ |
332 | <browser:page |
333 | name="+langchart" |
334 | template="../templates/distroseries-langchart.pt"/> |
335 | + <browser:page |
336 | + name="+portlet-not-using-launchpad" |
337 | + template="../templates/translations-portlet-not-using-launchpad.pt"/> |
338 | + <browser:page |
339 | + name="+portlet-configuration" |
340 | + template="../templates/translations-portlet-configuration.pt"/> |
341 | + <browser:page |
342 | + name="+portlet-not-using-launchpad-extra" |
343 | + template="../templates/translations-portlet-not-using-launchpad-extra.pt"/> |
344 | </browser:pages> |
345 | <browser:page |
346 | for="lp.registry.interfaces.distroseries.IDistroSeries" |
347 | |
348 | === modified file 'lib/lp/translations/browser/distribution.py' |
349 | --- lib/lp/translations/browser/distribution.py 2010-08-24 10:45:57 +0000 |
350 | +++ lib/lp/translations/browser/distribution.py 2010-09-23 14:25:54 +0000 |
351 | @@ -21,7 +21,9 @@ |
352 | LaunchpadView, |
353 | Link, |
354 | ) |
355 | +from canonical.launchpad.webapp.authorization import check_permission |
356 | from canonical.launchpad.webapp.menu import NavigationMenu |
357 | +from lp.app.enums import service_uses_launchpad |
358 | from lp.registry.browser.distribution import DistributionEditView |
359 | from lp.registry.interfaces.distribution import IDistribution |
360 | from lp.registry.interfaces.series import SeriesStatus |
361 | @@ -96,6 +98,20 @@ |
362 | else: |
363 | return self.context.translation_focus |
364 | |
365 | + @cachedproperty |
366 | + def show_page_content(self): |
367 | + """Whether the main content of the page should be shown.""" |
368 | + return (service_uses_launchpad(self.context.translations_usage) or |
369 | + self.is_translations_admin) |
370 | + |
371 | + def can_configure_translations(self): |
372 | + """Whether or not the user can configure translations.""" |
373 | + return check_permission("launchpad.Edit", self.context) |
374 | + |
375 | + def is_translations_admin(self): |
376 | + """Whether or not the user is a translations admin.""" |
377 | + return check_permission("launchpad.TranslationsAdmin", self.context) |
378 | + |
379 | def secondary_translatable_series(self): |
380 | """Return a list of IDistroSeries that aren't the translation_focus. |
381 | |
382 | @@ -106,8 +122,7 @@ |
383 | for series in self.context.series |
384 | if (series.status != SeriesStatus.OBSOLETE |
385 | and (self.translation_focus is None or |
386 | - self.translation_focus.id != series.id)) |
387 | - ] |
388 | + self.translation_focus.id != series.id))] |
389 | |
390 | return sorted(series, key=operator.attrgetter('version'), |
391 | reverse=True) |
392 | |
393 | === modified file 'lib/lp/translations/browser/distroseries.py' |
394 | --- lib/lp/translations/browser/distroseries.py 2010-09-11 09:37:13 +0000 |
395 | +++ lib/lp/translations/browser/distroseries.py 2010-09-23 14:26:11 +0000 |
396 | @@ -30,6 +30,7 @@ |
397 | LaunchpadView, |
398 | ) |
399 | from lp.app.errors import TranslationUnavailable |
400 | +from lp.app.enums import service_uses_launchpad |
401 | from lp.registry.interfaces.distroseries import IDistroSeries |
402 | from lp.registry.interfaces.series import SeriesStatus |
403 | from lp.services.propertycache import cachedproperty |
404 | @@ -262,6 +263,20 @@ |
405 | """Is this DistroSeries the translation focus.""" |
406 | return self.context.distribution.translation_focus == self.context |
407 | |
408 | + @cachedproperty |
409 | + def show_page_content(self): |
410 | + """Whether the main content of the page should be shown.""" |
411 | + return (service_uses_launchpad(self.context.translations_usage) or |
412 | + self.is_translations_admin) |
413 | + |
414 | + def can_configure_translations(self): |
415 | + """Whether or not the user can configure translations.""" |
416 | + return check_permission("launchpad.Edit", self.context) |
417 | + |
418 | + def is_translations_admin(self): |
419 | + """Whether or not the user is a translations admin.""" |
420 | + return check_permission("launchpad.TranslationsAdmin", self.context) |
421 | + |
422 | |
423 | class DistroSeriesTranslationsMenu(NavigationMenu): |
424 | |
425 | |
426 | === modified file 'lib/lp/translations/browser/product.py' |
427 | --- lib/lp/translations/browser/product.py 2010-09-03 13:29:58 +0000 |
428 | +++ lib/lp/translations/browser/product.py 2010-09-23 14:26:34 +0000 |
429 | @@ -106,7 +106,15 @@ |
430 | def show_page_content(self): |
431 | """Whether the main content of the page should be shown.""" |
432 | return (service_uses_launchpad(self.context.translations_usage) or |
433 | - check_permission("launchpad.TranslationsAdmin", self.context)) |
434 | + self.is_translations_admin) |
435 | + |
436 | + def can_configure_translations(self): |
437 | + """Whether or not the user can configure translations.""" |
438 | + return check_permission("launchpad.Edit", self.context) |
439 | + |
440 | + def is_translations_admin(self): |
441 | + """Whether or not the user is a translations admin.""" |
442 | + return check_permission("launchpad.TranslationsAdmin", self.context) |
443 | |
444 | @cachedproperty |
445 | def primary_translatable(self): |
446 | |
447 | === modified file 'lib/lp/translations/browser/productseries.py' |
448 | --- lib/lp/translations/browser/productseries.py 2010-09-11 09:37:13 +0000 |
449 | +++ lib/lp/translations/browser/productseries.py 2010-09-23 14:26:57 +0000 |
450 | @@ -37,8 +37,10 @@ |
451 | Link, |
452 | NavigationMenu, |
453 | ) |
454 | +from canonical.launchpad.webapp.authorization import check_permission |
455 | from canonical.launchpad.webapp.menu import structured |
456 | from canonical.widgets.itemswidgets import LaunchpadRadioWidgetWithDescription |
457 | +from lp.app.enums import service_uses_launchpad |
458 | from lp.code.interfaces.branchjob import IRosettaUploadJobSource |
459 | from lp.registry.interfaces.productseries import IProductSeries |
460 | from lp.services.propertycache import cachedproperty |
461 | @@ -410,6 +412,20 @@ |
462 | """Does this ProductSeries have exactly one POTemplate.""" |
463 | return self.context.potemplate_count == 1 |
464 | |
465 | + @cachedproperty |
466 | + def show_page_content(self): |
467 | + """Whether the main content of the page should be shown.""" |
468 | + return (service_uses_launchpad(self.context.translations_usage) or |
469 | + self.is_translations_admin) |
470 | + |
471 | + def can_configure_translations(self): |
472 | + """Whether or not the user can configure translations.""" |
473 | + return check_permission("launchpad.Edit", self.context) |
474 | + |
475 | + def is_translations_admin(self): |
476 | + """Whether or not the user is a translations admin.""" |
477 | + return check_permission("launchpad.TranslationsAdmin", self.context) |
478 | + |
479 | |
480 | class SettingsRadioWidget(LaunchpadRadioWidgetWithDescription): |
481 | """Remove the confusing hint under the widget.""" |
482 | |
483 | === modified file 'lib/lp/translations/interfaces/potemplate.py' |
484 | --- lib/lp/translations/interfaces/potemplate.py 2010-08-25 20:04:40 +0000 |
485 | +++ lib/lp/translations/interfaces/potemplate.py 2010-09-23 14:27:34 +0000 |
486 | @@ -739,6 +739,10 @@ |
487 | title=_("Does this object have current translation templates?"), |
488 | readonly=True) |
489 | |
490 | + has_translation_files = Bool( |
491 | + title=_("Does this object have translation files?"), |
492 | + readonly=True) |
493 | + |
494 | def getTemplatesCollection(): |
495 | """Return templates as a `TranslationTemplatesCollection`. |
496 | |
497 | @@ -804,6 +808,7 @@ |
498 | exist for it. |
499 | """ |
500 | |
501 | + |
502 | class ITranslationTemplatesCollection(Interface): |
503 | """A `Collection` of `POTemplate`s.""" |
504 | |
505 | |
506 | === modified file 'lib/lp/translations/model/potemplate.py' |
507 | --- lib/lp/translations/model/potemplate.py 2010-09-03 13:29:58 +0000 |
508 | +++ lib/lp/translations/model/potemplate.py 2010-09-23 14:29:04 +0000 |
509 | @@ -1620,6 +1620,12 @@ |
510 | collection = self.getCurrentTemplatesCollection() |
511 | return collection.joinPOFile().select(selection) |
512 | |
513 | + @property |
514 | + def has_translation_files(self): |
515 | + """See `IHasTranslationTemplates`.""" |
516 | + return bool( |
517 | + self.getCurrentTranslationFiles(just_ids=True).any()) |
518 | + |
519 | def getObsoleteTranslationTemplates(self): |
520 | """See `IHasTranslationTemplates`.""" |
521 | # XXX JeroenVermeulen 2010-07-15 bug=605924: This returns a list |
522 | |
523 | === modified file 'lib/lp/translations/templates/distribution-translations.pt' |
524 | --- lib/lp/translations/templates/distribution-translations.pt 2010-08-20 01:41:58 +0000 |
525 | +++ lib/lp/translations/templates/distribution-translations.pt 2010-09-23 15:47:47 +0000 |
526 | @@ -22,6 +22,17 @@ |
527 | </a> |
528 | <div></div><!-- to clear-up all floats --> |
529 | </div> |
530 | + |
531 | + <tal:not-using-launchpad |
532 | + condition="not: context/translations_usage/enumvalue:LAUNCHPAD"> |
533 | + <tal:message |
534 | + replace="structure context/@@+portlet-not-using-launchpad"/> |
535 | + <tal:translations-configuration |
536 | + condition="view/can_configure_translations" |
537 | + replace="structure context/@@+portlet-configuration"/> |
538 | + </tal:not-using-launchpad> |
539 | + |
540 | + <tal:show-page-content condition="view/show_page_content"> |
541 | <tal:translation_focus condition="view/translation_focus" |
542 | define="target view/translation_focus"> |
543 | |
544 | @@ -71,27 +82,27 @@ |
545 | </div> |
546 | </tal:translation_focus> |
547 | |
548 | - <tal:secondary condition="view/secondary_translatable_series"> |
549 | - <h2 tal:condition="view/translation_focus"> |
550 | - Other versions of <span tal:replace="context/displayname">Ubuntu</span> |
551 | - </h2> |
552 | - |
553 | - <ul id="distroseries-list"> |
554 | - <li tal:repeat="distroseries view/secondary_translatable_series"> |
555 | - <a tal:attributes="href distroseries/fmt:url:translations" |
556 | - tal:content="distroseries/named_version">Hoary (5.04)</a> |
557 | - </li> |
558 | - </ul> |
559 | - </tal:secondary> |
560 | - |
561 | - <tal:untranslatable condition="not: view/translation_focus"> |
562 | - <p> |
563 | - This distribution does not have any series to be translated. Once |
564 | - <span tal:replace="context/displayname">Ubuntu</span> has created a |
565 | - distroseries, you will be able to find or create its translations here. |
566 | - </p> |
567 | - </tal:untranslatable> |
568 | - |
569 | + <tal:secondary condition="view/secondary_translatable_series"> |
570 | + <h2 tal:condition="view/translation_focus"> |
571 | + Other versions of <span tal:replace="context/displayname">Ubuntu</span> |
572 | + </h2> |
573 | + |
574 | + <ul id="distroseries-list"> |
575 | + <li tal:repeat="distroseries view/secondary_translatable_series"> |
576 | + <a tal:attributes="href distroseries/fmt:url:translations" |
577 | + tal:content="distroseries/named_version">Hoary (5.04)</a> |
578 | + </li> |
579 | + </ul> |
580 | + </tal:secondary> |
581 | + |
582 | + <tal:untranslatable condition="not: view/translation_focus"> |
583 | + <p> |
584 | + This distribution does not have any series to be translated. Once |
585 | + <span tal:replace="context/displayname">Ubuntu</span> has created a |
586 | + distroseries, you will be able to find or create its translations here. |
587 | + </p> |
588 | + </tal:untranslatable> |
589 | + </tal:show-page-content> |
590 | </div> |
591 | </body> |
592 | </html> |
593 | |
594 | === modified file 'lib/lp/translations/templates/distroseries-translations.pt' |
595 | --- lib/lp/translations/templates/distroseries-translations.pt 2010-08-20 00:39:54 +0000 |
596 | +++ lib/lp/translations/templates/distroseries-translations.pt 2010-09-23 05:00:28 +0000 |
597 | @@ -21,8 +21,13 @@ |
598 | </a> |
599 | <div></div><!-- to clear-up all floats --> |
600 | </div> |
601 | - <div class="top-portlet" |
602 | - id="translation-focus" |
603 | + <div class="top-portlet"> |
604 | + <tal:not-using-launchpad |
605 | + condition="not: context/translations_usage/enumvalue:LAUNCHPAD"> |
606 | + <tal:message |
607 | + replace="structure context/@@+portlet-not-using-launchpad"/> |
608 | + </tal:not-using-launchpad> |
609 | + <div id="translation-focus" |
610 | tal:condition="context/distribution/translation_focus"> |
611 | <p tal:condition="not:view/is_translation_focus"> |
612 | Launchpad currently recommends translating |
613 | @@ -39,14 +44,16 @@ |
614 | </tal:distro>. |
615 | </p> |
616 | </div> |
617 | - <div class="yui-g"> |
618 | + </div> |
619 | + |
620 | + <div tal:condition="view/show_page_content" class="yui-g"> |
621 | <div class="yui-u first"> |
622 | <div class="portlet"> |
623 | <h3>Permissions</h3> |
624 | <p> |
625 | <tal:permissions replace=" |
626 | - structure |
627 | - context/distribution/@@+portlet-translation-groups-and-permission"/> |
628 | + structure |
629 | + context/distribution/@@+portlet-translation-groups-and-permission"/> |
630 | </p> |
631 | </div> |
632 | </div> |
633 | @@ -130,7 +137,7 @@ |
634 | </div> |
635 | </div> |
636 | </div> |
637 | - |
638 | + <tal:show-page-content condition="view/show_page_content"> |
639 | <tal:stats condition="view/distroserieslanguages"> |
640 | <div class="yui-b top-portlet"> |
641 | <h2>Translation statistics</h2> |
642 | @@ -140,6 +147,7 @@ |
643 | </div> |
644 | </div> |
645 | </tal:stats> |
646 | + </tal:show-page-content> |
647 | </div> |
648 | </body> |
649 | </html> |
650 | |
651 | === modified file 'lib/lp/translations/templates/product-translations.pt' |
652 | --- lib/lp/translations/templates/product-translations.pt 2010-08-20 00:39:54 +0000 |
653 | +++ lib/lp/translations/templates/product-translations.pt 2010-09-23 03:13:09 +0000 |
654 | @@ -23,14 +23,25 @@ |
655 | <div></div><!-- to clear-up all floats --> |
656 | </div> |
657 | <div class="top-portlet notice"> |
658 | - <tal:official_use replace=" |
659 | - structure |
660 | - context/@@+portlet-not-using-launchpad"/> |
661 | + |
662 | + <tal:not-using-launchpad |
663 | + condition="not: context/translations_usage/enumvalue:LAUNCHPAD"> |
664 | + <tal:message |
665 | + replace="structure context/@@+portlet-not-using-launchpad"/> |
666 | + <tal:translations-configuration |
667 | + condition="view/can_configure_translations" |
668 | + replace="structure context/@@+portlet-configuration"/> |
669 | + <tal:translatable-packages |
670 | + condition="not: view/is_translations_admin" |
671 | + replace="structure context/@@+portlet-not-using-launchpad-extra"/> |
672 | + </tal:not-using-launchpad> |
673 | + |
674 | <div tal:condition="view/no_translations_available"> |
675 | - There are no translations for this project. |
676 | + There are no translations for this project. |
677 | </div> |
678 | </div> |
679 | |
680 | + <!-- Not sure this should be shown at all if translations is off. --> |
681 | <tal:page_content condition="view/show_page_content"> |
682 | <tal:translatable define="target view/primary_translatable"> |
683 | |
684 | |
685 | === modified file 'lib/lp/translations/templates/productseries-translations.pt' |
686 | --- lib/lp/translations/templates/productseries-translations.pt 2010-08-30 21:16:40 +0000 |
687 | +++ lib/lp/translations/templates/productseries-translations.pt 2010-09-23 15:45:04 +0000 |
688 | @@ -24,30 +24,37 @@ |
689 | |
690 | <tal:no-languages condition="not:view/productserieslanguages"> |
691 | <div class="yui-b top-portlet"> |
692 | - <p>There are no translations for this release series.</p> |
693 | - |
694 | - <p tal:condition="context/product/required:launchpad.Edit">To |
695 | - <a href="https://help.launchpad.net/Translations/YourProject">start |
696 | - translating your project</a>, |
697 | - <tal:uses-translations condition="not: |
698 | - context/product/translations_usage/enumvalue:LAUNCHPAD"> |
699 | - you should enable translations in your project settings, and |
700 | - </tal:uses-translations> |
701 | - you can either |
702 | - <a |
703 | - tal:define="link context/menu:navigation/translationupload" |
704 | - tal:attributes="href link/url" |
705 | - >manually upload</a> templates and translations, or set up |
706 | + |
707 | + <tal:not-using-launchpad |
708 | + condition="not: context/translations_usage/enumvalue:LAUNCHPAD"> |
709 | + <tal:message |
710 | + replace="structure context/@@+portlet-not-using-launchpad"/> |
711 | + </tal:not-using-launchpad> |
712 | + |
713 | + <p>There are no translations for this release series.</p> |
714 | + |
715 | + <p tal:condition="context/product/required:launchpad.Edit">To |
716 | + <a href="https://help.launchpad.net/Translations/YourProject">start |
717 | + translating your project</a>, |
718 | + <tal:uses-translations condition="not: |
719 | + context/product/translations_usage/enumvalue:LAUNCHPAD"> |
720 | + you should enable translations in your project settings, and |
721 | + </tal:uses-translations> |
722 | + you can either |
723 | + <a |
724 | + tal:define="link context/menu:navigation/translationupload" |
725 | + tal:attributes="href link/url">manually upload</a> |
726 | + templates and translations, or set up |
727 | <a |
728 | tal:define="link context/menu:navigation/settings" |
729 | - tal:attributes="href link/url" |
730 | - >automatic import from branches</a> |
731 | + tal:attributes="href link/url">automatic import from branches |
732 | + </a> |
733 | (<a href="https://help.launchpad.net/Translations/ImportingFromBazaarBranches">read more</a>). |
734 | - </p> |
735 | + </p> |
736 | </div> |
737 | </tal:no-languages> |
738 | |
739 | - <div class="yui-g"> |
740 | + <div tal:condition="view/show_page_content" class="yui-g"> |
741 | <div class="yui-u first"> |
742 | <div class="portlet"> |
743 | <h3>Permissions</h3> |
744 | |
745 | === added file 'lib/lp/translations/templates/translations-portlet-configuration.pt' |
746 | --- lib/lp/translations/templates/translations-portlet-configuration.pt 1970-01-01 00:00:00 +0000 |
747 | +++ lib/lp/translations/templates/translations-portlet-configuration.pt 2010-09-23 14:32:01 +0000 |
748 | @@ -0,0 +1,25 @@ |
749 | +<tal:root |
750 | + xmlns:tal="http://xml.zope.org/namespaces/tal" |
751 | + xmlns:metal="http://xml.zope.org/namespaces/metal" |
752 | + xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
753 | + omit-tag=""> |
754 | + |
755 | + <div id="translations-explanation"> |
756 | + <ul> |
757 | + <li> |
758 | + Launchpad allows communities to translate projects using imports |
759 | + or a branch. |
760 | + </li> |
761 | + <li> |
762 | + <a class="info sprite" |
763 | + href="/+help/getting-started-for-your-project.html" |
764 | + target="help"> |
765 | + Getting started with translating your project in Launchpad |
766 | + </a> |
767 | + </li> |
768 | + <li> |
769 | + <a tal:replace="structure context/menu:overview/configure_translations/fmt:link"/> |
770 | + </li> |
771 | + </ul> |
772 | + </div> |
773 | +</tal:root> |
774 | |
775 | === added file 'lib/lp/translations/templates/translations-portlet-not-using-launchpad-extra.pt' |
776 | --- lib/lp/translations/templates/translations-portlet-not-using-launchpad-extra.pt 1970-01-01 00:00:00 +0000 |
777 | +++ lib/lp/translations/templates/translations-portlet-not-using-launchpad-extra.pt 2010-09-23 02:30:32 +0000 |
778 | @@ -0,0 +1,16 @@ |
779 | +<tal:root |
780 | + xmlns:tal="http://xml.zope.org/namespaces/tal" |
781 | + xmlns:metal="http://xml.zope.org/namespaces/metal" |
782 | + xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
783 | + omit-tag=""> |
784 | + |
785 | + <div id="ubuntu-translations" |
786 | + tal:define="packages context/translatable_packages | nothing" |
787 | + tal:condition="packages"> |
788 | + <tal:project replace="context/displayname" /> messages are |
789 | + tracked in: <tal:packages repeat="package packages"> |
790 | + <tal:package replace="structure package/fmt:link" /> |
791 | + <tal:comma condition="not:repeat/package/end">, </tal:comma> |
792 | + </tal:packages>. |
793 | + </div> |
794 | +</tal:root> |
795 | |
796 | === renamed file 'lib/lp/translations/templates/product-portlet-not-using-launchpad.pt' => 'lib/lp/translations/templates/translations-portlet-not-using-launchpad.pt' |
797 | --- lib/lp/translations/templates/product-portlet-not-using-launchpad.pt 2010-08-30 21:16:40 +0000 |
798 | +++ lib/lp/translations/templates/translations-portlet-not-using-launchpad.pt 2010-09-23 15:50:00 +0000 |
799 | @@ -4,20 +4,23 @@ |
800 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
801 | omit-tag=""> |
802 | |
803 | - <div id="not-translated-in-launchpad" |
804 | - tal:condition="not: context/translations_usage/enumvalue:LAUNCHPAD"> |
805 | + <div id="not-translated-in-launchpad"> |
806 | <strong> |
807 | - This project is not using Launchpad for translations. |
808 | + <tal:lauchpad-unknown |
809 | + condition="context/translations_usage/enumvalue:UNKNOWN"> |
810 | + Launchpad does not know where |
811 | + <tal:project replace="context/displayname" /> translates its messages. |
812 | + </tal:lauchpad-unknown> |
813 | + <tal:launchpad-external |
814 | + condition="context/translations_usage/enumvalue:EXTERNAL"> |
815 | + <tal:project replace="context/displayname" /> does not use Launchpad |
816 | + to translate its messages. |
817 | + </tal:launchpad-external> |
818 | + <tal:launchpad-not-applicable |
819 | + tal:condition="context/translations_usage/enumvalue:NOT_APPLICABLE"> |
820 | + <tal:project replace="context/displayname" /> does not translate its |
821 | + messages. |
822 | + </tal:launchpad-not-applicable> |
823 | </strong> |
824 | - <ul> |
825 | - <li> |
826 | - <a tal:replace="structure context/menu:overview/configure_translations/fmt:link"/> |
827 | - </li> |
828 | - <li> |
829 | - <a href="/+help/getting-started-for-your-project.html" target="help" |
830 | - >Getting started with translating your project in Launchpad</a> |
831 | - </li> |
832 | - </ul> |
833 | </div> |
834 | - |
835 | </tal:root> |
836 | |
837 | === modified file 'lib/lp/translations/tests/test_hastranslationtemplates.py' |
838 | --- lib/lp/translations/tests/test_hastranslationtemplates.py 2010-08-30 21:11:21 +0000 |
839 | +++ lib/lp/translations/tests/test_hastranslationtemplates.py 2010-09-23 18:00:41 +0000 |
840 | @@ -29,6 +29,11 @@ |
841 | raise NotImplementedError( |
842 | 'This must be provided by an executable test.') |
843 | |
844 | + def createTranslationFile(self, name, priority=0): |
845 | + """Attaches a pofile to appropriate container.""" |
846 | + raise NotImplementedError( |
847 | + 'This must be provided by an executable test.') |
848 | + |
849 | def test_implements_interface(self): |
850 | # Make sure container implements IHasTranslationTemplates. |
851 | verifyObject(IHasTranslationTemplates, self.container) |
852 | @@ -156,6 +161,13 @@ |
853 | self.product_or_distro.translations_usage = ServiceUsage.EXTERNAL |
854 | self.assertFalse(self.container.has_current_translation_templates) |
855 | |
856 | + def test_has_translation_files(self): |
857 | + # has_translations_files should only return true if the object has |
858 | + # pofiles. |
859 | + self.assertFalse(self.container.has_translation_files) |
860 | + self.createTranslationFile("one") |
861 | + self.assertTrue(self.container.has_translation_files) |
862 | + |
863 | def test_getTranslationTemplateFormats(self): |
864 | # Check that translation_template_formats works properly. |
865 | |
866 | @@ -202,6 +214,13 @@ |
867 | potemplate.priority = priority |
868 | return potemplate |
869 | |
870 | + def createTranslationFile(self, name, priority=0): |
871 | + potemplate = self.createTranslationTemplate(name, priority) |
872 | + pofile = self.factory.makePOFile( |
873 | + language_code='es', |
874 | + potemplate=potemplate) |
875 | + return pofile |
876 | + |
877 | def setUp(self): |
878 | super(TestProductSeriesHasTranslationTemplates, self).setUp() |
879 | self.container = self.factory.makeProductSeries() |
880 | @@ -220,6 +239,13 @@ |
881 | potemplate.priority = priority |
882 | return potemplate |
883 | |
884 | + def createTranslationFile(self, name, priority=0): |
885 | + potemplate = self.createTranslationTemplate(name, priority) |
886 | + pofile = self.factory.makePOFile( |
887 | + language_code='es', |
888 | + potemplate=potemplate) |
889 | + return pofile |
890 | + |
891 | def setUp(self): |
892 | super(TestSourcePackageHasTranslationTemplates, self).setUp() |
893 | self.container = self.factory.makeSourcePackage() |
894 | @@ -240,6 +266,13 @@ |
895 | potemplate.priority = priority |
896 | return potemplate |
897 | |
898 | + def createTranslationFile(self, name, priority=0): |
899 | + potemplate = self.createTranslationTemplate(name, priority) |
900 | + pofile = self.factory.makePOFile( |
901 | + language_code='es', |
902 | + potemplate=potemplate) |
903 | + return pofile |
904 | + |
905 | def setUp(self): |
906 | super(TestDistroSeriesHasTranslationTemplates, self).setUp() |
907 | self.container = self.factory.makeDistroRelease() |
Adding a diff here as a snapshot since I'm about to add sample data and it will totally bork the diff.