zope.browserresource-3.12.0/bootstrap.py 0000644 0000000 0000000 00000007330 11401613004 016512 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006 Zope Foundation 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.
#
##############################################################################
"""Bootstrap a buildout-based project
Simply run this script in a directory containing a buildout.cfg.
The script accepts buildout command-line options, so you can
use the -c option to specify an alternate configuration file.
"""
import os, shutil, sys, tempfile, urllib2
from optparse import OptionParser
tmpeggs = tempfile.mkdtemp()
is_jython = sys.platform.startswith('java')
# parsing arguments
parser = OptionParser()
parser.add_option("-v", "--version", dest="version",
help="use a specific zc.buildout version")
parser.add_option("-d", "--distribute",
action="store_true", dest="distribute", default=False,
help="Use Disribute rather than Setuptools.")
parser.add_option("-c", None, action="store", dest="config_file",
help=("Specify the path to the buildout configuration "
"file to be used."))
options, args = parser.parse_args()
# if -c was provided, we push it back into args for buildout' main function
if options.config_file is not None:
args += ['-c', options.config_file]
if options.version is not None:
VERSION = '==%s' % options.version
else:
VERSION = ''
USE_DISTRIBUTE = options.distribute
args = args + ['bootstrap']
to_reload = False
try:
import pkg_resources
if not hasattr(pkg_resources, '_distribute'):
to_reload = True
raise ImportError
except ImportError:
ez = {}
if USE_DISTRIBUTE:
exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py'
).read() in ez
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True)
else:
exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
).read() in ez
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
if to_reload:
reload(pkg_resources)
else:
import pkg_resources
if sys.platform == 'win32':
def quote(c):
if ' ' in c:
return '"%s"' % c # work around spawn lamosity on windows
else:
return c
else:
def quote (c):
return c
cmd = 'from setuptools.command.easy_install import main; main()'
ws = pkg_resources.working_set
if USE_DISTRIBUTE:
requirement = 'distribute'
else:
requirement = 'setuptools'
if is_jython:
import subprocess
assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd',
quote(tmpeggs), 'zc.buildout' + VERSION],
env=dict(os.environ,
PYTHONPATH=
ws.find(pkg_resources.Requirement.parse(requirement)).location
),
).wait() == 0
else:
assert os.spawnle(
os.P_WAIT, sys.executable, quote (sys.executable),
'-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION,
dict(os.environ,
PYTHONPATH=
ws.find(pkg_resources.Requirement.parse(requirement)).location
),
) == 0
ws.add_entry(tmpeggs)
ws.require('zc.buildout' + VERSION)
import zc.buildout.buildout
zc.buildout.buildout.main(args)
shutil.rmtree(tmpeggs)
zope.browserresource-3.12.0/buildout.cfg 0000644 0000000 0000000 00000000666 11470675670 016467 0 ustar 0000000 0000000 [buildout]
develop = .
../zope.security
parts = test coverage-test coverage-report
[test]
recipe = zc.recipe.testrunner
eggs = zope.browserresource [test,zcml]
[coverage-test]
recipe = zc.recipe.testrunner
eggs = zope.browserresource [test]
defaults = ['--coverage', '../../coverage']
[coverage-report]
recipe = zc.recipe.egg
eggs = z3c.coverage
scripts = coverage=coverage-report
arguments = ('coverage', 'coverage/report')
zope.browserresource-3.12.0/CHANGES.txt 0000644 0000000 0000000 00000006417 11501731204 015745 0 ustar 0000000 0000000 =======
CHANGES
=======
3.12.0 (2010-12-14)
===================
- Added ``zcml`` extra dependencies and fixed dependencies of
``configure.zcml`` on other packages' ``meta.zcml``.
- Added a test for including our own ``configure.zcml``.
3.11.0 (2010-08-13)
===================
- Support the HTTP ETag header for file resources. ETag generation can be
customized or disabled by providing an IETag multi-adapter on
(IFileResource, your-application-skin).
3.10.3 (2010-04-30)
===================
- Prefer the standard libraries doctest module to the one from zope.testing.
3.10.2 (2009-11-25)
===================
- The previous release had a broken egg, sorry.
3.10.1 (2009-11-24)
===================
- Import hooks functionality from zope.component after it was moved there from
zope.site. This lifts the dependency on zope.site and thereby, ZODB.
- Import ISite and IPossibleSite from zope.component after they were moved
there from zope.location.
3.10.0 (2009-09-25)
===================
- Add an ability to forbid publishing of some files in the resource directory,
this is done by fnmatch'ing the wildcards in the ``forbidden_names``class
attribute of ``DirectoryResource``. By default, the ``.svn`` is in that
attribute, so directories won't publish subversion system directory that can
contain private information.
3.9.0 (2009-08-27)
==================
Initial release. This package was splitted off zope.app.publisher as a part
of refactoring process.
Additional changes that are made during refactoring:
* Resource class for file resources are now selected the pluggable way.
The resource directory publisher and browser:resource ZCML directive
now creating file resources using factory utility lookup based on the
file extension, so it's now possible to add new resource types without
introducing new ZCML directives and they will work inside resource
directories as well.
NOTE: the "resource_factories" attribute from the DirectoryResource
was removed, so if you were using this attribute for changing resource
classes for some file extensions, you need to migrate your code to new
utility-based mechanism.
See zope.browserresource.interfaces.IResourceFactoryFactory interface.
* The Image resource class was removed, as they are actually simple files.
To migrate, simply rename the "image" argument in browser:resource and
browser:i18n-resource directives to "file", if you don't do this, resouces
will work, but you'll get deprecation warnings.
If you need custom behaviour for images, you can register a resource
factory utility for needed file extensions.
* The PageTemplateResource was moved into a separate package, "zope.ptresource",
which is a plugin for this package now. Because of that, the "template"
argument of browser:resource directive was deprecated and you should rename
it to "file" to migrate. The PageTemplateResource will be created for
"pt", "zpt" and "html" files automatically, if zope.ptresource package is
included in your configuration.
* Fix stripping the "I" from an interface name for icon title, if no
title is specified.
* When publishing a resource via Resources view, set resource parent
to an ISite object, not to current site manager.
* Clean up code and improve test coverage.
zope.browserresource-3.12.0/COPYRIGHT.txt 0000644 0000000 0000000 00000000040 11370317146 016240 0 ustar 0000000 0000000 Zope Foundation and Contributors zope.browserresource-3.12.0/LICENSE.txt 0000644 0000000 0000000 00000004026 11370317146 015762 0 ustar 0000000 0000000 Zope Public License (ZPL) Version 2.1
A copyright notice accompanies this license document that identifies the
copyright holders.
This license has been certified as open source. It has also been designated as
GPL compatible by the Free Software Foundation (FSF).
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions in source code must retain the accompanying copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the accompanying copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Names of the copyright holders must not be used to endorse or promote
products derived from this software without prior written permission from the
copyright holders.
4. The right to distribute this software or to use it for any purpose does not
give you the right to use Servicemarks (sm) or Trademarks (tm) of the
copyright
holders. Use of them is covered by separate agreement with the copyright
holders.
5. If any files are modified, you must cause the modified files to carry
prominent notices stating that you changed the files and the date of any
change.
Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
zope.browserresource-3.12.0/PKG-INFO 0000644 0000000 0000000 00000016735 11501731312 015235 0 ustar 0000000 0000000 Metadata-Version: 1.0
Name: zope.browserresource
Version: 3.12.0
Summary: Browser resources implementation for Zope.
Home-page: http://pypi.python.org/pypi/zope.browserresource/
Author: Zope Foundation and Contributors
Author-email: zope-dev@zope.org
License: ZPL 2.1
Description: ========
Overview
========
*This package is at present not reusable without depending on a large
chunk of the Zope Toolkit and its assumptions. It is maintained by the*
`Zope Toolkit project `_.
This package provides an implementation of browser resources. It also
provides directives for defining those resources using ZCML.
Resources are static files and directories that are served to the browser
directly from the filesystem. The most common example are images, CSS style
sheets, or JavaScript files.
Resources are be registered under a symbolic name and can later be referred to
by that name, so their usage is independent from their physical location.
You can register a single file with the `` directive, and a
whole directory with the `` directive, for example
This causes a named adapter to be registered that adapts the request to
zope.interface.Interface (XXX why do we not use an explicit interface?),
so to later retrieve a resource, use
`zope.component.getAdapter(request, name='myfile')`.
There are two ways to traverse to a resource,
1. with the 'empty' view on a site, e. g. `http://localhost/@@/myfile`
(This is declared by zope.browserresource)
2. with the `++resource++` namespace, e. g. `http://localhost/++resource++myfile`
(This is declared by zope.traversing.namespace)
In case of resource-directories traversal simply continues through its contents,
e. g. `http://localhost/@@/main-images/subdir/sample.jpg`
Rather than putting together the URL to a resource manually, you should use
zope.traversing.browser.interfaces.IAbsoluteURL to get the URL, or for a
shorthand, call the resource object. This has an additional benefit:
If you want to serve resources from a different URL, for example
because you want to use a web server specialized in serving static files instead
of the appserver, you can register an IAbsoluteURL adapter for the site under
the name 'resource' that will be used to compute the base URLs for resources.
For example, if you register 'http://static.example.com/' as the base 'resource'
URL, the resources from the above example would yield the following absolute
URLs: http://static.example.com/@@/myfile and
http://static.example.com/@@/main-images
=======
CHANGES
=======
3.12.0 (2010-12-14)
===================
- Added ``zcml`` extra dependencies and fixed dependencies of
``configure.zcml`` on other packages' ``meta.zcml``.
- Added a test for including our own ``configure.zcml``.
3.11.0 (2010-08-13)
===================
- Support the HTTP ETag header for file resources. ETag generation can be
customized or disabled by providing an IETag multi-adapter on
(IFileResource, your-application-skin).
3.10.3 (2010-04-30)
===================
- Prefer the standard libraries doctest module to the one from zope.testing.
3.10.2 (2009-11-25)
===================
- The previous release had a broken egg, sorry.
3.10.1 (2009-11-24)
===================
- Import hooks functionality from zope.component after it was moved there from
zope.site. This lifts the dependency on zope.site and thereby, ZODB.
- Import ISite and IPossibleSite from zope.component after they were moved
there from zope.location.
3.10.0 (2009-09-25)
===================
- Add an ability to forbid publishing of some files in the resource directory,
this is done by fnmatch'ing the wildcards in the ``forbidden_names``class
attribute of ``DirectoryResource``. By default, the ``.svn`` is in that
attribute, so directories won't publish subversion system directory that can
contain private information.
3.9.0 (2009-08-27)
==================
Initial release. This package was splitted off zope.app.publisher as a part
of refactoring process.
Additional changes that are made during refactoring:
* Resource class for file resources are now selected the pluggable way.
The resource directory publisher and browser:resource ZCML directive
now creating file resources using factory utility lookup based on the
file extension, so it's now possible to add new resource types without
introducing new ZCML directives and they will work inside resource
directories as well.
NOTE: the "resource_factories" attribute from the DirectoryResource
was removed, so if you were using this attribute for changing resource
classes for some file extensions, you need to migrate your code to new
utility-based mechanism.
See zope.browserresource.interfaces.IResourceFactoryFactory interface.
* The Image resource class was removed, as they are actually simple files.
To migrate, simply rename the "image" argument in browser:resource and
browser:i18n-resource directives to "file", if you don't do this, resouces
will work, but you'll get deprecation warnings.
If you need custom behaviour for images, you can register a resource
factory utility for needed file extensions.
* The PageTemplateResource was moved into a separate package, "zope.ptresource",
which is a plugin for this package now. Because of that, the "template"
argument of browser:resource directive was deprecated and you should rename
it to "file" to migrate. The PageTemplateResource will be created for
"pt", "zpt" and "html" files automatically, if zope.ptresource package is
included in your configuration.
* Fix stripping the "I" from an interface name for icon title, if no
title is specified.
* When publishing a resource via Resources view, set resource parent
to an ISite object, not to current site manager.
* Clean up code and improve test coverage.
Platform: UNKNOWN
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: Zope3
zope.browserresource-3.12.0/README.txt 0000644 0000000 0000000 00000004643 11244531310 015631 0 ustar 0000000 0000000 ========
Overview
========
*This package is at present not reusable without depending on a large
chunk of the Zope Toolkit and its assumptions. It is maintained by the*
`Zope Toolkit project `_.
This package provides an implementation of browser resources. It also
provides directives for defining those resources using ZCML.
Resources are static files and directories that are served to the browser
directly from the filesystem. The most common example are images, CSS style
sheets, or JavaScript files.
Resources are be registered under a symbolic name and can later be referred to
by that name, so their usage is independent from their physical location.
You can register a single file with the `` directive, and a
whole directory with the `` directive, for example
This causes a named adapter to be registered that adapts the request to
zope.interface.Interface (XXX why do we not use an explicit interface?),
so to later retrieve a resource, use
`zope.component.getAdapter(request, name='myfile')`.
There are two ways to traverse to a resource,
1. with the 'empty' view on a site, e. g. `http://localhost/@@/myfile`
(This is declared by zope.browserresource)
2. with the `++resource++` namespace, e. g. `http://localhost/++resource++myfile`
(This is declared by zope.traversing.namespace)
In case of resource-directories traversal simply continues through its contents,
e. g. `http://localhost/@@/main-images/subdir/sample.jpg`
Rather than putting together the URL to a resource manually, you should use
zope.traversing.browser.interfaces.IAbsoluteURL to get the URL, or for a
shorthand, call the resource object. This has an additional benefit:
If you want to serve resources from a different URL, for example
because you want to use a web server specialized in serving static files instead
of the appserver, you can register an IAbsoluteURL adapter for the site under
the name 'resource' that will be used to compute the base URLs for resources.
For example, if you register 'http://static.example.com/' as the base 'resource'
URL, the resources from the above example would yield the following absolute
URLs: http://static.example.com/@@/myfile and
http://static.example.com/@@/main-images
zope.browserresource-3.12.0/setup.cfg 0000644 0000000 0000000 00000000073 11501731312 015745 0 ustar 0000000 0000000 [egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
zope.browserresource-3.12.0/setup.py 0000644 0000000 0000000 00000004503 11501731254 015645 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2007 Zope Foundation 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.
#
##############################################################################
"""zope.browserresource setup
"""
from setuptools import setup, find_packages
long_description = (open('README.txt').read() + '\n\n' +
open('CHANGES.txt').read())
setup(name='zope.browserresource',
version = '3.12.0',
url='http://pypi.python.org/pypi/zope.browserresource/',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
classifiers = ['Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Framework :: Zope3',
],
description='Browser resources implementation for Zope.',
long_description=long_description,
license='ZPL 2.1',
packages=find_packages('src'),
package_dir={'': 'src'},
namespace_packages=['zope'],
include_package_data=True,
install_requires=['setuptools',
'zope.component>=3.8.0',
'zope.configuration',
'zope.contenttype',
'zope.i18n',
'zope.interface',
'zope.location',
'zope.publisher>=3.8',
'zope.schema',
'zope.traversing>3.7',
],
extras_require={
'test': ['zope.testing'],
'zcml': ['zope.component[zcml]',
'zope.security[zcml]>=3.8'],
},
zip_safe = False,
)
zope.browserresource-3.12.0/src/zope/__init__.py 0000644 0000000 0000000 00000000070 11244217222 020001 0 ustar 0000000 0000000 __import__('pkg_resources').declare_namespace(__name__)
zope.browserresource-3.12.0/src/zope/browserresource/__init__.py 0000644 0000000 0000000 00000000000 11244217222 023225 0 ustar 0000000 0000000 zope.browserresource-3.12.0/src/zope/browserresource/configure.zcml 0000644 0000000 0000000 00000002134 11445370374 024011 0 ustar 0000000 0000000
zope.browserresource-3.12.0/src/zope/browserresource/directory.py 0000644 0000000 0000000 00000010060 11401613004 023472 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation 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 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.
"""
import fnmatch
import os
from zope.component import queryUtility
from zope.interface import implements, classProvides
from zope.publisher.browser import BrowserView
from zope.publisher.interfaces import NotFound
from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.browserresource.file import FileResourceFactory
from zope.browserresource.resource import Resource
from zope.browserresource.interfaces import IResourceFactory
from zope.browserresource.interfaces import IResourceFactoryFactory
_marker = object()
def empty():
return ''
# 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)
default_factory = FileResourceFactory
directory_factory = None # this will be assigned later in the module
forbidden_names = ('.svn', )
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):
for pat in self.forbidden_names:
if fnmatch.fnmatch(name, pat):
if default is _marker:
raise NotFound(None, name)
else:
return default
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][1:]
factory = queryUtility(IResourceFactoryFactory, ext,
self.default_factory)
else:
factory = self.directory_factory
rname = self.__name__ + '/' + name
resource = factory(filename, self.context.checker, rname)(self.request)
resource.__parent__ = self
return resource
class DirectoryResourceFactory(object):
implements(IResourceFactory)
classProvides(IResourceFactoryFactory)
factoryClass = DirectoryResource
def __init__(self, path, checker, name):
self.__dir = Directory(path, checker, name)
self.__checker = checker
self.__name = name
def __call__(self, request):
resource = self.factoryClass(self.__dir, request)
resource.__Security_checker__ = self.__checker
resource.__name__ = self.__name
return resource
DirectoryResource.directory_factory = DirectoryResourceFactory
zope.browserresource-3.12.0/src/zope/browserresource/file.py 0000644 0000000 0000000 00000023775 11431247212 022435 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation 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.
#
##############################################################################
"""File-based browser resources.
"""
import os
import time
import re
try:
from email.utils import formatdate, parsedate_tz, mktime_tz
except ImportError: # python 2.4
from email.Utils import formatdate, parsedate_tz, mktime_tz
from zope.contenttype import guess_content_type
from zope.interface import implements, classProvides
from zope.component import adapts, getMultiAdapter
from zope.publisher.browser import BrowserView
from zope.publisher.interfaces import NotFound
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.browserresource.resource import Resource
from zope.browserresource.interfaces import IETag
from zope.browserresource.interfaces import IFileResource
from zope.browserresource.interfaces import IResourceFactory
from zope.browserresource.interfaces import IResourceFactoryFactory
ETAG_RX = re.compile(r'[*]|(?:W/)?"(?:[^"\\]|[\\].)*"')
def parse_etags(value):
r"""Parse a list of entity tags.
HTTP/1.1 specifies the following syntax for If-Match/If-None-Match
headers::
If-Match = "If-Match" ":" ( "*" | 1#entity-tag )
If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )
entity-tag = [ weak ] opaque-tag
weak = "W/"
opaque-tag = quoted-string
quoted-string = ( <"> *(qdtext) <"> )
qdtext = >
The backslash character ("\") may be used as a single-character
quoting mechanism only within quoted-string and comment constructs.
Examples:
>>> parse_etags('*')
['*']
>>> parse_etags(r' "qwerty", ,"foo",W/"bar" , "baz","\""')
['"qwerty"', '"foo"', 'W/"bar"', '"baz"', '"\\""']
Ill-formed headers are ignored
>>> parse_etags("not an etag at all")
[]
"""
return ETAG_RX.findall(value)
def etag_matches(etag, tags):
"""Check if the entity tag matches any of the given tags.
>>> etag_matches('"xyzzy"', ['"abc"', '"xyzzy"', 'W/"woof"'])
True
>>> etag_matches('"woof"', ['"abc"', 'W/"woof"'])
False
>>> etag_matches('"xyzzy"', ['*'])
True
Note that you pass quoted etags in both arguments!
"""
for tag in tags:
if tag == etag or tag == '*':
return True
return False
def quote_etag(etag):
r"""Quote an etag value
>>> quote_etag("foo")
'"foo"'
Special characters are escaped
>>> quote_etag('"')
'"\\""'
>>> quote_etag('\\')
'"\\\\"'
"""
return '"%s"' % etag.replace('\\', '\\\\').replace('"', '\\"')
class File(object):
def __init__(self, path, name):
self.path = path
self.__name__ = name
f = open(path, 'rb')
self.data = f.read()
f.close()
self.content_type = guess_content_type(path, self.data)[0]
self.lmt = float(os.path.getmtime(path)) or time.time()
self.lmh = formatdate(self.lmt, usegmt=True)
class FileResource(BrowserView, Resource):
implements(IFileResource, IBrowserPublisher)
cacheTimeout = 86400
def publishTraverse(self, request, name):
'''File resources can't be traversed further, so raise NotFound if
someone tries to traverse it.
>>> factory = FileResourceFactory(testFilePath, nullChecker, 'test.txt')
>>> request = TestRequest()
>>> resource = factory(request)
>>> resource.publishTraverse(request, '_testData')
Traceback (most recent call last):
...
NotFound: Object: None, name: '_testData'
'''
raise NotFound(None, name)
def browserDefault(self, request):
'''Return a callable for processing browser requests.
>>> factory = FileResourceFactory(testFilePath, nullChecker, 'test.txt')
>>> request = TestRequest(REQUEST_METHOD='GET')
>>> resource = factory(request)
>>> view, next = resource.browserDefault(request)
>>> view() == open(testFilePath, 'rb').read()
True
>>> next == ()
True
>>> request = TestRequest(REQUEST_METHOD='HEAD')
>>> resource = factory(request)
>>> view, next = resource.browserDefault(request)
>>> view() == ''
True
>>> next == ()
True
'''
return getattr(self, request.method), ()
def chooseContext(self):
'''Choose the appropriate context.
This method can be overriden in subclasses, that need to choose
appropriate file, based on current request or other condition,
like, for example, i18n files.
'''
return self.context
def GET(self):
'''Return a file data for downloading with GET requests
>>> factory = FileResourceFactory(testFilePath, nullChecker, 'test.txt')
>>> request = TestRequest()
>>> resource = factory(request)
>>> resource.GET() == open(testFilePath, 'rb').read()
True
>>> request.response.getHeader('Content-Type') == 'text/plain'
True
'''
file = self.chooseContext()
request = self.request
response = request.response
etag = getMultiAdapter((self, request), IETag)(file.lmt, file.data)
setCacheControl(response, self.cacheTimeout)
can_return_304 = False
all_cache_checks_passed = True
# 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:
can_return_304 = True
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(mktime_tz(parsedate_tz(header)))
except:
mod_since = None
if getattr(file, 'lmt', None):
last_mod = long(file.lmt)
else:
last_mod = 0L
if mod_since is None or last_mod <= 0 or last_mod > mod_since:
all_cache_checks_passed = False
# HTTP If-None-Match header handling
header = request.getHeader('If-None-Match', None)
if header is not None:
can_return_304 = True
tags = parse_etags(header)
if not etag or not etag_matches(quote_etag(etag), tags):
all_cache_checks_passed = False
# 304 responses MUST contain ETag, if one would've been sent with
# a 200 response
if etag:
response.setHeader('ETag', quote_etag(etag))
if can_return_304 and all_cache_checks_passed:
response.setStatus(304)
return ''
# 304 responses SHOULD NOT or MUST NOT include other entity headers,
# depending on whether the conditional GET used a strong or a weak
# validator. We only use strong validators, which makes it SHOULD
# NOT.
response.setHeader('Content-Type', file.content_type)
response.setHeader('Last-Modified', file.lmh)
return file.data
def HEAD(self):
'''Return proper headers and no content for HEAD requests
>>> factory = FileResourceFactory(testFilePath, nullChecker, 'test.txt')
>>> request = TestRequest()
>>> resource = factory(request)
>>> resource.HEAD() == ''
True
>>> request.response.getHeader('Content-Type') == 'text/plain'
True
'''
file = self.chooseContext()
etag = getMultiAdapter((self, self.request), IETag)(file.lmt, file.data)
response = self.request.response
response.setHeader('Content-Type', file.content_type)
response.setHeader('Last-Modified', file.lmh)
if etag:
response.setHeader('ETag', etag)
setCacheControl(response, self.cacheTimeout)
return ''
# for unit tests
def _testData(self):
f = open(self.context.path, 'rb')
data = f.read()
f.close()
return data
class FileETag(object):
adapts(IFileResource, IBrowserRequest)
implements(IETag)
def __init__(self, context, request):
self.context = context
self.request = request
def __call__(self, mtime, content):
return '%s-%s' % (mtime, len(content))
def setCacheControl(response, secs=86400):
# Cache for one day by default
response.setHeader('Cache-Control', 'public,max-age=%s' % secs)
t = time.time() + secs
response.setHeader('Expires', formatdate(t, usegmt=True))
class FileResourceFactory(object):
resourceClass = FileResource
implements(IResourceFactory)
classProvides(IResourceFactoryFactory)
def __init__(self, path, checker, name):
self.__file = File(path, name)
self.__checker = checker
self.__name = name
def __call__(self, request):
resource = self.resourceClass(self.__file, request)
resource.__Security_checker__ = self.__checker
resource.__name__ = self.__name
return resource
zope.browserresource-3.12.0/src/zope/browserresource/i18nfile.py 0000644 0000000 0000000 00000005201 11401613004 023106 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation 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.
#
##############################################################################
"""Internationalized file resource.
"""
from zope.i18n.interfaces import II18nAware
from zope.i18n.negotiator import negotiator
from zope.interface import implements, classProvides
from zope.browserresource.file import FileResource
from zope.browserresource.interfaces import IResourceFactory
from zope.browserresource.interfaces import IResourceFactoryFactory
class I18nFileResource(FileResource):
implements(II18nAware)
def __init__(self, data, request, defaultLanguage='en'):
"""Creates an internationalized file resource. data should be
a mapping from languages to File objects.
"""
self._data = data
self.request = request
self.defaultLanguage = defaultLanguage
def chooseContext(self):
"""Choose the appropriate context according to language"""
langs = self.getAvailableLanguages()
language = negotiator.getLanguage(langs, self.request)
try:
return self._data[language]
except KeyError:
return self._data[self.defaultLanguage]
def getDefaultLanguage(self):
'See II18nAware'
return self.defaultLanguage
def setDefaultLanguage(self, language):
'See II18nAware'
if language not in self._data:
raise ValueError(
'cannot set nonexistent language (%s) as default' % language)
self.defaultLanguage = language
def getAvailableLanguages(self):
'See II18nAware'
return self._data.keys()
# for unit tests
def _testData(self, language):
file = self._data[language]
f=open(file.path,'rb')
data=f.read()
f.close()
return data
class I18nFileResourceFactory(object):
implements(IResourceFactory)
classProvides(IResourceFactoryFactory)
def __init__(self, data, defaultLanguage):
self.__data = data
self.__defaultLanguage = defaultLanguage
def __call__(self, request):
return I18nFileResource(self.__data, request, self.__defaultLanguage)
zope.browserresource-3.12.0/src/zope/browserresource/icon.py 0000644 0000000 0000000 00000003260 11401613004 022422 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation 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.
#
##############################################################################
"""Icon support
"""
import zope.component.hooks
from zope.component import getAdapter
from zope.location import locate
class IconView(object):
def __init__(self, context, request, rname, alt, width, height):
self.context = context
self.request = request
self.rname = rname
self.alt = alt
self.width = width
self.height = height
def __call__(self):
return ('
'
% (self.url(), self.alt, self.width, self.height))
def url(self):
resource = getAdapter(self.request, name=self.rname)
locate(resource, zope.component.hooks.getSite(), self.rname)
return resource()
class IconViewFactory(object):
def __init__(self, rname, alt, width, height):
self.rname = rname
self.alt = alt
self.width = width
self.height = height
def __call__(self, context, request):
return IconView(context, request, self.rname, self.alt,
self.width, self.height)
zope.browserresource-3.12.0/src/zope/browserresource/interfaces.py 0000644 0000000 0000000 00000003404 11431247212 023624 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2009 Zope Foundation 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 interfaces
"""
from zope.interface import Interface, Attribute
class IResource(Interface):
request = Attribute('Request object that is requesting the resource')
def __call__():
"""return the absolute URL of this resource."""
class IFileResource(IResource):
pass
class IResourceFactory(Interface):
def __call__(request):
"""Return an IResource object"""
class IResourceFactoryFactory(Interface):
"""A factory for IResourceFactory objects
These factories are registered as named utilities that can be selected
for creating resource factories in a pluggable way.
Resource directories and browser:resource directive use these utilities
to choose what resource to create, depending on the file extension, so
third-party packages could easily plug-in additional resource types.
"""
def __call__(path, checker, name):
"""Return an IResourceFactory"""
class IETag(Interface):
"""An adapter for computing resource ETags."""
def __call__(mtime, content):
"""Compute an ETag for a resource.
May return None to disable the ETag header.
"""
zope.browserresource-3.12.0/src/zope/browserresource/meta.zcml 0000644 0000000 0000000 00000001705 11244220740 022745 0 ustar 0000000 0000000
zope.browserresource-3.12.0/src/zope/browserresource/metaconfigure.py 0000644 0000000 0000000 00000022156 11401613004 024327 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation 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.
#
##############################################################################
"""ZCML directive handlers for browser resources
"""
import os
from zope.component import queryUtility
from zope.component.interface import provideInterface
from zope.component.zcml import handler
from zope.configuration.exceptions import ConfigurationError
from zope.interface import Interface, implements, classProvides
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.publisher.interfaces.browser import IDefaultBrowserLayer
from zope.security.checker import CheckerPublic, NamesChecker, Checker
from zope.security.proxy import Proxy
from zope.browserresource.directory import DirectoryResourceFactory
from zope.browserresource.file import File, FileResourceFactory
from zope.browserresource.i18nfile import I18nFileResourceFactory
from zope.browserresource.icon import IconViewFactory
from zope.browserresource.interfaces import IResourceFactory
from zope.browserresource.interfaces import IResourceFactoryFactory
allowed_names = ('GET', 'HEAD', 'publishTraverse', 'browserDefault',
'request', '__call__')
class ResourceFactoryWrapper(object):
implements(IResourceFactory)
classProvides(IResourceFactoryFactory)
def __init__(self, factory, checker, name):
self.__factory = factory
self.__checker = checker
self.__name = name
def __call__(self, request):
resource = self.__factory(request)
resource.__Security_checker__ = self.__checker
resource.__name__ = self.__name
return resource
def resource(_context, name, layer=IDefaultBrowserLayer,
permission='zope.Public', factory=None,
file=None, image=None, template=None):
if permission == 'zope.Public':
permission = CheckerPublic
checker = NamesChecker(allowed_names, permission)
if (factory and (file or image or template)) or \
(file and (factory or image or template)) or \
(image and (factory or file or template)) or \
(template and (factory or file or image)):
raise ConfigurationError(
"Must use exactly one of factory or file or image or template"
" attributes for resource directives"
)
if image or template:
import warnings
warnings.warn_explicit(
'The "template" and "image" attributes of resource '
'directive are deprecated in favor of pluggable '
'file resource factories based on file extensions. '
'Use the "file" attribute instead.',
DeprecationWarning,
_context.info.file, _context.info.line)
if image:
file = image
elif template:
file = template
_context.action(
discriminator = ('resource', name, IBrowserRequest, layer),
callable = resourceHandler,
args = (name, layer, checker, factory, file, _context.info),
)
def resourceHandler(name, layer, checker, factory, file, context_info):
if factory is not None:
factory = ResourceFactoryWrapper(factory, checker, name)
else:
ext = os.path.splitext(os.path.normcase(file))[1][1:]
factory_factory = queryUtility(IResourceFactoryFactory, ext,
FileResourceFactory)
factory = factory_factory(file, checker, name)
handler('registerAdapter', factory, (layer,), Interface, name, context_info)
def resourceDirectory(_context, name, directory, layer=IDefaultBrowserLayer,
permission='zope.Public'):
if permission == 'zope.Public':
permission = CheckerPublic
checker = NamesChecker(allowed_names + ('__getitem__', 'get'),
permission)
if not os.path.isdir(directory):
raise ConfigurationError(
"Directory %s does not exist" % directory
)
factory = DirectoryResourceFactory(directory, checker, name)
_context.action(
discriminator = ('resource', name, IBrowserRequest, layer),
callable = handler,
args = ('registerAdapter',
factory, (layer,), Interface, name, _context.info),
)
def icon(_context, name, for_, file=None, resource=None,
layer=IDefaultBrowserLayer, title=None,
width=16, height=16):
iname = for_.getName()
if title is None:
title = iname
if title.startswith('I'):
title = title[1:] # Remove leading 'I'
if file is not None and resource is not None:
raise ConfigurationError(
"Can't use more than one of file, and resource "
"attributes for icon directives"
)
elif file is not None:
resource = '-'.join(for_.__module__.split('.'))
resource = "%s-%s-%s" % (resource, iname, name)
ext = os.path.splitext(file)[1]
if ext:
resource += ext
# give this module another name, so we can use the "resource" directive
# in it that won't conflict with our local variable with the same name.
from zope.browserresource import metaconfigure
metaconfigure.resource(_context, file=file, name=resource, layer=layer)
elif resource is None:
raise ConfigurationError(
"At least one of the file, and resource "
"attributes for resource directives must be specified"
)
vfactory = IconViewFactory(resource, title, width, height)
_context.action(
discriminator = ('view', name, vfactory, layer),
callable = handler,
args = ('registerAdapter',
vfactory, (for_, layer), Interface, name, _context.info)
)
_context.action(
discriminator = None,
callable = provideInterface,
args = (for_.__module__+'.'+for_.getName(),
for_)
)
class I18nResource(object):
type = IBrowserRequest
default_allowed_attributes = '__call__'
def __init__(self, _context, name=None, defaultLanguage='en',
layer=IDefaultBrowserLayer, permission=None):
self._context = _context
self.name = name
self.defaultLanguage = defaultLanguage
self.layer = layer
self.permission = permission
self.__data = {}
def translation(self, _context, language, file=None, image=None):
if file is not None and image is not None:
raise ConfigurationError(
"Can't use more than one of file, and image "
"attributes for resource directives"
)
elif file is None and image is None:
raise ConfigurationError(
"At least one of the file, and image "
"attributes for resource directives must be specified"
)
if image is not None:
import warnings
warnings.warn_explicit(
'The "image" attribute of i18n-resource directive is '
'deprecated in favor of simple files. Use the "file" '
'attribute instead.',
DeprecationWarning,
_context.info.file, _context.info.line)
file = image
self.__data[language] = File(_context.path(file), self.name)
def __call__(self, require = None):
if self.name is None:
return
if self.defaultLanguage not in self.__data:
raise ConfigurationError(
"A translation for the default language (%s) "
"must be specified" % self.defaultLanguage
)
permission = self.permission
factory = I18nFileResourceFactory(self.__data, self.defaultLanguage)
if permission:
if require is None:
require = {}
if permission == 'zope.Public':
permission = CheckerPublic
if require:
checker = Checker(require)
factory = self._proxyFactory(factory, checker)
self._context.action(
discriminator = ('i18n-resource', self.name, self.type, self.layer),
callable = handler,
args = ('registerAdapter',
factory, (self.layer,), Interface, self.name,
self._context.info)
)
def _proxyFactory(self, factory, checker):
def proxyView(request,
factory=factory, checker=checker):
resource = factory(request)
# We need this in case the resource gets unwrapped and
# needs to be rewrapped
resource.__Security_checker__ = checker
return Proxy(resource, checker)
return proxyView
zope.browserresource-3.12.0/src/zope/browserresource/metadirectives.py 0000644 0000000 0000000 00000016475 11401613004 024516 0 ustar 0000000 0000000 #############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation 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.
#
##############################################################################
"""ZCML directives for defining browser resources
"""
from zope.configuration.fields import GlobalObject, GlobalInterface
from zope.configuration.fields import Path, MessageID
from zope.interface import Interface
from zope.schema import TextLine, Int
from zope.security.zcml import Permission
class IBasicResourceInformation(Interface):
"""
This is the basic information for all browser resources.
"""
layer = GlobalInterface(
title=u"The layer the resource should be found in",
description=u"""
For information on layers, see the documentation for the skin
directive. Defaults to "default".""",
required=False
)
permission = Permission(
title=u"The permission needed to access the resource.",
description=u"""
If a permission isn't specified, the resource will always be
accessible.""",
required=False
)
class IResourceDirective(IBasicResourceInformation):
"""
Defines a browser resource
"""
name = TextLine(
title=u"The name of the resource",
description=u"""
This is the name used in resource urls. Resource urls are of
the form site/@@/resourcename, where site is the url of
"site", a folder with a site manager.
We make resource urls site-relative (as opposed to
content-relative) so as not to defeat caches.""",
required=True
)
factory = GlobalObject(
title=u"Resource Factory",
description=u"The factory used to create the resource. The factory "
u"should only expect to get the request passed when "
u"called.",
required=False
)
file = Path(
title=u"File",
description=u"The file containing the resource data. The resource "
u"type that will be created depends on file extension. "
u"The named IResourceFactoryFactory utilities are "
u"registered per extension. If no factory is registered "
u"for given file extension, the default FileResource "
u"factory will be used.",
required=False
)
image = Path(
title=u"Image",
description=u"""
If the image attribute is used, then an image resource, rather
than a file resource will be created.
This attribute is deprecated in favor of pluggable resource types,
registered per extension. Use the "file" attribute instead.
""",
required=False
)
template = Path(
title=u"Template",
description=u"""
If the template attribute is used, then a page template resource,
rather than a file resource will be created.
This attribute is deprecated in favor of pluggable resource types,
registered per extension. Use the "file" attribute instead. To
use page template resources, you need to instal zope.ptresource
package.
""",
required=False
)
class II18nResourceDirective(IBasicResourceInformation):
"""
Defines an i18n'd resource.
"""
name = TextLine(
title=u"The name of the resource",
description=u"""
This is the name used in resource urls. Resource urls are of
the form site/@@/resourcename, where site is the url of
"site", a folder with a site manager.
We make resource urls site-relative (as opposed to
content-relative) so as not to defeat caches.""",
required=True
)
defaultLanguage = TextLine(
title=u"Default language",
description=u"Defines the default language",
required=False
)
class II18nResourceTranslationSubdirective(IBasicResourceInformation):
"""
Subdirective to II18nResourceDirective.
"""
language = TextLine(
title=u"Language",
description=u"Language of this translation of the resource",
required=True
)
file = Path(
title=u"File",
description=u"The file containing the resource data.",
required=False
)
image = Path(
title=u"Image",
description=u"""
If the image attribute is used, then an image resource, rather
than a file resource will be created.
This attribute is deprecated, as images are now simply files.
Use the "file" attribute instead.
""",
required=False
)
class IResourceDirectoryDirective(IBasicResourceInformation):
"""
Defines a directory containing browser resource
"""
name = TextLine(
title=u"The name of the resource",
description=u"""
This is the name used in resource urls. Resource urls are of
the form site/@@/resourcename, where site is the url of
"site", a folder with a site manager.
We make resource urls site-relative (as opposed to
content-relative) so as not to defeat caches.""",
required=True
)
directory = Path(
title=u"Directory",
description=u"The directory containing the resource data.",
required=True
)
class IIconDirective(Interface):
"""
Define an icon for an interface
"""
name = TextLine(
title=u"The name of the icon.",
description=u"The name shows up in URLs/paths. For example 'foo'.",
required=True
)
for_ = GlobalInterface(
title=u"The interface this icon is for.",
description=u"""
The icon will be for all objects that implement this
interface.""",
required=True
)
file = Path(
title=u"File",
description=u"The file containing the icon.",
required=False
)
resource = TextLine(
title=u"Resource",
description=u"A resource containing the icon.",
required=False
)
title = MessageID(
title=u"Title",
description=u"Descriptive title",
required=False
)
layer = GlobalInterface(
title=u"The layer the icon should be found in",
description=u"""
For information on layers, see the documentation for the skin
directive. Defaults to "default".""",
required=False
)
width = Int(
title=u"The width of the icon.",
description=u"""
The width will be used for the
attribute. Defaults to 16.""",
required=False,
default=16
)
height = Int(
title=u"The height of the icon.",
description=u"""
The height will be used for the
attribute. Defaults to 16.""",
required=False,
default=16
)
zope.browserresource-3.12.0/src/zope/browserresource/resource.py 0000644 0000000 0000000 00000004075 11401613004 023326 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation 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 base class and AbsoluteURL adapter
"""
import zope.component.hooks
from zope.component import adapts, getMultiAdapter, queryMultiAdapter
from zope.interface import implements, implementsOnly
from zope.location import Location
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.traversing.browser.interfaces import IAbsoluteURL
import zope.traversing.browser.absoluteurl
from zope.browserresource.interfaces import IResource
class Resource(Location):
implements(IResource)
def __init__(self, request):
self.request = request
def __call__(self):
return str(getMultiAdapter((self, self.request), IAbsoluteURL))
class AbsoluteURL(zope.traversing.browser.absoluteurl.AbsoluteURL):
implementsOnly(IAbsoluteURL)
adapts(IResource, IBrowserRequest)
def __init__(self, context, request):
self.context = context
self.request = request
def _createUrl(self, baseUrl, name):
return "%s/@@/%s" % (baseUrl, name)
def __str__(self):
name = self.context.__name__
if name.startswith('++resource++'):
name = name[12:]
site = zope.component.hooks.getSite()
base = queryMultiAdapter((site, self.request), IAbsoluteURL,
name="resource")
if base is None:
url = str(getMultiAdapter((site, self.request), IAbsoluteURL))
else:
url = str(base)
return self._createUrl(url, name)
zope.browserresource-3.12.0/src/zope/browserresource/resources.py 0000644 0000000 0000000 00000007761 11401613004 023516 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation 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 URL access
"""
from zope.component import queryAdapter
from zope.interface import implements
from zope.location import locate
from zope.publisher.browser import BrowserView
from zope.publisher.interfaces import NotFound
from zope.publisher.interfaces.browser import IBrowserPublisher
class Resources(BrowserView):
"""A view that can be traversed further to access browser resources
This view is usually registered for zope.component.interfaces.ISite objects
with no name, so resources will be available at /@@/.
Let's test how it's traversed to get registered resources. Let's create
a sample resource class and register it.
>>> from zope.component import provideAdapter
>>> from zope.interface import Interface
>>> from zope.publisher.interfaces import NotFound
>>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
>>> from zope.publisher.browser import TestRequest
>>> class Resource(object):
... def __init__(self,request):
... self.request = request
... def __call__(self):
... return 'http://localhost/testresource'
>>> provideAdapter(Resource, (IDefaultBrowserLayer,), Interface, 'test')
Now, create a site and request objects and get the Resources object to
work with.
>>> site = object()
>>> request = TestRequest()
>>> resources = Resources(site, request)
Okay, let's test the publishTraverse method. It should traverse to our
registered resource.
>>> resource = resources.publishTraverse(request, 'test')
>>> resource.__parent__ is site
True
>>> resource.__name__ == 'test'
True
>>> resource()
'http://localhost/testresource'
However, it will raise NotFound exception if we try to traverse to an
unregistered resource.
>>> resources.publishTraverse(request, 'does-not-exist')
Traceback (most recent call last):
...
NotFound: Object: ,
name: 'does-not-exist'
When accessed without further traversing, it returns an empty page and no
futher traversing steps.
>>> view, path = resources.browserDefault(request)
>>> view() == ''
True
>>> path == ()
True
The Resources view also provides __getitem__ method for use in templates.
>>> resource = resources['test']
>>> resource.__parent__ is site
True
>>> resource.__name__ == 'test'
True
>>> resource()
'http://localhost/testresource'
"""
implements(IBrowserPublisher)
def publishTraverse(self, request, name):
'''See zope.publisher.interfaces.browser.IBrowserPublisher interface'''
resource = queryAdapter(request, name=name)
if resource is None:
raise NotFound(self, name)
locate(resource, self.context, name)
return resource
def browserDefault(self, request):
'''See zope.publisher.interfaces.browser.IBrowserPublisher interface'''
return empty, ()
def __getitem__(self, name):
'''A helper method to make this view usable from templates,
so resources can be acessed in template like context/@@/.
'''
return self.publishTraverse(self.request, name)
def empty():
return ''
zope.browserresource-3.12.0/src/zope/browserresource/tests/__init__.py 0000644 0000000 0000000 00000000000 11244456266 024404 0 ustar 0000000 0000000 zope.browserresource-3.12.0/src/zope/browserresource/tests/configure.txt 0000644 0000000 0000000 00000000760 11445374740 025031 0 ustar 0000000 0000000 Package configuration
=====================
The ``zope.browserresource`` package provides a ZCML file that configures some
adapters and views and a couple of security declarations:
>>> from zope.configuration.xmlconfig import XMLConfig
>>> import zope.browserresource
>>> XMLConfig('configure.zcml', zope.browserresource)()
>>> len(list(zope.component.getGlobalSiteManager().registeredUtilities()))
9
>>> len(list(zope.component.getGlobalSiteManager().registeredAdapters()))
3
zope.browserresource-3.12.0/src/zope/browserresource/tests/support.py 0000644 0000000 0000000 00000002631 11401613004 024351 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2004 Zope Foundation 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.
#
##############################################################################
"""Support for tests that need a simple site to be provided.
"""
import zope.component
import zope.component.hooks
import zope.component.interfaces
from zope.interface import implements
from zope.traversing.interfaces import IContainmentRoot
import zope.browserresource.resource
class Site:
implements(zope.component.interfaces.ISite, IContainmentRoot)
def getSiteManager(self):
return zope.component.getGlobalSiteManager()
site = Site()
class SiteHandler(object):
def setUp(self):
super(SiteHandler, self).setUp()
zope.component.hooks.setSite(site)
zope.component.provideAdapter(
zope.browserresource.resource.AbsoluteURL)
def tearDown(self):
zope.component.hooks.setSite()
super(SiteHandler, self).tearDown()
zope.browserresource-3.12.0/src/zope/browserresource/tests/test_configure.py 0000644 0000000 0000000 00000000376 11445374740 025704 0 ustar 0000000 0000000 from zope.component.testing import setUp, tearDown
import doctest
import unittest
def test_suite():
suite = unittest.TestSuite()
suite.addTest(doctest.DocFileSuite(
'configure.txt', setUp=setUp, tearDown=tearDown))
return suite
zope.browserresource-3.12.0/src/zope/browserresource/tests/test_directives.py 0000644 0000000 0000000 00000020261 11401613004 026034 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation 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.
#
##############################################################################
"""'browser' namespace directive tests
"""
import os
import unittest
from cStringIO import StringIO
from zope import component
from zope.interface import Interface, implements, directlyProvides, providedBy
import zope.security.management
from zope.configuration.xmlconfig import xmlconfig, XMLConfig
from zope.configuration.exceptions import ConfigurationError
from zope.publisher.browser import TestRequest
from zope.publisher.interfaces import IDefaultViewName
from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.publisher.interfaces.browser import IBrowserSkinType, IDefaultSkin
from zope.security.proxy import removeSecurityProxy, ProxyFactory
from zope.security.permission import Permission
from zope.security.interfaces import IPermission
from zope.traversing.adapters import DefaultTraversable
from zope.traversing.interfaces import ITraversable
import zope.publisher.defaultview
import zope.browserresource
from zope.component import provideAdapter, provideUtility
from zope.component.testfiles.views import R1, IV
from zope.browserresource.file import FileResource
from zope.browserresource.i18nfile import I18nFileResource
from zope.browserresource.directory import DirectoryResource
from zope.testing import cleanup
tests_path = os.path.join(
os.path.dirname(zope.browserresource.__file__),
'tests')
template = """
%s
"""
request = TestRequest()
class ITestLayer(IBrowserRequest):
"""Test Layer."""
class ITestSkin(ITestLayer):
"""Test Skin."""
class MyResource(object):
def __init__(self, request):
self.request = request
class Test(cleanup.CleanUp, unittest.TestCase):
def setUp(self):
super(Test, self).setUp()
XMLConfig('meta.zcml', zope.browserresource)()
provideAdapter(DefaultTraversable, (None,), ITraversable)
def tearDown(self):
super(Test, self).tearDown()
def testI18nResource(self):
self.assertEqual(component.queryAdapter(request, name='test'), None)
path1 = os.path.join(tests_path, 'testfiles', 'test.pt')
path2 = os.path.join(tests_path, 'testfiles', 'test2.pt')
xmlconfig(StringIO(template % (
'''
''' % (path1, path2)
)))
v = component.getAdapter(request, name='test')
self.assertEqual(
component.queryAdapter(request, name='test').__class__,
I18nFileResource)
self.assertEqual(v._testData('en'), open(path1, 'rb').read())
self.assertEqual(v._testData('fr'), open(path2, 'rb').read())
# translation must be provided for the default language
config = StringIO(template % (
'''
''' % (path1, path2)
))
self.assertRaises(ConfigurationError, xmlconfig, config)
def testFactory(self):
self.assertEqual(
component.queryAdapter(request, name='index.html'), None)
xmlconfig(StringIO(template %
'''
'''
))
r = component.getAdapter(request, name='index.html')
self.assertEquals(r.__class__, MyResource)
r = ProxyFactory(r)
self.assertEqual(r.__name__, "index.html")
def testFile(self):
path = os.path.join(tests_path, 'testfiles', 'test.pt')
self.assertEqual(component.queryAdapter(request, name='test'), None)
xmlconfig(StringIO(template %
'''
''' % path
))
r = component.getAdapter(request, name='index.html')
self.assertTrue(isinstance(r, FileResource))
r = ProxyFactory(r)
self.assertEqual(r.__name__, "index.html")
# Make sure we can access available attrs and not others
for n in ('GET', 'HEAD', 'publishTraverse', 'request', '__call__'):
getattr(r, n)
self.assertRaises(Exception, getattr, r, '_testData')
r = removeSecurityProxy(r)
self.assertEqual(r._testData(), open(path, 'rb').read())
def testPluggableFactory(self):
class ImageResource(object):
def __init__(self, image, request):
pass
class ImageResourceFactory(object):
def __init__(self, path, checker, name):
pass
def __call__(self, request):
return ImageResource(None, request)
from zope.browserresource.interfaces import IResourceFactoryFactory
component.provideUtility(ImageResourceFactory, IResourceFactoryFactory,
name='gif')
xmlconfig(StringIO(template %
'''
''' % os.path.join(tests_path, 'testfiles', 'test.gif')
))
r = component.getAdapter(request, name='test.gif')
self.assertTrue(isinstance(r, ImageResource))
def testDirectory(self):
path = os.path.join(tests_path, 'testfiles', 'subdir')
self.assertEqual(component.queryAdapter(request, name='dir'), None)
xmlconfig(StringIO(template %
'''
''' % path
))
r = component.getAdapter(request, name='dir')
self.assertTrue(isinstance(r, DirectoryResource))
r = ProxyFactory(r)
self.assertEqual(r.__name__, "dir")
# Make sure we can access available attrs and not others
for n in ('publishTraverse', 'browserDefault', 'request', '__call__',
'get', '__getitem__'):
getattr(r, n)
self.assertRaises(Exception, getattr, r, 'directory_factory')
inexistent_dir = StringIO(template %
'''
''')
self.assertRaises(ConfigurationError, xmlconfig, inexistent_dir)
def test_SkinResource(self):
self.assertEqual(component.queryAdapter(request, name='test'), None)
path = os.path.join(tests_path, 'testfiles', 'test.pt')
xmlconfig(StringIO(template % (
'''
''' % path
)))
self.assertEqual(component.queryAdapter(request, name='test'), None)
r = component.getAdapter(TestRequest(skin=ITestSkin), name='test')
self.assertEqual(r._testData(), open(path, 'rb').read())
def test_suite():
return unittest.makeSuite(Test)
zope.browserresource-3.12.0/src/zope/browserresource/tests/test_directory.py 0000644 0000000 0000000 00000014733 11401613004 025706 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation 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.
#
##############################################################################
"""Directory-based resources test
"""
import os
import tempfile
import shutil
from unittest import TestCase, main, makeSuite
from zope.publisher.interfaces import NotFound
from zope.proxy import isProxy
from zope.publisher.browser import TestRequest
from zope.security import proxy
from zope.security.checker import NamesChecker, ProxyFactory
from zope.interface import implements
from zope.location.interfaces import IContained
from zope.traversing.browser.absoluteurl import AbsoluteURL
from zope.traversing.browser.interfaces import IAbsoluteURL
from zope.component import provideAdapter, provideUtility
from zope.testing import cleanup
from zope.browserresource.directory import \
DirectoryResourceFactory, DirectoryResource
from zope.browserresource.file import FileResource
import zope.browserresource.tests as p
from zope.browserresource.tests import support
test_directory = os.path.dirname(p.__file__)
checker = NamesChecker(
('get', '__getitem__', 'request', 'publishTraverse')
)
class Ob(object):
implements(IContained)
__parent__ = __name__ = None
ob = Ob()
class Test(support.SiteHandler, cleanup.CleanUp, TestCase):
def setUp(self):
super(Test, self).setUp()
provideAdapter(AbsoluteURL, (None, None), IAbsoluteURL)
def testNotFound(self):
path = os.path.join(test_directory, 'testfiles')
request = TestRequest()
factory = DirectoryResourceFactory(path, checker, 'testfiles')
resource = factory(request)
self.assertRaises(NotFound, resource.publishTraverse,
resource.request, 'doesnotexist')
self.assertRaises(NotFound, resource.get, 'doesnotexist')
def testBrowserDefault(self):
path = os.path.join(test_directory, 'testfiles')
request = TestRequest()
factory = DirectoryResourceFactory(path, checker, 'testfiles')
resource = factory(request)
view, next = resource.browserDefault(request)
self.assertEquals(view(), '')
self.assertEquals(next, ())
def testGetitem(self):
path = os.path.join(test_directory, 'testfiles')
request = TestRequest()
factory = DirectoryResourceFactory(path, checker, 'testfiles')
resource = factory(request)
self.assertRaises(KeyError, resource.__getitem__, 'doesnotexist')
file = resource['test.txt']
def testForbiddenNames(self):
request = TestRequest()
old_forbidden_names = DirectoryResource.forbidden_names
path = tempfile.mkdtemp()
try:
os.mkdir(os.path.join(path, '.svn'))
open(os.path.join(path, 'test.txt'), 'w').write('')
factory = DirectoryResourceFactory(path, checker, 'testfiles')
resource = factory(request)
self.assertEquals(resource.get('.svn', None), None)
self.assertNotEquals(resource.get('test.txt', None), None)
DirectoryResource.forbidden_names = ('*.txt', )
self.assertEquals(resource.get('test.txt', None), None)
self.assertNotEquals(resource.get('.svn', None), None)
finally:
shutil.rmtree(path)
DirectoryResource.forbidden_names = old_forbidden_names
def testProxy(self):
path = os.path.join(test_directory, 'testfiles')
request = TestRequest()
factory = DirectoryResourceFactory(path, checker, 'testfiles')
resource = factory(request)
file = ProxyFactory(resource['test.txt'])
self.assert_(isProxy(file))
def testURL(self):
request = TestRequest()
request._vh_root = support.site
path = os.path.join(test_directory, 'testfiles')
files = DirectoryResourceFactory(path, checker, 'test_files')(request)
files.__parent__ = support.site
file = files['test.gif']
self.assertEquals(file(), 'http://127.0.0.1/@@/test_files/test.gif')
def testURL2Level(self):
request = TestRequest()
request._vh_root = support.site
ob.__parent__ = support.site
ob.__name__ = 'ob'
path = os.path.join(test_directory, 'testfiles')
files = DirectoryResourceFactory(path, checker, 'test_files')(request)
files.__parent__ = ob
file = files['test.gif']
self.assertEquals(file(), 'http://127.0.0.1/@@/test_files/test.gif')
def testURL3Level(self):
request = TestRequest()
request._vh_root = support.site
ob.__parent__ = support.site
ob.__name__ = 'ob'
path = os.path.join(test_directory, 'testfiles')
files = DirectoryResourceFactory(path, checker, 'test_files')(request)
files.__parent__ = ob
file = files['test.gif']
self.assertEquals(file(), 'http://127.0.0.1/@@/test_files/test.gif')
subdir = files['subdir']
self.assert_(proxy.isinstance(subdir, DirectoryResource))
file = subdir['test.gif']
self.assertEquals(file(),
'http://127.0.0.1/@@/test_files/subdir/test.gif')
def testPluggableFactories(self):
path = os.path.join(test_directory, 'testfiles')
request = TestRequest()
resource = DirectoryResourceFactory(path, checker, 'files')(request)
class ImageResource(object):
def __init__(self, image, request):
pass
class ImageResourceFactory(object):
def __init__(self, path, checker, name):
pass
def __call__(self, request):
return ImageResource(None, request)
from zope.browserresource.interfaces import IResourceFactoryFactory
provideUtility(ImageResourceFactory, IResourceFactoryFactory, 'gif')
image = resource['test.gif']
self.assert_(proxy.isinstance(image, ImageResource))
file = resource['test.txt']
self.assert_(proxy.isinstance(file, FileResource))
def test_suite():
return makeSuite(Test)
zope.browserresource-3.12.0/src/zope/browserresource/tests/test_file.py 0000644 0000000 0000000 00000021114 11431247212 024617 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation 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.
#
##############################################################################
"""File-based browser resource tests.
"""
import doctest
import os
import unittest
import time
try:
from email.utils import formatdate, parsedate_tz, mktime_tz
except ImportError: # python 2.4
from email.Utils import formatdate, parsedate_tz, mktime_tz
from zope.testing import cleanup
from zope.publisher.browser import TestRequest
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.security.checker import NamesChecker
from zope.component import provideAdapter, adapts
from zope.interface import implements
from zope.interface.verify import verifyObject
from zope.browserresource.file import FileResourceFactory, FileETag
from zope.browserresource.interfaces import IFileResource, IETag
class MyETag(object):
adapts(IFileResource, IBrowserRequest)
implements(IETag)
def __init__(self, context, request):
pass
def __call__(self, mtime, content):
return 'myetag'
class NoETag(object):
adapts(IFileResource, IBrowserRequest)
implements(IETag)
def __init__(self, context, request):
pass
def __call__(self, mtime, content):
return None
def setUp(test):
cleanup.setUp()
data_dir = os.path.join(os.path.dirname(__file__), 'testfiles')
test.globs['testFilePath'] = os.path.join(data_dir, 'test.txt')
test.globs['nullChecker'] = NamesChecker()
test.globs['TestRequest'] = TestRequest
provideAdapter(MyETag)
def tearDown(test):
cleanup.tearDown()
def doctest_FileETag():
"""Tests for FileETag
>>> etag_maker = FileETag(object(), TestRequest())
>>> verifyObject(IETag, etag_maker)
True
By default we constuct an ETag from the file's mtime and size
>>> etag_maker(1234, 'abc')
'1234-3'
"""
def doctest_FileResource_GET_sets_cache_headers():
"""Test caching headers set by FileResource.GET
>>> factory = FileResourceFactory(testFilePath, nullChecker, 'test.txt')
>>> timestamp = time.time()
>>> file = factory._FileResourceFactory__file # get mangled file
>>> file.lmt = timestamp
>>> file.lmh = formatdate(timestamp, usegmt=True)
>>> request = TestRequest()
>>> resource = factory(request)
>>> bool(resource.GET())
True
>>> request.response.getHeader('Last-Modified') == file.lmh
True
>>> request.response.getHeader('ETag')
'"myetag"'
>>> request.response.getHeader('Cache-Control')
'public,max-age=86400'
>>> bool(request.response.getHeader('Expires'))
True
"""
def doctest_FileResource_GET_if_modified_since():
"""Test If-Modified-Since header support
>>> factory = FileResourceFactory(testFilePath, nullChecker, 'test.txt')
>>> timestamp = time.time()
>>> file = factory._FileResourceFactory__file # get mangled file
>>> file.lmt = timestamp
>>> file.lmh = formatdate(timestamp, usegmt=True)
>>> before = timestamp - 1000
>>> request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(before, usegmt=True))
>>> resource = factory(request)
>>> bool(resource.GET())
True
>>> after = timestamp + 1000
>>> request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(after, usegmt=True))
>>> resource = factory(request)
>>> bool(resource.GET())
False
>>> request.response.getStatus()
304
Cache control headers and ETag are set on 304 responses
>>> request.response.getHeader('ETag')
'"myetag"'
>>> request.response.getHeader('Cache-Control')
'public,max-age=86400'
>>> bool(request.response.getHeader('Expires'))
True
Other entity headers are not
>>> request.response.getHeader('Last-Modified')
>>> request.response.getHeader('Content-Type')
It won't fail on bad If-Modified-Since headers.
>>> request = TestRequest(HTTP_IF_MODIFIED_SINCE='bad header')
>>> resource = factory(request)
>>> bool(resource.GET())
True
it also won't fail if we don't have a last modification time for the
resource
>>> file.lmt = None
>>> request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(after, usegmt=True))
>>> resource = factory(request)
>>> bool(resource.GET())
True
"""
def doctest_FileResource_GET_if_none_match():
"""Test If-None-Match header support
>>> factory = FileResourceFactory(testFilePath, nullChecker, 'test.txt')
>>> timestamp = time.time()
>>> file = factory._FileResourceFactory__file # get mangled file
>>> file.lmt = timestamp
>>> file.lmh = formatdate(timestamp, usegmt=True)
>>> request = TestRequest(HTTP_IF_NONE_MATCH='"othertag"')
>>> resource = factory(request)
>>> bool(resource.GET())
True
>>> request = TestRequest(HTTP_IF_NONE_MATCH='"myetag"')
>>> resource = factory(request)
>>> bool(resource.GET())
False
>>> request.response.getStatus()
304
Cache control headers and ETag are set on 304 responses
>>> request.response.getHeader('ETag')
'"myetag"'
>>> request.response.getHeader('Cache-Control')
'public,max-age=86400'
>>> bool(request.response.getHeader('Expires'))
True
Other entity headers are not
>>> request.response.getHeader('Last-Modified')
>>> request.response.getHeader('Content-Type')
It won't fail on bad If-None-Match headers.
>>> request = TestRequest(HTTP_IF_NONE_MATCH='bad header')
>>> resource = factory(request)
>>> bool(resource.GET())
True
it also won't fail if we don't have an etag for the resource
>>> provideAdapter(NoETag)
>>> request = TestRequest(HTTP_IF_NONE_MATCH='"someetag"')
>>> resource = factory(request)
>>> bool(resource.GET())
True
"""
def doctest_FileResource_GET_if_none_match_and_if_modified_since():
"""Test combined If-None-Match and If-Modified-Since header support
>>> factory = FileResourceFactory(testFilePath, nullChecker, 'test.txt')
>>> timestamp = time.time()
>>> file = factory._FileResourceFactory__file # get mangled file
>>> file.lmt = timestamp
>>> file.lmh = formatdate(timestamp, usegmt=True)
We've a match
>>> after = timestamp + 1000
>>> request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(after, usegmt=True),
... HTTP_IF_NONE_MATCH='"myetag"')
>>> resource = factory(request)
>>> bool(resource.GET())
False
>>> request.response.getStatus()
304
Last-modified matches, but ETag doesn't
>>> request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(after, usegmt=True),
... HTTP_IF_NONE_MATCH='"otheretag"')
>>> resource = factory(request)
>>> bool(resource.GET())
True
ETag matches but last-modified doesn't
>>> before = timestamp - 1000
>>> request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(before, usegmt=True),
... HTTP_IF_NONE_MATCH='"myetag"')
>>> resource = factory(request)
>>> bool(resource.GET())
True
Both don't match
>>> before = timestamp - 1000
>>> request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(before, usegmt=True),
... HTTP_IF_NONE_MATCH='"otheretag"')
>>> resource = factory(request)
>>> bool(resource.GET())
True
"""
def test_suite():
return unittest.TestSuite((
doctest.DocTestSuite(
'zope.browserresource.file',
setUp=setUp, tearDown=tearDown,
optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE),
doctest.DocTestSuite(
setUp=setUp, tearDown=tearDown,
optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE),
))
zope.browserresource-3.12.0/src/zope/browserresource/tests/test_i18nfile.py 0000644 0000000 0000000 00000013340 11431247212 025321 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation 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.
#
##############################################################################
"""I18n File-Resource Tests
"""
from unittest import main, makeSuite
import os
from zope.publisher.interfaces import NotFound
from zope.interface import implements
from zope.component import provideAdapter, provideUtility, adapts
from zope.testing import cleanup
from zope.i18n.interfaces import IUserPreferredCharsets, IUserPreferredLanguages
from zope.publisher.http import IHTTPRequest, HTTPCharsets
from zope.publisher.browser import BrowserLanguages, TestRequest
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.browserresource.interfaces import IFileResource, IETag
from zope.browserresource.i18nfile import I18nFileResource
from zope.browserresource.i18nfile import I18nFileResourceFactory
from zope.browserresource.file import File
import zope.browserresource.tests as p
from zope.i18n.interfaces import INegotiator
from zope.i18n.negotiator import negotiator
from zope.i18n.tests.testii18naware import TestII18nAware
test_directory = os.path.dirname(p.__file__)
class MyETag(object):
adapts(IFileResource, IBrowserRequest)
implements(IETag)
def __init__(self, context, request):
pass
def __call__(self, mtime, content):
return 'myetag'
class Test(cleanup.CleanUp, TestII18nAware):
def setUp(self):
super(Test, self).setUp()
TestII18nAware.setUp(self)
provideAdapter(HTTPCharsets, (IHTTPRequest,), IUserPreferredCharsets)
provideAdapter(BrowserLanguages, (IHTTPRequest,), IUserPreferredLanguages)
# Setup the negotiator utility
provideUtility(negotiator, INegotiator)
provideAdapter(MyETag)
def _createObject(self):
obj = I18nFileResource({'en':None, 'lt':None, 'fr':None},
TestRequest(), 'fr')
return obj
def test_setDefaultLanguage(self):
ob = self._createObject()
self.assertRaises(ValueError, ob.setDefaultLanguage, 'ru')
def _createDict(self, filename1='test.pt', filename2='test2.pt'):
path1 = os.path.join(test_directory, 'testfiles', filename1)
path2 = os.path.join(test_directory, 'testfiles', filename2)
return { 'en': File(path1, filename1),
'fr': File(path2, filename2) }
def testNoTraversal(self):
resource = I18nFileResourceFactory(self._createDict(), 'en')\
(TestRequest())
self.assertRaises(NotFound,
resource.publishTraverse,
resource.request,
'_testData')
def testFileGET(self):
# case 1: no language preference, should get en
path = os.path.join(test_directory, 'testfiles', 'test.txt')
resource = I18nFileResourceFactory(self._createDict('test.txt'), 'en')\
(TestRequest())
self.assertEqual(resource.GET(), open(path, 'rb').read())
response = resource.request.response
self.assertEqual(response.getHeader('Content-Type'), 'text/plain')
# case 2: prefer lt, have only en and fr, should get en
resource = I18nFileResourceFactory(
self._createDict('test.txt'), 'en')\
(TestRequest(HTTP_ACCEPT_LANGUAGE='lt'))
self.assertEqual(resource.GET(), open(path, 'rb').read())
response = resource.request.response
self.assertEqual(response.getHeader('Content-Type'), 'text/plain')
# case 3: prefer fr, have it, should get fr
path = os.path.join(test_directory, 'testfiles', 'test2.pt')
resource = I18nFileResourceFactory(
self._createDict('test.pt', 'test2.pt'), 'en')\
(TestRequest(HTTP_ACCEPT_LANGUAGE='fr'))
self.assertEqual(resource.GET(), open(path, 'rb').read())
response = resource.request.response
self.assertEqual(response.getHeader('Content-Type'), 'text/html')
def testFileHEAD(self):
# case 1: no language preference, should get en
resource = I18nFileResourceFactory(self._createDict('test.txt'), 'en')\
(TestRequest())
self.assertEqual(resource.HEAD(), '')
response = resource.request.response
self.assertEqual(response.getHeader('Content-Type'), 'text/plain')
# case 2: prefer lt, have only en and fr, should get en
resource = I18nFileResourceFactory(
self._createDict('test.txt'), 'en')\
(TestRequest(HTTP_ACCEPT_LANGUAGE='lt'))
self.assertEqual(resource.HEAD(), '')
response = resource.request.response
self.assertEqual(response.getHeader('Content-Type'), 'text/plain')
# case 3: prefer fr, have it, should get fr
resource = I18nFileResourceFactory(
self._createDict('test.pt', 'test2.pt'), 'en')\
(TestRequest(HTTP_ACCEPT_LANGUAGE='fr'))
self.assertEqual(resource.HEAD(), '')
response = resource.request.response
self.assertEqual(response.getHeader('Content-Type'), 'text/html')
def test_suite():
return makeSuite(Test)
zope.browserresource-3.12.0/src/zope/browserresource/tests/test_icondirective.py 0000644 0000000 0000000 00000016226 11401613004 026530 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation 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.
#
##############################################################################
"""Test Icon-Directive
"""
import os
from StringIO import StringIO
from unittest import TestCase, main, makeSuite
from zope import component
from zope.configuration.exceptions import ConfigurationError
from zope.configuration.xmlconfig import xmlconfig, XMLConfig
from zope.interface import implements
from zope.publisher.browser import TestRequest
from zope.security.checker import ProxyFactory, CheckerPublic
from zope.security.interfaces import Forbidden
from zope.security.proxy import removeSecurityProxy
from zope.traversing.interfaces import IContainmentRoot
from zope.traversing.browser.absoluteurl import AbsoluteURL
from zope.traversing.browser.interfaces import IAbsoluteURL
import zope.location.interfaces
import zope.browserresource
from zope.component.testfiles.views import IC
from zope.browserresource.tests import support
from zope.testing import cleanup
template = """
%s
"""
request = TestRequest()
class Ob(object):
implements(IC)
ob = Ob()
request._vh_root = support.site
def defineCheckers():
# define the appropriate checker for a FileResource for these tests
from zope.security.protectclass import protectName
from zope.browserresource.file import FileResource
protectName(FileResource, '__call__', 'zope.Public')
class Test(support.SiteHandler, cleanup.CleanUp, TestCase):
def setUp(self):
super(Test, self).setUp()
XMLConfig('meta.zcml', zope.browserresource)()
defineCheckers()
component.provideAdapter(AbsoluteURL, (None, None), IAbsoluteURL)
def test(self):
self.assertEqual(
component.queryMultiAdapter((ob, request), name='zmi_icon'),
None)
import zope.browserresource.tests as p
path = os.path.dirname(p.__file__)
path = os.path.join(path, 'testfiles', 'test.gif')
# Configure the icon and make sure we can render the resulting view:
xmlconfig(StringIO(template % (
'''
''' % path
)))
view = component.getMultiAdapter((ob, request), name='zmi_icon')
rname = 'zope-component-testfiles-views-IC-zmi_icon.gif'
self.assertEqual(
view(),
'
'
% rname)
self.assertEqual(view.url(), 'http://127.0.0.1/@@/' + rname)
# Make sure that the title attribute works
xmlconfig(StringIO(template % (
'''
''' % path
)))
view = component.getMultiAdapter(
(ob, request), name='zmi_icon_w_title')
rname = 'zope-component-testfiles-views-IC-zmi_icon_w_title.gif'
self.assertEqual(
view(),
'
'
% rname)
# Make sure that the width and height attributes work
xmlconfig(StringIO(template % (
'''
''' % path
)))
view = component.getMultiAdapter((ob, request),
name='zmi_icon_w_width_and_height')
rname = ('zope-component-testfiles-views-IC-'
'zmi_icon_w_width_and_height.gif')
self.assertEqual(
view(),
'
'
% rname)
# Make sure that the image was installed as a resource:
resource = ProxyFactory(component.getAdapter(request, name=rname))
self.assertRaises(Forbidden, getattr, resource, '_testData')
resource = removeSecurityProxy(resource)
self.assertEqual(resource._testData(), open(path, 'rb').read())
def testResource(self):
self.assertEqual(
component.queryMultiAdapter((ob, request), name='zmi_icon'), None)
import zope.browserresource.tests as p
path = os.path.dirname(p.__file__)
path = os.path.join(path, 'testfiles', 'test.gif')
xmlconfig(StringIO(template % (
'''
''' % path
)))
view = component.getMultiAdapter((ob, request), name='zmi_icon')
rname = "zmi_icon_res"
self.assertEqual(
view(),
'
'
% rname)
resource = ProxyFactory(component.getAdapter(request, name=rname))
self.assertRaises(Forbidden, getattr, resource, '_testData')
resource = removeSecurityProxy(resource)
self.assertEqual(resource._testData(), open(path, 'rb').read())
def testResourceErrors(self):
self.assertEqual(
component.queryMultiAdapter((ob, request), name='zmi_icon'), None)
import zope.browserresource.tests as p
path = os.path.dirname(p.__file__)
path = os.path.join(path, 'testfiles', 'test.gif')
config = StringIO(template % (
'''
''' % (path, path)
))
self.assertRaises(ConfigurationError, xmlconfig, config)
config = StringIO(template % (
"""
"""
))
self.assertRaises(ConfigurationError, xmlconfig, config)
def test_suite():
return makeSuite(Test)
zope.browserresource-3.12.0/src/zope/browserresource/tests/test_resource.py 0000644 0000000 0000000 00000004667 11401613004 025536 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2003 Zope Foundation 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.
#
##############################################################################
"""Unit tests for Resource
"""
import unittest
from zope import component
from zope.publisher.browser import TestRequest
import zope.component.interfaces
from zope.browserresource.resource import Resource
from zope.browserresource.tests import support
from zope.traversing.browser.interfaces import IAbsoluteURL
from zope.traversing.browser.absoluteurl import AbsoluteURL
from zope.testing import cleanup
class TestResource(support.SiteHandler, cleanup.CleanUp, unittest.TestCase):
def setUp(self):
super(TestResource, self).setUp()
component.provideAdapter(AbsoluteURL, (None, None), IAbsoluteURL)
def testGlobal(self):
req = TestRequest()
r = Resource(req)
req._vh_root = support.site
r.__parent__ = support.site
r.__name__ = 'foo'
self.assertEquals(r(), 'http://127.0.0.1/@@/foo')
r.__name__ = '++resource++foo'
self.assertEquals(r(), 'http://127.0.0.1/@@/foo')
def testGlobalInVirtualHost(self):
req = TestRequest()
req.setVirtualHostRoot(['x', 'y'])
r = Resource(req)
req._vh_root = support.site
r.__parent__ = support.site
r.__name__ = 'foo'
self.assertEquals(r(), 'http://127.0.0.1/x/y/@@/foo')
def testResourceUrl(self):
# fake IAbsoluteURL adapter
def resourceBase(site, request):
return 'http://cdn.example.com'
component.provideAdapter(
resourceBase,
(zope.component.interfaces.ISite, TestRequest),
IAbsoluteURL, 'resource')
req = TestRequest()
r = Resource(req)
req._vh_root = support.site
r.__parent__ = support.site
r.__name__ = 'foo'
self.assertEquals(r(), 'http://cdn.example.com/@@/foo')
def test_suite():
return unittest.makeSuite(TestResource)
zope.browserresource-3.12.0/src/zope/browserresource/tests/test_resources.py 0000644 0000000 0000000 00000002063 11401613004 025705 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation 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.
#
##############################################################################
"""Test Browser Resources
"""
import doctest
import unittest
from zope.testing import cleanup
def setUp(test):
cleanup.setUp()
def tearDown(test):
cleanup.tearDown()
def test_suite():
return unittest.TestSuite((
doctest.DocTestSuite(
'zope.browserresource.resources',
setUp=setUp, tearDown=tearDown,
optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE),
))
zope.browserresource-3.12.0/src/zope/browserresource/tests/testfiles/test.gif 0000644 0000000 0000000 00000001615 11243747776 025770 0 ustar 0000000 0000000 GIF89a PPP @ @ @ @ @ ! , j @AxჅ*tpÄ)f8A=pa< dǓA$r"L*iH1ʚ&{ӡO/G~s̙?RlTӫ-* ; zope.browserresource-3.12.0/src/zope/browserresource/tests/testfiles/test.pt 0000644 0000000 0000000 00000000046 11243747776 025643 0 ustar 0000000 0000000 test
zope.browserresource-3.12.0/src/zope/browserresource/tests/testfiles/test.txt 0000644 0000000 0000000 00000000012 11243747776 026030 0 ustar 0000000 0000000 test
data
zope.browserresource-3.12.0/src/zope/browserresource/tests/testfiles/test2.pt 0000644 0000000 0000000 00000000076 11243747776 025730 0 ustar 0000000 0000000 test
zope.browserresource-3.12.0/src/zope/browserresource/tests/testfiles/subdir/test.gif 0000644 0000000 0000000 00000001615 11243747776 027260 0 ustar 0000000 0000000 GIF89a PPP @ @ @ @ @ ! , j @AxჅ*tpÄ)f8A=pa< dǓA$r"L*iH1ʚ&{ӡO/G~s̙?RlTӫ-* ; zope.browserresource-3.12.0/src/zope.browserresource.egg-info/dependency_links.txt 0000644 0000000 0000000 00000000001 11501731312 026662 0 ustar 0000000 0000000
zope.browserresource-3.12.0/src/zope.browserresource.egg-info/namespace_packages.txt 0000644 0000000 0000000 00000000005 11501731312 027142 0 ustar 0000000 0000000 zope
zope.browserresource-3.12.0/src/zope.browserresource.egg-info/not-zip-safe 0000644 0000000 0000000 00000000001 11501731310 025040 0 ustar 0000000 0000000
zope.browserresource-3.12.0/src/zope.browserresource.egg-info/PKG-INFO 0000644 0000000 0000000 00000016735 11501731312 023725 0 ustar 0000000 0000000 Metadata-Version: 1.0
Name: zope.browserresource
Version: 3.12.0
Summary: Browser resources implementation for Zope.
Home-page: http://pypi.python.org/pypi/zope.browserresource/
Author: Zope Foundation and Contributors
Author-email: zope-dev@zope.org
License: ZPL 2.1
Description: ========
Overview
========
*This package is at present not reusable without depending on a large
chunk of the Zope Toolkit and its assumptions. It is maintained by the*
`Zope Toolkit project `_.
This package provides an implementation of browser resources. It also
provides directives for defining those resources using ZCML.
Resources are static files and directories that are served to the browser
directly from the filesystem. The most common example are images, CSS style
sheets, or JavaScript files.
Resources are be registered under a symbolic name and can later be referred to
by that name, so their usage is independent from their physical location.
You can register a single file with the `` directive, and a
whole directory with the `` directive, for example
This causes a named adapter to be registered that adapts the request to
zope.interface.Interface (XXX why do we not use an explicit interface?),
so to later retrieve a resource, use
`zope.component.getAdapter(request, name='myfile')`.
There are two ways to traverse to a resource,
1. with the 'empty' view on a site, e. g. `http://localhost/@@/myfile`
(This is declared by zope.browserresource)
2. with the `++resource++` namespace, e. g. `http://localhost/++resource++myfile`
(This is declared by zope.traversing.namespace)
In case of resource-directories traversal simply continues through its contents,
e. g. `http://localhost/@@/main-images/subdir/sample.jpg`
Rather than putting together the URL to a resource manually, you should use
zope.traversing.browser.interfaces.IAbsoluteURL to get the URL, or for a
shorthand, call the resource object. This has an additional benefit:
If you want to serve resources from a different URL, for example
because you want to use a web server specialized in serving static files instead
of the appserver, you can register an IAbsoluteURL adapter for the site under
the name 'resource' that will be used to compute the base URLs for resources.
For example, if you register 'http://static.example.com/' as the base 'resource'
URL, the resources from the above example would yield the following absolute
URLs: http://static.example.com/@@/myfile and
http://static.example.com/@@/main-images
=======
CHANGES
=======
3.12.0 (2010-12-14)
===================
- Added ``zcml`` extra dependencies and fixed dependencies of
``configure.zcml`` on other packages' ``meta.zcml``.
- Added a test for including our own ``configure.zcml``.
3.11.0 (2010-08-13)
===================
- Support the HTTP ETag header for file resources. ETag generation can be
customized or disabled by providing an IETag multi-adapter on
(IFileResource, your-application-skin).
3.10.3 (2010-04-30)
===================
- Prefer the standard libraries doctest module to the one from zope.testing.
3.10.2 (2009-11-25)
===================
- The previous release had a broken egg, sorry.
3.10.1 (2009-11-24)
===================
- Import hooks functionality from zope.component after it was moved there from
zope.site. This lifts the dependency on zope.site and thereby, ZODB.
- Import ISite and IPossibleSite from zope.component after they were moved
there from zope.location.
3.10.0 (2009-09-25)
===================
- Add an ability to forbid publishing of some files in the resource directory,
this is done by fnmatch'ing the wildcards in the ``forbidden_names``class
attribute of ``DirectoryResource``. By default, the ``.svn`` is in that
attribute, so directories won't publish subversion system directory that can
contain private information.
3.9.0 (2009-08-27)
==================
Initial release. This package was splitted off zope.app.publisher as a part
of refactoring process.
Additional changes that are made during refactoring:
* Resource class for file resources are now selected the pluggable way.
The resource directory publisher and browser:resource ZCML directive
now creating file resources using factory utility lookup based on the
file extension, so it's now possible to add new resource types without
introducing new ZCML directives and they will work inside resource
directories as well.
NOTE: the "resource_factories" attribute from the DirectoryResource
was removed, so if you were using this attribute for changing resource
classes for some file extensions, you need to migrate your code to new
utility-based mechanism.
See zope.browserresource.interfaces.IResourceFactoryFactory interface.
* The Image resource class was removed, as they are actually simple files.
To migrate, simply rename the "image" argument in browser:resource and
browser:i18n-resource directives to "file", if you don't do this, resouces
will work, but you'll get deprecation warnings.
If you need custom behaviour for images, you can register a resource
factory utility for needed file extensions.
* The PageTemplateResource was moved into a separate package, "zope.ptresource",
which is a plugin for this package now. Because of that, the "template"
argument of browser:resource directive was deprecated and you should rename
it to "file" to migrate. The PageTemplateResource will be created for
"pt", "zpt" and "html" files automatically, if zope.ptresource package is
included in your configuration.
* Fix stripping the "I" from an interface name for icon title, if no
title is specified.
* When publishing a resource via Resources view, set resource parent
to an ISite object, not to current site manager.
* Clean up code and improve test coverage.
Platform: UNKNOWN
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: Zope3
zope.browserresource-3.12.0/src/zope.browserresource.egg-info/requires.txt 0000644 0000000 0000000 00000000352 11501731312 025214 0 ustar 0000000 0000000 setuptools
zope.component>=3.8.0
zope.configuration
zope.contenttype
zope.i18n
zope.interface
zope.location
zope.publisher>=3.8
zope.schema
zope.traversing>3.7
[test]
zope.testing
[zcml]
zope.component[zcml]
zope.security[zcml]>=3.8 zope.browserresource-3.12.0/src/zope.browserresource.egg-info/SOURCES.txt 0000644 0000000 0000000 00000003213 11501731312 024477 0 ustar 0000000 0000000 CHANGES.txt
COPYRIGHT.txt
LICENSE.txt
README.txt
bootstrap.py
buildout.cfg
setup.py
src/zope/__init__.py
src/zope.browserresource.egg-info/PKG-INFO
src/zope.browserresource.egg-info/SOURCES.txt
src/zope.browserresource.egg-info/dependency_links.txt
src/zope.browserresource.egg-info/namespace_packages.txt
src/zope.browserresource.egg-info/not-zip-safe
src/zope.browserresource.egg-info/requires.txt
src/zope.browserresource.egg-info/top_level.txt
src/zope/browserresource/__init__.py
src/zope/browserresource/configure.zcml
src/zope/browserresource/directory.py
src/zope/browserresource/file.py
src/zope/browserresource/i18nfile.py
src/zope/browserresource/icon.py
src/zope/browserresource/interfaces.py
src/zope/browserresource/meta.zcml
src/zope/browserresource/metaconfigure.py
src/zope/browserresource/metadirectives.py
src/zope/browserresource/resource.py
src/zope/browserresource/resources.py
src/zope/browserresource/tests/__init__.py
src/zope/browserresource/tests/configure.txt
src/zope/browserresource/tests/support.py
src/zope/browserresource/tests/test_configure.py
src/zope/browserresource/tests/test_directives.py
src/zope/browserresource/tests/test_directory.py
src/zope/browserresource/tests/test_file.py
src/zope/browserresource/tests/test_i18nfile.py
src/zope/browserresource/tests/test_icondirective.py
src/zope/browserresource/tests/test_resource.py
src/zope/browserresource/tests/test_resources.py
src/zope/browserresource/tests/testfiles/test.gif
src/zope/browserresource/tests/testfiles/test.pt
src/zope/browserresource/tests/testfiles/test.txt
src/zope/browserresource/tests/testfiles/test2.pt
src/zope/browserresource/tests/testfiles/subdir/test.gif zope.browserresource-3.12.0/src/zope.browserresource.egg-info/top_level.txt 0000644 0000000 0000000 00000000005 11501731312 025341 0 ustar 0000000 0000000 zope