[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Publisher/Browser - FileResource.py:1.1 Resource.py:1.1 Resources.py:1.1 config.zcml:1.1 metaConfigure.py:1.3 browser.zcml:NONE
Jim Fulton
jim@zope.com
Thu, 13 Jun 2002 19:16:14 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/App/Publisher/Browser
In directory cvs.zope.org:/tmp/cvs-serv10697/lib/python/Zope/App/Publisher/Browser
Modified Files:
metaConfigure.py
Added Files:
FileResource.py Resource.py Resources.py config.zcml
Removed Files:
browser.zcml
Log Message:
Got icons working, and, along the way:
- Implemented the icon directive
- Implemented
http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/ResourcesProposal
- Added a special view, named '', for service manager containers that
allows resources to have URLs like:
http://foo.com/@@/resourcename
- Fixed some server code that caused HTTP response data to get
promoted to unicode
- Updated the folder contents page to display icons.
- Ported icons for folder, file, image, and zptpage. Many more icons
need to be ported or created.
=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/FileResource.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""
$Id: FileResource.py,v 1.1 2002/06/13 23:15:43 jim Exp $
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
from Zope.Exceptions import NotFoundError
from Zope.Publisher.Browser.BrowserView import BrowserView
from Zope.Publisher.Browser.IBrowserResource import IBrowserResource
from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher
from Zope.App.Publisher.FileResource import File, Image
from Zope.App.Publisher.Browser.Resource import Resource
class FileResource(BrowserView, Resource):
__implements__ = IBrowserResource, IBrowserPublisher
############################################################
# Implementation methods for interface
# Zope.Publisher.Browser.IBrowserPublisher.
def publishTraverse(self, request, name):
'''See interface IBrowserPublisher'''
raise NotFoundError(name)
def browserDefault(self, request):
'''See interface IBrowserPublisher'''
method = request.get('REQUET_METHOD', 'GET').upper()
return getattr(self, method), ()
#
############################################################
# for unit tests
def _testData(self):
f=open(self.context.path,'rb')
data=f.read()
f.close()
return data
def GET(self):
"""Default document"""
file = self.context
request = self.request
response = request.getResponse()
# HTTP If-Modified-Since header handling. This is duplicated
# from OFS.Image.Image - it really should be consolidated
# somewhere...
header = request.getHeader('If-Modified-Since', None)
if header is not None:
header = header.split(';')[0]
# Some proxies seem to send invalid date strings for this
# header. If the date string is not valid, we ignore it
# rather than raise an error to be generally consistent
# with common servers such as Apache (which can usually
# understand the screwy date string as a lucky side effect
# of the way they parse it).
try: mod_since=long(timeFromDateTimeString(header))
except: mod_since=None
if mod_since is not None:
if getattr(file, 'lmt', None):
last_mod = long(file.lmt)
else:
last_mod = long(0)
if last_mod > 0 and last_mod <= mod_since:
response.setStatus(304)
return ''
response.setHeader('Content-Type', file.content_type)
response.setHeader('Last-Modified', file.lmh)
f=open(file.path,'rb')
data=f.read()
f.close()
return data
def HEAD(self):
file = self.context
response = self.request.getResponse()
response.setHeader('Content-Type', file.content_type)
response.setHeader('Last-Modified', file.lmh)
return ''
class FileResourceFactory:
def __init__(self, path):
self.__file = File(path)
def __call__(self, request):
return FileResource(self.__file, request)
class ImageResourceFactory:
def __init__(self, path):
self.__file = Image(path)
def __call__(self, request):
return FileResource(self.__file, request)
=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/Resource.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""
$Id: Resource.py,v 1.1 2002/06/13 23:15:43 jim Exp $
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
from Zope.ComponentArchitecture import queryView
from Zope.Proxy.ContextWrapper import getWrapperContainer, getWrapperData
from Zope.ContextWrapper import ContextMethod
class Resource:
def __init__(self, request):
self.request = request
def __call__(self):
name = getWrapperData(self)['name']
if name.startswith('++resource++'):
name = name[12:]
service = getWrapperContainer(self)
site = getWrapperContainer(service)
if site is None:
return "/@@/%s" % (name)
absolute_url = queryView(service, 'absolute_url', self.request)
if absolute_url is None:
return "/@@/%s" % (name)
site_url = absolute_url()
return "%s/@@/%s" % (site_url, name)
__call__ = ContextMethod(__call__)
=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/Resources.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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 URL acess
$Id: Resources.py,v 1.1 2002/06/13 23:15:43 jim Exp $
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
from Zope.Publisher.Browser.BrowserView import BrowserView
from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher
from Zope.ComponentArchitecture import getService
from Zope.Proxy.ContextWrapper import ContextWrapper
from Zope.ContextWrapper import ContextMethod
class Resources(BrowserView):
"""Provide a URL-accessible resource namespace
"""
__implements__ = BrowserView.__implements__, IBrowserPublisher
############################################################
# Implementation methods for interface
# Zope.Publisher.Browser.IBrowserPublisher.
def publishTraverse(self, request, name):
'''See interface IBrowserPublisher'''
resource_service = getService(self, 'Resources')
resource = resource_service.queryResource(self, name, request)
if resource is None:
raise NotFoundError(self, name)
return ContextWrapper(resource, resource_service)
publishTraverse = ContextMethod(publishTraverse)
def browserDefault(self, request):
'''See interface IBrowserPublisher'''
return empty, ()
#
############################################################
def empty():
return ''
=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/config.zcml ===
<zopeConfigure
xmlns='http://namespaces.zope.org/zope'
xmlns:security='http://namespaces.zope.org/security'
xmlns:browser='http://namespaces.zope.org/browser'
>
<content class="Zope.Publisher.Browser.BrowserRequest.">
<security:allow
interface="Zope.Publisher.Browser.IBrowserApplicationRequest." />
<security:allow
interface="Zope.ComponentArchitecture.IPresentationRequest." />
</content>
<content class=".FileResource.">
<security:allow interface="Zope.Publisher.Browser.IBrowserPublisher." />
<security:allow attributes="GET HEAD __call__" />
</content>
<browser:view name=""
factory=".Resources."
for="Zope.ComponentArchitecture.IServiceManagerContainer."
permission="Zope.Public"
allowed_interface="Zope.Publisher.Browser.IBrowserPublisher."
/>
</zopeConfigure>
=== Zope3/lib/python/Zope/App/Publisher/Browser/metaConfigure.py 1.2 => 1.3 ===
from Zope.App.PageTemplate.SimpleViewClass import SimpleViewClass
+from Zope.App.Publisher.Browser.FileResource \
+ import FileResourceFactory, ImageResourceFactory
def skin(_context, **__kw):
return _skin(_context,
@@ -41,12 +43,13 @@
type = IBrowserPresentation
default_allowed_attributes = '__call__'
- def __init__(self, _context, factory, name=None, layer='default',
+ def __init__(self, _context, factory=None, name=None, layer='default',
permission=None,
- allowed_interface=None, allowed_attributes=None):
+ allowed_interface=None, allowed_attributes=None,
+ file=None, image=None):
if ((allowed_attributes or allowed_interface)
- and (not name or not permission)):
+ and ((name is None) or not permission)):
raise ConfigurationError(
"Must use name attribute with allowed_interface or "
"allowed_attributes"
@@ -55,6 +58,9 @@
if allowed_interface is not None:
allowed_interface = _context.resolve(allowed_interface)
+ self.__file = file
+ self.__image = image
+
self.factory = self._factory(_context, factory)
self.layer = layer
self.name = name
@@ -64,7 +70,29 @@
self.pages = 0
def _factory(self, _context, factory):
- return _context.resolve(factory)
+ if ((factory is not None)
+ + (self.__file is not None)
+ + (self.__image is not None)
+ ) > 1:
+ raise ConfigurationError(
+ "Can't use more than one of factory, file, and image "
+ "attributes for resource directives"
+ )
+
+ if factory is not None:
+ return _context.resolve(factory)
+
+ if self.__file is not None:
+ return FileResourceFactory(_context.path(self.__file))
+
+ if self.__image is not None:
+ return FileResourceFactory(_context.path(self.__image))
+
+ raise ConfigurationError(
+ "At least one of the factory, file, and image "
+ "attributes for resource directives must be specified"
+ )
+
def page(self, _context, name, attribute, permission=None, layer=None):
@@ -112,7 +140,7 @@
return pageView
def __call__(self):
- if not self.name:
+ if self.name is None:
return ()
permission = self.permission
@@ -169,7 +197,7 @@
template=None):
if template:
- if not name:
+ if name is None:
raise ConfigurationError(
"Must specify name for template view")
@@ -252,10 +280,11 @@
view = factory(context, request)
- # We need this in case the resource gets unwrapped and needs to be rewrapped
+ # We need this in case the resource gets unwrapped and
+ # needs to be rewrapped
view.__Security_checker__ = checker
- return Proxy(view, checker)
+ return view
factory[-1] = proxyView
=== Removed File Zope3/lib/python/Zope/App/Publisher/Browser/browser.zcml ===