12293.1.11
by Curtis Hovey
Updated copyright. |
1 |
# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
|
8687.15.18
by Karl Fogel
Add the copyright header block to files under lib/canonical/. |
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
3 |
||
1936
by Canonical.com Patch Queue Manager
Fix various bugs to do with login links, and use a view with page template fragment and a view class to do the algorithmic stuff. r=spiv. |
4 |
"""Browser code for the launchpad application."""
|
5 |
||
6 |
__metaclass__ = type |
|
1716.1.190
by Christian Reis
Merge from RF, again, this time for real |
7 |
__all__ = [ |
3842.2.9
by jml at canonical
Add AppFrontPageSearchView to __all__ so browser/specification.py can import it. |
8 |
'AppFrontPageSearchView', |
7675.117.1
by Francis J. Lacoste
+login is now a 404 on the SSO and Unauthorized are really 500 |
9 |
'DoesNotExistView', |
6476.13.1
by Matthew Paul Thomas
more changes |
10 |
'Hierarchy', |
6574.1.2
by Francis J. Lacoste
Moved ShipIt resources to their icing folder. |
11 |
'IcingFolder', |
14382.1.5
by Aaron Bentley
view_name is included in BugTaskSearchListingView RequestCache. |
12 |
'iter_view_registrations', |
9322.10.16
by Guilherme Salgado
Re-add a line I accidentally removed |
13 |
'LaunchpadImageFolder', |
9474.2.1
by Gary Poster
convert three templates to 3.0; also correct some oddities in table layout in +graphics |
14 |
'LaunchpadGraphics', |
6574.1.2
by Francis J. Lacoste
Moved ShipIt resources to their icing folder. |
15 |
'LaunchpadRootNavigation', |
5530.1.21
by Carlos Perello Marin
Applied again my changes to allow a way to test disabled links |
16 |
'LinkView', |
1716.1.190
by Christian Reis
Merge from RF, again, this time for real |
17 |
'LoginStatus', |
13678.1.2
by Benji York
checkpoint |
18 |
'Macro', |
1716.1.190
by Christian Reis
Merge from RF, again, this time for real |
19 |
'MaintenanceMessage', |
5863.17.18
by Carlos Perello Marin
Applied review comments |
20 |
'NavigationMenuTabs', |
3489.1.1
by Bjorn Tillenius
add test for soft timeouts and make sure they do get logged. |
21 |
'SoftTimeoutView', |
14382.1.8
by Aaron Bentley
Cleanup |
22 |
'get_launchpad_views', |
1716.1.190
by Christian Reis
Merge from RF, again, this time for real |
23 |
]
|
1936
by Canonical.com Patch Queue Manager
Fix various bugs to do with login links, and use a view with page template fragment and a view class to do the algorithmic stuff. r=spiv. |
24 |
|
6061.2.20
by Curtis Hovey
Resolved merge conflicts. Added an XXX and condition to getTopLevelPublications. |
25 |
|
2389
by Canonical.com Patch Queue Manager
[r=sabdfl] improvements to logout pages |
26 |
import cgi |
14550.1.1
by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad |
27 |
from datetime import timedelta |
5472.2.13
by Carlos Perello Marin
Sorted menu entries by ILink.text |
28 |
import operator |
3731
by Steve Alexander
merge from mpt resolving conflicts |
29 |
import os |
8296.2.1
by Brad Crittenden
Optimize redirection for lp.net/bugs/xxx URLs. |
30 |
import re |
3489.1.2
by Bjorn Tillenius
review commments. |
31 |
import time |
8296.2.1
by Brad Crittenden
Optimize redirection for lp.net/bugs/xxx URLs. |
32 |
import urllib |
2389
by Canonical.com Patch Queue Manager
[r=sabdfl] improvements to logout pages |
33 |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
34 |
from lazr.uri import URI |
9550.4.1
by Guilherme Salgado
Fix it |
35 |
from zope import i18n |
9271.6.2
by Guilherme Salgado
Do not append a page breadcrumb when we're looking at an object's default page, plus a couple fixes. |
36 |
from zope.app import zapi |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
37 |
from zope.component import ( |
14382.1.5
by Aaron Bentley
view_name is included in BugTaskSearchListingView RequestCache. |
38 |
getGlobalSiteManager, |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
39 |
getUtility, |
40 |
queryAdapter, |
|
41 |
)
|
|
42 |
from zope.datetime import ( |
|
43 |
DateTimeError, |
|
44 |
parseDatetimetz, |
|
45 |
)
|
|
46 |
from zope.i18nmessageid import Message |
|
3722
by Steve Alexander
merge from main ui branch, resolving conflict |
47 |
from zope.interface import implements |
6753.5.1
by Diogo Matsubara
merge the twozero tour again |
48 |
from zope.publisher.interfaces import NotFound |
7675.117.1
by Francis J. Lacoste
+login is now a 404 on the SSO and Unauthorized are really 500 |
49 |
from zope.publisher.interfaces.browser import IBrowserPublisher |
3691.267.37
by Stuart Bishop
Bazaar needs old XML-RPC URL to remain functional |
50 |
from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest |
3489.1.1
by Bjorn Tillenius
add test for soft timeouts and make sure they do get logged. |
51 |
from zope.security.interfaces import Unauthorized |
13678.1.2
by Benji York
checkpoint |
52 |
from zope.traversing.interfaces import ITraversable |
1716.1.192
by Christian Reis
Fix missing import. Man.. |
53 |
|
3489.1.1
by Bjorn Tillenius
add test for soft timeouts and make sure they do get logged. |
54 |
from canonical.config import config |
55 |
from canonical.launchpad.helpers import intOrZero |
|
7675.560.2
by Graham Binns
More api work. Still doesn't work. |
56 |
from canonical.launchpad.interfaces.launchpad import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
57 |
IAppFrontPageSearchForm, |
58 |
IBazaarApplication, |
|
59 |
IRosettaApplication, |
|
60 |
)
|
|
14557.1.5
by Curtis Hovey
Simplified names. |
61 |
from lp.services.statistics.interfaces.statistic import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
62 |
ILaunchpadStatisticSet, |
63 |
)
|
|
14557.1.9
by Curtis Hovey
Moved logintoken to lp.verification. |
64 |
from lp.services.verification.interfaces.logintoken import ILoginTokenSet |
14557.1.12
by Curtis Hovey
Moved temporaryblobstorage to lp.services. |
65 |
from lp.services.temporaryblobstorage.interfaces import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
66 |
ITemporaryStorageManager, |
67 |
)
|
|
68 |
from canonical.launchpad.layers import WebServiceLayer |
|
7675.560.7
by Graham Binns
Tidied up imports in canonical.launchpad.browswer.launchpad. |
69 |
from canonical.launchpad.webapp import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
70 |
canonical_name, |
71 |
canonical_url, |
|
72 |
LaunchpadView, |
|
73 |
Link, |
|
74 |
Navigation, |
|
75 |
StandardLaunchpadFacets, |
|
76 |
stepto, |
|
77 |
)
|
|
78 |
from canonical.launchpad.webapp.authorization import check_permission |
|
7675.560.7
by Graham Binns
Tidied up imports in canonical.launchpad.browswer.launchpad. |
79 |
from canonical.launchpad.webapp.breadcrumb import Breadcrumb |
80 |
from canonical.launchpad.webapp.interfaces import ( |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
81 |
IBreadcrumb, |
82 |
ILaunchBag, |
|
83 |
ILaunchpadRoot, |
|
84 |
INavigationMenu, |
|
85 |
)
|
|
7675.560.7
by Graham Binns
Tidied up imports in canonical.launchpad.browswer.launchpad. |
86 |
from canonical.launchpad.webapp.publisher import RedirectionView |
11848.2.10
by Edwin Grubbs
Formatted imports. |
87 |
from canonical.launchpad.webapp.url import urlappend |
88 |
from canonical.launchpad.webapp.vhosts import allvhosts |
|
89 |
from canonical.lazr import ( |
|
90 |
ExportedFolder, |
|
91 |
ExportedImageFolder, |
|
92 |
)
|
|
93 |
from lp.answers.interfaces.questioncollection import IQuestionSet |
|
11929.9.1
by Tim Penhey
Move launchpadform into lp.app.browser. |
94 |
from lp.app.browser.launchpadform import ( |
95 |
custom_widget, |
|
96 |
LaunchpadFormView, |
|
97 |
)
|
|
11626.3.2
by Curtis Hovey
Move tales gto lp.app. |
98 |
from lp.app.browser.tales import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
99 |
DurationFormatterAPI, |
100 |
MenuAPI, |
|
101 |
)
|
|
102 |
from lp.app.errors import ( |
|
103 |
GoneError, |
|
104 |
NotFoundError, |
|
105 |
POSTToNonCanonicalURL, |
|
106 |
)
|
|
9511.2.7
by Michael Nelson
Fixed bug 433852 |
107 |
from lp.app.interfaces.headings import IMajorHeadingView |
13130.1.13
by Curtis Hovey
Fixed import errors. |
108 |
from lp.app.interfaces.launchpad import ILaunchpadCelebrities |
12293.1.10
by Curtis Hovey
Formatted imports. |
109 |
from lp.app.widgets.project import ProjectScopeWidget |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
110 |
from lp.blueprints.interfaces.specification import ISpecificationSet |
111 |
from lp.blueprints.interfaces.sprint import ISprintSet |
|
7675.560.7
by Graham Binns
Tidied up imports in canonical.launchpad.browswer.launchpad. |
112 |
from lp.bugs.interfaces.bug import IBugSet |
113 |
from lp.bugs.interfaces.malone import IMaloneApplication |
|
114 |
from lp.buildmaster.interfaces.builder import IBuilderSet |
|
11270.2.11
by Tim Penhey
Move InvalidNamespace from lp.code.interfaces.branchnamespace to lp.code.errors |
115 |
from lp.code.errors import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
116 |
CannotHaveLinkedBranch, |
117 |
InvalidNamespace, |
|
118 |
NoLinkedBranch, |
|
119 |
)
|
|
8777.4.7
by Jonathan Lange
Update the other old uses of IBranches. |
120 |
from lp.code.interfaces.branch import IBranchSet |
11515.5.10
by Ian Booth
Lint fixes |
121 |
from lp.code.interfaces.branchlookup import IBranchLookup |
7675.560.7
by Graham Binns
Tidied up imports in canonical.launchpad.browswer.launchpad. |
122 |
from lp.code.interfaces.codeimport import ICodeImportSet |
123 |
from lp.hardwaredb.interfaces.hwdb import IHWDBApplication |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
124 |
from lp.registry.interfaces.announcement import IAnnouncementSet |
7675.110.3
by Curtis Hovey
Ran the migration script to move registry code to lp.registry. |
125 |
from lp.registry.interfaces.codeofconduct import ICodeOfConductSet |
126 |
from lp.registry.interfaces.distribution import IDistributionSet |
|
127 |
from lp.registry.interfaces.karma import IKarmaActionSet |
|
11848.2.4
by Edwin Grubbs
Added browser classes and permissions. |
128 |
from lp.registry.interfaces.nameblacklist import INameBlacklistSet |
7675.110.3
by Curtis Hovey
Ran the migration script to move registry code to lp.registry. |
129 |
from lp.registry.interfaces.person import IPersonSet |
130 |
from lp.registry.interfaces.pillar import IPillarNameSet |
|
131 |
from lp.registry.interfaces.product import ( |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
132 |
InvalidProductName, |
133 |
IProductSet, |
|
134 |
)
|
|
10326.1.2
by Henning Eggers
Renamed project interfaces module to projectgroup. |
135 |
from lp.registry.interfaces.projectgroup import IProjectGroupSet |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
136 |
from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet |
14550.1.1
by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad |
137 |
from lp.services.identity.interfaces.account import AccountStatus |
11382.6.34
by Gavin Panella
Reformat imports in all files touched so far. |
138 |
from lp.services.propertycache import cachedproperty |
13333.5.3
by Jonathan Lange
Use the new utc_now() |
139 |
from lp.services.utils import utc_now |
10348.3.1
by Jonathan Davies
Put in place the foundations for exporting Country's over the API. |
140 |
from lp.services.worlddata.interfaces.country import ICountrySet |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
141 |
from lp.services.worlddata.interfaces.language import ILanguageSet |
142 |
from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet |
|
143 |
from lp.soyuz.interfaces.packageset import IPackagesetSet |
|
13387.1.10
by Francis J. Lacoste
URL to processor is now of the form /+processors/<name> |
144 |
from lp.soyuz.interfaces.processor import ( |
145 |
IProcessorFamilySet, |
|
146 |
IProcessorSet, |
|
147 |
)
|
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
148 |
from lp.testopenid.interfaces.server import ITestOpenIDApplication |
149 |
from lp.translations.interfaces.translationgroup import ITranslationGroupSet |
|
8751.1.1
by Danilo Å egan
Store migration changes so far. |
150 |
from lp.translations.interfaces.translationimportqueue import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
151 |
ITranslationImportQueue, |
152 |
)
|
|
7944.3.3
by Francis J. Lacoste
Moved interfaces. |
153 |
|
2519
by Canonical.com Patch Queue Manager
r=BjornT, more actions portlets converted to menus, introduction of LaunchpadView. |
154 |
|
5863.17.9
by Carlos Perello Marin
Applied most changes discussed with Francis |
155 |
class NavigationMenuTabs(LaunchpadView): |
156 |
"""View class that helps its template render the navigation menu tabs.
|
|
157 |
||
5863.17.18
by Carlos Perello Marin
Applied review comments |
158 |
Nothing at all is rendered if there are no navigation menu items.
|
5863.17.9
by Carlos Perello Marin
Applied most changes discussed with Francis |
159 |
"""
|
160 |
||
161 |
def initialize(self): |
|
6574.3.1
by Curtis Hovey
Updated NavigationMenuTabs.initialize to MenuAPI. |
162 |
menuapi = MenuAPI(self.context) |
5863.17.11
by Carlos Perello Marin
Reverted the changes to menubox so we don't include Navigation links there, we need to duplicate that information until the migration is complete |
163 |
self.links = sorted([ |
9061.2.15
by Edwin Grubbs
Circumvent confusing AttributeErrors. |
164 |
link for link in menuapi.navigation.values() |
6574.3.1
by Curtis Hovey
Updated NavigationMenuTabs.initialize to MenuAPI. |
165 |
if (link.enabled or config.devmode)], |
5863.17.11
by Carlos Perello Marin
Reverted the changes to menubox so we don't include Navigation links there, we need to duplicate that information until the migration is complete |
166 |
key=operator.attrgetter('sort_key')) |
6574.3.1
by Curtis Hovey
Updated NavigationMenuTabs.initialize to MenuAPI. |
167 |
self.title = None |
168 |
if len(self.links) > 0: |
|
169 |
facet = menuapi.selectedfacetname() |
|
170 |
menu = queryAdapter(self.context, INavigationMenu, name=facet) |
|
171 |
if menu is not None: |
|
172 |
self.title = menu.title |
|
7675.295.8
by Curtis Hovey
Revised the layout to hide holes created by optional content. |
173 |
self.enabled_links = [link for link in self.links if link.enabled] |
5863.17.9
by Carlos Perello Marin
Applied most changes discussed with Francis |
174 |
|
175 |
def render(self): |
|
176 |
if not self.links: |
|
2519
by Canonical.com Patch Queue Manager
r=BjornT, more actions portlets converted to menus, introduction of LaunchpadView. |
177 |
return '' |
178 |
else: |
|
179 |
return self.template() |
|
2494
by Canonical.com Patch Queue Manager
r=stub add 'launchpad (or shipit) is going down for maintenance' facility. |
180 |
|
181 |
||
5530.1.21
by Carlos Perello Marin
Applied again my changes to allow a way to test disabled links |
182 |
class LinkView(LaunchpadView): |
183 |
"""View class that helps its template render a menu link.
|
|
184 |
||
185 |
The link is not rendered if it's not enabled and we are not in development
|
|
186 |
mode.
|
|
187 |
"""
|
|
7675.285.9
by Curtis Hovey
Revised the fmt:link rule to use 'sprite modify' when rendering links for the mofidy icons. |
188 |
MODIFY_ICONS = ('edit', 'remove', 'trash-icon') |
8868.1.1
by Curtis Hovey
Simplify the fmt:link options and ensure edit, remove and trash icons are after link text. |
189 |
|
190 |
@property
|
|
191 |
def sprite_class(self): |
|
192 |
"""Return the class used to display the link's icon."""
|
|
7675.285.9
by Curtis Hovey
Revised the fmt:link rule to use 'sprite modify' when rendering links for the mofidy icons. |
193 |
if self.context.icon in self.MODIFY_ICONS: |
194 |
# The 3.0 UI design says these are displayed like other icons
|
|
195 |
# But they do not have the same use so we want to keep this rule
|
|
196 |
# separate.
|
|
197 |
return 'sprite modify' |
|
8868.1.1
by Curtis Hovey
Simplify the fmt:link options and ensure edit, remove and trash icons are after link text. |
198 |
else: |
199 |
return 'sprite' |
|
5530.1.21
by Carlos Perello Marin
Applied again my changes to allow a way to test disabled links |
200 |
|
201 |
def render(self): |
|
202 |
"""Render the menu link if it's enabled or we're in dev mode."""
|
|
203 |
if self.context.enabled or config.devmode: |
|
6912.5.19
by Curtis Hovey
Revised XXX comment metadata to remove anonmalies from the XXX report. |
204 |
# XXX: Tom Berger 2008-04-16 bug=218706:
|
6087.4.2
by Tom Berger
remove the actions menu from the bug target bugs index page |
205 |
# We strip the result of the template rendering
|
6087.4.4
by Tom Berger
typo |
206 |
# since ZPT seems to always insert a line break
|
6087.4.2
by Tom Berger
remove the actions menu from the bug target bugs index page |
207 |
# at the end of an embedded template.
|
208 |
return self.template().strip() |
|
5530.1.21
by Carlos Perello Marin
Applied again my changes to allow a way to test disabled links |
209 |
else: |
210 |
return '' |
|
211 |
||
12611.2.5
by Brad Crittenden
Simplified the launchpad-inline page template by moving logic into the view. Removed unnecessary styling. |
212 |
@property
|
213 |
def css_class(self): |
|
214 |
"""Return the CSS class."""
|
|
215 |
value = ["menu-link-%s" % self.context.name] |
|
12611.2.7
by Brad Crittenden
Fixed failing tests |
216 |
if not self.context.linked: |
217 |
value.append('nolink') |
|
12611.2.5
by Brad Crittenden
Simplified the launchpad-inline page template by moving logic into the view. Removed unnecessary styling. |
218 |
if self.context.icon: |
219 |
value.append(self.sprite_class) |
|
220 |
value.append(self.context.icon) |
|
221 |
if self.context.hidden: |
|
222 |
value.append('invisible-link') |
|
223 |
return " ".join(value) |
|
224 |
||
225 |
@property
|
|
226 |
def url(self): |
|
227 |
"""Return the url if linked."""
|
|
228 |
if self.context.linked: |
|
229 |
return self.context.url |
|
230 |
return '' |
|
231 |
||
232 |
@property
|
|
233 |
def summary(self): |
|
234 |
"""Return the summary if linked."""
|
|
235 |
if self.context.linked: |
|
236 |
return self.context.summary |
|
237 |
return '' |
|
238 |
||
5530.1.21
by Carlos Perello Marin
Applied again my changes to allow a way to test disabled links |
239 |
|
6476.13.1
by Matthew Paul Thomas
more changes |
240 |
class Hierarchy(LaunchpadView): |
241 |
"""The hierarchy part of the location bar on each page."""
|
|
242 |
||
7675.618.54
by Paul Hummer
Patched Hierarchy to optionally leave off the vhost request |
243 |
vhost_breadcrumb = True |
244 |
||
9087.4.3
by Guilherme Salgado
Finally, something that works with all examples |
245 |
@property
|
246 |
def objects(self): |
|
247 |
"""The objects for which we want breadcrumbs."""
|
|
9322.10.15
by Guilherme Salgado
Fix a bunch of things |
248 |
return self.request.traversed_objects |
9087.4.3
by Guilherme Salgado
Finally, something that works with all examples |
249 |
|
9225.1.3
by Michael Nelson
New styled breadcrumbs. |
250 |
@cachedproperty
|
6767.5.8
by Maris Fogels
Added the Hierarchy.items() method. |
251 |
def items(self): |
6767.5.40
by Maris Fogels
Rework based on reviewer feedback. |
252 |
"""Return a list of `IBreadcrumb` objects visible in the hierarchy.
|
6767.5.8
by Maris Fogels
Added the Hierarchy.items() method. |
253 |
|
254 |
The list starts with the breadcrumb closest to the hierarchy root.
|
|
255 |
"""
|
|
9087.4.9
by Guilherme Salgado
Fix a couple existing tests and tweak my implementation to not break others |
256 |
breadcrumbs = [] |
9087.4.3
by Guilherme Salgado
Finally, something that works with all examples |
257 |
for obj in self.objects: |
7675.618.60
by Paul Hummer
Fixed some more breadcrumbs assery and now it's NIIIICE</borat> |
258 |
breadcrumb = IBreadcrumb(obj, None) |
9209.4.1
by Guilherme Salgado
Get rid of BreadcrumbBuilder as it's not necessary anymore |
259 |
if breadcrumb is not None: |
260 |
breadcrumbs.append(breadcrumb) |
|
9087.4.3
by Guilherme Salgado
Finally, something that works with all examples |
261 |
|
262 |
host = URI(self.request.getURL()).host |
|
9271.6.1
by Guilherme Salgado
Breadcrumbs for leaf pages |
263 |
mainhost = allvhosts.configs['mainsite'].hostname |
7675.618.54
by Paul Hummer
Patched Hierarchy to optionally leave off the vhost request |
264 |
if (len(breadcrumbs) != 0 and |
265 |
host != mainhost and |
|
266 |
self.vhost_breadcrumb): |
|
9271.6.1
by Guilherme Salgado
Breadcrumbs for leaf pages |
267 |
# We have breadcrumbs and we're not on the mainsite, so we'll
|
268 |
# sneak an extra breadcrumb for the vhost we're on.
|
|
269 |
vhost = host.split('.')[0] |
|
270 |
||
271 |
# Iterate over the context of our breadcrumbs in reverse order and
|
|
272 |
# for the first one we find an adapter named after the vhost we're
|
|
273 |
# on, generate an extra breadcrumb and insert it in our list.
|
|
274 |
for idx, breadcrumb in reversed(list(enumerate(breadcrumbs))): |
|
275 |
extra_breadcrumb = queryAdapter( |
|
276 |
breadcrumb.context, IBreadcrumb, name=vhost) |
|
277 |
if extra_breadcrumb is not None: |
|
278 |
breadcrumbs.insert(idx + 1, extra_breadcrumb) |
|
279 |
break
|
|
9469.1.1
by Barry Warsaw
Redesign ~person/+editemails for UI 3.0. Along the way, fix bug 180349 by linking the team name to the canonical url for the team. |
280 |
if len(breadcrumbs) > 0: |
9271.6.3
by Guilherme Salgado
Better names |
281 |
page_crumb = self.makeBreadcrumbForRequestedPage() |
9271.6.2
by Guilherme Salgado
Do not append a page breadcrumb when we're looking at an object's default page, plus a couple fixes. |
282 |
if page_crumb: |
283 |
breadcrumbs.append(page_crumb) |
|
9209.4.1
by Guilherme Salgado
Get rid of BreadcrumbBuilder as it's not necessary anymore |
284 |
return breadcrumbs |
6767.5.21
by Maris Fogels
Changed the hierarchy interface a bit, so that breadcrumb construction is handed off to the class. This ensures consistency in presentation. |
285 |
|
9511.2.7
by Michael Nelson
Fixed bug 433852 |
286 |
@property
|
9511.2.10
by Michael Nelson
Small style changes from barry. |
287 |
def _naked_context_view(self): |
9511.2.7
by Michael Nelson
Fixed bug 433852 |
288 |
"""Return the unproxied view for the context of the hierarchy."""
|
289 |
from zope.security.proxy import removeSecurityProxy |
|
9511.2.11
by Michael Nelson
Fix for test failures during ec2test run. Ensure traversed objects is not empty before trying to get the last traversed object. |
290 |
if len(self.request.traversed_objects) > 0: |
291 |
return removeSecurityProxy(self.request.traversed_objects[-1]) |
|
292 |
else: |
|
293 |
return None |
|
9511.2.7
by Michael Nelson
Fixed bug 433852 |
294 |
|
9271.6.3
by Guilherme Salgado
Better names |
295 |
def makeBreadcrumbForRequestedPage(self): |
9271.6.2
by Guilherme Salgado
Do not append a page breadcrumb when we're looking at an object's default page, plus a couple fixes. |
296 |
"""Return an `IBreadcrumb` for the requested page.
|
297 |
||
9271.6.3
by Guilherme Salgado
Better names |
298 |
The `IBreadcrumb` for the requested page is created using the current
|
299 |
URL and the page's name (i.e. the last path segment of the URL).
|
|
300 |
||
9271.6.2
by Guilherme Salgado
Do not append a page breadcrumb when we're looking at an object's default page, plus a couple fixes. |
301 |
If the requested page (as specified in self.request) is the default
|
9322.10.11
by Guilherme Salgado
Do not rely on Navigation for having objects added to request.traversed_objects. |
302 |
one for our parent view's context, return None.
|
9271.6.2
by Guilherme Salgado
Do not append a page breadcrumb when we're looking at an object's default page, plus a couple fixes. |
303 |
"""
|
9271.6.1
by Guilherme Salgado
Breadcrumbs for leaf pages |
304 |
url = self.request.getURL() |
9322.10.15
by Guilherme Salgado
Fix a bunch of things |
305 |
obj = self.request.traversed_objects[-2] |
9322.10.1
by Guilherme Salgado
First attempt at using page titles for breadcrumbs. Get the page using getMultiAdapter() and check for a page_title attribute, falling back to getting the title from pagetitles.py |
306 |
default_view_name = zapi.getDefaultViewName(obj, self.request) |
9511.2.10
by Michael Nelson
Small style changes from barry. |
307 |
view = self._naked_context_view |
9322.10.15
by Guilherme Salgado
Fix a bunch of things |
308 |
if view.__name__ != default_view_name: |
9322.10.1
by Guilherme Salgado
First attempt at using page titles for breadcrumbs. Get the page using getMultiAdapter() and check for a page_title attribute, falling back to getting the title from pagetitles.py |
309 |
title = getattr(view, 'page_title', None) |
310 |
if title is None: |
|
9322.10.22
by Guilherme Salgado
Fix a bunch of tests and change makeBreadcrumbForRequestedPage() to use view.label before trying to look up a title in pagetitles.py |
311 |
title = getattr(view, 'label', None) |
9550.4.1
by Guilherme Salgado
Fix it |
312 |
if isinstance(title, Message): |
313 |
title = i18n.translate(title, context=self.request) |
|
9271.6.1
by Guilherme Salgado
Breadcrumbs for leaf pages |
314 |
breadcrumb = Breadcrumb(None) |
315 |
breadcrumb._url = url |
|
9322.10.1
by Guilherme Salgado
First attempt at using page titles for breadcrumbs. Get the page using getMultiAdapter() and check for a page_title attribute, falling back to getting the title from pagetitles.py |
316 |
breadcrumb.text = title |
9271.6.1
by Guilherme Salgado
Breadcrumbs for leaf pages |
317 |
return breadcrumb |
9271.6.3
by Guilherme Salgado
Better names |
318 |
else: |
319 |
return None |
|
9271.6.1
by Guilherme Salgado
Breadcrumbs for leaf pages |
320 |
|
9225.1.3
by Michael Nelson
New styled breadcrumbs. |
321 |
@property
|
322 |
def display_breadcrumbs(self): |
|
323 |
"""Return whether the breadcrumbs should be displayed."""
|
|
324 |
# If there is only one breadcrumb then it does not make sense
|
|
325 |
# to display it as it will simply repeat the context.title.
|
|
9511.2.7
by Michael Nelson
Fixed bug 433852 |
326 |
# If the view is an IMajorHeadingView then we do not want
|
327 |
# to display breadcrumbs either.
|
|
9511.2.10
by Michael Nelson
Small style changes from barry. |
328 |
has_major_heading = IMajorHeadingView.providedBy( |
329 |
self._naked_context_view) |
|
330 |
return len(self.items) > 1 and not has_major_heading |
|
6476.12.2
by Matthew Paul Thomas
more changes |
331 |
|
9297.2.5
by Barry Warsaw
cleanup |
332 |
|
13678.1.4
by Benji York
move the Macro class up so it can be subclassed |
333 |
class Macro: |
334 |
"""Keeps templates that are registered as pages from being URL accessable.
|
|
335 |
||
336 |
The standard pattern in LP is to register templates that contain macros as
|
|
337 |
views on all objects:
|
|
338 |
||
339 |
<browser:page
|
|
340 |
for="*"
|
|
341 |
name="+main-template-macros"
|
|
342 |
template="../templates/base-layout-macros.pt"
|
|
343 |
permission="zope.Public"
|
|
344 |
/>
|
|
345 |
||
13678.1.9
by Benji York
improve wording using suggestion from review |
346 |
Without this class, that pattern would make the template URL traversable
|
347 |
from any object. Therefore requests like these would all "work":
|
|
13678.1.4
by Benji York
move the Macro class up so it can be subclassed |
348 |
|
349 |
http://launchpad.net/+main-template-macros
|
|
350 |
http://launchpad.net/ubuntu/+main-template-macros
|
|
351 |
http://launchpad.net/ubuntu/+main-template-macros
|
|
352 |
https://blueprints.launchpad.dev/ubuntu/hoary/+main-template-macros
|
|
353 |
||
354 |
Obviously, those requests wouldn't do anything useful and would instead
|
|
355 |
generate an OOPS.
|
|
356 |
||
357 |
It would be nice to use a different pattern for macros instead, but we've
|
|
358 |
grown dependent on some of the peculiatrities of registering macro
|
|
359 |
templates in this way.
|
|
360 |
||
361 |
This class was created in order to prevent macro templates from being
|
|
362 |
accessable via URL without having to make nontrivial changes to the many,
|
|
363 |
many templates that use macros. To use the class add a "class" parameter
|
|
364 |
to macro template registrations:
|
|
365 |
||
366 |
<browser:page
|
|
367 |
for="*"
|
|
368 |
name="+main-template-macros"
|
|
369 |
template="../templates/base-layout-macros.pt"
|
|
370 |
class="lp.app.browser.launchpad.Macro"
|
|
371 |
permission="zope.Public"
|
|
372 |
/>
|
|
373 |
"""
|
|
374 |
implements(IBrowserPublisher, ITraversable) |
|
375 |
||
376 |
def __init__(self, context, request): |
|
377 |
self.context = context |
|
378 |
||
379 |
def traverse(self, name, furtherPath): |
|
380 |
return self.index.macros[name] |
|
381 |
||
382 |
def browserDefault(self, request): |
|
383 |
return self, () |
|
384 |
||
385 |
def publishTraverse(self, request, name): |
|
386 |
raise NotFound(self.context, self.__name__) |
|
387 |
||
388 |
def __call__(self): |
|
389 |
raise NotFound(self.context, self.__name__) |
|
390 |
||
391 |
||
13678.1.10
by Benji York
fix failures found in EC2 |
392 |
class MaintenanceMessage: |
2494
by Canonical.com Patch Queue Manager
r=stub add 'launchpad (or shipit) is going down for maintenance' facility. |
393 |
"""Display a maintenance message if the control file is present and
|
394 |
it contains a valid iso format time.
|
|
395 |
||
396 |
The maintenance message shows the approximate time before launchpad will
|
|
397 |
be taken offline for maintenance.
|
|
398 |
||
399 |
The control file is +maintenancetime.txt in the launchpad root.
|
|
400 |
||
401 |
If there is no maintenance message, an empty string is returned.
|
|
402 |
||
403 |
If the maintenance time is too far in the future, then an empty string
|
|
404 |
is returned.
|
|
405 |
||
406 |
If the maintenance time is in the past, then the maintenance message says
|
|
407 |
that Launchpad will go offline "very very soon".
|
|
408 |
||
409 |
If the text in the maintenance message is poorly formatted, then an
|
|
410 |
empty string is returned, and a warning should be logged.
|
|
411 |
"""
|
|
412 |
||
413 |
timelefttext = None |
|
414 |
||
415 |
notmuchtime = timedelta(seconds=30) |
|
416 |
toomuchtime = timedelta(seconds=1800) # 30 minutes |
|
417 |
||
418 |
def __call__(self): |
|
419 |
if os.path.exists('+maintenancetime.txt'): |
|
420 |
message = file('+maintenancetime.txt').read() |
|
421 |
try: |
|
422 |
maintenancetime = parseDatetimetz(message) |
|
423 |
except DateTimeError: |
|
4664.1.1
by Curtis Hovey
Normalized comments for bug 3732. |
424 |
# XXX SteveAlexander 2005-09-22: log a warning here.
|
2494
by Canonical.com Patch Queue Manager
r=stub add 'launchpad (or shipit) is going down for maintenance' facility. |
425 |
return '' |
13333.5.3
by Jonathan Lange
Use the new utc_now() |
426 |
timeleft = maintenancetime - utc_now() |
2494
by Canonical.com Patch Queue Manager
r=stub add 'launchpad (or shipit) is going down for maintenance' facility. |
427 |
if timeleft > self.toomuchtime: |
428 |
return '' |
|
429 |
elif timeleft < self.notmuchtime: |
|
430 |
self.timelefttext = 'very very soon' |
|
431 |
else: |
|
432 |
self.timelefttext = 'in %s' % ( |
|
433 |
DurationFormatterAPI(timeleft).approximateduration()) |
|
434 |
return self.index() |
|
435 |
return '' |
|
1970
by Canonical.com Patch Queue Manager
Daf's menus branch. r=SteveA. |
436 |
|
437 |
||
438 |
class LaunchpadRootFacets(StandardLaunchpadFacets): |
|
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
439 |
|
1970
by Canonical.com Patch Queue Manager
Daf's menus branch. r=SteveA. |
440 |
usedfor = ILaunchpadRoot |
441 |
||
3691.398.22
by Francis J. Lacoste
Rename support facet to answers. |
442 |
enable_only = ['overview', 'bugs', 'answers', 'specifications', |
3691.147.3
by Matthew Paul Thomas
Removes Calendar facet links, and begins renaming 'Specifications' to 'Features' and 'Branches' to 'Code'. |
443 |
'translations', 'branches'] |
2738
by Canonical.com Patch Queue Manager
[trivial] various bugs fixed |
444 |
|
1970
by Canonical.com Patch Queue Manager
Daf's menus branch. r=SteveA. |
445 |
def overview(self): |
446 |
target = '' |
|
6713.2.1
by Matthew Paul Thomas
Adds application tabs to the application front pages. |
447 |
text = 'Launchpad Home' |
3691.31.31
by Steve Alexander
extend facet menu hook to choose appropriate site for facet menus by name. |
448 |
return Link(target, text) |
1970
by Canonical.com Patch Queue Manager
Daf's menus branch. r=SteveA. |
449 |
|
450 |
def translations(self): |
|
3618.1.50
by Steve Alexander
implement all vhosts, update main template presentation of vhosts |
451 |
target = '' |
1970
by Canonical.com Patch Queue Manager
Daf's menus branch. r=SteveA. |
452 |
text = 'Translations' |
3691.31.31
by Steve Alexander
extend facet menu hook to choose appropriate site for facet menus by name. |
453 |
return Link(target, text) |
1970
by Canonical.com Patch Queue Manager
Daf's menus branch. r=SteveA. |
454 |
|
455 |
def bugs(self): |
|
3618.1.50
by Steve Alexander
implement all vhosts, update main template presentation of vhosts |
456 |
target = '' |
1970
by Canonical.com Patch Queue Manager
Daf's menus branch. r=SteveA. |
457 |
text = 'Bugs' |
3691.31.31
by Steve Alexander
extend facet menu hook to choose appropriate site for facet menus by name. |
458 |
return Link(target, text) |
1970
by Canonical.com Patch Queue Manager
Daf's menus branch. r=SteveA. |
459 |
|
3691.398.22
by Francis J. Lacoste
Rename support facet to answers. |
460 |
def answers(self): |
3618.1.50
by Steve Alexander
implement all vhosts, update main template presentation of vhosts |
461 |
target = '' |
462 |
text = 'Answers' |
|
3691.398.22
by Francis J. Lacoste
Rename support facet to answers. |
463 |
summary = 'Launchpad Answer Tracker' |
3691.31.31
by Steve Alexander
extend facet menu hook to choose appropriate site for facet menus by name. |
464 |
return Link(target, text, summary) |
2396
by Canonical.com Patch Queue Manager
[r=spiv] launchpad support tracker |
465 |
|
2423
by Canonical.com Patch Queue Manager
r=bjornt plus some [trivial] extra refactorings. more consistent facet menus across the whole of launchpad. improvements in the API. |
466 |
def specifications(self): |
3691.31.28
by Steve Alexander
kinda hacky implementation of binding facets to particular sites |
467 |
target = '' |
3618.1.49
by Steve Alexander
various small refactorings, change features.launchpad.dev to blueprint.launchpad.dev, implement code.launchpad.dev |
468 |
text = 'Blueprints' |
2396
by Canonical.com Patch Queue Manager
[r=spiv] launchpad support tracker |
469 |
summary = 'Launchpad feature specification tracker.' |
3691.31.31
by Steve Alexander
extend facet menu hook to choose appropriate site for facet menus by name. |
470 |
return Link(target, text, summary) |
2396
by Canonical.com Patch Queue Manager
[r=spiv] launchpad support tracker |
471 |
|
3311.1.1
by Mark Shuttleworth
Polish up the Bazaar front page |
472 |
def branches(self): |
3618.1.49
by Steve Alexander
various small refactorings, change features.launchpad.dev to blueprint.launchpad.dev, implement code.launchpad.dev |
473 |
target = '' |
10842.1.1
by Paul Hummer
Changed 'Branches' to 'Code' and prepping to run tests |
474 |
text = 'Code' |
3311.1.1
by Mark Shuttleworth
Polish up the Bazaar front page |
475 |
summary = 'The Code Bazaar' |
3691.31.31
by Steve Alexander
extend facet menu hook to choose appropriate site for facet menus by name. |
476 |
return Link(target, text, summary) |
3311.1.1
by Mark Shuttleworth
Polish up the Bazaar front page |
477 |
|
1970
by Canonical.com Patch Queue Manager
Daf's menus branch. r=SteveA. |
478 |
|
1936
by Canonical.com Patch Queue Manager
Fix various bugs to do with login links, and use a view with page template fragment and a view class to do the algorithmic stuff. r=spiv. |
479 |
class LoginStatus: |
480 |
||
481 |
def __init__(self, context, request): |
|
482 |
self.context = context |
|
483 |
self.request = request |
|
484 |
self.user = getUtility(ILaunchBag).user |
|
485 |
||
486 |
@property
|
|
487 |
def login_shown(self): |
|
488 |
return (self.user is None and |
|
489 |
'+login' not in self.request['PATH_INFO']) |
|
490 |
||
491 |
@property
|
|
492 |
def logged_in(self): |
|
493 |
return self.user is not None |
|
494 |
||
495 |
@property
|
|
496 |
def login_url(self): |
|
497 |
query_string = self.request.get('QUERY_STRING', '') |
|
2389
by Canonical.com Patch Queue Manager
[r=sabdfl] improvements to logout pages |
498 |
|
499 |
# If we have a query string, remove some things we don't want, and
|
|
500 |
# keep it around.
|
|
1936
by Canonical.com Patch Queue Manager
Fix various bugs to do with login links, and use a view with page template fragment and a view class to do the algorithmic stuff. r=spiv. |
501 |
if query_string: |
2389
by Canonical.com Patch Queue Manager
[r=sabdfl] improvements to logout pages |
502 |
query_dict = cgi.parse_qs(query_string, keep_blank_values=True) |
503 |
query_dict.pop('loggingout', None) |
|
504 |
query_string = urllib.urlencode( |
|
505 |
sorted(query_dict.items()), doseq=True) |
|
506 |
# If we still have a query_string after things we don't want
|
|
507 |
# have been removed, add it onto the url.
|
|
508 |
if query_string: |
|
509 |
query_string = '?' + query_string |
|
1966
by Canonical.com Patch Queue Manager
[trivial] really fix regression this time. new approach, combining request.getApplicationURL() with PATH_INFO with its virtual hosting info removed, to get the URL. This is not ideal, but it will work more reliably. |
510 |
|
511 |
# The approach we're taking is to combine the application url with
|
|
512 |
# the path_info, taking out path steps that are to do with virtual
|
|
513 |
# hosting. This is not exactly correct, as the application url
|
|
514 |
# can have other path steps in it. We're not using the feature of
|
|
515 |
# having other path steps in the application url, so this will work
|
|
516 |
# for us, assuming we don't need that in the future.
|
|
517 |
||
518 |
# The application_url is typically like 'http://thing:port'. No
|
|
519 |
# trailing slash.
|
|
520 |
application_url = self.request.getApplicationURL() |
|
1965
by Canonical.com Patch Queue Manager
[trivial] fixed virtual hosting regression for login links, with tests. |
521 |
|
522 |
# We're going to use PATH_INFO to remove any spurious '+index' at the
|
|
523 |
# end of the URL. But, PATH_INFO will contain virtual hosting
|
|
524 |
# configuration, if there is any.
|
|
1936
by Canonical.com Patch Queue Manager
Fix various bugs to do with login links, and use a view with page template fragment and a view class to do the algorithmic stuff. r=spiv. |
525 |
path_info = self.request['PATH_INFO'] |
1966
by Canonical.com Patch Queue Manager
[trivial] really fix regression this time. new approach, combining request.getApplicationURL() with PATH_INFO with its virtual hosting info removed, to get the URL. This is not ideal, but it will work more reliably. |
526 |
|
1965
by Canonical.com Patch Queue Manager
[trivial] fixed virtual hosting regression for login links, with tests. |
527 |
# Remove any virtual hosting segments.
|
528 |
path_steps = [] |
|
529 |
in_virtual_hosting_section = False |
|
530 |
for step in path_info.split('/'): |
|
531 |
if step.startswith('++vh++'): |
|
532 |
in_virtual_hosting_section = True |
|
533 |
continue
|
|
534 |
if step == '++': |
|
535 |
in_virtual_hosting_section = False |
|
536 |
continue
|
|
537 |
if not in_virtual_hosting_section: |
|
538 |
path_steps.append(step) |
|
539 |
path = '/'.join(path_steps) |
|
1966
by Canonical.com Patch Queue Manager
[trivial] really fix regression this time. new approach, combining request.getApplicationURL() with PATH_INFO with its virtual hosting info removed, to get the URL. This is not ideal, but it will work more reliably. |
540 |
|
1936
by Canonical.com Patch Queue Manager
Fix various bugs to do with login links, and use a view with page template fragment and a view class to do the algorithmic stuff. r=spiv. |
541 |
# Make the URL stop at the end of path_info so that we don't get
|
542 |
# spurious '+index' at the end.
|
|
1966
by Canonical.com Patch Queue Manager
[trivial] really fix regression this time. new approach, combining request.getApplicationURL() with PATH_INFO with its virtual hosting info removed, to get the URL. This is not ideal, but it will work more reliably. |
543 |
full_url = '%s%s' % (application_url, path) |
1936
by Canonical.com Patch Queue Manager
Fix various bugs to do with login links, and use a view with page template fragment and a view class to do the algorithmic stuff. r=spiv. |
544 |
if full_url.endswith('/'): |
545 |
full_url = full_url[:-1] |
|
546 |
logout_url_end = '/+logout' |
|
10420.3.1
by Guilherme Salgado
Fix the bug by not including a +openid-callback path element on the link to the +login page. |
547 |
openid_callback_url_end = '/+openid-callback' |
1936
by Canonical.com Patch Queue Manager
Fix various bugs to do with login links, and use a view with page template fragment and a view class to do the algorithmic stuff. r=spiv. |
548 |
if full_url.endswith(logout_url_end): |
549 |
full_url = full_url[:-len(logout_url_end)] |
|
10420.3.1
by Guilherme Salgado
Fix the bug by not including a +openid-callback path element on the link to the +login page. |
550 |
elif full_url.endswith(openid_callback_url_end): |
551 |
full_url = full_url[:-len(openid_callback_url_end)] |
|
552 |
else: |
|
553 |
# No need to remove anything from full_url.
|
|
554 |
pass
|
|
1936
by Canonical.com Patch Queue Manager
Fix various bugs to do with login links, and use a view with page template fragment and a view class to do the algorithmic stuff. r=spiv. |
555 |
return '%s/+login%s' % (full_url, query_string) |
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
556 |
|
557 |
||
558 |
class LaunchpadRootNavigation(Navigation): |
|
559 |
||
560 |
usedfor = ILaunchpadRoot |
|
561 |
||
3859.4.3
by Francis J. Lacoste
Rename URLs of the Answer Tracker containging ticket or support-contact. |
562 |
@stepto('support') |
563 |
def redirect_support(self): |
|
11626.4.1
by Curtis Hovey
Save spike for switch from feedback@ to /support. There are open questions about the criteria for showing suppot--anonymous or cannot login. Should /support not be reused. |
564 |
"""Redirect /support to launchpad Answers site."""
|
5576.1.9
by Barry Warsaw
lint fixes |
565 |
target_url = canonical_url( |
11626.4.1
by Curtis Hovey
Save spike for switch from feedback@ to /support. There are open questions about the criteria for showing suppot--anonymous or cannot login. Should /support not be reused. |
566 |
getUtility(ILaunchpadCelebrities).launchpad, rootsite='answers') |
567 |
return self.redirectSubTree(target_url, status=301) |
|
3859.4.3
by Francis J. Lacoste
Rename URLs of the Answer Tracker containging ticket or support-contact. |
568 |
|
4906.1.1
by Diogo Matsubara
Fix bug 141057 (Move Legal items from /legal to help.lp.net) by redirecting lp.net/legal to the wiki h.l.net/Legal |
569 |
@stepto('legal') |
570 |
def redirect_legal(self): |
|
571 |
"""Redirect /legal to help.launchpad.net/Legal site."""
|
|
572 |
return self.redirectSubTree( |
|
573 |
'https://help.launchpad.net/Legal', status=301) |
|
574 |
||
4934.3.24
by Elliot Murphy
Restore code from a bad merge from trunk. |
575 |
@stepto('faq') |
576 |
def redirect_faq(self): |
|
7178.1.1
by Diogo Matsubara
[r=kiko, release-critical=kiko] Fixes bug 273612 (The FAQs on the help wiki should use Launchpad's FAQ system), bug 257444 (Tour spelling polish for branch hosting), bug 282969 (dogfood is displaying traceback to any user) and [release-critical=joey] update what's new for 2.1.10 |
577 |
"""Redirect /faq to launchpad-project/+faqs."""
|
4934.3.24
by Elliot Murphy
Restore code from a bad merge from trunk. |
578 |
return self.redirectSubTree( |
7178.1.1
by Diogo Matsubara
[r=kiko, release-critical=kiko] Fixes bug 273612 (The FAQs on the help wiki should use Launchpad's FAQ system), bug 257444 (Tour spelling polish for branch hosting), bug 282969 (dogfood is displaying traceback to any user) and [release-critical=joey] update what's new for 2.1.10 |
579 |
'https://answers.launchpad.net/launchpad-project/+faqs', |
580 |
status=301) |
|
4934.3.24
by Elliot Murphy
Restore code from a bad merge from trunk. |
581 |
|
582 |
@stepto('feedback') |
|
583 |
def redirect_feedback(self): |
|
584 |
"""Redirect /feedback to help.launchpad.net/Feedback site."""
|
|
585 |
return self.redirectSubTree( |
|
586 |
'https://help.launchpad.net/Feedback', status=301) |
|
587 |
||
7876.1.1
by Jonathan Lange
Basic branch redirection. |
588 |
@stepto('+branch') |
589 |
def redirect_branch(self): |
|
7876.1.3
by Jonathan Lange
Add trailing path support |
590 |
"""Redirect /+branch/<foo> to the branch named 'foo'.
|
591 |
||
592 |
'foo' can be the unique name of the branch, or any of the aliases for
|
|
593 |
the branch.
|
|
11515.5.1
by Ian Booth
redirect_branch changes |
594 |
If 'foo' resolves to an ICanHasLinkedBranch instance but the linked
|
11515.5.7
by Ian Booth
Code review fixes |
595 |
branch is not yet set, redirect back to the referring page with a
|
596 |
suitable notification message.
|
|
11515.5.1
by Ian Booth
redirect_branch changes |
597 |
If 'foo' is completely invalid, redirect back to the referring page
|
598 |
with a suitable error message.
|
|
7876.1.3
by Jonathan Lange
Add trailing path support |
599 |
"""
|
11515.5.7
by Ian Booth
Code review fixes |
600 |
|
11582.3.2
by Ian Booth
Add new test for untested code path |
601 |
# The default target url to go to will be back to the referring page
|
602 |
# (in the case that there is an error resolving the branch url).
|
|
603 |
# Note: the http referer may be None if someone has hacked a url
|
|
604 |
# directly rather than following a /+branch/<foo> link.
|
|
605 |
target_url = self.request.getHeader('referer') |
|
7876.1.1
by Jonathan Lange
Basic branch redirection. |
606 |
path = '/'.join(self.request.stepstogo) |
7876.1.2
by Jonathan Lange
Support 'product' names at the end of +branch. |
607 |
try: |
11769.1.1
by Tim Penhey
Raise NotFoundError not the original error in the case where there is no referrer. |
608 |
branch_data = getUtility(IBranchLookup).getByLPPath(path) |
609 |
branch, trailing = branch_data |
|
610 |
target_url = canonical_url(branch) |
|
611 |
if trailing is not None: |
|
612 |
target_url = urlappend(target_url, trailing) |
|
613 |
except (NoLinkedBranch), e: |
|
614 |
# A valid ICanHasLinkedBranch target exists but there's no
|
|
615 |
# branch or it's not visible.
|
|
616 |
||
617 |
# If are aren't arriving at this invalid branch URL from
|
|
618 |
# another page then we just raise a NotFoundError to generate
|
|
619 |
# a 404, otherwise we end up in a bad recursion loop. The
|
|
620 |
# target url will be None in that case.
|
|
621 |
if target_url is None: |
|
622 |
raise NotFoundError |
|
623 |
self.request.response.addNotification( |
|
624 |
"The target %s does not have a linked branch." % path) |
|
11515.5.1
by Ian Booth
redirect_branch changes |
625 |
except (CannotHaveLinkedBranch, InvalidNamespace, |
11582.3.3
by Ian Booth
Fix 2.6 syntax |
626 |
InvalidProductName, NotFoundError), e: |
11582.3.1
by Ian Booth
Initial coding |
627 |
# If are aren't arriving at this invalid branch URL from another
|
11769.1.1
by Tim Penhey
Raise NotFoundError not the original error in the case where there is no referrer. |
628 |
# page then we just raise a NotFoundError to generate a 404,
|
629 |
# otherwise we end up in a bad recursion loop. The target url will
|
|
630 |
# be None in that case.
|
|
11582.3.2
by Ian Booth
Add new test for untested code path |
631 |
if target_url is None: |
11769.1.1
by Tim Penhey
Raise NotFoundError not the original error in the case where there is no referrer. |
632 |
raise NotFoundError |
11515.5.8
by Ian Booth
Improve error messages |
633 |
error_msg = str(e) |
11515.5.12
by Ian Booth
Small fixes as per code review |
634 |
if error_msg == '': |
11515.5.8
by Ian Booth
Improve error messages |
635 |
error_msg = "Invalid branch lp:%s." % path |
636 |
self.request.response.addErrorNotification(error_msg) |
|
11515.5.7
by Ian Booth
Code review fixes |
637 |
|
11582.3.2
by Ian Booth
Add new test for untested code path |
638 |
return self.redirectSubTree(target_url) |
7876.1.1
by Jonathan Lange
Basic branch redirection. |
639 |
|
8003.1.2
by Celso Providelo
Change traversal to IBuilderSet (buildfarm) to not use '+' since it is not a path prefix. Now the buildfarm page is available at '/builders', but '/+builds' will permanently redirects to the new URL. |
640 |
@stepto('+builds') |
641 |
def redirect_buildfarm(self): |
|
642 |
"""Redirect old /+builds requests to new URL, /builders."""
|
|
643 |
new_url = '/builders' |
|
644 |
return self.redirectSubTree( |
|
645 |
urlappend(new_url, '/'.join(self.request.stepstogo))) |
|
646 |
||
8003.1.4
by Celso Providelo
applying review comments, r=intellectronica. |
647 |
# XXX cprov 2009-03-19 bug=345877: path segments starting with '+'
|
648 |
# should never correspond to a valid traversal, they confuse the
|
|
649 |
# hierarchical navigation model.
|
|
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
650 |
stepto_utilities = { |
5151.1.14
by Mark Shuttleworth
Publish single Atom feed with all announcements hosted in LP |
651 |
'+announcements': IAnnouncementSet, |
3691.436.8
by Mark Shuttleworth
Create overview of all mentoring activity |
652 |
'binarypackagenames': IBinaryPackageNameSet, |
8777.4.7
by Jonathan Lange
Update the other old uses of IBranches. |
653 |
'branches': IBranchSet, |
3691.436.8
by Mark Shuttleworth
Create overview of all mentoring activity |
654 |
'bugs': IMaloneApplication, |
8003.1.2
by Celso Providelo
Change traversal to IBuilderSet (buildfarm) to not use '+' since it is not a path prefix. Now the buildfarm page is available at '/builders', but '/+builds' will permanently redirects to the new URL. |
655 |
'builders': IBuilderSet, |
3691.436.8
by Mark Shuttleworth
Create overview of all mentoring activity |
656 |
'+code': IBazaarApplication, |
4236.3.10
by Michael Hudson
do the z3 plumbing in what looks to me like a more sensible way |
657 |
'+code-imports': ICodeImportSet, |
3691.436.8
by Mark Shuttleworth
Create overview of all mentoring activity |
658 |
'codeofconduct': ICodeOfConductSet, |
10348.3.1
by Jonathan Davies
Put in place the foundations for exporting Country's over the API. |
659 |
'+countries': ICountrySet, |
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
660 |
'distros': IDistributionSet, |
4974.3.1
by Abel Deuring
renamed the first URL component of the HWDB from hwdb to +hwdb |
661 |
'+hwdb': IHWDBApplication, |
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
662 |
'karmaaction': IKarmaActionSet, |
4268.3.23
by Carlos Perello Marin
Ported old import queue page to use the new infrastructure |
663 |
'+imports': ITranslationImportQueue, |
3691.436.57
by Mark Shuttleworth
Merge BETA |
664 |
'+languages': ILanguageSet, |
11848.2.9
by Edwin Grubbs
Added tests. Changed +nameblacklists to +nameblacklist. |
665 |
'+nameblacklist': INameBlacklistSet, |
8485.3.1
by Muharem Hrnjadovic
first stab at exposing package sets at the LP API |
666 |
'package-sets': IPackagesetSet, |
3691.436.8
by Mark Shuttleworth
Create overview of all mentoring activity |
667 |
'people': IPersonSet, |
6989.2.1
by Leonard Richardson
Initial attempt at implementation. |
668 |
'pillars': IPillarNameSet, |
13240.2.3
by Brad Crittenden
Broken to hell |
669 |
'+processor-families': IProcessorFamilySet, |
13387.1.10
by Francis J. Lacoste
URL to processor is now of the form /+processors/<name> |
670 |
'+processors': IProcessorSet, |
4011.2.7
by Bjorn Tillenius
move /products to /projects |
671 |
'projects': IProductSet, |
10326.1.1
by Henning Eggers
Mechanically renamed IProject* to IProjectGroup*. |
672 |
'projectgroups': IProjectGroupSet, |
3691.436.8
by Mark Shuttleworth
Create overview of all mentoring activity |
673 |
'sourcepackagenames': ISourcePackageNameSet, |
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
674 |
'specs': ISpecificationSet, |
675 |
'sprints': ISprintSet, |
|
3691.436.76
by Mark Shuttleworth
Make LP stats available to admins |
676 |
'+statistics': ILaunchpadStatisticSet, |
3691.436.26
by Mark Shuttleworth
Make sure offers of mentoring are only displayed when appropriate. |
677 |
'token': ILoginTokenSet, |
3691.8.96
by Carlos Perello Marin
Changed +translation-groups with +groups as agreed with mpt |
678 |
'+groups': ITranslationGroupSet, |
3691.267.29
by Stuart Bishop
Fix more page tests |
679 |
'translations': IRosettaApplication, |
10065.2.3
by Guilherme Salgado
Move the test openid views under a newly created testopenid vhost. |
680 |
'testopenid': ITestOpenIDApplication, |
3859.4.3
by Francis J. Lacoste
Rename URLs of the Answer Tracker containging ticket or support-contact. |
681 |
'questions': IQuestionSet, |
7675.560.10
by Graham Binns
Merged Gavin's changes. |
682 |
'temporary-blobs': ITemporaryStorageManager, |
3691.267.7
by Stuart Bishop
URL changees |
683 |
# These three have been renamed, and no redirects done, as the old
|
684 |
# urls now point to the product pages.
|
|
685 |
#'bazaar': IBazaarApplication,
|
|
686 |
#'malone': IMaloneApplication,
|
|
687 |
#'rosetta': IRosettaApplication,
|
|
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
688 |
}
|
689 |
||
4011.2.7
by Bjorn Tillenius
move /products to /projects |
690 |
@stepto('products') |
691 |
def products(self): |
|
4011.2.10
by Bjorn Tillenius
fix all test failures related to /products |
692 |
return self.redirectSubTree( |
693 |
canonical_url(getUtility(IProductSet)), status=301) |
|
4011.2.7
by Bjorn Tillenius
move /products to /projects |
694 |
|
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
695 |
def traverse(self, name): |
696 |
if name in self.stepto_utilities: |
|
4823.6.7
by Barry Warsaw
Much simplification and improvement in the way private ports are done. |
697 |
return getUtility(self.stepto_utilities[name]) |
3691.267.1
by Stuart Bishop
Work in progress |
698 |
|
13303.4.1
by mbp at canonical
launchpad.net/~ now redirects you to your user page |
699 |
if name == '~': |
700 |
person = getUtility(ILaunchBag).user |
|
701 |
if person is None: |
|
702 |
raise Unauthorized() |
|
703 |
# Keep the context and the subtree so that
|
|
704 |
# bugs.l.n/~/+assignedbugs goes to the person's canonical
|
|
705 |
# assigned list.
|
|
706 |
return self.redirectSubTree( |
|
707 |
canonical_url(self.context) + "~" |
|
708 |
+ canonical_name(person.name), |
|
709 |
status=302) |
|
710 |
elif name.startswith('~'): # Allow traversal to ~foo for People |
|
4934.3.24
by Elliot Murphy
Restore code from a bad merge from trunk. |
711 |
if canonical_name(name) != name: |
13303.4.1
by mbp at canonical
launchpad.net/~ now redirects you to your user page |
712 |
# (for instance, uppercase username?)
|
4934.3.24
by Elliot Murphy
Restore code from a bad merge from trunk. |
713 |
if self.request.method == 'POST': |
714 |
raise POSTToNonCanonicalURL |
|
715 |
return self.redirectSubTree( |
|
716 |
canonical_url(self.context) + canonical_name(name), |
|
717 |
status=301) |
|
718 |
else: |
|
719 |
person = getUtility(IPersonSet).getByName(name[1:]) |
|
10067.3.1
by Curtis Hovey
Raise a GoneError (HTTP 410) when traversing suspended user |
720 |
if person is None: |
721 |
return person |
|
7510.4.6
by Barry Warsaw
Respond to reviews. Move the check code into the LaunchpadRootNavigation |
722 |
# Check to see if this is a team, and if so, whether the
|
723 |
# logged in user is allowed to view the team, by virtue of
|
|
724 |
# team membership or Launchpad administration.
|
|
14494.4.2
by Curtis Hovey
Patched the private team traversal rules back into the tree because merge3 and diff3 suck. |
725 |
if (person.is_team and |
726 |
not check_permission('launchpad.LimitedView', person)): |
|
10067.3.1
by Curtis Hovey
Raise a GoneError (HTTP 410) when traversing suspended user |
727 |
raise NotFound(self.context, name) |
728 |
# Only admins are permitted to see suspended users.
|
|
729 |
if person.account_status == AccountStatus.SUSPENDED: |
|
12552.1.1
by j.c.sackett
Changed the permission check. |
730 |
if not check_permission('launchpad.Moderate', person): |
10067.3.1
by Curtis Hovey
Raise a GoneError (HTTP 410) when traversing suspended user |
731 |
raise GoneError( |
732 |
'User is suspended: %s' % name) |
|
733 |
return person |
|
3691.267.39
by Stuart Bishop
Trivial optimization to traverse() |
734 |
|
3691.267.37
by Stuart Bishop
Bazaar needs old XML-RPC URL to remain functional |
735 |
# Dapper and Edgy shipped with https://launchpad.net/bazaar hard coded
|
736 |
# into the Bazaar Launchpad plugin (part of Bazaar core). So in theory
|
|
737 |
# we need to support this URL until 2011 (although I suspect the API
|
|
738 |
# will break much sooner than that) or updates sent to
|
|
739 |
# {dapper,edgy}-updates. Probably all irrelevant, as I suspect the
|
|
740 |
# number of people using the plugin in edgy and dapper is 0.
|
|
3691.267.39
by Stuart Bishop
Trivial optimization to traverse() |
741 |
if name == 'bazaar' and IXMLRPCRequest.providedBy(self.request): |
3691.267.37
by Stuart Bishop
Bazaar needs old XML-RPC URL to remain functional |
742 |
return getUtility(IBazaarApplication) |
743 |
||
5088.1.1
by Christian Robottom Reis
Fix for bug #156271, Allow administrators to reactivate disabled projects. |
744 |
# account for common typing mistakes
|
745 |
if canonical_name(name) != name: |
|
746 |
if self.request.method == 'POST': |
|
747 |
raise POSTToNonCanonicalURL |
|
748 |
return self.redirectSubTree( |
|
9080.2.2
by Brad Crittenden
Formatting changes per review. |
749 |
(canonical_url(self.context, request=self.request) + |
750 |
canonical_name(name)), |
|
5088.1.1
by Christian Robottom Reis
Fix for bug #156271, Allow administrators to reactivate disabled projects. |
751 |
status=301) |
752 |
||
753 |
pillar = getUtility(IPillarNameSet).getByName( |
|
6080.9.8
by Edwin Grubbs
Added IPillar interface and security |
754 |
name, ignore_inactive=False) |
755 |
if pillar is not None and check_permission('launchpad.View', pillar): |
|
7332.1.1
by Guilherme Salgado
Make it possible to traverse to pillars using any of their aliases. Also rewrite I{Product,Distribution,Project}.getByName() using IPillarNameSet.getByName() |
756 |
if pillar.name != name: |
757 |
# This pillar was accessed through one of its aliases, so we
|
|
758 |
# must redirect to its canonical URL.
|
|
12338.4.3
by j.c.sackett
Rewrapped a line. |
759 |
return self.redirectSubTree( |
12338.4.6
by j.c.sackett
Updated use of canonical_url when finding the url of a pillar found by alias to pass in the request. |
760 |
canonical_url(pillar, self.request), status=301) |
6080.9.8
by Edwin Grubbs
Added IPillar interface and security |
761 |
return pillar |
762 |
return None |
|
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
763 |
|
3691.412.16
by James Henstridge
resurrect redirection code that carlos reverted in carlos.perello@canonical.com-20070226121532-guyv8nodkvhs12nx |
764 |
def _getBetaRedirectionView(self): |
5622.2.5
by Maris Fogels
Rework. Fixed some style issues, and clarified a comment string. |
765 |
# If the inhibit_beta_redirect cookie is set, don't redirect.
|
3691.412.16
by James Henstridge
resurrect redirection code that carlos reverted in carlos.perello@canonical.com-20070226121532-guyv8nodkvhs12nx |
766 |
if self.request.cookies.get('inhibit_beta_redirect', '0') == '1': |
767 |
return None |
|
768 |
||
5622.2.5
by Maris Fogels
Rework. Fixed some style issues, and clarified a comment string. |
769 |
# If we are looking at the front page, don't redirect.
|
3691.412.16
by James Henstridge
resurrect redirection code that carlos reverted in carlos.perello@canonical.com-20070226121532-guyv8nodkvhs12nx |
770 |
if self.request['PATH_INFO'] == '/': |
771 |
return None |
|
3973.1.29
by Steve Alexander
remove unused root Launchpad breadcrumb |
772 |
|
5622.2.5
by Maris Fogels
Rework. Fixed some style issues, and clarified a comment string. |
773 |
# If this is a HTTP POST, we don't want to issue a redirect.
|
774 |
# Doing so would go against the HTTP standard.
|
|
5622.2.2
by Maris Fogels
Implemented the fix for beta redirection on POST. Fixed the pagetest output to match the working test. |
775 |
if self.request.method == 'POST': |
776 |
return None |
|
777 |
||
8920.1.2
by Francis J. Lacoste
Disable beta team redirection on the webservice. |
778 |
# If this is a web service request, don't redirect.
|
779 |
if WebServiceLayer.providedBy(self.request): |
|
780 |
return None |
|
781 |
||
8296.2.2
by Brad Crittenden
Untabified file. |
782 |
# If the request is for a bug then redirect straight to that bug.
|
783 |
bug_match = re.match("/bugs/(\d+)$", self.request['PATH_INFO']) |
|
784 |
if bug_match: |
|
785 |
bug_number = bug_match.group(1) |
|
786 |
bug_set = getUtility(IBugSet) |
|
787 |
try: |
|
788 |
bug = bug_set.get(bug_number) |
|
11929.9.1
by Tim Penhey
Move launchpadform into lp.app.browser. |
789 |
except NotFoundError: |
8296.2.1
by Brad Crittenden
Optimize redirection for lp.net/bugs/xxx URLs. |
790 |
raise NotFound(self.context, bug_number) |
8296.2.3
by Brad Crittenden
Don't leak bugtasks for private bugs and avoid blowing up when if the launchpad_beta_tester celebrity is missing. |
791 |
if not check_permission("launchpad.View", bug): |
12599.4.2
by Leonard Richardson
Merge from trunk. |
792 |
return None |
11815.1.2
by Robert Collins
Drop beta site redirect support. |
793 |
# Empty the traversal stack, since we're redirecting.
|
794 |
self.request.setTraversalStack([]) |
|
795 |
# And perform a temporary redirect.
|
|
11815.1.3
by Robert Collins
Tweak from thumper. |
796 |
return RedirectionView(canonical_url(bug.default_bugtask), |
797 |
self.request, status=303) |
|
11815.1.2
by Robert Collins
Drop beta site redirect support. |
798 |
# Explicit catchall - do not redirect.
|
799 |
return None |
|
3691.412.16
by James Henstridge
resurrect redirection code that carlos reverted in carlos.perello@canonical.com-20070226121532-guyv8nodkvhs12nx |
800 |
|
801 |
def publishTraverse(self, request, name): |
|
802 |
beta_redirection_view = self._getBetaRedirectionView() |
|
803 |
if beta_redirection_view is not None: |
|
804 |
return beta_redirection_view |
|
805 |
return Navigation.publishTraverse(self, request, name) |
|
806 |
||
2622
by Canonical.com Patch Queue Manager
[trivial] remove all uses of browser:suburl and nuke the suburl directive code. |
807 |
|
3489.1.1
by Bjorn Tillenius
add test for soft timeouts and make sure they do get logged. |
808 |
class SoftTimeoutView(LaunchpadView): |
809 |
||
810 |
def __call__(self): |
|
811 |
"""Generate a soft timeout by sleeping enough time."""
|
|
3489.1.2
by Bjorn Tillenius
review commments. |
812 |
start_time = time.time() |
3489.1.1
by Bjorn Tillenius
add test for soft timeouts and make sure they do get logged. |
813 |
celebrities = getUtility(ILaunchpadCelebrities) |
814 |
if (self.user is None or |
|
815 |
not self.user.inTeam(celebrities.launchpad_developers)): |
|
816 |
raise Unauthorized |
|
817 |
||
818 |
self.request.response.setHeader('content-type', 'text/plain') |
|
5855.5.6
by Curtis Hovey
Revisions to remove the timeout keys from the launchpad config section and the |
819 |
soft_timeout = intOrZero(config.database.soft_request_timeout) |
3489.1.1
by Bjorn Tillenius
add test for soft timeouts and make sure they do get logged. |
820 |
if soft_timeout == 0: |
821 |
return 'No soft timeout threshold is set.' |
|
822 |
||
13130.1.6
by Curtis Hovey
Move ILaunchpadCelebrity to lp.app. |
823 |
time.sleep(soft_timeout / 1000.0) |
3489.1.2
by Bjorn Tillenius
review commments. |
824 |
time_to_generate_page = (time.time() - start_time) * 1000 |
825 |
# In case we didn't sleep enogh time, sleep a while longer to
|
|
826 |
# pass the soft timeout threshold.
|
|
3489.1.1
by Bjorn Tillenius
add test for soft timeouts and make sure they do get logged. |
827 |
while time_to_generate_page < soft_timeout: |
3489.1.2
by Bjorn Tillenius
review commments. |
828 |
time.sleep(0.1) |
829 |
time_to_generate_page = (time.time() - start_time) * 1000 |
|
3489.1.1
by Bjorn Tillenius
add test for soft timeouts and make sure they do get logged. |
830 |
return ( |
831 |
'Soft timeout threshold is set to %s ms. This page took' |
|
832 |
' %s ms to render.' % (soft_timeout, time_to_generate_page)) |
|
3691.270.4
by Guilherme Salgado
New page (at /+search) which lets people search across products, projects and distributions all at once |
833 |
|
834 |
||
5369.1.1
by Mark Shuttleworth
Add PopCalXP in date and datetime picker configurations |
835 |
class IcingFolder(ExportedFolder): |
836 |
"""Export the Launchpad icing."""
|
|
3712
by Steve Alexander
add IcingFolder |
837 |
|
7459.4.3
by Francis J. Lacoste
Export lazr-js under icing. |
838 |
export_subdirectories = True |
839 |
||
5369.1.16
by Mark Shuttleworth
Changes based on review from JamesH |
840 |
folder = os.path.join( |
13130.1.23
by Curtis Hovey
Fixed paths to directories. |
841 |
config.root, 'lib/canonical/launchpad/icing/') |
3712
by Steve Alexander
add IcingFolder |
842 |
|
3717
by Steve Alexander
rough draft of structural object presentation |
843 |
|
6574.1.5
by Francis J. Lacoste
Replace zope resources by LaunchpadImageFolder. |
844 |
class LaunchpadImageFolder(ExportedImageFolder): |
845 |
"""Export the Launchpad images - supporting retrieval without extension.
|
|
846 |
"""
|
|
847 |
||
848 |
folder = os.path.join( |
|
13130.1.23
by Curtis Hovey
Fixed paths to directories. |
849 |
config.root, 'lib/canonical/launchpad/images/') |
6574.1.5
by Francis J. Lacoste
Replace zope resources by LaunchpadImageFolder. |
850 |
|
851 |
||
6753.5.1
by Diogo Matsubara
merge the twozero tour again |
852 |
class LaunchpadTourFolder(ExportedFolder): |
853 |
"""Export a launchpad tour folder.
|
|
854 |
||
855 |
This exported folder supports traversing to subfolders.
|
|
856 |
"""
|
|
857 |
||
858 |
folder = os.path.join( |
|
859 |
os.path.dirname(os.path.realpath(__file__)), '../tour/') |
|
860 |
||
861 |
export_subdirectories = True |
|
862 |
||
863 |
def publishTraverse(self, request, name): |
|
864 |
"""Hide the source directory.
|
|
865 |
||
866 |
The source directory contains source material that we don't want
|
|
867 |
published over the web.
|
|
868 |
"""
|
|
869 |
if name == 'source': |
|
870 |
raise NotFound(request, name) |
|
871 |
return super(LaunchpadTourFolder, self).publishTraverse(request, name) |
|
872 |
||
873 |
def browserDefault(self, request): |
|
874 |
"""Redirect to index.html if the directory itself is requested."""
|
|
875 |
if len(self.names) == 0: |
|
876 |
return RedirectionView( |
|
6721.2.12
by Christian Reis
Drop the .html in tour pages, yuck |
877 |
"%s+tour/index" % canonical_url(self.context), |
6753.5.1
by Diogo Matsubara
merge the twozero tour again |
878 |
self.request, status=302), () |
879 |
else: |
|
880 |
return self, () |
|
881 |
||
882 |
||
6770.2.14
by Francis J. Lacoste
Server API documentation from +apidoc. |
883 |
class LaunchpadAPIDocFolder(ExportedFolder): |
884 |
"""Export the API documentation."""
|
|
885 |
||
886 |
folder = os.path.join( |
|
13130.1.23
by Curtis Hovey
Fixed paths to directories. |
887 |
config.root, 'lib/canonical/launchpad/apidoc/') |
6770.2.14
by Francis J. Lacoste
Server API documentation from +apidoc. |
888 |
|
889 |
def browserDefault(self, request): |
|
890 |
"""Traverse to index.html if the directory itself is requested."""
|
|
891 |
if len(self.names) == 0: |
|
892 |
return self, ('index.html', ) |
|
893 |
else: |
|
894 |
return self, () |
|
895 |
||
896 |
||
3847.2.40
by Mark Shuttleworth
Implement blueprint app home page search |
897 |
class AppFrontPageSearchView(LaunchpadFormView): |
898 |
||
899 |
schema = IAppFrontPageSearchForm |
|
900 |
custom_widget('scope', ProjectScopeWidget) |
|
901 |
||
902 |
@property
|
|
903 |
def scope_css_class(self): |
|
904 |
"""The CSS class for used in the scope widget."""
|
|
905 |
if self.scope_error: |
|
906 |
return 'error' |
|
907 |
else: |
|
908 |
return None |
|
909 |
||
910 |
@property
|
|
911 |
def scope_error(self): |
|
912 |
"""The error message for the scope widget."""
|
|
5243.1.1
by Jonathan Knowles
Renaming method getWidgetError (in LaunchpadFormView) to getFieldError. |
913 |
return self.getFieldError('scope') |
3847.2.40
by Mark Shuttleworth
Implement blueprint app home page search |
914 |
|
915 |
||
9474.2.1
by Gary Poster
convert three templates to 3.0; also correct some oddities in table layout in +graphics |
916 |
class LaunchpadGraphics(LaunchpadView): |
917 |
label = page_title = 'Overview of Launchpad graphics and icons' |
|
918 |
||
919 |
||
7841.5.5
by Curtis Hovey
Add a control to show or hide small maps. Uses a reimplentation of the portlet |
920 |
def get_launchpad_views(cookies): |
7841.5.15
by Curtis Hovey
Changes per review. |
921 |
"""The state of optional page elements the user may choose to view.
|
7841.5.5
by Curtis Hovey
Add a control to show or hide small maps. Uses a reimplentation of the portlet |
922 |
|
923 |
:param cookies: The request.cookies object that contains launchpad_views.
|
|
924 |
:return: A dict of all the view states.
|
|
925 |
"""
|
|
926 |
views = { |
|
927 |
'small_maps': True, |
|
928 |
}
|
|
929 |
cookie = cookies.get('launchpad_views', '') |
|
930 |
if len(cookie) > 0: |
|
931 |
pairs = cookie.split('&') |
|
932 |
for pair in pairs: |
|
7841.5.15
by Curtis Hovey
Changes per review. |
933 |
parts = pair.split('=') |
934 |
if len(parts) != 2: |
|
935 |
# The cookie is malformed, possibly hacked.
|
|
936 |
continue
|
|
937 |
key, value = parts |
|
7841.5.5
by Curtis Hovey
Add a control to show or hide small maps. Uses a reimplentation of the portlet |
938 |
if not key in views: |
7841.5.15
by Curtis Hovey
Changes per review. |
939 |
# The cookie may be hacked.
|
7841.5.5
by Curtis Hovey
Add a control to show or hide small maps. Uses a reimplentation of the portlet |
940 |
continue
|
941 |
# 'false' is the value that the browser script sets to disable a
|
|
942 |
# part of a page. Any other value is considered to be 'true'.
|
|
943 |
views[key] = value != 'false' |
|
944 |
return views |
|
7675.117.1
by Francis J. Lacoste
+login is now a 404 on the SSO and Unauthorized are really 500 |
945 |
|
946 |
||
14382.1.5
by Aaron Bentley
view_name is included in BugTaskSearchListingView RequestCache. |
947 |
def iter_view_registrations(cls): |
14382.1.11
by Aaron Bentley
Fix text. |
948 |
"""Iterate through the AdapterRegistrations of a view.
|
14382.1.5
by Aaron Bentley
view_name is included in BugTaskSearchListingView RequestCache. |
949 |
|
14382.1.7
by Aaron Bentley
Simplify iter_view_registrations, fix tests. |
950 |
The input must be the final registered form of the class, which is
|
951 |
typically a SimpleViewClass variant.
|
|
14382.1.5
by Aaron Bentley
view_name is included in BugTaskSearchListingView RequestCache. |
952 |
"""
|
953 |
for registration in getGlobalSiteManager().registeredAdapters(): |
|
14382.1.6
by Aaron Bentley
Actually use view_name in ListingNavigator. |
954 |
if registration.factory == cls: |
14382.1.7
by Aaron Bentley
Simplify iter_view_registrations, fix tests. |
955 |
yield registration |
14382.1.5
by Aaron Bentley
view_name is included in BugTaskSearchListingView RequestCache. |
956 |
|
957 |
||
7675.117.1
by Francis J. Lacoste
+login is now a 404 on the SSO and Unauthorized are really 500 |
958 |
class DoesNotExistView: |
7675.117.9
by Francis J. Lacoste
Typo. |
959 |
"""A view that simply raises NotFound when rendered.
|
7675.117.1
by Francis J. Lacoste
+login is now a 404 on the SSO and Unauthorized are really 500 |
960 |
|
961 |
Useful to register as a view that shouldn't appear on a particular
|
|
962 |
virtual host.
|
|
963 |
"""
|
|
964 |
implements(IBrowserPublisher) |
|
965 |
||
966 |
def __init__(self, context, request): |
|
967 |
self.context = context |
|
968 |
||
969 |
def publishTraverse(self, request, name): |
|
970 |
"""See `IBrowserPublisher`."""
|
|
971 |
return self |
|
972 |
||
973 |
def browserDefault(self, request): |
|
974 |
"""See `IBrowserPublisher`."""
|
|
975 |
return self, () |
|
976 |
||
977 |
def __call__(self): |
|
978 |
raise NotFound(self.context, self.__name__) |