-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix up zope.app according to new location of BrowserView.
- Loading branch information
Showing
8 changed files
with
490 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
############################################################################## | ||
# | ||
# Copyright (c) 2002 Zope Corporation and Contributors. | ||
# All Rights Reserved. | ||
# | ||
# This software is subject to the provisions of the Zope Public License, | ||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
# FOR A PARTICULAR PURPOSE. | ||
# | ||
############################################################################## | ||
"""Resource Directory | ||
A 'resource directory' is an on-disk directory which is registered as | ||
a resource using the <resourceDirectory> ZCML directive. The | ||
directory is treated as a source for individual resources; it can be | ||
traversed to retrieve resources represented by contained files, which | ||
can in turn be treated as resources. The contained files have | ||
__name__ values which include a '/' separating the __name__ of the | ||
resource directory from the name of the file within the directory. | ||
$Id$ | ||
""" | ||
import os | ||
import posixpath | ||
|
||
from zope.interface import implements | ||
from zope.publisher.interfaces import NotFound | ||
from zope.security.proxy import Proxy | ||
from zope.publisher.browser import BrowserView | ||
from zope.publisher.interfaces.browser import IBrowserPublisher | ||
|
||
from zope.app.publisher.browser.resource import Resource | ||
|
||
from fileresource import FileResourceFactory, ImageResourceFactory | ||
from pagetemplateresource import PageTemplateResourceFactory | ||
from resources import empty | ||
|
||
_marker = object() | ||
|
||
# we only need this class as a context for DirectoryResource | ||
class Directory(object): | ||
|
||
def __init__(self, path, checker, name): | ||
self.path = path | ||
self.checker = checker | ||
self.__name__ = name | ||
|
||
class DirectoryResource(BrowserView, Resource): | ||
|
||
implements(IBrowserPublisher) | ||
|
||
resource_factories = { | ||
'.gif': ImageResourceFactory, | ||
'.png': ImageResourceFactory, | ||
'.jpg': ImageResourceFactory, | ||
'.pt': PageTemplateResourceFactory, | ||
'.zpt': PageTemplateResourceFactory, | ||
'.html': PageTemplateResourceFactory, | ||
} | ||
|
||
default_factory = FileResourceFactory | ||
|
||
def publishTraverse(self, request, name): | ||
'''See interface IBrowserPublisher''' | ||
return self.get(name) | ||
|
||
def browserDefault(self, request): | ||
'''See interface IBrowserPublisher''' | ||
return empty, () | ||
|
||
def __getitem__(self, name): | ||
res = self.get(name, None) | ||
if res is None: | ||
raise KeyError(name) | ||
return res | ||
|
||
def get(self, name, default=_marker): | ||
path = self.context.path | ||
filename = os.path.join(path, name) | ||
isfile = os.path.isfile(filename) | ||
isdir = os.path.isdir(filename) | ||
|
||
if not (isfile or isdir): | ||
if default is _marker: | ||
raise NotFound(None, name) | ||
return default | ||
|
||
if isfile: | ||
ext = os.path.splitext(os.path.normcase(name))[1] | ||
factory = self.resource_factories.get(ext, self.default_factory) | ||
else: | ||
factory = DirectoryResourceFactory | ||
|
||
rname = posixpath.join(self.__name__, name) | ||
resource = factory(filename, self.context.checker, rname)(self.request) | ||
resource.__parent__ = self | ||
return resource | ||
|
||
class DirectoryResourceFactory(object): | ||
|
||
def __init__(self, path, checker, name): | ||
self.__dir = Directory(path, checker, name) | ||
self.__checker = checker | ||
self.__name = name | ||
|
||
def __call__(self, request): | ||
resource = DirectoryResource(self.__dir, request) | ||
resource.__Security_checker__ = self.__checker | ||
resource.__name__ = self.__name | ||
return resource |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
############################################################################## | ||
# | ||
# Copyright (c) 2002 Zope Corporation and Contributors. | ||
# All Rights Reserved. | ||
# | ||
# This software is subject to the provisions of the Zope Public License, | ||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
# FOR A PARTICULAR PURPOSE. | ||
# | ||
############################################################################## | ||
"""Selecting first available and allowed management view | ||
$Id$ | ||
""" | ||
from zope.interface import implements | ||
from zope.publisher.interfaces.browser import IBrowserPublisher | ||
from zope.publisher.browser import BrowserView | ||
from zope.app.publisher.browser.menu import getFirstMenuItem | ||
|
||
class ManagementViewSelector(BrowserView): | ||
"""View that selects the first available management view. | ||
Support 'zmi_views' actions like: 'javascript:alert("hello")', | ||
'../view_on_parent.html' or '++rollover++'. | ||
""" | ||
implements(IBrowserPublisher) | ||
|
||
def browserDefault(self, request): | ||
return self, () | ||
|
||
def __call__(self): | ||
item = getFirstMenuItem('zmi_views', self.context, self.request) | ||
|
||
if item: | ||
redirect_url = item['action'] | ||
if not (redirect_url.startswith('../') or \ | ||
redirect_url.lower().startswith('javascript:') or \ | ||
redirect_url.lower().startswith('++')): | ||
self.request.response.redirect(redirect_url) | ||
return u'' | ||
|
||
self.request.response.redirect('.') # Redirect to content/ | ||
return u'' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
############################################################################## | ||
# | ||
# Copyright (c) 2004 Zope Corporation and Contributors. | ||
# All Rights Reserved. | ||
# | ||
# This software is subject to the provisions of the Zope Public License, | ||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
# FOR A PARTICULAR PURPOSE. | ||
# | ||
############################################################################## | ||
"""Menu Registration code. | ||
$Id$ | ||
""" | ||
__docformat__ = "reStructuredText" | ||
import sys | ||
|
||
import zope.component | ||
from zope.interface import Interface, implements, providedBy | ||
from zope.security import checkPermission, canAccess | ||
from zope.security.interfaces import Unauthorized, Forbidden | ||
from zope.security.proxy import removeSecurityProxy | ||
from zope.publisher.browser import BrowserView | ||
|
||
from zope.app.pagetemplate.engine import Engine | ||
from zope.app.publication.browser import PublicationTraverser | ||
from zope.app.publisher.interfaces.browser import IMenuAccessView | ||
from zope.app.publisher.interfaces.browser import IBrowserMenu | ||
from zope.app.publisher.interfaces.browser import IBrowserMenuItem | ||
from zope.app.publisher.interfaces.browser import IBrowserSubMenuItem | ||
from zope.app.publisher.interfaces.browser import IMenuItemType | ||
|
||
class BrowserMenu(object): | ||
"""Browser Menu""" | ||
implements(IBrowserMenu) | ||
|
||
def __init__(self, id, title=u'', description=u''): | ||
self.id = id | ||
self.title = title | ||
self.description = description | ||
|
||
def getMenuItemType(self): | ||
return zope.component.getUtility(IMenuItemType, self.id) | ||
|
||
def getMenuItems(self, object, request): | ||
"""Return menu item entries in a TAL-friendly form.""" | ||
result = [] | ||
for name, item in zope.component.getAdapters((object, request), | ||
self.getMenuItemType()): | ||
if item.available(): | ||
result.append(item) | ||
|
||
# Now order the result. This is not as easy as it seems. | ||
# | ||
# (1) Look at the interfaces and put the more specific menu entries | ||
# to the front. | ||
# (2) Sort unabigious entries by order and then by title. | ||
ifaces = list(providedBy(removeSecurityProxy(object)).__iro__) | ||
result = [(ifaces.index(item._for or Interface), | ||
item.order, item.title, item) for item in result] | ||
result.sort() | ||
|
||
result = [ | ||
{'title': item.title, | ||
'description': item.description, | ||
'action': item.action, | ||
'selected': (item.selected() and u'selected') or u'', | ||
'icon': item.icon, | ||
'extra': item.extra, | ||
'submenu': (IBrowserSubMenuItem.providedBy(item) and | ||
getMenu(item.submenuId, object, request)) or None} | ||
for index, order, title, item in result] | ||
|
||
return result | ||
|
||
|
||
class BrowserMenuItem(BrowserView): | ||
"""Browser Menu Item Class""" | ||
implements(IBrowserMenuItem) | ||
|
||
# See zope.app.publisher.interfaces.browser.IBrowserMenuItem | ||
title = u'' | ||
description = u'' | ||
action = u'' | ||
extra = None | ||
order = 0 | ||
permission = None | ||
filter = None | ||
icon = None | ||
_for = Interface | ||
|
||
def available(self): | ||
"""See zope.app.publisher.interfaces.browser.IBrowserMenuItem""" | ||
# Make sure we have the permission needed to access the menu's action | ||
if self.permission is not None: | ||
# If we have an explicit permission, check that we | ||
# can access it. | ||
if not checkPermission(self.permission, self.context): | ||
return False | ||
|
||
elif self.action != u'': | ||
# Otherwise, test access by attempting access | ||
path = self.action | ||
l = self.action.find('?') | ||
if l >= 0: | ||
path = self.action[:l] | ||
|
||
traverser = PublicationTraverser() | ||
try: | ||
view = traverser.traverseRelativeURL( | ||
self.request, self.context, path) | ||
except (Unauthorized, Forbidden, LookupError): | ||
return False | ||
else: | ||
# we're assuming that view pages are callable | ||
# this is a pretty sound assumption | ||
if not canAccess(view, '__call__'): | ||
return False | ||
|
||
# Make sure that we really want to see this menu item | ||
if self.filter is not None: | ||
|
||
try: | ||
include = self.filter(Engine.getContext( | ||
context = self.context, | ||
nothing = None, | ||
request = self.request, | ||
modules = sys.modules, | ||
)) | ||
except Unauthorized: | ||
return False | ||
else: | ||
if not include: | ||
return False | ||
|
||
return True | ||
|
||
def selected(self): | ||
"""See zope.app.publisher.interfaces.browser.IBrowserMenuItem""" | ||
request_url = self.request.getURL() | ||
|
||
normalized_action = self.action | ||
if self.action.startswith('@@'): | ||
normalized_action = self.action[2:] | ||
|
||
if request_url.endswith('/'+normalized_action): | ||
return True | ||
if request_url.endswith('/++view++'+normalized_action): | ||
return True | ||
if request_url.endswith('/@@'+normalized_action): | ||
return True | ||
|
||
return False | ||
|
||
|
||
class BrowserSubMenuItem(BrowserMenuItem): | ||
"""Browser Menu Item Base Class""" | ||
implements(IBrowserSubMenuItem) | ||
|
||
# See zope.app.publisher.interfaces.browser.IBrowserSubMenuItem | ||
submenuId = None | ||
|
||
def selected(self): | ||
"""See zope.app.publisher.interfaces.browser.IBrowserMenuItem""" | ||
if self.action is u'': | ||
return False | ||
return super(BrowserSubMenuItem, self).selected() | ||
|
||
|
||
def getMenu(id, object, request): | ||
"""Return menu item entries in a TAL-friendly form.""" | ||
menu = zope.component.getUtility(IBrowserMenu, id) | ||
return menu.getMenuItems(object, request) | ||
|
||
|
||
def getFirstMenuItem(id, object, request): | ||
"""Get the first item of a menu.""" | ||
items = getMenu(id, object, request) | ||
if items: | ||
return items[0] | ||
return None | ||
|
||
|
||
class MenuAccessView(BrowserView): | ||
"""A view allowing easy access to menus.""" | ||
implements(IMenuAccessView) | ||
|
||
def __getitem__(self, menuId): | ||
return getMenu(menuId, self.context, self.request) |
Oops, something went wrong.