[Checkins] SVN: Sandbox/nadako/zope.browserresource/ Upload code

Dan Korostelev nadako at gmail.com
Sat Aug 22 08:01:19 EDT 2009


Log message for revision 103079:
  Upload code 

Changed:
  _U  Sandbox/nadako/zope.browserresource/
  A   Sandbox/nadako/zope.browserresource/CHANGES.txt
  A   Sandbox/nadako/zope.browserresource/README.txt
  A   Sandbox/nadako/zope.browserresource/bootstrap.py
  A   Sandbox/nadako/zope.browserresource/buildout.cfg
  A   Sandbox/nadako/zope.browserresource/setup.py
  A   Sandbox/nadako/zope.browserresource/src/
  A   Sandbox/nadako/zope.browserresource/src/zope/
  A   Sandbox/nadako/zope.browserresource/src/zope/__init__.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/__init__.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/configure.zcml
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/directoryresource.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/fileresource.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/i18nfileresource.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/icon.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/interfaces.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/meta.zcml
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/metaconfigure.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/metadirectives.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/pagetemplateresource.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/resource.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/resources.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/__init__.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/support.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_directives.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_directoryresource.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_fileresource.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_icondirective.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_pagetemplateresource.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_resource.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_resources.py
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/png
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/subdir/
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/subdir/test.gif
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.gif
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.pt
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.txt
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test2.pt
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test3.pt
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/testresource.pt
  A   Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testi18nfileresource.py

-=-

Property changes on: Sandbox/nadako/zope.browserresource
___________________________________________________________________
Added: svn:ignore
   + bin
coverage
develop-eggs
parts
.installed.cfg


Added: Sandbox/nadako/zope.browserresource/CHANGES.txt
===================================================================
--- Sandbox/nadako/zope.browserresource/CHANGES.txt	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/CHANGES.txt	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,9 @@
+=======
+CHANGES
+=======
+
+3.9.0 (unreleased)
+==================
+
+Initial release. This package was splitted off zope.app.publisher as a part
+of refactoring process.

Added: Sandbox/nadako/zope.browserresource/README.txt
===================================================================
--- Sandbox/nadako/zope.browserresource/README.txt	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/README.txt	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,66 @@
+========
+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 <http://docs.zope.org/zopetoolkit/>`_.
+
+This package provides an implementation of browser resources, like
+files and directories. It also provides directives for defining
+those resources using ZCML.
+
+
+Resources
+=========
+
+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 `<browser:resource>` directive, and a
+whole directory with the `<browser:resourceDirectory>` directive, for example
+
+  <browser:resource
+    directory="/path/to/static.file"
+    name="myfile"
+    />
+
+  <browser:resourceDirectory
+    directory="/path/to/images"
+    name="main-images"
+    />
+
+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
+(XXX what about http://static.example.com/main-images/subdir/sample.jpg?)

Added: Sandbox/nadako/zope.browserresource/bootstrap.py
===================================================================
--- Sandbox/nadako/zope.browserresource/bootstrap.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/bootstrap.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""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.
+
+$Id: bootstrap.py 73800 2007-03-27 16:16:42Z dobe $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                     ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, sys.executable,
+    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)

