Merge lp:~thumper/launchpad/fix-canonical-url into lp:launchpad

Proposed by Tim Penhey on 2010-08-19
Status: Merged
Approved by: Tim Penhey on 2010-08-20
Approved revision: no longer in the source branch.
Merged at revision: 11403
Proposed branch: lp:~thumper/launchpad/fix-canonical-url
Merge into: lp:launchpad
Diff against target: 1083 lines (+227/-151)
32 files modified
lib/canonical/launchpad/doc/canonical_url.txt (+5/-4)
lib/canonical/launchpad/webapp/publisher.py (+44/-10)
lib/lp/answers/configure.zcml (+6/-2)
lib/lp/blueprints/configure.zcml (+11/-6)
lib/lp/bugs/configure.zcml (+10/-6)
lib/lp/code/configure.zcml (+6/-2)
lib/lp/code/publisher.py (+6/-2)
lib/lp/translations/browser/customlanguagecode.py (+12/-10)
lib/lp/translations/browser/distribution.py (+9/-11)
lib/lp/translations/browser/distroseries.py (+15/-14)
lib/lp/translations/browser/person.py (+10/-7)
lib/lp/translations/browser/poexportrequest.py (+2/-1)
lib/lp/translations/browser/pofile.py (+2/-1)
lib/lp/translations/browser/product.py (+6/-7)
lib/lp/translations/browser/productseries.py (+24/-24)
lib/lp/translations/browser/project.py (+4/-6)
lib/lp/translations/browser/sourcepackage.py (+4/-3)
lib/lp/translations/configure.zcml (+10/-6)
lib/lp/translations/templates/customlanguagecode-index.pt (+2/-2)
lib/lp/translations/templates/customlanguagecodes-index.pt (+3/-3)
lib/lp/translations/templates/distribution-language-pack-admin-info.pt (+2/-3)
lib/lp/translations/templates/distribution-translations.pt (+2/-2)
lib/lp/translations/templates/distroseries-language-packs.pt (+1/-1)
lib/lp/translations/templates/distroseries-translations.pt (+1/-1)
lib/lp/translations/templates/languageset-index.pt (+1/-1)
lib/lp/translations/templates/product-portlet-translatables.pt (+5/-5)
lib/lp/translations/templates/product-translations.pt (+3/-3)
lib/lp/translations/templates/productseries-translations-upload.pt (+1/-1)
lib/lp/translations/templates/rosetta-index.pt (+1/-1)
lib/lp/translations/templates/sourcepackage-translations.pt (+1/-1)
lib/lp/translations/tests/test_pofile.py (+10/-1)
lib/lp/vostok/configure.zcml (+8/-4)
To merge this branch: bzr merge lp:~thumper/launchpad/fix-canonical-url
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) 2010-08-19 Approve on 2010-08-19
Review via email: mp+33079@code.launchpad.net

Commit Message

Fix canonical_url to look on the right rootsite for views.

Description of the Change

This branch changes the way that canonical_url does the view_name check.

Currently it checks using the current browser request to define the layer rather than the layer that is defined by the canonical_url_data of the context object.

Instead we lookup the layer for the given rootsite and use that to query for the existence of the view.

Pre-impl call: mwhudson, and the mailing list thread: https://lists.launchpad.net/launchpad-dev/msg04345.html

Tests:
  canonical_url

To post a comment you must log in.
Jeroen T. Vermeulen (jtv) wrote :

I'll trust you on this not breaking any tests (of course you'll want to run a lot more than just the canonical_url one!) and on the tests being sufficient.

