Commit c75f735c authored by Evan Simpson's avatar Evan Simpson

Merge Before-traverse-Dev-branch

parent dbf73423
......@@ -89,8 +89,8 @@ Aqueduct database adapters, etc.
This module can also be used as a simple template for implementing new
item types.
$Id: SimpleItem.py,v 1.75 2000/06/01 17:29:37 jim Exp $'''
__version__='$Revision: 1.75 $'[11:-2]
$Id: SimpleItem.py,v 1.76 2000/06/09 23:57:46 evan Exp $'''
__version__='$Revision: 1.76 $'[11:-2]
import regex, sys, Globals, App.Management, Acquisition, App.Undo
import AccessControl.Role, AccessControl.Owned, App.Common
......@@ -143,7 +143,7 @@ class Item(Base, Resource, CopySource, App.Management.Tabs,
# Default propertysheet info:
__propsets__=()
manage_options=(
App.Undo.UndoSupport.manage_options
+AccessControl.Owned.Owned.manage_options
......@@ -338,14 +338,19 @@ class Item(Base, Resource, CopySource, App.Management.Tabs,
return 1
def absolute_url(self, relative=0):
id=quote(self.id)
p=getattr(self,'aq_inner', None)
if p is not None:
url=p.aq_parent.absolute_url(relative)
if url: id=url+'/'+id
return id
req = self.REQUEST
rpp = req.get('VirtualRootPhysicalPath', ('',))
spp = self.getPhysicalPath()
i = 0
for name in rpp[:len(spp)]:
if spp[i] == name:
i = i + 1
else:
break
path = map(quote, spp[i:])
if relative: # Deprecated - use getPhysicalPath
return join(path, '/')
return join([req['SERVER_URL']] + req._script + path, '/')
def getPhysicalPath(self):
'''Returns a path (an immutable sequence of strings)
......@@ -462,14 +467,20 @@ class Item_w__name__(Item):
self.__name__=id
def absolute_url(self, relative=0):
id=quote(self.__name__)
p=getattr(self,'aq_inner', None)
if p is not None:
url=p.aq_parent.absolute_url(relative)
if url: id=url+'/'+id
return id
req = self.REQUEST
rpp = req.get('VirtualRootPhysicalPath', ('',))
spp = self.getPhysicalPath()
i = 0
for name in rpp[:len(spp)]:
if spp[i] == name:
i = i + 1
else:
break
path = map(quote, spp[i:])
if relative:
# This is useful for physical path relative to a VirtualRoot
return join(path, '/')
return join([req['SERVER_URL']] + req._script + path, '/')
def getPhysicalPath(self):
'''Returns a path (an immutable sequence of strings)
......
This diff is collapsed.
"""BeforeTraverse interface and helper classes"""
# Interface
def registerBeforeTraverse(container, object, app_handle, priority=99):
"""Register an object to be called before a container is traversed.
'app_handle' should be a string or other hashable value that
distinguishes the application of this object, and which must
be used in order to unregister the object.
If the container will be pickled, the object must be a callable class
instance, not a function or method.
'priority' is optional, and determines the relative order in which
registered objects will be called.
"""
btr = getattr(container, '__before_traverse__', {})
btr[(priority, app_handle)] = object
rewriteBeforeTraverse(container, btr)
def unregisterBeforeTraverse(container, app_handle):
"""Unregister a __before_traverse__ hook object, given its 'app_handle'.
Returns a list of unregistered objects."""
btr = getattr(container, '__before_traverse__', {})
objects = []
for k in btr.keys():
if k[1] == app_handle:
objects.append(btr[k])
del btr[k]
if objects:
rewriteBeforeTraverse(container, btr)
return objects
def queryBeforeTraverse(container, app_handle):
"""Find __before_traverse__ hook objects, given an 'app_handle'.
Returns a list of (priority, object) pairs."""
btr = getattr(container, '__before_traverse__', {})
objects = []
for k in btr.keys():
if k[1] == app_handle:
objects.append((k[0], btr[k]))
return objects
# Implementation tools
def rewriteBeforeTraverse(container, btr):
"""Rewrite the list of __before_traverse__ hook objects"""
container.__before_traverse__ = btr
hookname = '__before_publishing_traverse__'
dic = hasattr(container.__class__, hookname)
bpth = container.__dict__.get(hookname, None)
if isinstance(bpth, MultiHook):
bpth = bpth._prior
bpth = MultiHook(hookname, bpth, dic)
setattr(container, hookname, bpth)
keys = btr.keys()
keys.sort()
for key in keys:
bpth.add(btr[key])
class MultiHook:
"""Class used to multiplex hook.
MultiHook calls the named hook from the class of the container, then
the prior hook, then all the hooks in its list.
"""
def __init__(self, hookname, prior, defined_in_class):
self._hookname = hookname
self._prior = prior
self._defined_in_class = defined_in_class
self._list = []
def __call__(self, container, request):
if self._defined_in_class:
# Assume it's an unbound method
getattr(container.__class__, self._hookname)(container, request)
prior = self._prior
if prior is not None:
prior(container, request)
for cob in self._list:
cob(container, request)
def add(self, cob):
self._list.append(cob)
# Helper class
class NameCaller:
"""Class used to proxy sibling objects by name.
When called with a container and request object, it gets the named
attribute from the container and calls it. If the name is not
found, it fails silently.
>>> registerBeforeTraverse(folder, NameCaller('preop'), 'XApp')
"""
def __init__(self, name):
self.name = name
def __call__(self, container, request):
try:
meth = getattr(container, self.name)
except AttributeError:
return
args = getattr(getattr(meth, 'func_code', None), 'co_argcount', 2)
apply(meth, (container, request, None)[:args])
......@@ -83,14 +83,14 @@
#
##############################################################################
__version__='$Revision: 1.34 $'[11:-2]
__version__='$Revision: 1.35 $'[11:-2]
import regex, sys, os, string
import regex, sys, os, string, urllib
from string import lower, atoi, rfind, split, strip, join, upper, find
from BaseRequest import BaseRequest
from HTTPResponse import HTTPResponse
from cgi import FieldStorage
from urllib import quote, unquote
from urllib import quote, unquote, splittype, splitport
from Converters import get_converter
from maybe_lock import allocate_lock
xmlrpc=None # Placeholder for module that we'll import if we have to.
......@@ -120,6 +120,8 @@ hide_key={'HTTP_AUTHORIZATION':1,
'HTTP_CGI_AUTHORIZATION': 1,
}.has_key
default_port={'http': '80', 'https': '443'}
_marker=[]
class HTTPRequest(BaseRequest):
"""\
......@@ -186,19 +188,46 @@ class HTTPRequest(BaseRequest):
return r
def setSite(self, base=None):
""" blah """
if base is not None:
self.script = self.base = base
# reset the URL
self.other['URL'] = self.script
# clear the 'cache' of URLx and BASEx
def setServerURL(self, protocol=None, hostname=None, port=None):
""" Set the parts of generated URLs. """
other = self.other
server_url = other.get('SERVER_URL', '')
if protocol is None and hostname is None and port is None:
return server_url
oldprotocol, oldhost = splittype(server_url)
oldhostname, oldport = splitport(oldhost[2:])
if protocol is None: protocol = oldprotocol
if hostname is None: hostname = oldhostname
if port is None: port = oldport
if (port is None or default_port[protocol] == port):
host = hostname
else:
host = hostname + ':' + port
server_url = other['SERVER_URL'] = '%s://%s' % (protocol, host)
self._resetURLS()
return server_url
def setVirtualRoot(self, path, hard=0):
""" Treat the current publishing object as a VirtualRoot """
other = self.other
if type(path) is type(''):
path = filter(None, split(path, '/'))
self._script[:] = map(quote, path)
del self._steps[:]
parents = other['PARENTS']
if hard:
del parents[:-1]
other['VirtualRootPhysicalPath'] = parents[-1].getPhysicalPath()
self._resetURLS()
def _resetURLS(self):
other = self.other
other['URL'] = join([other['SERVER_URL']] + self._script +
self._steps, '/')
for x in self._urls:
del self.other[x]
del self.other['PARENTS'][:]
self._urls = ()
def __init__(self, stdin, environ, response, clean=0):
self._orig_env=environ
......@@ -221,11 +250,16 @@ class HTTPRequest(BaseRequest):
other=self.other={'RESPONSE': response}
self.form={}
self.steps=[]
self._steps=[]
################################################################
# Get base info first. This isn't likely to cause
# errors and might be useful to error handlers.
b=script=strip(get_env('SCRIPT_NAME',''))
# _script and the other _names are meant for URL construction
self._script = map(quote, filter(None, split(script, '/')))
while b and b[-1]=='/': b=b[:-1]
p = rfind(b,'/')
if p >= 0: b=b[:p+1]
......@@ -234,23 +268,24 @@ class HTTPRequest(BaseRequest):
server_url=get_env('SERVER_URL',None)
if server_url is not None:
server_url=strip(server_url)
other['SERVER_URL'] = server_url = strip(server_url)
else:
if have_env('HTTPS') and (
environ['HTTPS'] == "on" or environ['HTTPS'] == "ON"):
server_url='https://'
protocol = 'https'
elif (have_env('SERVER_PORT_SECURE') and
environ['SERVER_PORT_SECURE'] == "1"):
server_url='https://'
else: server_url='http://'
protocol = 'https'
else: protocol = 'http'
if have_env('HTTP_HOST'):
server_url=server_url+strip(environ['HTTP_HOST'])
host = strip(environ['HTTP_HOST'])
hostname, port = splitport(host)
else:
server_url=server_url+strip(environ['SERVER_NAME'])
server_port=environ['SERVER_PORT']
if server_port!='80': server_url=server_url+':'+server_port
other['SERVER_URL']=server_url
hostname = strip(environ['SERVER_NAME'])
port = environ['SERVER_PORT']
self.setServerURL(protocol=protocol, hostname=hostname, port=port)
server_url = other['SERVER_URL']
if server_url[-1:]=='/': server_url=server_url[:-1]
......@@ -437,7 +472,7 @@ class HTTPRequest(BaseRequest):
reclist.reverse()
if not hasattr(x,attr):
#If the attribute does not
#exist, set it
#exist, setit
if flags&SEQUENCE: item=[item]
reclist.remove(x)
setattr(x,attr,item)
......@@ -722,13 +757,11 @@ class HTTPRequest(BaseRequest):
return other[key]
if key[:1]=='U' and URLmatch(key) >= 0:
n=atoi(key[3:])
URL=other['URL']
for i in range(0,n):
l=rfind(URL,'/')
if l >= 0: URL=URL[:l]
else: raise KeyError, key
if len(URL) < len(self.base) and n > 1: raise KeyError, key
path = self._script + self._steps
n = len(path) - atoi(key[3:])
if n < 0:
raise KeyError, key
URL=join([other['SERVER_URL']] + path[:n], '/')
other[key]=URL
self._urls = self._urls + (key,)
return URL
......@@ -743,20 +776,17 @@ class HTTPRequest(BaseRequest):
if key[:1]=='B':
if BASEmatch(key) >= 0:
n=atoi(key[4:])
path = self._steps
n = atoi(key[4:])
if n:
n=n-1
if len(self.steps) < n:
n = n - 1
if len(path) < n:
raise KeyError, key
v=self.script
while v[-1:]=='/': v=v[:-1]
v=join([v]+self.steps[:n],'/')
v = self._script + path[:n]
else:
v=self.base
while v[-1:]=='/': v=v[:-1]
other[key]=v
v = self._script[:-1]
other[key] = v = join([other['SERVER_URL']] + v, '/')
self._urls = self._urls + (key,)
return v
......@@ -977,8 +1007,6 @@ def parse_cookie(text,
return apply(parse_cookie,(text[l:],result))
import sys
# add class
class record:
def __getattr__(self, key, default=None):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment