[Zope-Checkins] CVS: Zope3/lib/python/Zope/Publisher - Converters.py:1.1.2.1 mapply.py:1.1.2.1 maybe_lock.py:1.1.2.1 BaseRequest.py:1.1.2.2

Shane Hathaway shane@digicool.com
Wed, 14 Nov 2001 18:50:04 -0500


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

Modified Files:
      Tag: Zope-3x-branch
	BaseRequest.py 
Added Files:
      Tag: Zope-3x-branch
	Converters.py mapply.py maybe_lock.py 
Log Message:
More of publisher converted


=== Added File Zope3/lib/python/Zope/Publisher/Converters.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################
__version__='$Revision: 1.1.2.1 $'[11:-2]

import re
from string import atoi, atol, atof, join, split, strip
from types import ListType, TupleType

def field2string(v):
    if hasattr(v,'read'): v=v.read()
    else: v=str(v)
    return v

def field2text(v, nl=re.compile('\r\n|\n\r').search):
    if hasattr(v,'read'): v=v.read()
    else: v=str(v)
    mo = nl(v)
    if mo is None: return v
    l = mo.start(0)
    r=[]
    s=0
    while l >= s:
        r.append(v[s:l])
        s=l+2
        mo=nl(v,s)
        if mo is None: l=-1
        else:          l=mo.start(0)

    r.append(v[s:])
        
    return join(r,'\n')

def field2required(v):
    if hasattr(v,'read'): v=v.read()
    else: v=str(v)
    if strip(v): return v
    raise ValueError, 'No input for required field<p>'

def field2int(v):
    if type(v) in (ListType, TupleType):
        return map(field2int, v)
    if hasattr(v,'read'): v=v.read()
    else: v=str(v)
    if v:
        try: return atoi(v)
        except ValueError:
            raise ValueError, (
                "An integer was expected in the value '%s'" % v
                )
    raise ValueError, 'Empty entry when <strong>integer</strong> expected'

def field2float(v):
    if type(v) in (ListType, TupleType):
        return map(field2float, v)
    if hasattr(v,'read'): v=v.read()
    else: v=str(v)
    if v:
        try: return atof(v)
        except ValueError:
            raise ValueError, (
                "A floating-point number was expected in the value '%s'" % v
                )
    raise ValueError, (
        'Empty entry when <strong>floating-point number</strong> expected')

def field2long(v):
    if type(v) in (ListType, TupleType):
        return map(field2long, v)
    if hasattr(v,'read'): v=v.read()
    else: v=str(v)

    # handle trailing 'L' if present.
    if v[-1:] in ('L', 'l'):
        v = v[:-1]
    if v:
        try: return atol(v)
        except ValueError:
            raise ValueError, (
                "A long integer was expected in the value '%s'" % v
                )
    raise ValueError, 'Empty entry when <strong>integer</strong> expected'

def field2tokens(v):
    if hasattr(v,'read'): v=v.read()
    else: v=str(v)
    return split(v)

def field2lines(v):
    if type(v) in (ListType, TupleType):
        result=[]
        for item in v:
            result.append(str(item))
        return result
    return split(field2text(v),'\n')

def field2date(v):
    from DateTime import DateTime
    if hasattr(v,'read'): v=v.read()
    else: v=str(v)
    return DateTime(v)

def field2boolean(v):
    return v

type_converters = {
    'float':    field2float,
    'int':      field2int,
    'long':     field2long,
    'string':   field2string,
    'date':     field2date,
    'required': field2required,
    'tokens':   field2tokens,
    'lines':    field2lines,
    'text':     field2text,
    'boolean':     field2boolean,
    }

get_converter=type_converters.get


=== Added File Zope3/lib/python/Zope/Publisher/mapply.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################
"""Provide an apply-like facility that works with any mapping object
"""

def default_call_object(object, args, context):
    result=apply(object,args) # Type s<cr> to step into published object.
    return result

def default_missing_name(name, context):
    raise TypeError, 'argument %s was ommitted' % name

def default_handle_class(klass, context):
    if hasattr(klass,'__init__'): 
        f=klass.__init__.im_func
        c=f.func_code
        names=c.co_varnames[1:c.co_argcount]
        return klass, names, f.func_defaults
    else:
        return klass, (), ()

def mapply(object, positional=(), keyword={},
           debug=None, maybe=None,
           missing_name=default_missing_name,
           handle_class=default_handle_class,
           context=None, bind=0,
           ):

    if hasattr(object,'__bases__'):
        f, names, defaults = handle_class(object, context)
    else:
        f=object
        im=0
        if hasattr(f, 'im_func'):
            im=1
        elif not hasattr(f,'func_defaults'):
            if hasattr(f, '__call__'):
                f=f.__call__
                if hasattr(f, 'im_func'):
                    im=1
                elif not hasattr(f,'func_defaults') and maybe: return object
            elif maybe: return object
    
        if im:
            f=f.im_func
            c=f.func_code
            defaults=f.func_defaults
            names=c.co_varnames[1:c.co_argcount]
        else:
            defaults=f.func_defaults
            c=f.func_code
            names=c.co_varnames[:c.co_argcount]

    nargs=len(names)
    if positional:
        positional=list(positional)
        if bind and nargs and names[0]=='self':
            positional.insert(0, missing_name('self', context))
        if len(positional) > nargs: raise TypeError, 'too many arguments'
        args=positional
    else:
        if bind and nargs and names[0]=='self':
            args=[missing_name('self', context)]
        else:
            args=[]

    get=keyword.get
    nrequired=len(names) - (len(defaults or ()))
    for index in range(len(args), len(names)):
        name=names[index]
        v=get(name, args)
        if v is args:
            if index < nrequired: v=missing_name(name, context)
            else: v=defaults[index-nrequired]
        args.append(v)

    args=tuple(args)
    if debug is not None: return debug(object,args,context)
    else: return apply(object,args)