Discussed on IRC: incurring an exception for the default case isn't likely to be expensive.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/doc/canonical_url.txt'
2--- lib/canonical/launchpad/doc/canonical_url.txt 2009-11-14 22:44:07 +0000
3+++ lib/canonical/launchpad/doc/canonical_url.txt 2010-08-20 05:52:56 +0000
4@@ -28,11 +28,11 @@
5 Add a view for Country/+map.
6
7 >>> from zope.component import provideAdapter
8- >>> from zope.publisher.interfaces.http import IHTTPApplicationRequest
9+ >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
10 >>> class CountryMapView(object):
11 ... def __init__(self, country, request):
12 ... pass
13- >>> provideAdapter(CountryMapView, (ICountry, IHTTPApplicationRequest),
14+ >>> provideAdapter(CountryMapView, (ICountry, IDefaultBrowserLayer),
15 ... name='+map', provides=Interface)
16
17 Define a navigation for the Country URL.
18@@ -56,7 +56,7 @@
19 ... town.name = 'Greenwich'
20 ... return town
21 >>> provideAdapter(
22- ... CountryNavigation, [ICountry, IHTTPApplicationRequest],
23+ ... CountryNavigation, [ICountry, IDefaultBrowserLayer],
24 ... IBrowserPublisher)
25
26 Put the interfaces into canonical.launchpad.ftests, ensuring that there
27@@ -352,6 +352,7 @@
28 getApplicationURL() from
29 zope.publisher.interfaces.http.IHTTPApplicationRequest.
30
31+ >>> from zope.publisher.interfaces.http import IHTTPApplicationRequest
32 >>> class FakeRequest:
33 ...
34 ... implements(IHTTPApplicationRequest)
35@@ -468,7 +469,7 @@
36 Traceback (most recent call last):
37 ...
38 AssertionError: Name "+does-not-exist" is not registered as a view
39- or navigation step for "Country".
40+ or navigation step for "Country" on "bugs".
41
42
43 == The 'nearest' helper function ==
44
45=== modified file 'lib/canonical/launchpad/webapp/publisher.py'
46--- lib/canonical/launchpad/webapp/publisher.py 2010-08-02 02:13:52 +0000
47+++ lib/canonical/launchpad/webapp/publisher.py 2010-08-20 05:52:56 +0000
48@@ -31,14 +31,22 @@
49 from zope.app.publisher.interfaces.xmlrpc import IXMLRPCView
50 from zope.app.publisher.xmlrpc import IMethodPublisher
51 from zope.component import getUtility, queryMultiAdapter
52-from zope.interface import implements
53+from zope.component.interfaces import ComponentLookupError
54+from zope.interface import directlyProvides, implements
55 from zope.interface.advice import addClassAdvisor
56 from zope.publisher.interfaces import NotFound
57-from zope.publisher.interfaces.browser import IBrowserPublisher
58+from zope.publisher.interfaces.browser import (
59+ IBrowserPublisher,
60+ IDefaultBrowserLayer,
61+ )
62 from zope.security.checker import ProxyFactory, NamesChecker
63 from zope.traversing.browser.interfaces import IAbsoluteURL
64
65-from canonical.launchpad.layers import setFirstLayer, WebServiceLayer
66+from canonical.launchpad.layers import (
67+ LaunchpadLayer,
68+ WebServiceLayer,
69+ setFirstLayer,
70+ )
71 from canonical.launchpad.webapp.vhosts import allvhosts
72 from canonical.launchpad.webapp.interfaces import (
73 ICanonicalUrlData, ILaunchBag, ILaunchpadApplication, ILaunchpadContainer,
74@@ -408,6 +416,29 @@
75 __call__ = __str__
76
77
78+def layer_for_rootsite(rootsite):
79+ """Return the registered layer for the specified rootsite.
80+
81+ 'code' -> lp.code.publisher.CodeLayer
82+ 'translations' -> lp.translations.publisher.TranslationsLayer
83+ et al.
84+
85+ The layer is defined in ZCML using a named utility with the name of the
86+ rootsite, and providing IDefaultBrowserLayer. If there is no utility
87+ defined with the specified name, then LaunchpadLayer is returned.
88+ """
89+ try:
90+ return getUtility(IDefaultBrowserLayer, rootsite)
91+ except ComponentLookupError:
92+ return LaunchpadLayer
93+
94+
95+class FakeRequest:
96+ """Used solely to provide a layer for the view check in canonical_url."""
97+
98+ form_ng = None
99+
100+
101 def canonical_url(
102 obj, request=None, rootsite=None, path_only_if_possible=False,
103 view_name=None, force_local_path=False):
104@@ -472,14 +503,14 @@
105 request = current_request
106
107 if view_name is not None:
108- assert request is not None, (
109- "Cannot check view_name parameter when the request is not "
110- "available.")
111-
112+ # Make sure that the view is registered for the site requested.
113+ fake_request = FakeRequest()
114+ directlyProvides(fake_request, layer_for_rootsite(rootsite))
115 # Look first for a view.
116- if queryMultiAdapter((obj, request), name=view_name) is None:
117+ if queryMultiAdapter((obj, fake_request), name=view_name) is None:
118 # Look if this is a special name defined by Navigation.
119- navigation = queryMultiAdapter((obj, request), IBrowserPublisher)
120+ navigation = queryMultiAdapter(
121+ (obj, fake_request), IBrowserPublisher)
122 if isinstance(navigation, Navigation):
123 all_names = navigation.all_traversal_and_redirection_names
124 else:
125@@ -487,10 +518,13 @@
126 if view_name not in all_names:
127 raise AssertionError(
128 'Name "%s" is not registered as a view or navigation '
129- 'step for "%s".' % (view_name, obj.__class__.__name__))
130+ 'step for "%s" on "%s".' % (
131+ view_name, obj.__class__.__name__, rootsite))
132 urlparts.insert(0, view_name)
133
134 if request is None:
135+ # Yes this really does need to be here, as rootsite can be None, and
136+ # we don't want to make the getRootURL from the request break.
137 if rootsite is None:
138 rootsite = 'mainsite'
139 root_url = allvhosts.configs[rootsite].rooturl
140
141=== modified file 'lib/lp/answers/configure.zcml'
142--- lib/lp/answers/configure.zcml 2010-08-18 21:11:49 +0000
143+++ lib/lp/answers/configure.zcml 2010-08-20 05:52:56 +0000
144@@ -11,8 +11,12 @@
145 <include package=".browser" />
146
147 <publisher
148- name="answers"
149- factory="lp.answers.publisher.answers_request_publication_factory"/>
150+ name="answers"
151+ factory="lp.answers.publisher.answers_request_publication_factory"/>
152+ <utility
153+ component="lp.answers.publisher.AnswersLayer"
154+ provides="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
155+ name="answers" />
156
157 <subscriber
158 for=".interfaces.question.IQuestion
159
160=== modified file 'lib/lp/blueprints/configure.zcml'
161--- lib/lp/blueprints/configure.zcml 2010-07-16 16:58:55 +0000
162+++ lib/lp/blueprints/configure.zcml 2010-08-20 05:52:56 +0000
163@@ -9,12 +9,17 @@
164 xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
165 xmlns:lp="http://namespaces.canonical.com/lp"
166 i18n_domain="launchpad">
167- <include
168- package=".browser"/>
169-
170- <publisher
171- name="blueprints"
172- factory="lp.blueprints.publisher.blueprints_request_publication_factory"/>
173+
174+ <include package=".browser"/>
175+
176+ <publisher
177+ name="blueprints"
178+ factory="lp.blueprints.publisher.blueprints_request_publication_factory"/>
179+ <utility
180+ component="lp.blueprints.publisher.BlueprintsLayer"
181+ provides="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
182+ name="blueprints" />
183+
184
185 <lp:help-folder
186 folder="help" type="lp.blueprints.publisher.BlueprintsLayer" />
187
188=== modified file 'lib/lp/bugs/configure.zcml'
189--- lib/lp/bugs/configure.zcml 2010-08-02 17:48:13 +0000
190+++ lib/lp/bugs/configure.zcml 2010-08-20 05:52:56 +0000
191@@ -9,12 +9,16 @@
192 xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
193 xmlns:lp="http://namespaces.canonical.com/lp"
194 i18n_domain="launchpad">
195- <include
196- package=".browser"/>
197-
198- <publisher
199- name="bugs"
200- factory="lp.bugs.publisher.bugs_request_publication_factory"/>
201+
202+ <include package=".browser"/>
203+
204+ <publisher
205+ name="bugs"
206+ factory="lp.bugs.publisher.bugs_request_publication_factory"/>
207+ <utility
208+ component="lp.bugs.publisher.BugsLayer"
209+ provides="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
210+ name="bugs" />
211
212 <lp:help-folder
213 folder="help" type="lp.bugs.publisher.BugsLayer" />
214
215=== modified file 'lib/lp/code/configure.zcml'
216--- lib/lp/code/configure.zcml 2010-08-17 18:33:26 +0000
217+++ lib/lp/code/configure.zcml 2010-08-20 05:52:56 +0000
218@@ -14,8 +14,12 @@
219 <authorizations module="lp.code.security" />
220
221 <publisher
222- name="code"
223- factory="lp.code.publisher.code_request_publication_factory"/>
224+ name="code"
225+ factory="lp.code.publisher.code_request_publication_factory"/>
226+ <utility
227+ component="lp.code.publisher.CodeLayer"
228+ provides="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
229+ name="code" />
230
231 <!-- Branch Merge Queue -->
232
233
234=== modified file 'lib/lp/code/publisher.py'
235--- lib/lp/code/publisher.py 2010-07-20 23:52:46 +0000
236+++ lib/lp/code/publisher.py 2010-08-20 05:52:56 +0000
237@@ -13,11 +13,15 @@
238
239 from zope.interface import implements
240 from zope.publisher.interfaces.browser import (
241- IBrowserRequest, IDefaultBrowserLayer)
242+ IBrowserRequest,
243+ IDefaultBrowserLayer,
244+ )
245
246 from canonical.launchpad.webapp.publication import LaunchpadBrowserPublication
247 from canonical.launchpad.webapp.servers import (
248- LaunchpadBrowserRequest, VHostWebServiceRequestPublicationFactory)
249+ LaunchpadBrowserRequest,
250+ VHostWebServiceRequestPublicationFactory,
251+ )
252
253
254 class CodeLayer(IBrowserRequest, IDefaultBrowserLayer):
255
256=== modified file 'lib/lp/translations/browser/customlanguagecode.py'
257--- lib/lp/translations/browser/customlanguagecode.py 2010-08-02 02:13:52 +0000
258+++ lib/lp/translations/browser/customlanguagecode.py 2010-08-20 05:52:56 +0000
259@@ -103,16 +103,18 @@
260
261 @property
262 def action_url(self):
263- return "%s/+add-custom-language-code" % canonical_url(self.context)
264+ return canonical_url(
265+ self.context, rootsite='translations',
266+ view_name='+add-custom-language-code')
267
268 @property
269 def next_url(self):
270 """See `LaunchpadFormView`."""
271- return "%s/+custom-language-codes" % canonical_url(self.context)
272+ return canonical_url(
273+ self.context, rootsite='translations',
274+ view_name='+custom-language-codes')
275
276- @property
277- def cancel_url(self):
278- return self.next_url
279+ cancel_url = next_url
280
281
282 class CustomLanguageCodeView(LaunchpadView):
283@@ -145,12 +147,12 @@
284
285 @property
286 def next_url(self):
287- return "%s/+custom-language-codes" % canonical_url(
288- self.context.translation_target)
289+ """See `LaunchpadFormView`."""
290+ return canonical_url(
291+ self.context.translation_target, rootsite='translations',
292+ view_name='+custom-language-codes')
293
294- @property
295- def cancel_url(self):
296- return self.next_url
297+ cancel_url = next_url
298
299
300 class HasCustomLanguageCodesTraversalMixin:
301
302=== modified file 'lib/lp/translations/browser/distribution.py'
303--- lib/lp/translations/browser/distribution.py 2010-02-16 21:21:14 +0000
304+++ lib/lp/translations/browser/distribution.py 2010-08-20 05:52:56 +0000
305@@ -38,16 +38,18 @@
306 @enabled_with_permission('launchpad.TranslationsAdmin')
307 def settings(self):
308 text = 'Change permissions'
309- return Link('+settings', text, icon='edit')
310+ return Link('+settings', text, icon='edit', site='translations')
311
312 @enabled_with_permission('launchpad.TranslationsAdmin')
313 def language_pack_admin(self):
314 text = 'Language pack admin'
315- return Link('+select-language-pack-admin', text, icon='edit')
316+ return Link(
317+ '+select-language-pack-admin', text, icon='edit',
318+ site='translations')
319
320 def imports(self):
321 text = 'Import queue'
322- return Link('+imports', text)
323+ return Link('+imports', text, site='translations')
324
325
326 class DistributionLanguagePackAdminView(LaunchpadEditFormView):
327@@ -59,11 +61,9 @@
328
329 @property
330 def cancel_url(self):
331- return canonical_url(self.context)
332+ return canonical_url(self.context, rootsite="translations")
333
334- @property
335- def next_url(self):
336- return canonical_url(self.context)
337+ next_url = cancel_url
338
339 @property
340 def page_title(self):
341@@ -119,11 +119,9 @@
342
343 @property
344 def cancel_url(self):
345- return canonical_url(self.context)
346+ return canonical_url(self.context, rootsite="translations")
347
348- @property
349- def next_url(self):
350- return self.cancel_url
351+ next_url = cancel_url
352
353 @action('Change', name='change')
354 def edit(self, action, data):
355
356=== modified file 'lib/lp/translations/browser/distroseries.py'
357--- lib/lp/translations/browser/distroseries.py 2010-08-02 02:23:26 +0000
358+++ lib/lp/translations/browser/distroseries.py 2010-08-20 05:52:56 +0000
359@@ -43,11 +43,9 @@
360
361 @property
362 def cancel_url(self):
363- return canonical_url(self.context)
364+ return canonical_url(self.context, rootsite="translations")
365
366- @property
367- def next_url(self):
368- return canonical_url(self.context)
369+ next_url = cancel_url
370
371 @action("Change")
372 def change_action(self, action, data):
373@@ -174,14 +172,15 @@
374 self._request_full_export()
375 self.request.response.addInfoNotification(
376 'Your changes have been applied.')
377- self.next_url = '%s/+language-packs' % canonical_url(self.context)
378+ self.next_url = canonical_url(
379+ self.context, rootsite='translations', view_name='+language-packs')
380
381 @action("Request", condition=is_langpack_admin)
382 def request_action(self, action, data):
383 self.updateContextFromData(data)
384 self._request_full_export()
385- self.next_url = '/'.join(
386- [canonical_url(self.context), '+language-packs'])
387+ self.next_url = canonical_url(
388+ self.context, rootsite='translations', view_name='+language-packs')
389
390
391 class DistroSeriesTemplatesView(BaseSeriesTemplatesView):
392@@ -261,31 +260,33 @@
393 'latest_full_language_pack', 'latest_delta_language_pack', 'imports']
394
395 def translations(self):
396- return Link('', 'Overview')
397+ return Link('', 'Overview', site='translations')
398
399 def imports(self):
400- return Link('+imports', 'Import queue')
401+ return Link('+imports', 'Import queue', site='translations')
402
403 @enabled_with_permission('launchpad.TranslationsAdmin')
404 def admin(self):
405- return Link('+admin', 'Settings')
406+ return Link('+admin', 'Settings', site='translations')
407
408 @enabled_with_permission('launchpad.Edit')
409 def templates(self):
410- return Link('+templates', 'Templates')
411+ return Link('+templates', 'Templates', site='translations')
412
413 def language_packs(self):
414- return Link('+language-packs', 'Language packs')
415+ return Link('+language-packs', 'Language packs', site='translations')
416
417 def latest_full_language_pack(self):
418 return Link(
419 '+latest-full-language-pack',
420- 'Latest full language pack')
421+ 'Latest full language pack',
422+ site='translations')
423
424 def latest_delta_language_pack(self):
425 return Link(
426 '+latest-delta-language-pack',
427- 'Latest delta language pack')
428+ 'Latest delta language pack',
429+ site='translations')
430
431
432 def check_distroseries_translations_viewable(distroseries):
433
434=== modified file 'lib/lp/translations/browser/person.py'
435--- lib/lp/translations/browser/person.py 2009-11-25 16:51:53 +0000
436+++ lib/lp/translations/browser/person.py 2010-08-20 05:52:56 +0000
437@@ -146,22 +146,24 @@
438
439 def overview(self):
440 text = 'Overview'
441- return Link('', text, icon='info')
442+ return Link('', text, icon='info', site='translations')
443
444 def imports(self):
445 text = 'Import queue'
446- return Link('+imports', text, icon='info')
447+ return Link('+imports', text, icon='info', site='translations')
448
449 def licensing(self):
450 text = 'Translations licensing'
451 enabled = (self.person == self.user)
452- return Link('+licensing', text, enabled=enabled, icon='info')
453+ return Link('+licensing', text, enabled=enabled, icon='info',
454+ site='translations')
455
456 def translations_to_review(self):
457 text = 'Translations to review'
458 enabled = person_is_reviewer(self.person)
459 return Link(
460- '+translations-to-review', text, enabled=enabled, icon='info')
461+ '+translations-to-review', text, enabled=enabled, icon='info',
462+ site='translations')
463
464
465 class PersonTranslationView(LaunchpadView):
466@@ -449,19 +451,20 @@
467 @property
468 def relicensing_url(self):
469 """Return an URL for this view."""
470- return canonical_url(self.context, view_name='+licensing')
471+ return canonical_url(self.context, view_name='+licensing',
472+ rootsite='translations')
473
474 @property
475 def cancel_url(self):
476 """Escape to the person's main Translations page."""
477- return canonical_url(self.context)
478+ return canonical_url(self.context, rootsite='translations')
479
480 def getSafeRedirectURL(self, url):
481 """Successful form submission should send to this URL."""
482 if url and url.startswith(self.request.getApplicationURL()):
483 return url
484 else:
485- return canonical_url(self.context)
486+ return canonical_url(self.context, rootsite='translations')
487
488 @action(_("Confirm"), name="submit")
489 def submit_action(self, action, data):
490
491=== modified file 'lib/lp/translations/browser/poexportrequest.py'
492--- lib/lp/translations/browser/poexportrequest.py 2010-02-23 23:26:15 +0000
493+++ lib/lp/translations/browser/poexportrequest.py 2010-08-20 05:52:56 +0000
494@@ -152,7 +152,8 @@
495 self.request.response.addInfoNotification(_(
496 "Your request has been received. Expect to receive an email "
497 "shortly."))
498- self.request.response.redirect(canonical_url(self.context))
499+ self.request.response.redirect(
500+ canonical_url(self.context, rootsite='translations'))
501
502 def formats(self):
503 """Return a list of formats available for translation exports."""
504
505=== modified file 'lib/lp/translations/browser/pofile.py'
506--- lib/lp/translations/browser/pofile.py 2010-08-02 02:13:52 +0000
507+++ lib/lp/translations/browser/pofile.py 2010-08-20 05:52:56 +0000
508@@ -679,7 +679,8 @@
509 url = url + '?' + self.request['QUERY_STRING']
510
511 return self.request.response.redirect(
512- canonical_url(self.user, view_name='+licensing') +
513+ canonical_url(self.user, view_name='+licensing',
514+ rootsite='translations') +
515 '?' + urllib.urlencode({'back_to': url}))
516
517 # The handling of errors is slightly tricky here. Because this
518
519=== modified file 'lib/lp/translations/browser/product.py'
520--- lib/lp/translations/browser/product.py 2010-07-30 06:08:54 +0000
521+++ lib/lp/translations/browser/product.py 2010-08-20 05:52:56 +0000
522@@ -36,12 +36,12 @@
523
524 def imports(self):
525 text = 'Import queue'
526- return Link('+imports', text)
527+ return Link('+imports', text, site='translations')
528
529 @enabled_with_permission('launchpad.TranslationsAdmin')
530 def settings(self):
531 text = 'Change permissions'
532- return Link('+settings', text, icon='edit')
533+ return Link('+settings', text, icon='edit', site='translations')
534
535 @enabled_with_permission('launchpad.AnyPerson')
536 def translationdownload(self):
537@@ -51,7 +51,8 @@
538 preferred_series is not None)
539 link = ''
540 if enabled:
541- link = '%s/+export' % preferred_series.name
542+ link = canonical_url(
543+ preferred_series, rootsite='translations', view_name='+export')
544 text = 'Download "%s"' % preferred_series.name
545
546 return Link(link, text, icon='download', enabled=enabled)
547@@ -73,11 +74,9 @@
548
549 @property
550 def cancel_url(self):
551- return canonical_url(self.context)
552+ return canonical_url(self.context, rootsite="translations")
553
554- @property
555- def next_url(self):
556- return self.cancel_url
557+ next_url = cancel_url
558
559
560 class ProductView(LaunchpadView):
561
562=== modified file 'lib/lp/translations/browser/productseries.py'
563--- lib/lp/translations/browser/productseries.py 2010-07-24 14:52:29 +0000
564+++ lib/lp/translations/browser/productseries.py 2010-08-20 05:52:56 +0000
565@@ -61,35 +61,37 @@
566
567 def overview(self):
568 """Return a link to the overview page."""
569- return Link('', 'Overview')
570+ return Link('', 'Overview', site='translations')
571
572 @enabled_with_permission('launchpad.Edit')
573 def templates(self):
574 """Return a link to series PO templates."""
575- return Link('+templates', 'Templates')
576+ return Link('+templates', 'Templates', site='translations')
577
578 @enabled_with_permission('launchpad.Edit')
579 def settings(self):
580 """Return a link to configure the translations settings."""
581- return Link('+translations-settings', 'Settings')
582+ return Link('+translations-settings', 'Settings', site='translations')
583
584 @enabled_with_permission('launchpad.Edit')
585 def requestbzrimport(self):
586 """Return a link to request a bazaar import."""
587- return Link('+request-bzr-import', 'Request Bazaar import')
588+ return Link(
589+ '+request-bzr-import', 'Request Bazaar import',
590+ site="translations")
591
592 @enabled_with_permission('launchpad.Edit')
593 def translationupload(self):
594 """Return a link to upload translations."""
595- return Link('+translations-upload', 'Upload')
596+ return Link('+translations-upload', 'Upload', site="translations")
597
598 def translationdownload(self):
599 """Return a link to download the translations."""
600- return Link('+export', 'Download')
601+ return Link('+export', 'Download', site="translations")
602
603 def imports(self):
604 """Return a link to the import queue."""
605- return Link('+imports', 'Import queue')
606+ return Link('+imports', 'Import queue', site="translations")
607
608
609 class ProductSeriesTranslationsMenu(NavigationMenu,
610@@ -120,7 +122,7 @@
611
612 @property
613 def cancel_url(self):
614- return canonical_url(self.context)
615+ return canonical_url(self.context, rootsite='translations')
616
617
618 class ProductSeriesTranslationsMixin(TranslationsMixin):
619@@ -142,7 +144,8 @@
620 def request_bzr_import_url(self):
621 """URL to request a bazaar import."""
622 return canonical_url(self.context,
623- view_name="+request-bzr-import")
624+ view_name="+request-bzr-import",
625+ rootsite="translations")
626
627 @property
628 def link_branch_url(self):
629@@ -153,7 +156,7 @@
630 @property
631 def translations_settings_url(self):
632 """URL to change the translations for the series."""
633- return canonical_url(self.context,
634+ return canonical_url(self.context, rootsite="translations",
635 view_name="+translations-settings")
636
637
638@@ -170,7 +173,7 @@
639
640 @property
641 def cancel_url(self):
642- return canonical_url(self.context)
643+ return canonical_url(self.context, rootsite='translations')
644
645 def processForm(self):
646 """Process a form if it was submitted."""
647@@ -244,7 +247,7 @@
648 'administrator in the coming few days. You can track '
649 'your upload\'s status in the '
650 '<a href="%s/+imports">Translation Import Queue</a>' %(
651- canonical_url(self.context))))
652+ canonical_url(self.context, rootsite='translations'))))
653
654 elif is_tar_filename(filename):
655 # Add the whole tarball to the import queue.
656@@ -271,7 +274,7 @@
657 'your upload\'s status in the '
658 '<a href="%s/+imports">Translation Import Queue</a>' %(
659 num, plural_s, plural_s, itthey,
660- canonical_url(self.context))))
661+ canonical_url(self.context, rootsite='translations'))))
662 if len(conflicts) > 0:
663 if len(conflicts) == 1:
664 warning = (
665@@ -427,7 +430,7 @@
666 def __init__(self, context, request):
667 super(ProductSeriesTranslationsSettingsView, self).__init__(
668 context, request)
669- self.cancel_url = canonical_url(self.context)
670+ self.cancel_url = canonical_url(self.context, rootsite='translations')
671
672 @action(u"Save settings", name="save_settings")
673 def change_settings_action(self, action, data):
674@@ -456,12 +459,9 @@
675
676 @property
677 def next_url(self):
678- return canonical_url(self.context)
679+ return canonical_url(self.context, rootsite='translations')
680
681- def __init__(self, context, request):
682- super(ProductSeriesTranslationsBzrImportView, self).__init__(
683- context, request)
684- self.cancel_url = canonical_url(self.context)
685+ cancel_url = next_url
686
687 def validate(self, action):
688 """See `LaunchpadFormView`."""
689@@ -500,12 +500,12 @@
690 page_title = "Export to branch"
691
692 @property
693- def cancel_url(self):
694- return canonical_url(self.context) + '/+translations-settings'
695-
696- @property
697 def next_url(self):
698- return canonical_url(self.context) + '/+translations-settings'
699+ return canonical_url(
700+ self.context, rootsite='translations',
701+ view_name='+translations-settings')
702+
703+ cancel_url = next_url
704
705 @action(_('Update'), name='update')
706 def update_action(self, action, data):
707
708=== modified file 'lib/lp/translations/browser/project.py'
709--- lib/lp/translations/browser/project.py 2010-04-19 08:11:52 +0000
710+++ lib/lp/translations/browser/project.py 2010-08-20 05:52:56 +0000
711@@ -28,11 +28,11 @@
712 @enabled_with_permission('launchpad.TranslationsAdmin')
713 def settings(self):
714 text = 'Change permissions'
715- return Link('+settings', text, icon='edit')
716+ return Link('+settings', text, icon='edit', site='translations')
717
718 def products(self):
719 text = 'Products'
720- return Link('', text)
721+ return Link('', text, site='translations')
722
723 def overview(self):
724 text = 'Overview'
725@@ -59,11 +59,9 @@
726
727 @property
728 def cancel_url(self):
729- return canonical_url(self.context)
730+ return canonical_url(self.context, rootsite="translations")
731
732- @property
733- def next_url(self):
734- return self.cancel_url
735+ next_url = cancel_url
736
737 @action('Change', name='change')
738 def edit(self, action, data):
739
740=== modified file 'lib/lp/translations/browser/sourcepackage.py'
741--- lib/lp/translations/browser/sourcepackage.py 2009-09-17 15:27:58 +0000
742+++ lib/lp/translations/browser/sourcepackage.py 2010-08-20 05:52:56 +0000
743@@ -34,16 +34,17 @@
744
745 def imports(self):
746 text = 'Import queue'
747- return Link('+imports', text)
748+ return Link('+imports', text, site='translations')
749
750 @enabled_with_permission('launchpad.ExpensiveRequest')
751 def download(self):
752 text = 'Download'
753 enabled = bool(self.context.getCurrentTranslationTemplates().any())
754- return Link('+export', text, icon='download', enabled=enabled)
755+ return Link('+export', text, icon='download', enabled=enabled,
756+ site='translations')
757
758 def overview(self):
759- return Link('', 'Overview', icon='info')
760+ return Link('', 'Overview', icon='info', site='translations')
761
762
763 class SourcePackageTranslationsExportView(BaseExportView):
764
765=== modified file 'lib/lp/translations/configure.zcml'
766--- lib/lp/translations/configure.zcml 2010-07-23 09:41:07 +0000
767+++ lib/lp/translations/configure.zcml 2010-08-20 05:52:56 +0000
768@@ -10,12 +10,16 @@
769 xmlns:webservice="http://namespaces.canonical.com/webservice"
770 xmlns:lp="http://namespaces.canonical.com/lp"
771 i18n_domain="launchpad">
772- <include
773- package=".browser"/>
774-
775- <publisher
776- name="translations"
777- factory="lp.translations.publisher.translations_request_publication_factory"/>
778+
779+ <include package=".browser"/>
780+
781+ <publisher
782+ name="translations"
783+ factory="lp.translations.publisher.translations_request_publication_factory"/>
784+ <utility
785+ component="lp.translations.publisher.TranslationsLayer"
786+ provides="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
787+ name="translations" />
788
789 <lp:help-folder
790 folder="help" type="lp.translations.publisher.TranslationsLayer" />
791
792=== modified file 'lib/lp/translations/templates/customlanguagecode-index.pt'
793--- lib/lp/translations/templates/customlanguagecode-index.pt 2009-11-05 14:45:13 +0000
794+++ lib/lp/translations/templates/customlanguagecode-index.pt 2010-08-20 05:52:56 +0000
795@@ -28,13 +28,13 @@
796 <ul class="horizontal">
797 <li tal:condition="context/required:launchpad.Admin">
798 <a class="remove sprite"
799- tal:attributes="href context/fmt:url/+remove">
800+ tal:attributes="href context/fmt:url:translations/+remove">
801 remove custom language code
802 </a>
803 </li>
804 <li>
805 <a class="info sprite"
806- tal:attributes="href context/translation_target/fmt:url/+custom-language-codes">
807+ tal:attributes="href context/translation_target/fmt:url:translations/+custom-language-codes">
808 custom language codes overview
809 </a>
810 </li>
811
812=== modified file 'lib/lp/translations/templates/customlanguagecodes-index.pt'
813--- lib/lp/translations/templates/customlanguagecodes-index.pt 2009-11-05 14:45:13 +0000
814+++ lib/lp/translations/templates/customlanguagecodes-index.pt 2010-08-20 05:52:56 +0000
815@@ -39,7 +39,7 @@
816 <tbody>
817 <tr tal:repeat="entry context/custom_language_codes">
818 <td align="center">
819- <a tal:attributes="href entry/fmt:url"
820+ <a tal:attributes="href entry/fmt:url:translations"
821 tal:content="entry/language_code">pt-PT</a>
822 </td>
823 <td>
824@@ -52,7 +52,7 @@
825 </tal:nolanguage>
826 </td>
827 <td tal:condition="context/required:launchpad.Admin">
828- <a tal:attributes="href entry/fmt:url/+remove"
829+ <a tal:attributes="href entry/fmt:url:translations/+remove"
830 alt="Remove"
831 title="Remove"
832 class="remove sprite"></a>
833@@ -69,7 +69,7 @@
834 </p>
835
836 <div>
837- <a tal:attributes="href context/fmt:url/+add-custom-language-code"
838+ <a tal:attributes="href context/fmt:url:translations/+add-custom-language-code"
839 tal:condition="context/required:launchpad.Admin"
840 class="add sprite">
841 Add a custom language code
842
843=== modified file 'lib/lp/translations/templates/distribution-language-pack-admin-info.pt'
844--- lib/lp/translations/templates/distribution-language-pack-admin-info.pt 2009-12-24 17:46:32 +0000
845+++ lib/lp/translations/templates/distribution-language-pack-admin-info.pt 2010-08-20 05:52:56 +0000
846@@ -13,8 +13,7 @@
847 <tal:admin
848 condition="context/required:launchpad.TranslationsAdmin">
849 <a tal:attributes="
850- href
851- context/fmt:url/+select-language-pack-admin"
852+ href context/fmt:url:translations/+select-language-pack-admin"
853 class="edit sprite"></a>
854 </tal:admin>
855 </p>
856@@ -23,7 +22,7 @@
857 <p tal:condition="not:context/language_pack_admin">
858 <a tal:attributes="
859 href
860- context/fmt:url/+select-language-pack-admin"
861+ context/fmt:url:translations/+select-language-pack-admin"
862 class="edit sprite">Set language pack administrator</a>
863 </p>
864 </tal:admin>
865
866=== modified file 'lib/lp/translations/templates/distribution-translations.pt'
867--- lib/lp/translations/templates/distribution-translations.pt 2009-12-16 15:21:36 +0000
868+++ lib/lp/translations/templates/distribution-translations.pt 2010-08-20 05:52:56 +0000
869@@ -48,7 +48,7 @@
870 <h3>Administration</h3>
871 <p>To see all the translation files that are waiting to be
872 imported, please look at
873- <a tal:attributes="href context/fmt:url/+imports"
874+ <a tal:attributes="href context/fmt:url:translations/+imports"
875 tal:content="string:${context/displayname} import queue">
876 import queue</a>.
877 </p>
878@@ -78,7 +78,7 @@
879
880 <ul id="distroseries-list">
881 <li tal:repeat="distroseries view/secondary_translatable_series">
882- <a tal:attributes="href distroseries/fmt:url"
883+ <a tal:attributes="href distroseries/fmt:url:translations"
884 tal:content="distroseries/named_version">Hoary (5.04)</a>
885 </li>
886 </ul>
887
888=== modified file 'lib/lp/translations/templates/distroseries-language-packs.pt'
889--- lib/lp/translations/templates/distroseries-language-packs.pt 2010-04-21 22:28:02 +0000
890+++ lib/lp/translations/templates/distroseries-language-packs.pt 2010-08-20 05:52:56 +0000
891@@ -25,7 +25,7 @@
892 Peter Langomat
893 </tal:admin><a
894 tal:condition="context/distribution/required:launchpad.Edit"
895- tal:attributes="href string:${context/distribution/fmt:url}/+select-language-pack-admin"
896+ tal:attributes="href context/distribution/fmt:url:translations/+select-language-pack-admin"
897 title="Change language pack administrator"><img
898 class="edit sprite"/></a>.
899 </p>
900
901=== modified file 'lib/lp/translations/templates/distroseries-translations.pt'
902--- lib/lp/translations/templates/distroseries-translations.pt 2010-04-21 20:52:57 +0000
903+++ lib/lp/translations/templates/distroseries-translations.pt 2010-08-20 05:52:56 +0000
904@@ -55,7 +55,7 @@
905 <h3>Administration</h3>
906 <p>Translation files that are waiting to be imported are shown in
907 the
908- <a tal:attributes="href context/fmt:url/+imports"
909+ <a tal:attributes="href context/fmt:url:translations/+imports"
910 tal:content="string:${context/displayname} import queue">
911 import queue</a>.
912 </p>
913
914=== modified file 'lib/lp/translations/templates/languageset-index.pt'
915--- lib/lp/translations/templates/languageset-index.pt 2009-12-08 10:20:37 +0000
916+++ lib/lp/translations/templates/languageset-index.pt 2010-08-20 05:52:56 +0000
917@@ -41,7 +41,7 @@
918 <dl id="preferred_languages"
919 tal:condition="view/user">
920 <dt>Your preferred languages:
921- <a tal:attributes="href string:${view/user/fmt:url}/+editlanguages"
922+ <a tal:attributes="href view/user/fmt:url:translations/+editlanguages"
923 class="edit sprite"></a>
924 </dt>
925 <dd tal:content="structure view/user_languages">
926
927=== modified file 'lib/lp/translations/templates/product-portlet-translatables.pt'
928--- lib/lp/translations/templates/product-portlet-translatables.pt 2009-11-17 10:17:34 +0000
929+++ lib/lp/translations/templates/product-portlet-translatables.pt 2010-08-20 05:52:56 +0000
930@@ -13,7 +13,7 @@
931 <li class="translations"
932 tal:repeat="series context/translatable_series">
933 <a tal:content="series/title"
934- tal:attributes="href string:${series/fmt:url}/+translations">
935+ tal:attributes="href series/fmt:url:translations/+translations">
936 series title</a>
937 </li>
938 </ul>
939@@ -30,13 +30,13 @@
940 <li class="translations"
941 tal:repeat="series view/untranslatable_series">
942 <a tal:content="series/title"
943- tal:attributes="href string:${series/fmt:url}/+translations">
944+ tal:attributes="href series/fmt:url:translations/+translations">
945 series title</a> —
946 <a tal:attributes="
947- href string:${series/fmt:url}/+translations-upload">
948+ href series/fmt:url:translations/+translations-upload">
949 manual</a> or
950 <a tal:attributes="
951- href string:${series/fmt:url}/+translations-settings">
952+ href series/fmt:url:translations/+translations-settings">
953 automatic import</a>.
954 </li>
955 </ul>
956@@ -68,7 +68,7 @@
957 tal:condition="context/required:launchpad.Admin"
958 id="custom-language-codes">
959 If necessary, you may
960- <a tal:attributes="href context/fmt:url/+custom-language-codes"
961+ <a tal:attributes="href context/fmt:url:translations/+custom-language-codes"
962 class="edit sprite">
963 define custom language codes
964 </a>
965
966=== modified file 'lib/lp/translations/templates/product-translations.pt'
967--- lib/lp/translations/templates/product-translations.pt 2010-01-15 14:44:39 +0000
968+++ lib/lp/translations/templates/product-translations.pt 2010-08-20 05:52:56 +0000
969@@ -44,12 +44,12 @@
970 >trunk</tal:target>.
971 <span tal:condition="context/required:launchpad.AnyPerson">
972 You can also
973- <a tal:attributes="href target/fmt:url/+export"
974+ <a tal:attributes="href target/fmt:url:translations/+export"
975 >download</a>
976 <tal:owner-or-admin condition="admin_user">
977 or
978 <a tal:attributes="
979- href target/fmt:url/+translations-upload"
980+ href target/fmt:url:translations/+translations-upload"
981 >upload</a>
982 </tal:owner-or-admin>
983 translations for
984@@ -59,7 +59,7 @@
985 </p>
986 <p>To see all the translation files that are waiting to be
987 imported, please look at
988- <a tal:attributes="href context/fmt:url/+imports"
989+ <a tal:attributes="href context/fmt:url:translations/+imports"
990 tal:content="string:${context/displayname} import queue">
991 import queue</a>.
992 </p>
993
994=== modified file 'lib/lp/translations/templates/productseries-translations-upload.pt'
995--- lib/lp/translations/templates/productseries-translations-upload.pt 2010-01-12 13:48:24 +0000
996+++ lib/lp/translations/templates/productseries-translations-upload.pt 2010-08-20 05:52:56 +0000
997@@ -24,7 +24,7 @@
998
999 <p>
1000 <strong>Note:</strong> it's quicker and easier to <a tal:attributes="
1001- href string:${context/fmt:url}/+translations-settings">import from a
1002+ href context/fmt:url:translations/+translations-settings">import from a
1003 Bazaar branch</a> instead (<a href="/+help/importing-from-bzr.html"
1004 target="help">More about importing from Bazaar</a>)
1005 </p>
1006
1007=== modified file 'lib/lp/translations/templates/rosetta-index.pt'
1008--- lib/lp/translations/templates/rosetta-index.pt 2009-11-07 07:46:54 +0000
1009+++ lib/lp/translations/templates/rosetta-index.pt 2010-08-20 05:52:56 +0000
1010@@ -55,7 +55,7 @@
1011 tal:attributes="style string:font-size:${product/font_size}%;">
1012 <a
1013 tal:attributes="
1014- href string:${product/pillar/fmt:url}/+translations"
1015+ href product/pillar/fmt:url:translations/+translations"
1016 tal:content="product/pillar/displayname" />
1017 </span>
1018 <div>
1019
1020=== modified file 'lib/lp/translations/templates/sourcepackage-translations.pt'
1021--- lib/lp/translations/templates/sourcepackage-translations.pt 2009-11-17 10:17:34 +0000
1022+++ lib/lp/translations/templates/sourcepackage-translations.pt 2010-08-20 05:52:56 +0000
1023@@ -42,7 +42,7 @@
1024 <p tal:condition="context/required:launchpad.Admin"
1025 id="custom-language-codes">
1026 If necessary, you may
1027- <a tal:attributes="href context/distribution_sourcepackage/fmt:url/+custom-language-codes"
1028+ <a tal:attributes="href context/distribution_sourcepackage/fmt:url:translations/+custom-language-codes"
1029 class="edit sprite">
1030 define custom language codes
1031 </a>
1032
1033=== modified file 'lib/lp/translations/tests/test_pofile.py'
1034--- lib/lp/translations/tests/test_pofile.py 2010-08-06 06:51:37 +0000
1035+++ lib/lp/translations/tests/test_pofile.py 2010-08-20 05:52:56 +0000
1036@@ -34,7 +34,7 @@
1037 # Create a product with two series and a shared POTemplate
1038 # in different series ('devel' and 'stable').
1039 super(TestTranslationSharedPOFile, self).setUp()
1040- self.foo = self.factory.makeProduct()
1041+ self.foo = self.factory.makeProduct(name='foo')
1042 self.foo_devel = self.factory.makeProductSeries(
1043 name='devel', product=self.foo)
1044 self.foo_stable = self.factory.makeProductSeries(
1045@@ -58,6 +58,15 @@
1046 self.potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)
1047 self.potmsgset.setSequence(self.devel_potemplate, 1)
1048
1049+ def test_POFile_canonical_url(self):
1050+ # Test the canonical_url of the POFile.
1051+ self.assertEqual(
1052+ 'http://translations.launchpad.dev/foo/devel/+pots/messages/sr',
1053+ canonical_url(self.devel_sr_pofile))
1054+ self.assertEqual(
1055+ 'http://translations.launchpad.dev/foo/devel/+pots/messages/sr/+details',
1056+ canonical_url(self.devel_sr_pofile, view_name="+details"))
1057+
1058 def test_findPOTMsgSetsContaining(self):
1059 # Test that search works correctly.
1060
1061
1062=== modified file 'lib/lp/vostok/configure.zcml'
1063--- lib/lp/vostok/configure.zcml 2010-08-06 18:13:00 +0000
1064+++ lib/lp/vostok/configure.zcml 2010-08-20 05:52:56 +0000
1065@@ -8,10 +8,14 @@
1066 <include package=".browser" />
1067
1068 <publisher
1069- name="vostok"
1070- factory="lp.vostok.publisher.vostok_request_publication_factory"
1071- methods="*"
1072- mimetypes="*" />
1073+ name="vostok"
1074+ factory="lp.vostok.publisher.vostok_request_publication_factory"
1075+ methods="*"
1076+ mimetypes="*" />
1077+ <utility
1078+ component="lp.vostok.publisher.VostokLayer"
1079+ provides="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
1080+ name="vostok" />
1081
1082 <securedutility
1083 class="lp.vostok.publisher.VostokRoot"