[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Publisher/Browser - I18nFileResource.py:1.1 I18nResourceMeta.py:1.1 FileResource.py:1.4 configure.zcml:1.4 meta.zcml:1.5 metaConfigure.py:1.5

Marius Gedminas mgedmin@delfi.lt
Tue, 25 Jun 2002 10:30:09 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/App/Publisher/Browser
In directory cvs.zope.org:/tmp/cvs-serv19310/lib/python/Zope/App/Publisher/Browser

Modified Files:
	FileResource.py configure.zcml meta.zcml metaConfigure.py 
Added Files:
	I18nFileResource.py I18nResourceMeta.py 
Log Message:
Added <browser:i18n-resource> ZCML directive.


=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/I18nFileResource.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""
Internationalized file resource.

$Id: I18nFileResource.py,v 1.1 2002/06/25 14:30:08 mgedmin Exp $
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+

from Zope.Publisher.Browser.IBrowserResource import IBrowserResource
from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher

from Zope.App.Publisher.FileResource import File, Image

from FileResource import FileResource

from Zope.I18n.Negotiator import negotiator
from Zope.I18n.II18nAware import II18nAware


class I18nFileResource(FileResource):

    __implements__ = IBrowserResource, 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 Zope.I18n.II18nAware.II18nAware'
        return self.defaultLanguage

    def setDefaultLanguage(self, language):
        'See Zope.I18n.II18nAware.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 Zope.I18n.II18nAware.II18nAware'
        return self._data.keys()

    #
    ############################################################


class I18nFileResourceFactory:

    def __init__(self, data, defaultLanguage):
        self.__data = data
        self.__defaultLanguage = defaultLanguage

    def __call__(self, request):
        return I18nFileResource(self.__data, request, self.__defaultLanguage)



=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/I18nResourceMeta.py ===
##############################################################################
#
# 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.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""Browser configuration code

$Id: I18nResourceMeta.py,v 1.1 2002/06/25 14:30:08 mgedmin Exp $
"""

from Zope.Security.Proxy import Proxy
from Zope.Security.Checker \
     import CheckerPublic, NamesChecker, Checker

from Zope.Configuration.Action import Action
from Zope.Configuration.Exceptions import ConfigurationError

from Zope.Publisher.Browser.IBrowserPresentation import IBrowserPresentation

from Zope.App.ComponentArchitecture.metaConfigure import handler

from Zope.App.Publisher.FileResource import File, Image
from Zope.App.Publisher.Browser.I18nFileResource \
     import I18nFileResourceFactory

class I18nResource(object):

    type = IBrowserPresentation
    default_allowed_attributes = '__call__'

    def __init__(self, _context, name=None, defaultLanguage='en',
                 layer='default', permission=None):
        self.name = name
        self.defaultLanguage = defaultLanguage
        self.layer = layer
        self.permission = permission
        self.__data = {}


    def translation(self, _context, language, file=None, image=None):

        if file is not None and image is not None:
            raise ConfigurationError(
                "Can't use more than one of file, and image "
                "attributes for resource directives"
                )
        elif file is not None:
            self.__data[language] = File(_context.path(file))
        elif image is not None:
            self.__data[language] = Image(_context.path(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 ()

        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.get)

            factory = self._proxyFactory(factory, checker)

        return [
            Action(
                discriminator = ('i18n-resource', self.name, self.type,
                                 self.layer),
                callable = handler,
                args = ('Resources', 'provideResource', self.name, self.type,
                        factory, self.layer)
                )
            ]


    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


=== Zope3/lib/python/Zope/App/Publisher/Browser/FileResource.py 1.3 => 1.4 ===
         method = request.get('REQUEST_METHOD', 'GET').upper()
         return getattr(self, method), ()
-        
+
     #
     ############################################################
 
     # for unit tests
     def _testData(self):
+        file = self.chooseContext()
         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.context
+        file = self.chooseContext()
         request = self.request
         response = request.response
 
@@ -94,7 +100,8 @@
         return data
 
     def HEAD(self):
-        file = self.context
+        file = self.chooseContext()
+        response = self.request.response
         response = self.request.response
         response.setHeader('Content-Type', file.content_type)
         response.setHeader('Last-Modified', file.lmh)


=== Zope3/lib/python/Zope/App/Publisher/Browser/configure.zcml 1.3 => 1.4 ===
 </content>
 
+<content class=".I18nFileResource.">
+  <allow interface="Zope.Publisher.Browser.IBrowserPublisher." />
+  <allow attributes="GET HEAD __call__" />
+</content>
+
 
 <browser:view name=""
               factory=".Resources."


=== Zope3/lib/python/Zope/App/Publisher/Browser/meta.zcml 1.4 => 1.5 ===
     <directive
         name="resource"
-        attributes="factory name layer
+        attributes="factory name layer file image
                     permission allowed_interface allowed_attributes"
         handler="Zope.App.Publisher.Browser.metaConfigure.resource">
        <subdirective name="page" 
                      attributes="name attribute permission layer" 
        /> 
+    </directive>
+
+    <directive
+        name="i18n-resource"
+        attributes="name default_language"
+        handler="Zope.App.Publisher.Browser.metaConfigure.I18nResource">
+        <subdirective name="translation"
+                      attributes="language file image" />
     </directive>
 
     <directive name="skin" attributes="name layers" 


=== Zope3/lib/python/Zope/App/Publisher/Browser/metaConfigure.py 1.4 => 1.5 ===
 
 from ResourceMeta import resource
+from I18nResourceMeta import I18nResource
 from ViewMeta import view
 
 def skin(_context, **__kw):