=== Added File Zope3/lib/python/Zope/Publisher/maybe_lock.py ===
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################
__version__='$Revision: 1.1.2.1 $'[11:-2]

# Waaaa, I wish I didn't have to work this hard.
try: from thread import allocate_lock
except:
    class allocate_lock:
        def acquire(*args): pass
        def release(*args): pass


=== Zope3/lib/python/Zope/Publisher/BaseRequest.py 1.1.2.1 => 1.1.2.2 ===
     # TODO: add security assertion declaring this to be public
 
-    _file = None  # The request input stream
+    body_instream = None  # The body input stream
     common = {}   # Common request data
 
     # _held contains objects kept until the request is closed,
     # such as the database connection closer.
     _held = ()
-    _auth = None  # Unverified credentials presented by the user.
+    _request_default = None  # Overrides publication.getDefault().
+    _body = None             # Cached body
 
     # URL is a string built up during traversal and url_quoted.
     # It does not include names built from publication.getDefault().
@@ -54,12 +55,12 @@
     AUTHENTICATED_USER = None # Authorized user object
     AUTHENTICATION_PATH = ''  # Unquoted path to parent of user folder
 
-    def __init__(self, file, mapping, response):
+    def __init__(self, response, body_instream=None):
         """
         The constructor should not raise errors.
         processInputs() should perform the unsafe initialization.
         """
-        self._file = file
+        self.body_instream = body_instream
         self.steps = []
         self.quoted_steps = []
         self.other = {}
@@ -79,32 +80,33 @@
 
     _key_handlers = {}
 
-    def getRequest(self):
+    def getRequest(self, default):
         return self
     _key_handlers['REQUEST'] = getRequest
 
-    def getURL(self):
+    def getURL(self, default):
         return self.URL
     _key_handlers['URL'] = getURL
 
-    def getBody(self):
-        body = self.BODY
+    def getBody(self, default):
+        body = self._body
         if body is None:
-            p = self._file.tell()
-            self._file.seek(0)
-            body = self._file.read()
-            self._file.seek(p)
-            self.BODY = body
+            s = self.body_instream
+            if s is None:
+                return default
+            p = s.tell()
+            s.seek(0)
+            body = s.read()
+            s.seek(p)
+            self._body = body
         return body
     _key_handlers['BODY'] = getBody
 
-    def getBodyFile(self):
-        return self._file
+    def getBodyFile(self, default):
+        return self.body_instream
     _key_handlers['BODYFILE'] = getBodyFile
 
-    def __getitem__(self, key,
-                    default=_marker, # Any special internal marker will do
-                    ):
+    def __getitem__(self, key, default=_marker):
         """Get a variable value
 
         Return a value for the required variable name.
@@ -113,16 +115,22 @@
         other variables, form data, and then cookies. 
         
         """
-        h = self._key_handlers.get(key, None)
-        if h is not None:
-            return h(self)
-
-        v=self.other.get(key, _marker)
-        if v is not _marker: return v
-        v=self.common.get(key, default)
-        if v is not _marker: return v
-        
-        raise KeyError, key
+        handler = self._key_handlers.get(key, None)
+        if handler is not None:
+            v = handler(self, _marker)
+            if v is not _marker:
+                return v
+        v = self.other.get(key, _marker)
+        if v is not _marker:
+            return v
+        v = self.common.get(key, _marker)
+        if v is not _marker:
+            return v
+
+        if default is not _marker:
+            return default
+        else:
+            raise KeyError, key
 
     def get(self, key, default=None):
         return self.__getitem__(key, default)
@@ -157,7 +165,7 @@
 
     __repr__=__str__
 
-    def _splitPath(self, path):
+    def splitPath(self, path):
         # Split and clean up the path.
         if path[:1] == '/':  path = path[1:]
         if path[-1:] == '/': path = path[:-1]
@@ -170,6 +178,14 @@
             else: clean.append(item)
         return clean
 
+    def setRequestDefault(self, path):
+        """
+        Adds the specified steps to the URL, overriding
+        publication.getDefault().
+        """
+        steps = path.split('/')
+        steps.reverse()
+        self._request_default = steps
 
 ##    def _getDefaultView(self, object, m_name='_browser_default'):
 ##        """
@@ -217,7 +233,7 @@
         Private.
         """
         added_default = 0
-        to_traverse = self._splitPath(path_str)
+        to_traverse = self.splitPath(path_str)
 
         if hasattr(object, '__of__'):
             # Try to bind the top-level object to the request.
@@ -260,7 +276,9 @@
             elif not added_default:
                 # Traverse to the default view, if any.
                 added_default = 1
-                object, add_steps = publication.getDefault(self, object)
+                add_steps = self._request_default
+                if add_steps is None:
+                    object, add_steps = publication.getDefault(self, object)
                 if add_steps:
                     to_traverse.extend(add_steps)