1
# Copyright 2010 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""Vostok's custom publication."""
8
'VostokBrowserRequest',
10
'VostokRootNavigation',
11
'vostok_request_publication_factory',
15
from zope.component import getUtility
16
from zope.interface import (
20
from zope.publisher.interfaces.browser import (
25
from canonical.launchpad.webapp import (
29
from canonical.launchpad.webapp.publication import LaunchpadBrowserPublication
30
from canonical.launchpad.webapp.servers import (
31
LaunchpadBrowserRequest,
32
LaunchpadBrowserResponse,
33
VirtualHostRequestPublicationFactory,
35
from canonical.launchpad.webapp.vhosts import allvhosts
36
from lp.registry.interfaces.distribution import IDistributionSet
39
class VostokLayer(IBrowserRequest, IDefaultBrowserLayer):
40
"""The Vostok layer."""
43
class VostokRequestMixin:
44
"""This mixin defines behaviour for the real and test Vostok requests."""
46
implements(VostokLayer)
48
def getRootURL(self, rootsite):
49
"""See `IBasicLaunchpadRequest`."""
50
return allvhosts.configs['vostok'].rooturl
53
class VostokBrowserRequest(VostokRequestMixin, LaunchpadBrowserRequest):
54
"""Request class for Vostok layer."""
56
def _createResponse(self):
57
"""As per zope.publisher.browser.BrowserRequest._createResponse"""
58
return VostokBrowserResponse()
61
class VostokBrowserResponse(LaunchpadBrowserResponse):
63
def redirect(self, location, status=None, trusted=False,
64
temporary_if_possible=False):
65
"""Override the parent method to make redirects untrusted by default.
67
This is so that we don't allow redirects to any hosts other than
70
# Need to call LaunchpadBrowserResponse.redirect() directly because
71
# the temporary_if_possible argument only exists there.
72
LaunchpadBrowserResponse.redirect(
73
self, location, status=status, trusted=trusted,
74
temporary_if_possible=temporary_if_possible)
77
class IVostokRoot(Interface):
78
"""Marker interface for the root vostok object."""
82
"""The root object for the Vostok site.
84
No behaviour here, it just exists so it can have view and navigation
85
registrations attached to it.
88
implements(IVostokRoot)
91
class VostokRootNavigation(Navigation):
95
def traverse(self, name):
96
distro = getUtility(IDistributionSet)[name]
97
if distro is not None and distro.name != name:
98
# This distro was accessed through one of its aliases, so we
99
# must redirect to its canonical URL.
100
return self.redirectSubTree(canonical_url(distro), status=301)
104
class VostokBrowserPublication(LaunchpadBrowserPublication):
105
root_object_interface = IVostokRoot
108
def vostok_request_publication_factory():
109
return VirtualHostRequestPublicationFactory(
110
'vostok', VostokBrowserRequest, VostokBrowserPublication)