Added: Sandbox/nadako/zope.browserresource/buildout.cfg
===================================================================
--- Sandbox/nadako/zope.browserresource/buildout.cfg	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/buildout.cfg	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,18 @@
+[buildout]
+develop = .
+parts = test coverage-test coverage-report
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = zope.browserresource [test]
+
+[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')

Added: Sandbox/nadako/zope.browserresource/setup.py
===================================================================
--- Sandbox/nadako/zope.browserresource/setup.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/setup.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""zope.browserresource setup
+"""
+from setuptools import setup, find_packages, Extension
+
+long_description = (open('README.txt').read() + '\n\n' +
+                    open('CHANGES.txt').read())
+
+setup(name='zope.browserresource',
+      version = '3.9.0dev',
+      url='http://pypi.python.org/pypi/zope.browserresource/',
+      author='Zope Corporation and Contributors',
+      author_email='zope-dev at 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 resource implementation for Zope.',
+      long_description=long_description,
+
+      packages=find_packages('src'),
+      package_dir={'': 'src'},
+
+      namespace_packages=['zope'],
+      include_package_data=True,
+      install_requires=['setuptools',
+                        'zope.component>=3.7.0',
+                        'zope.configuration',
+                        'zope.contenttype',
+                        'zope.datetime',
+                        'zope.i18n',
+                        'zope.interface',
+                        'zope.location',
+                        'zope.pagetemplate>=3.5.0',
+                        'zope.publisher>=3.8.0',
+                        'zope.schema',
+                        'zope.site',
+                        'zope.security[untrustedpython]',
+                        'zope.traversing>3.7.0',
+                        'zope.browser',
+                        ],
+      extras_require={
+          'test': ['zope.testing', 'zope.app.testing'],
+          },
+
+      zip_safe = False,
+      )

Added: Sandbox/nadako/zope.browserresource/src/zope/__init__.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/__init__.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/__init__.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,7 @@
+# this is a namespace package
+try:
+    import pkg_resources
+    pkg_resources.declare_namespace(__name__)
+except ImportError:
+    import pkgutil
+    __path__ = pkgutil.extend_path(__path__, __name__)

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/__init__.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/__init__.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/__init__.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/configure.zcml
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/configure.zcml	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/configure.zcml	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,34 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <class class=".fileresource.FileResource">
+    <allow interface="zope.publisher.interfaces.browser.IBrowserPublisher" />
+    <allow attributes="GET HEAD __call__" />
+  </class>
+  
+  <class class=".i18nfileresource.I18nFileResource">
+    <allow interface="zope.publisher.interfaces.browser.IBrowserPublisher" />
+    <allow attributes="GET HEAD __call__" />
+  </class>
+  
+  <class class=".pagetemplateresource.PageTemplateResource">
+    <allow interface="zope.publisher.interfaces.browser.IBrowserPublisher" />
+    <allow attributes="__call__" />
+  </class>
+  
+  <class class=".directoryresource.DirectoryResource">
+    <allow interface="zope.publisher.interfaces.browser.IBrowserPublisher" />
+    <allow attributes="get __getitem__" />
+  </class>
+  
+  <adapter factory=".resource.AbsoluteURL" />
+  
+  <view
+      for="zope.location.interfaces.ISite"
+      type="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
+      name=""
+      factory=".resources.Resources"
+      permission="zope.Public"
+      allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
+      />
+
+</configure>

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/directoryresource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/directoryresource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/directoryresource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,119 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Resource Directory
+
+A 'resource directory' is an on-disk directory which is registered as
+a resource using the <resourceDirectory> ZCML directive.  The
+directory is treated as a source for individual resources; it can be
+traversed to retrieve resources represented by contained files, which
+can in turn be treated as resources.  The contained files have
+__name__ values which include a '/' separating the __name__ of the
+resource directory from the name of the file within the directory.
+
+$Id: directoryresource.py 89359 2008-08-05 07:35:05Z srichter $
+"""
+import os
+import posixpath
+
+from zope.interface import implements
+from zope.publisher.interfaces import NotFound
+from zope.publisher.browser import BrowserView
+from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from zope.browserresource.resource import Resource
+from zope.browserresource.resources import empty
+from zope.browserresource.fileresource import FileResourceFactory
+from zope.browserresource.fileresource import ImageResourceFactory
+from zope.browserresource.pagetemplateresource import PageTemplateResourceFactory
+
+_marker = object()
+
+# we only need this class as a context for DirectoryResource
+class Directory(object):
+
+    def __init__(self, path, checker, name):
+        self.path = path
+        self.checker = checker
+        self.__name__ = name
+
+class DirectoryResource(BrowserView, Resource):
+
+    implements(IBrowserPublisher)
+
+    resource_factories = {
+        '.gif':  ImageResourceFactory,
+        '.png':  ImageResourceFactory,
+        '.jpg':  ImageResourceFactory,
+        '.pt':   PageTemplateResourceFactory,
+        '.zpt':  PageTemplateResourceFactory,
+        '.html': PageTemplateResourceFactory,
+        }
+
+    default_factory = FileResourceFactory
+    directory_factory = None
+
+    def publishTraverse(self, request, name):
+        '''See interface IBrowserPublisher'''
+        return self.get(name)
+
+    def browserDefault(self, request):
+        '''See interface IBrowserPublisher'''
+        return empty, ()
+
+    def __getitem__(self, name):
+        res = self.get(name, None)
+        if res is None:
+            raise KeyError(name)
+        return res
+
+    def get(self, name, default=_marker):
+        path = self.context.path
+        filename = os.path.join(path, name)
+        isfile = os.path.isfile(filename)
+        isdir = os.path.isdir(filename)
+
+        if not (isfile or isdir):
+            if default is _marker:
+                raise NotFound(None, name)
+            return default
+
+        if isfile:
+            ext = os.path.splitext(os.path.normcase(name))[1]
+            factory = self.resource_factories.get(ext, self.default_factory)
+        else:
+            factory = self.directory_factory
+
+        rname = posixpath.join(self.__name__, name)
+        resource = factory(filename, self.context.checker, rname)(self.request)
+        resource.__parent__ = self
+        return resource
+
+
+class DirectoryResourceFactory(object):
+
+    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

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/fileresource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/fileresource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/fileresource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,178 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""File-based browser resources.
+
+$Id: fileresource.py 89359 2008-08-05 07:35:05Z srichter $
+"""
+
+import os
+import time
+try:
+    from email.utils import formatdate
+except ImportError: # python 2.4
+    from email.Utils import formatdate
+
+from zope.interface import implements
+from zope.contenttype import guess_content_type
+from zope.datetime import time as timeFromDateTimeString
+from zope.publisher.interfaces import NotFound
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.publisher.browser import BrowserView
+
+from zope.browserresource.resource import Resource
+
+
+class File(object):
+    
+    def __init__(self, path, name):
+        self.path = path
+
+        f = open(path, 'rb')
+        data = f.read()
+        f.close()
+        self.content_type, enc = guess_content_type(path, data)
+        self.__name__ = name
+        self.lmt = float(os.path.getmtime(path)) or time.time()
+        self.lmh = formatdate(self.lmt, usegmt=True)
+
+
+class Image(File):
+    """Image objects stored in external files."""
+
+    def __init__(self, path, name):
+        super(Image, self).__init__(path, name)
+        if self.content_type in (None, 'application/octet-stream'):
+            ext = os.path.splitext(self.path)[1]
+            if ext:
+                self.content_type = 'image/%s' % ext[1:]
+
+class FileResource(BrowserView, Resource):
+
+    implements(IBrowserPublisher)
+
+    cacheTimeout = 86400
+
+    def publishTraverse(self, request, name):
+        '''See interface IBrowserPublisher'''
+        raise NotFound(None, name)
+
+    def browserDefault(self, request):
+        '''See interface IBrowserPublisher'''
+        return getattr(self, request.method), ()
+
+    #
+    ############################################################
+
+    # for unit tests
+    def _testData(self):
+        f = open(self.context.path, 'rb')
+        data = f.read()
+        f.close()
+        return data
+
+
+    def chooseContext(self):
+        """Choose the appropriate context"""
+        return self.context
+
+
+    def GET(self):
+        """Default document"""
+
+        file = self.chooseContext()
+        request = self.request
+        response = request.response
+
+        setCacheControl(response, self.cacheTimeout)
+
+        # HTTP If-Modified-Since header handling. This is duplicated
+        # from OFS.Image.Image - it really should be consolidated
+        # somewhere...
+        header = request.getHeader('If-Modified-Since', None)
+        if header is not None:
+            header = header.split(';')[0]
+            # Some proxies seem to send invalid date strings for this
+            # header. If the date string is not valid, we ignore it
+            # rather than raise an error to be generally consistent
+            # with common servers such as Apache (which can usually
+            # understand the screwy date string as a lucky side effect
+            # of the way they parse it).
+            try:    mod_since=long(timeFromDateTimeString(header))
+            except: mod_since=None
+            if mod_since is not None:
+                if getattr(file, 'lmt', None):
+                    last_mod = long(file.lmt)
+                else:
+                    last_mod = long(0)
+                if last_mod > 0 and last_mod <= mod_since:
+                    response.setStatus(304)
+                    return ''
+
+        response.setHeader('Content-Type', file.content_type)
+        response.setHeader('Last-Modified', file.lmh)
+
+        f = open(file.path,'rb')
+        data = f.read()
+        f.close()
+
+        return data
+
+    def HEAD(self):
+        file = self.chooseContext()
+        response = self.request.response
+        response.setHeader('Content-Type', file.content_type)
+        response.setHeader('Last-Modified', file.lmh)
+        setCacheControl(response, self.cacheTimeout)
+        return ''
+
+
+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',
+                       time.strftime("%a, %d %b %Y %H:%M:%S GMT",
+                                     time.gmtime(t)))
+
+
+class FileResourceFactory(object):
+
+    resourceClass = FileResource
+
+    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
+
+
+class ImageResourceFactory(object):
+
+    resourceClass = FileResource
+
+    def __init__(self, path, checker, name):
+        self.__file = Image(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

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/i18nfileresource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/i18nfileresource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/i18nfileresource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,89 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Internationalized file resource.
+
+$Id: i18nfileresource.py 38178 2005-08-30 21:50:19Z mj $
+"""
+from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from zope.browserresource.fileresource import FileResource
+
+from zope.i18n.negotiator import negotiator
+from zope.i18n.interfaces import II18nAware
+from zope.interface import implements
+
+
+class I18nFileResource(FileResource):
+
+    implements(IBrowserPublisher, II18nAware)
+
+    def __init__(self, data, request, defaultLanguage='en'):
+        """Creates an internationalized file resource.  data should be
+        a mapping from languages to File or Image 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]
+
+
+    # for unit tests
+    def _testData(self, language):
+        file = self._data[language]
+        f=open(file.path,'rb')
+        data=f.read()
+        f.close()
+        return data
+
+
+    ############################################################
+    # Implementation methods for interface
+    # II18nAware.py
+
+    def getDefaultLanguage(self):
+        'See II18nAware'
+        return self.defaultLanguage
+
+    def setDefaultLanguage(self, language):
+        'See II18nAware'
+        if not self._data.has_key(language):
+            raise ValueError(
+                  'cannot set nonexistent language (%s) as default' % language)
+        self.defaultLanguage = language
+
+    def getAvailableLanguages(self):
+        'See II18nAware'
+        return self._data.keys()
+
+    #
+    ############################################################
+
+
+class I18nFileResourceFactory(object):
+
+    def __init__(self, data, defaultLanguage):
+        self.__data = data
+        self.__defaultLanguage = defaultLanguage
+
+    def __call__(self, request):
+        return I18nFileResource(self.__data, request, self.__defaultLanguage)

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/icon.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/icon.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/icon.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,114 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""Icon support
+
+$Id: icon.py 72646 2007-02-16 14:06:12Z romanofski $
+"""
+import os
+import re
+
+from zope.interface import Interface
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.configuration.exceptions import ConfigurationError
+from zope.traversing.namespace import getResource
+from zope.component.interface import provideInterface
+from zope.component.zcml import handler
+
+from zope.browserresource import metaconfigure
+
+IName = re.compile('I[A-Z][a-z]')
+
+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):
+        # The context is important here, since it becomes the parent of the
+        # icon, which is needed to generate the absolute URL.
+        resource = getResource(self.context, self.rname, self.request)
+        src = resource()
+
+        return ('<img src="%s" alt="%s" width="%s" height="%s" border="0" />'
+                % (src, self.alt, self.width, self.height))
+
+    def url(self):
+        resource = getResource(self.context, self.rname, self.request)
+        src = resource()
+        return src
+
+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)
+
+def IconDirective(_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 IName.match(title):
+            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
+        metaconfigure.resource(_context, image=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_)
+        )
+
+    

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/interfaces.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/interfaces.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/interfaces.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Resource
+
+$Id: __init__.py 100783 2009-06-10 08:17:59Z wosc $
+"""
+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."""

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/meta.zcml
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/meta.zcml	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/meta.zcml	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,38 @@
+<configure xmlns:meta="http://namespaces.zope.org/meta">
+
+  <meta:directives namespace="http://namespaces.zope.org/browser">
+
+    <meta:directive
+        name="resource"
+        schema=".metadirectives.IResourceDirective"
+        handler=".metaconfigure.resource"
+        />
+
+    <meta:directive
+        name="resourceDirectory"
+        schema=".metadirectives.IResourceDirectoryDirective"
+        handler=".metaconfigure.resourceDirectory"
+        />
+
+    <meta:complexDirective
+        name="i18n-resource"
+        schema=".metadirectives.II18nResourceDirective"
+        handler=".metaconfigure.I18nResource"
+        >
+
+      <meta:subdirective
+          name="translation"
+          schema=".metadirectives.II18nResourceTranslationSubdirective"
+          />
+
+    </meta:complexDirective>
+
+    <meta:directive
+        name="icon"
+        schema=".metadirectives.IIconDirective"
+        handler=".icon.IconDirective"
+        />
+
+  </meta:directives>
+
+</configure>

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/metaconfigure.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/metaconfigure.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/metaconfigure.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,207 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Browser configuration code
+
+$Id: resourcemeta.py 73579 2007-03-25 10:14:23Z fdrake $
+"""
+import os
+
+from zope.configuration.exceptions import ConfigurationError
+from zope.interface import Interface
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.security.checker import CheckerPublic, NamesChecker
+from zope.component.zcml import handler
+
+from zope.configuration.exceptions import ConfigurationError
+from zope.interface import Interface
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.security.proxy import Proxy
+from zope.security.checker import CheckerPublic, Checker
+from zope.component.zcml import handler
+
+from zope.browserresource.directoryresource import DirectoryResourceFactory
+from zope.browserresource.fileresource import File, Image
+from zope.browserresource.fileresource import FileResourceFactory
+from zope.browserresource.fileresource import ImageResourceFactory
+from zope.browserresource.i18nfileresource import I18nFileResourceFactory
+from zope.browserresource.pagetemplateresource import PageTemplateResourceFactory
+
+allowed_names = ('GET', 'HEAD', 'publishTraverse', 'browserDefault',
+                 'request', '__call__')
+
+class ResourceFactoryWrapper(object):
+
+    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 factory is not None:
+        factory = ResourceFactoryWrapper(factory, checker, name)
+    elif file:
+        factory = FileResourceFactory(file, checker, name)
+    elif image:
+        factory = ImageResourceFactory(image, checker, name)
+    else:
+        factory = PageTemplateResourceFactory(template, checker, name)
+
+    _context.action(
+        discriminator = ('resource', name, IBrowserRequest, layer),
+        callable = handler,
+        args = ('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),
+        )
+
+
+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 = {}
+        self.__format = None
+
+    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 not None:
+            if self.__format is not None and self.__format != File:
+                raise ConfigurationError(
+                    "Can't use both files and images in the same "
+                    "i18n-resource directive"
+                    )
+            self.__data[language] = File(_context.path(file), self.name)
+            self.__format = File
+        elif image is not None:
+            if self.__format is not None and self.__format != Image:
+                raise ConfigurationError(
+                    "Can't use both files and images in the same "
+                    "i18n-resource directive"
+                    )
+            self.__data[language] = Image(_context.path(image), self.name)
+            self.__format = Image
+        else:
+            raise ConfigurationError(
+                "At least one of the file, and image "
+                "attributes for resource directives must be specified"
+                )
+
+        return ()
+
+
+    def __call__(self, require = None):
+        if self.name is None:
+            return ()
+
+        if not self.__data.has_key(self.defaultLanguage):
+            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

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/metadirectives.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/metadirectives.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/metadirectives.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,228 @@
+#############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Browser configuration code
+
+This module defines the schemas for browser directives.
+
+$Id: metadirectives.py 100280 2009-05-23 06:03:27Z shane $
+"""
+from zope.interface import Interface
+from zope.configuration.fields import GlobalObject, GlobalInterface
+from zope.configuration.fields import Path, MessageID
+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.",
+        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.""",
+        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.""",
+        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.""",
+        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 <img width="..." />
+        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 <img height="..." />
+        attribute. Defaults to 16.""",
+        required=False,
+        default=16
+        )

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/pagetemplateresource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/pagetemplateresource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/pagetemplateresource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Page Template Resource
+
+$Id: pagetemplateresource.py 73637 2007-03-26 16:22:07Z dobe $
+"""
+
+from zope.interface import implements
+from zope.pagetemplate.engine import TrustedAppPT
+from zope.pagetemplate.pagetemplatefile import PageTemplateFile
+from zope.publisher.browser import BrowserView
+from zope.publisher.interfaces import NotFound
+from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from zope.browserresource.resource import Resource
+
+class PageTemplate(TrustedAppPT, PageTemplateFile):
+    """
+    Resource that is a page template
+    """
+
+    def __init__(self, filename, _prefix=None, content_type=None):
+        _prefix = self.get_path_from_prefix(_prefix)
+        super(PageTemplate, self).__init__(filename, _prefix)
+        if content_type is not None:
+            self.content_type = content_type
+
+    def pt_getContext(self, request, **kw):
+        namespace = super(PageTemplate, self).pt_getContext(**kw)
+        namespace['context'] = None
+        namespace['request'] = request
+        return namespace
+
+    def __call__(self, request, **keywords):
+        namespace = self.pt_getContext(
+            request=request,
+            options=keywords
+            )
+        return self.pt_render(namespace)
+
+class PageTemplateResource(BrowserView, Resource):
+
+    implements(IBrowserPublisher)
+
+    def publishTraverse(self, request, name):
+        '''See interface IBrowserPublisher'''
+        raise NotFound(None, name)
+
+    def browserDefault(self, request):
+        '''See interface IBrowserPublisher'''
+        return self, ()
+
+    def __call__(self):
+        pt = self.context
+        response = self.request.response
+        if not response.getHeader("Content-Type"):
+            response.setHeader("Content-Type", pt.content_type)
+        return pt(self.request)
+
+class PageTemplateResourceFactory(object):
+
+    def __init__(self, path, checker, name):
+        self.__pt = PageTemplate(path)
+        self.__checker = checker
+        self.__name = name
+
+    def __call__(self, request):
+        resource = PageTemplateResource(self.__pt, request)
+        resource.__Security_checker__ = self.__checker
+        resource.__name__ = self.__name
+        return resource

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/resource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/resource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/resource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,62 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Browser Resource
+
+$Id: resource.py 101130 2009-06-18 21:38:57Z rogerineichen $
+"""
+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.site.hooks import getSite
+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 __str__(self):
+        name = self.context.__name__
+        if name.startswith('++resource++'):
+            name = name[12:]
+
+        site = 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 "%s/@@/%s" % (url, name)

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/resources.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/resources.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/resources.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,51 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Resource URL acess
+
+$Id: resources.py 67630 2006-04-27 00:54:03Z jim $
+"""
+import zope.component
+from zope.publisher.browser import BrowserView
+from zope.publisher.interfaces import NotFound
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.interface import implements
+from zope.location import locate
+
+class Resources(BrowserView):
+    """Provide a URL-accessible resource namespace
+    """
+
+    implements(IBrowserPublisher)
+
+    def publishTraverse(self, request, name):
+        '''See interface IBrowserPublisher'''
+
+        resource = zope.component.queryAdapter(request, name=name)
+        if resource is None:
+            raise NotFound(self, name)
+
+        sm = zope.component.getSiteManager()
+        locate(resource, sm, name)
+        return resource
+
+    def browserDefault(self, request):
+        '''See IBrowserPublisher'''
+        return empty, ()
+
+    def __getitem__(self, name):
+        return self.publishTraverse(self.request, name)
+
+
+def empty():
+    return ''

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/__init__.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/__init__.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/__init__.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/support.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/support.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/support.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,47 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Support for tests that need a simple site to be provided.
+
+$Id: support.py 100783 2009-06-10 08:17:59Z wosc $
+"""
+
+import zope.component
+import zope.location.interfaces
+from zope.interface import implements
+from zope.traversing.interfaces import IContainmentRoot
+
+from zope.site.hooks import setSite
+import zope.browserresource.resource
+
+class Site:
+
+    implements(zope.location.interfaces.ISite, IContainmentRoot)
+
+    def getSiteManager(self):
+        return zope.component.getGlobalSiteManager()
+
+site = Site()
+
+
+class SiteHandler(object):
+
+    def setUp(self):
+        super(SiteHandler, self).setUp()
+        setSite(site)
+        zope.component.provideAdapter(
+            zope.browserresource.resource.AbsoluteURL)
+
+    def tearDown(self):
+        setSite()
+        super(SiteHandler, self).tearDown()

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_directives.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_directives.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_directives.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,276 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""'browser' namespace directive tests
+
+$Id: test_directives.py 100280 2009-05-23 06:03:27Z shane $
+"""
+
+import sys
+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.testing.doctestunit import DocTestSuite
+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 IC, V1, VZMI, R1, IV
+from zope.browserresource.fileresource import FileResource
+from zope.browserresource.i18nfileresource import I18nFileResource
+from zope.app.testing import placelesssetup
+
+tests_path = os.path.join(
+    os.path.dirname(zope.browserresource.__file__),
+    'tests')
+
+template = """<configure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:browser='http://namespaces.zope.org/browser'
+   i18n_domain='zope'>
+   %s
+   </configure>"""
+
+
+request = TestRequest()
+
+class V2(V1, object):
+
+    def action(self):
+        return self.action2()
+
+    def action2(self):
+        return "done"
+
+class VT(V1, object):
+    def publishTraverse(self, request, name):
+        try:
+            return int(name)
+        except:
+            return super(VT, self).publishTraverse(request, name)
+
+class Ob(object):
+    implements(IC)
+
+ob = Ob()
+
+class NCV(object):
+    "non callable view"
+
+    def __init__(self, context, request):
+        pass
+
+class CV(NCV):
+    "callable view"
+    def __call__(self):
+        pass
+
+
+class C_w_implements(NCV):
+    implements(Interface)
+
+    def index(self):
+        return self
+
+class ITestLayer(IBrowserRequest):
+    """Test Layer."""
+
+class ITestSkin(ITestLayer):
+    """Test Skin."""
+
+
+class MyResource(object):
+
+    def __init__(self, request):
+        self.request = request
+
+
+class Test(placelesssetup.PlacelessSetup, 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 testSkinResource(self):
+        self.assertEqual(
+            component.queryAdapter(Request(IV), name='test'), None)
+
+        xmlconfig(StringIO(template % (
+            '''
+            <browser:resource
+                name="test"
+                factory="zope.component.testfiles.views.RZMI"
+                layer="
+                  zope.browserresource.tests.test_directives.ITestLayer"
+                />
+            <browser:resource
+                name="test"
+                factory="zope.component.testfiles.views.R1"
+                />
+            '''
+            )))
+
+        self.assertEqual(
+            component.queryAdapter(request, name='test').__class__, R1)
+        self.assertEqual(
+            component.queryAdapter(
+                TestRequest(skin=ITestSkin), name='test').__class__,
+            RZMI)
+
+    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 % (
+            '''
+            <browser:i18n-resource name="test" defaultLanguage="fr">
+              <browser:translation language="en" file="%s" />
+              <browser:translation language="fr" file="%s" />
+            </browser:i18n-resource>
+            ''' % (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 % (
+            '''
+            <browser:i18n-resource name="test" defaultLanguage="fr">
+              <browser:translation language="en" file="%s" />
+              <browser:translation language="lt" file="%s" />
+            </browser:i18n-resource>
+            ''' % (path1, path2)
+            ))
+        self.assertRaises(ConfigurationError, xmlconfig, config)
+
+        # files and images can't be mixed
+        config = StringIO(template % (
+            '''
+            <browser:i18n-resource name="test" defaultLanguage="fr">
+              <browser:translation language="en" file="%s" />
+              <browser:translation language="fr" image="%s" />
+            </browser:i18n-resource>
+            ''' % (path1, path2)
+            ))
+        self.assertRaises(ConfigurationError, xmlconfig, config)
+
+    def testFactory(self):
+        self.assertEqual(
+            component.queryAdapter(request, name='index.html'), None)
+
+        xmlconfig(StringIO(template %
+            '''
+            <browser:resource
+                name="index.html"
+                factory="
+                  zope.browserresource.tests.test_directives.MyResource"
+                />
+            '''
+            ))
+
+        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 %
+            '''
+            <browser:resource
+                name="index.html"
+                file="%s"
+                />
+            ''' % path
+            ))
+
+        r = component.getAdapter(request, name='index.html')
+        self.assertEquals(r.__class__, 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.assertEqual(r.__name__, "index.html")
+
+        self.assertRaises(Exception, getattr, r, '_testData')
+
+        r = removeSecurityProxy(r)
+        self.assert_(r.__class__ is FileResource)
+        self.assertEqual(r._testData(), open(path, 'rb').read())
+
+
+    def testSkinResource(self):
+        self.assertEqual(component.queryAdapter(request, name='test'), None)
+
+        path = os.path.join(tests_path, 'testfiles', 'test.pt')
+        xmlconfig(StringIO(template % (
+            '''
+            <browser:resource
+                name="test"
+                file="%s"
+                layer="
+                  zope.browserresource.tests.test_directives.ITestLayer"
+                />
+            ''' % path
+            )))
+
+        self.assertEqual(component.queryAdapter(request, name='test'), None)
+
+        r = component.getAdapter(TestRequest(skin=ITestSkin), name='test')
+        r = removeSecurityProxy(r)
+        self.assertEqual(r._testData(), open(path, 'rb').read())
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(Test),
+        DocTestSuite('zope.browserresource.metaconfigure',
+                     setUp=placelesssetup.setUp,
+                     tearDown=placelesssetup.tearDown)
+        ))
+
+if __name__=='__main__':
+    unittest.main(defaultTest="test_suite")
+

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_directoryresource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_directoryresource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_directoryresource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,131 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Directory-based resources test
+
+$Id: test_directoryresource.py 95447 2009-01-29 16:28:18Z wosc $
+"""
+import os
+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.app.testing.placelesssetup import PlacelessSetup
+from zope.browserresource.directoryresource import \
+     DirectoryResourceFactory, DirectoryResource
+from zope.browserresource.fileresource import FileResource
+from zope.browserresource.pagetemplateresource import \
+     PageTemplateResource
+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, PlacelessSetup, TestCase):
+
+    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 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 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 testCorrectFactories(self):
+        path = os.path.join(test_directory, 'testfiles')
+        request = TestRequest()
+        resource = DirectoryResourceFactory(path, checker, 'files')(request)
+
+        image = resource['test.gif']
+        self.assert_(proxy.isinstance(image, FileResource))
+        template = resource['test.pt']
+        self.assert_(proxy.isinstance(template, PageTemplateResource))
+        file = resource['test.txt']
+        self.assert_(proxy.isinstance(file, FileResource))
+        file = resource['png']
+        self.assert_(proxy.isinstance(file, FileResource))
+
+def test_suite():
+    return makeSuite(Test)
+
+if __name__ == '__main__':
+    main(defaultTest='test_suite')

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_fileresource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_fileresource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_fileresource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,110 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""File-based browser resource tests.
+
+$Id: test_fileresource.py 29143 2005-02-14 22:43:16Z srichter $
+"""
+import os
+from unittest import TestCase, main, makeSuite
+
+from zope.publisher.interfaces import NotFound
+from zope.i18n.interfaces import IUserPreferredCharsets
+from zope.security.proxy import removeSecurityProxy
+from zope.security.checker import NamesChecker
+
+from zope.app.testing.placelesssetup import PlacelessSetup
+from zope.component import provideAdapter
+
+from zope.publisher.http import IHTTPRequest
+from zope.publisher.http import HTTPCharsets
+from zope.publisher.browser import TestRequest
+
+from zope.browserresource.fileresource import FileResourceFactory
+from zope.browserresource.fileresource import ImageResourceFactory
+import zope.browserresource.tests as p
+
+checker = NamesChecker(
+    ('__call__', 'HEAD', 'request', 'publishTraverse', 'GET')
+    )
+
+test_directory = os.path.dirname(p.__file__)
+
+class Test(PlacelessSetup, TestCase):
+
+    def setUp(self):
+        super(Test, self).setUp()
+        provideAdapter(HTTPCharsets, (IHTTPRequest,), IUserPreferredCharsets)
+
+    def testNoTraversal(self):
+
+        path = os.path.join(test_directory, 'testfiles', 'test.txt')
+        factory = FileResourceFactory(path, checker, 'test.txt')
+        resource = factory(TestRequest())
+        self.assertRaises(NotFound,
+                          resource.publishTraverse,
+                          resource.request,
+                          '_testData')
+
+    def testFileGET(self):
+
+        path = os.path.join(test_directory, 'testfiles', 'test.txt')
+
+        factory = FileResourceFactory(path, checker, 'test.txt')
+        resource = factory(TestRequest())
+        self.assertEqual(resource.GET(), open(path, 'rb').read())
+
+        response = removeSecurityProxy(resource.request).response
+        self.assertEqual(response.getHeader('Content-Type'), 'text/plain')
+
+    def testFileHEAD(self):
+
+        path = os.path.join(test_directory, 'testfiles', 'test.txt')
+        factory = FileResourceFactory(path, checker, 'test.txt')
+        resource = factory(TestRequest())
+
+        self.assertEqual(resource.HEAD(), '')
+
+        response = removeSecurityProxy(resource.request).response
+        self.assertEqual(response.getHeader('Content-Type'), 'text/plain')
+
+    def testImageGET(self):
+
+        path = os.path.join(test_directory, 'testfiles', 'test.gif')
+
+        factory = ImageResourceFactory(path, checker, 'test.gif')
+        resource = factory(TestRequest())
+
+        self.assertEqual(resource.GET(), open(path, 'rb').read())
+
+        response = removeSecurityProxy(resource.request).response
+        self.assertEqual(response.getHeader('Content-Type'), 'image/gif')
+
+    def testImageHEAD(self):
+
+        path = os.path.join(test_directory, 'testfiles', 'test.gif')
+        factory = ImageResourceFactory(path, checker, 'test.gif')
+        resource = factory(TestRequest())
+
+        self.assertEqual(resource.HEAD(), '')
+
+        response = removeSecurityProxy(resource.request).response
+        self.assertEqual(response.getHeader('Content-Type'), 'image/gif')
+
+
+
+def test_suite():
+    return makeSuite(Test)
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_icondirective.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_icondirective.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_icondirective.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,206 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test Icon-Directive
+
+$Id: test_icondirective.py 100223 2009-05-22 00:40:23Z asmith $
+"""
+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
+
+import zope.location.interfaces
+import zope.browserresource
+from zope.component.testfiles.views import IC
+from zope.browserresource.tests import support
+from zope.app.testing.placelesssetup import PlacelessSetup
+
+
+template = """<configure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:browser='http://namespaces.zope.org/browser'
+   i18n_domain='zope'
+   >
+   %s
+   </configure>"""
+
+
+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.fileresource import FileResource
+    protectName(FileResource, '__call__', 'zope.Public')
+
+
+class Test(support.SiteHandler, PlacelessSetup, TestCase):
+
+    def setUp(self):
+        super(Test, self).setUp()
+        XMLConfig('meta.zcml', zope.browserresource)()
+        defineCheckers()
+        
+    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 % (
+            '''
+            <browser:icon name="zmi_icon"
+                      for="zope.component.testfiles.views.IC"
+                      file="%s" />
+            ''' % path
+            )))
+
+        view = component.getMultiAdapter((ob, request), name='zmi_icon')
+        rname = 'zope-component-testfiles-views-IC-zmi_icon.gif'
+        self.assertEqual(
+            view(),
+            '<img src="http://127.0.0.1/@@/%s" alt="IC" '
+            'width="16" height="16" border="0" />'
+            % rname)
+
+        # Make sure that the title attribute works
+        xmlconfig(StringIO(template % (
+            '''
+            <browser:icon name="zmi_icon_w_title"
+                      for="zope.component.testfiles.views.IC"
+                      file="%s" title="click this!" />
+            ''' % 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(),
+            '<img src="http://127.0.0.1/@@/%s" alt="click this!" '
+            'width="16" height="16" border="0" />'
+            % rname)
+
+        # Make sure that the width and height attributes work
+        xmlconfig(StringIO(template % (
+            '''
+            <browser:icon name="zmi_icon_w_width_and_height"
+                      for="zope.component.testfiles.views.IC"
+                      file="%s"
+                      width="20" height="12" />
+            ''' % 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(),
+            '<img src="http://127.0.0.1/@@/%s" alt="IC" '
+            'width="20" height="12" border="0" />'
+            % 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 % (
+            '''
+            <browser:resource name="zmi_icon_res"
+                      image="%s" />
+            <browser:icon name="zmi_icon"
+                      for="zope.component.testfiles.views.IC"
+                      resource="zmi_icon_res" />
+            ''' % path
+            )))
+
+        view = component.getMultiAdapter((ob, request), name='zmi_icon')
+        rname = "zmi_icon_res"
+        self.assertEqual(
+            view(),
+            '<img src="http://127.0.0.1/@@/%s" alt="IC" width="16" '
+            'height="16" border="0" />'
+            % 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 % (
+            '''
+            <browser:resource name="zmi_icon_res"
+                      image="%s" />
+            <browser:icon name="zmi_icon"
+                      for="zope.component.testfiles.views.IC"
+                      file="%s"
+                      resource="zmi_icon_res" />
+            ''' % (path, path)
+            ))
+        self.assertRaises(ConfigurationError, xmlconfig, config)
+
+        config = StringIO(template % (
+            """
+            <browser:icon name="zmi_icon"
+                      for="zope.component.testfiles.views.IC"
+                      />
+            """
+            ))
+        self.assertRaises(ConfigurationError, xmlconfig, config)
+
+
+def test_suite():
+    return makeSuite(Test)
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_pagetemplateresource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_pagetemplateresource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_pagetemplateresource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,72 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Page Template based Resources Test
+
+$Id: test_pagetemplateresource.py 73025 2007-03-07 10:44:01Z zagy $
+"""
+import os
+from unittest import TestCase, main, makeSuite
+
+import zope.component
+from zope.publisher.interfaces import NotFound
+from zope.security.checker import NamesChecker
+from zope.publisher.browser import TestRequest
+from zope.traversing.interfaces import ITraversable
+from zope.traversing.adapters import DefaultTraversable
+
+from zope.app.testing.placelesssetup import PlacelessSetup
+from zope.browserresource.pagetemplateresource import \
+     PageTemplateResourceFactory
+import zope.browserresource.tests as p
+
+
+test_directory = os.path.dirname(p.__file__)
+
+
+checker = NamesChecker(
+    ('__call__', 'request', 'publishTraverse')
+    )
+
+
+class Test(PlacelessSetup, TestCase):
+
+    def setUp(self):
+        super(Test, self).setUp()
+        zope.component.provideAdapter(DefaultTraversable, (None,), ITraversable)
+
+    def testNoTraversal(self):
+        path = os.path.join(test_directory, 'testfiles', 'test.pt')
+        request = TestRequest()
+        factory = PageTemplateResourceFactory(path, checker, 'test.pt')
+        resource = factory(request)
+        self.assertRaises(NotFound, resource.publishTraverse,
+                          resource.request, ())
+
+    def testCall(self):
+        path = os.path.join(test_directory, 'testfiles', 'testresource.pt')
+        test_data = "Foobar"
+        request = TestRequest(test_data=test_data)
+        factory = PageTemplateResourceFactory(path, checker, 'testresource.pt')
+        resource = factory(request)
+        self.assert_(resource(), test_data)
+        self.assertEquals('text/html',
+                          request.response.getHeader('Content-Type'))
+
+
+def test_suite():
+    return makeSuite(Test)
+
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_resource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_resource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_resource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,70 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Unit tests for Resource
+
+$Id: test_resource.py 95607 2009-01-30 21:55:25Z ctheune $
+"""
+import unittest
+
+from zope import component
+
+from zope.publisher.browser import TestRequest
+
+import zope.location.interfaces
+from zope.browserresource.resource import Resource
+from zope.browserresource.tests import support
+from zope.app.testing.placelesssetup import PlacelessSetup
+from zope.traversing.browser.interfaces import IAbsoluteURL
+
+
+class TestResource(support.SiteHandler, PlacelessSetup, unittest.TestCase):
+
+    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.location.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)

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_resources.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_resources.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/test_resources.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,78 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test Browser Resources
+
+$Id: test_resources.py 67630 2006-04-27 00:54:03Z jim $
+"""
+from unittest import TestCase, main, makeSuite
+
+from zope.i18n.interfaces import IUserPreferredCharsets
+from zope.publisher.http import IHTTPRequest
+from zope.publisher.http import HTTPCharsets
+from zope.publisher.browser import TestRequest
+from zope.publisher.interfaces.browser import IBrowserView, IDefaultBrowserLayer
+
+from zope.component import provideAdapter
+from zope.interface import Interface
+from zope.app.testing.placelesssetup import PlacelessSetup
+
+class Test(PlacelessSetup, TestCase):
+
+    def setUp(self):
+        super(Test, self).setUp()
+        provideAdapter(HTTPCharsets, (IHTTPRequest,), IUserPreferredCharsets)
+
+    def test_publishTraverse(self):
+        from zope.browserresource.resources import Resources
+        request = TestRequest()
+
+        class Resource(object):
+            def __init__(self, request): pass
+            def __call__(self): return 42
+
+        provideAdapter(Resource, (IDefaultBrowserLayer,), Interface, 'test')
+        view = Resources(None, request)
+        resource = view.publishTraverse(request, 'test')
+        self.assertEqual(resource(), 42)
+
+    def test_getitem(self):
+        from zope.browserresource.resources import Resources
+        request = TestRequest()
+
+        class Resource(object):
+            def __init__(self, request): pass
+            def __call__(self): return 42
+
+        provideAdapter(Resource, (IDefaultBrowserLayer,), Interface, 'test')
+        view = Resources(None, request)
+        resource = view['test']
+        self.assertEqual(resource(), 42)
+
+    def testNotFound(self):
+        from zope.browserresource.resources import Resources
+        from zope.publisher.interfaces import NotFound
+        request = TestRequest()
+        view = Resources(None, request)
+        self.assertRaises(NotFound,
+                          view.publishTraverse,
+                          request, 'test'
+                          )
+
+
+
+def test_suite():
+    return makeSuite(Test)
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/png
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/png	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/png	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,2 @@
+test
+data

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/subdir/test.gif
===================================================================
(Binary files differ)


Property changes on: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/subdir/test.gif
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.gif
===================================================================
(Binary files differ)


Property changes on: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.gif
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.pt
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.pt	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.pt	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1 @@
+<html><body><p>test</p></body></html>

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.txt
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.txt	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test.txt	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,2 @@
+test
+data

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test2.pt
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test2.pt	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test2.pt	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1 @@
+<html><body><p tal:content="view/data">test</p></body></html>

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test3.pt
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test3.pt	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/test3.pt	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1 @@
+<html><body><p tal:content="view/action">test</p></body></html>

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/testresource.pt
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/testresource.pt	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testfiles/testresource.pt	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1 @@
+<html><body tal:content="request/test_data"></body></html>
\ No newline at end of file

Added: Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testi18nfileresource.py
===================================================================
--- Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testi18nfileresource.py	                        (rev 0)
+++ Sandbox/nadako/zope.browserresource/src/zope/browserresource/tests/testi18nfileresource.py	2009-08-22 12:01:18 UTC (rev 103079)
@@ -0,0 +1,150 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""I18n File-Resource Tests
+
+$Id: testi18nfileresource.py 29143 2005-02-14 22:43:16Z srichter $
+"""
+from unittest import main, makeSuite
+import os
+
+from zope.publisher.interfaces import NotFound
+
+from zope.component import provideAdapter, provideUtility
+from zope.app.testing.placelesssetup import PlacelessSetup
+
+from zope.i18n.interfaces import IUserPreferredCharsets, IUserPreferredLanguages
+
+from zope.publisher.http import IHTTPRequest, HTTPCharsets
+from zope.publisher.browser import BrowserLanguages, TestRequest
+
+from zope.browserresource.i18nfileresource import I18nFileResource
+from zope.browserresource.i18nfileresource import I18nFileResourceFactory
+from zope.browserresource.fileresource 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 Test(PlacelessSetup, 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)
+
+
+    def _createObject(self):
+        obj = I18nFileResource({'en':None, 'lt':None, 'fr':None},
+                               TestRequest(), 'fr')
+        return obj
+
+
+    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)
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')



More information about the Checkins mailing list