Back to index

plone3  3.1.7
utils.py
Go to the documentation of this file.
00001 ################################################################################
00002 #
00003 # Copyright (c) 2002-2005, Benjamin Saller <bcsaller@ideasuite.com>, and
00004 #                              the respective authors. All rights reserved.
00005 # For a list of Archetypes contributors see docs/CREDITS.txt.
00006 #
00007 # Redistribution and use in source and binary forms, with or without
00008 # modification, are permitted provided that the following conditions are met:
00009 #
00010 # * Redistributions of source code must retain the above copyright notice, this
00011 #   list of conditions and the following disclaimer.
00012 # * Redistributions in binary form must reproduce the above copyright notice,
00013 #   this list of conditions and the following disclaimer in the documentation
00014 #   and/or other materials provided with the distribution.
00015 # * Neither the name of the author nor the names of its contributors may be used
00016 #   to endorse or promote products derived from this software without specific
00017 #   prior written permission.
00018 #
00019 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00020 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00022 # FOR A PARTICULAR PURPOSE.
00023 #
00024 ################################################################################
00025 """
00026 """
00027 
00028 import re
00029 import sys
00030 import logging
00031 
00032 from zope.tal import ndiff
00033 from Globals import InitializeClass, package_home
00034 from UserDict import UserDict
00035 import ExtensionClass
00036 from Acquisition import Implicit
00037 from AccessControl import ClassSecurityInfo
00038 from ZPublisher.BeforeTraverse import registerBeforeTraverse
00039 from ZPublisher.HTTPRequest import HTTPRequest
00040 from ZPublisher.HTTPResponse import HTTPResponse
00041 from Persistence import Persistent
00042 
00043 from Products.Archetypes.atapi import registerType
00044 from Products.Archetypes.atapi import process_types
00045 from Products.Archetypes.atapi import listTypes
00046 from Products.Archetypes.atapi import BaseContent
00047 from Products.Archetypes.config import PKG_NAME
00048 
00049 logger = logging.getLogger('Archetypes')
00050 
00051 PACKAGE_HOME = package_home(globals())
00052 
00053 try:
00054     import Zope2
00055 except ImportError:
00056     ZOPE28 = False
00057 else:
00058     ZOPE28 = True
00059 
00060 try:
00061     from OFS import subscribers
00062 except ImportError:
00063     ZOPE29 = False
00064 else:
00065     ZOPE29 = True
00066 
00067 
00068 def gen_class(klass, schema=None):
00069     """generats and registers the klass
00070     """
00071     if schema is not None:
00072         klass.schema = schema.copy()
00073     registerType(klass, 'Archetypes')
00074     content_types, constructors, ftis = process_types(listTypes(), PKG_NAME)
00075 
00076 def mkDummyInContext(klass, oid, context, schema=None):
00077     gen_class(klass, schema)
00078     dummy = klass(oid=oid).__of__(context)
00079     context._setObject(oid, dummy, suppress_events=True)
00080     dummy.initializeArchetype()
00081     return dummy
00082 
00083 def makeContent( container, portal_type, id='document', **kw ):
00084     container.invokeFactory( type_name=portal_type, id=id )
00085     return getattr( container, id )
00086 
00087 class Dummy(BaseContent):
00088     def Title(self):
00089         return 'title'
00090 
00091 def normalize_html(s):
00092     s = re.sub(r"\s+", " ", s)
00093     s = re.sub(r"(?s)\s+<", "<", s)
00094     s = re.sub(r"(?s)>\s+", ">", s)
00095     return s
00096 
00097 def nicerange(lo, hi):
00098     if hi <= lo+1:
00099         return str(lo+1)
00100     else:
00101         return "%d,%d" % (lo+1, hi)
00102 
00103 def showdiff(a, b):
00104     cruncher = ndiff.SequenceMatcher(ndiff.IS_LINE_JUNK, a, b)
00105     for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
00106         if tag == "equal":
00107             continue
00108         print nicerange(alo, ahi) + tag[0] + nicerange(blo, bhi)
00109         ndiff.dump('<', a, alo, ahi)
00110         if a and b:
00111             print '---'
00112         ndiff.dump('>', b, blo, bhi)
00113 
00114 def populateFolder(folder, folder_type, doc_type):
00115     """ Creates a structure like:
00116 
00117     \index_html
00118     \doc1
00119     \folder1
00120        \folder11
00121        \folder12
00122        \doc11
00123     \folder2
00124        \folder21
00125        \doc21
00126        \index_html
00127        \folder22
00128           \folder221
00129              \doc2211
00130              \doc2212
00131           \folder222
00132              \doc2221
00133              \doc2222
00134           \folder223
00135              \doc2231
00136              \doc2232
00137     """
00138     folder.invokeFactory(doc_type, id='index_html')
00139     folder.invokeFactory(doc_type, id='doc1')
00140     folder.invokeFactory(folder_type, id='folder1')
00141     folder.invokeFactory(folder_type, id='folder2')
00142     f1 = folder.folder1
00143     f2 = folder.folder2
00144     f1.invokeFactory(folder_type, id='folder11')
00145     f1.invokeFactory(folder_type, id='folder12')
00146     f1.invokeFactory(doc_type, id='doc11')
00147     f2.invokeFactory(folder_type, id='folder21')
00148     f2.invokeFactory(folder_type, id='folder22')
00149     f2.invokeFactory(doc_type, id='doc21')
00150     f2.invokeFactory(doc_type, id='index_html')
00151     f22 = f2.folder22
00152     f22.invokeFactory(folder_type, id='folder221')
00153     f221 = f22.folder221
00154     f221.invokeFactory(doc_type, id='doc2211')
00155     f221.invokeFactory(doc_type, id='doc2212')
00156     f22.invokeFactory(folder_type, id='folder222')
00157     f222 = f22.folder222
00158     f222.invokeFactory(doc_type, id='doc2221')
00159     f222.invokeFactory(doc_type, id='doc2222')
00160     f22.invokeFactory(folder_type, id='folder223')
00161     f223 = f22.folder223
00162     f223.invokeFactory(doc_type, id='doc2231')
00163     f223.invokeFactory(doc_type, id='doc2232')
00164 
00165 WRAPPER = '__at_is_wrapper_method__'
00166 ORIG_NAME = '__at_original_method_name__'
00167 def isWrapperMethod(meth):
00168     return getattr(meth, WRAPPER, False)
00169 
00170 def wrap_method(klass, name, method, pattern='__at_wrapped_%s__'):
00171     old_method = getattr(klass, name)
00172     if isWrapperMethod(old_method):
00173         logger.warning('Wrapping already wrapped method at %s.%s' %
00174                        (klass.__name__, name))
00175     new_name = pattern % name
00176     setattr(klass, new_name, old_method)
00177     setattr(method, ORIG_NAME, new_name)
00178     setattr(method, WRAPPER, True)
00179     setattr(klass, name, method)
00180 
00181 def unwrap_method(klass, name):
00182     old_method = getattr(klass, name)
00183     if not isWrapperMethod(old_method):
00184         raise ValueError, ('Trying to unwrap non-wrapped '
00185                            'method at %s.%s' % (klass.__name__, name))
00186     orig_name = getattr(old_method, ORIG_NAME)
00187     new_method = getattr(klass, orig_name)
00188     delattr(klass, orig_name)
00189     setattr(klass, name, new_method)
00190 
00191 class FakeRequestSession(ExtensionClass.Base, UserDict):
00192     """Dummy dict like object with set method for SESSION and REQUEST
00193     """
00194     security = ClassSecurityInfo()
00195     security.setDefaultAccess('allow')
00196     security.declareObjectPublic()
00197     
00198     def __init__(self):
00199         UserDict.__init__(self)
00200         # add a dummy because request mustn't be empty for test
00201         # like 'if REQUEST:'
00202         self['__dummy__'] = None
00203     
00204     def __nonzero__(self):
00205         return True
00206     
00207     def set(self, key, value):
00208         self[key] = value
00209 
00210 InitializeClass(FakeRequestSession)
00211 FakeRequestSession()
00212 
00213 class DummySessionDataManager(Implicit):
00214     """Dummy sdm for sessioning
00215     
00216     Uses traversal hooks to add the SESSION object as lazy item to the request
00217     """
00218     security = ClassSecurityInfo()
00219     security.setDefaultAccess('allow')
00220     security.declareObjectPublic()
00221     
00222     id = 'session_data_manager'
00223     
00224     def __init__(self):
00225         self.session = FakeRequestSession()
00226         
00227     def manage_afterAdd(self, item, container):
00228         """Register traversal hooks to add SESSION to request
00229         """
00230         parent = self.aq_inner.aq_parent
00231         hook = DummySDMTraverseHook()
00232         registerBeforeTraverse(parent, hook, 'SessionDataManager', 50)
00233 
00234     def getSessionData(self, create=1):
00235         """ """
00236         return self.session
00237     
00238     def hasSessionData(self):
00239         """ """
00240         return True
00241     
00242     def getSessionDataByKey(self, key):
00243         """ """
00244         return self.session
00245     
00246     def getBrowserIdManager(self):
00247         """ """
00248         # dummy
00249         return self
00250 
00251 InitializeClass(DummySessionDataManager)
00252 
00253 class DummySDMTraverseHook(Persistent):
00254     """Traversal hook for dummy sessions
00255     
00256     See Products.Sessions.SessionDataManager.SessionDataManagerTraverser
00257     """
00258     
00259     def __call__(self, container, request):
00260         id = DummySessionDataManager.id
00261         sdm = getattr(container, id)
00262         getSessionData = sdm.getSessionData
00263         request.set_lazy('SESSION', getSessionData)
00264 
00265 from Products.Five import BrowserView
00266 class SimpleView(BrowserView):
00267     def __call__(self):
00268         return 'SimpleView simple output'
00269 
00270 def aputrequest(file, content_type):
00271     resp = HTTPResponse(stdout=sys.stdout)
00272     environ = {}
00273     environ['SERVER_NAME']='foo'
00274     environ['SERVER_PORT']='80'
00275     environ['REQUEST_METHOD'] = 'PUT'
00276     environ['CONTENT_TYPE'] = content_type
00277     req = HTTPRequest(stdin=file, environ=environ, response=resp)
00278     return req