Commit 3a398c24 authored by Aurel's avatar Aurel Committed by Aurel

update local patches, imports and method parameters according to code of zope4

* "OFS.CopySupport exceptions have been removed: you should use strings instead."
* "WSGI is used in place of ZServer."
* "StringType must be imported from types"
* "'script' is forbidden as python script name"
parent 87f3ba91
......@@ -22,7 +22,10 @@ from zLOG import LOG,ERROR,INFO,WARNING
from OFS.Image import File, Image
import os, transaction
from AccessControl import getSecurityManager, ClassSecurityInfo
from Globals import package_home
try:
from App.Common import package_home
except ImportError: # BBB Zope2
from Globals import package_home
import PIL.Image as PIL_Image
import thread
import random
......
......@@ -20,8 +20,12 @@ import ZConfig
import Zope2
from Zope2.Startup.run import make_wsgi_app
from Products.ERP5Type.patches.WSGIPublisher import publish_module
try:
from ZPublisher.WSGIPublisher import _MODULES
from ZPublisher.WSGIPublisher import publish_module
except ImportError:
# BBB Zope2
from Products.ERP5Type.patches.WSGIPublisher import publish_module
# this class licensed under the MIT license (stolen from pyramid_translogger)
class TransLogger(object):
......@@ -167,6 +171,9 @@ def runwsgi():
args = parser.parse_args()
startup = os.path.dirname(Zope2.Startup.__file__)
if os.path.isfile(os.path.join(startup, 'wsgischema.xml')):
schema = ZConfig.loadSchema(os.path.join(startup, 'wsgischema.xml'))
else: # BBB
schema = ZConfig.loadSchema(os.path.join(startup, 'zopeschema.xml'))
conf, _ = ZConfig.loadConfig(schema, args.zope_conf)
......@@ -190,11 +197,11 @@ def runwsgi():
port = int(port)
createServer(
app_wrapper(
large_file_threshold=conf.large_file_threshold,
large_file_threshold=getattr(conf, 'large_file_threshold', None),
webdav_ports=[port] if args.webdav else ()),
listen=args.address,
logger=logging.getLogger("access"),
threads=conf.zserver_threads,
threads=getattr(conf, 'zserver_threads', 4),
asyncore_use_poll=True,
# Prevent waitress from adding its own Via and Server response headers.
ident=None,
......
......@@ -21,7 +21,7 @@ class ComputedAttributeGetItemCompatibleMixin(ZSQLBrain):
"""A brain that supports accessing computed attributes using __getitem__
protocol.
"""
def __init__(self):
def __init__(self, *args, **kw):
# __getitem__ returns the computed attribute directly, but if we access
# brain['node_title'] we expect to have the attribute after computation,
# not the ComputedAttribute attribue instance. Defining a __getitem__
......
......@@ -48,7 +48,10 @@ from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery, SimpleQuery
from Shared.DC.ZRDB.Results import Results
from Products.ERP5Type.Utils import mergeZRDBResults
from App.Extensions import getBrain
try: # BBB Zope 2.12
from App.Extensions import getBrain
except ImportError:
from Shared.DC.ZRDB.DA import getBrain
from MySQLdb import ProgrammingError
from MySQLdb.constants.ER import NO_SUCH_TABLE
......
......@@ -21,8 +21,6 @@ from AccessControl.Permission import Permission
from OFS.ObjectManager import ObjectManager
from OFS.CopySupport import CopyContainer as OriginalCopyContainer
from OFS.CopySupport import CopyError
from OFS.CopySupport import eNotSupported, eNoItemsSpecified, eNoData
from OFS.CopySupport import eNotFound, eInvalid
from OFS.CopySupport import _cb_encode, _cb_decode, cookie_path
from OFS.CopySupport import sanity_check
from Products.ERP5Type import Permissions
......@@ -70,7 +68,7 @@ class CopyContainer:
return OriginalCopyContainer.manage_copyObjects(self, ids, REQUEST,
RESPONSE)
if uids is None and REQUEST is not None:
return eNoItemsSpecified
raise BadRequest('No items specified')
elif uids is None:
raise ValueError('uids must be specified')
......@@ -80,7 +78,7 @@ class CopyContainer:
for uid in uids:
ob=self.getPortalObject().portal_catalog.getObject(uid)
if not ob.cb_isCopyable():
raise CopyError(eNotSupported % uid)
raise CopyError('Not Supported')
m=Moniker.Moniker(ob)
oblist.append(m.dump())
cp=(0, oblist)
......@@ -185,7 +183,7 @@ class CopyContainer:
# Use default methode
return OriginalCopyContainer.manage_cutObjects(self, ids, REQUEST)
if uids is None and REQUEST is not None:
return eNoItemsSpecified
raise BadRequest('No items specified')
elif uids is None:
raise ValueError('uids must be specified')
......@@ -195,7 +193,7 @@ class CopyContainer:
for uid in uids:
ob=self.getPortalObject().portal_catalog.getObject(uid)
if not ob.cb_isMoveable():
raise CopyError(eNotSupported % id)
raise CopyError('Not Supported')
m=Moniker.Moniker(ob)
oblist.append(m.dump())
cp=(1, oblist) # 0->1 This is the difference with manage_copyObject
......@@ -439,7 +437,7 @@ class CopyContainer:
try:
cp = _cb_decode(cp)
except:
raise CopyError(eInvalid)
raise CopyError("Clipboard Error")
oblist = []
op = cp[0]
app = self.getPhysicalRoot()
......@@ -448,7 +446,7 @@ class CopyContainer:
try:
ob = m.bind(app)
except:
raise CopyError(eNotFound)
raise CopyError('Item Not Found')
self._verifyObjectPaste(ob, validate_src=op + 1)
oblist.append(ob)
result = []
......@@ -475,7 +473,7 @@ class CopyContainer:
)[op]
for ob in oblist:
if not getattr(ob, is_doable_id)():
raise CopyError(eNotSupported % escape(ob.getId()))
raise CopyError('Not Supported')
try:
ob._notifyOfCopyTo(self, op=op)
except:
......@@ -595,7 +593,7 @@ class CopyContainer:
elif REQUEST is not None and '__cp' in REQUEST:
cp = REQUEST['__cp']
if cp is None:
raise CopyError(eNoData)
raise CopyError("No Data")
op, result = self.__duplicate(
cp,
duplicate=False,
......
......@@ -17,10 +17,9 @@ import re
try: from IOBTree import Bucket
except: Bucket=lambda:{}
from Shared.DC.ZRDB.Aqueduct import decodestring, parse
from Shared.DC.ZRDB.DA import DA, DatabaseError, SQLMethodTracebackSupplement
from Shared.DC.ZRDB.DA import DA, DatabaseError, SQLMethodTracebackSupplement, getBrain
from Shared.DC.ZRDB import RDB
from Shared.DC.ZRDB.Results import Results
from App.Extensions import getBrain
from AccessControl import ClassSecurityInfo, getSecurityManager
from Products.ERP5Type.Globals import InitializeClass
from Acquisition import aq_base, aq_parent
......
......@@ -89,6 +89,7 @@ DateTimeKlass.__getstate__ = DateTime__getstate__
def DateTime_parse(self, st, datefmt=getDefaultDateFormat()):
# Parse date-time components from a string
month=year=tz=tm=None
try: # BBB DateTime 2.12
spaces =self.space_chars
intpat =self.int_pattern
fltpat =self.flt_pattern
......@@ -97,8 +98,19 @@ def DateTime_parse(self, st, datefmt=getDefaultDateFormat()):
MonthNumbers =self._monthmap
DayOfWeekNames=self._daymap
ValidZones =self._tzinfo._zidx
_MONTH_LEN = self._month_len
except AttributeError:
from DateTime.DateTime import (SPACE_CHARS as spaces,
INT_PATTERN as intpat,
FLT_PATTERN as fltpat,
NAME_PATTERN as wordpat,
DELIMITERS as delimiters,
_MONTHMAP as MonthNumbers,
_DAYMAP as DayOfWeekNames,
_TZINFO,
_MONTH_LEN)
ValidZones = _TZINFO._zidx
TimeModifiers =['am','pm']
# Find timezone first, since it should always be the last
# element, and may contain a slash, confusing the parser.
st= st.strip()
......@@ -236,10 +248,9 @@ def DateTime_parse(self, st, datefmt=getDefaultDateFormat()):
year = _correctYear(year)
#handle dates before year 1000
#if year < 1000: raise SyntaxError, st
leap = year%4==0 and (year%100!=0 or year%400==0)
try:
if not day or day > self._month_len[leap][month]:
if not day or day > _MONTH_LEN[leap][month]:
raise DateError(st)
except IndexError:
raise DateError(st)
......
......@@ -13,7 +13,8 @@
#
##############################################################################
from OFS.PropertySheets import DAVProperties, isDavCollection
from OFS.PropertySheets import DAVProperties
from webdav.common import isDavCollection
from Acquisition import aq_base
# This is required to make an ERP5 Document (folderish) look like a file (non folderish)
......
......@@ -11,8 +11,208 @@
#
##############################################################################
from Products.ERP5Type.Timeout import getPublisherDeadlineValue
from ZPublisher import Publish
from ZPublisher.Publish import (
try:
from ZServer.ZPublisher import Publish
from ZServer.ZPublisher.Publish import (
# Produced using:
# dis.dis(
# compile(open(<this_file>, 'r').read(), 'foo', 'exec').co_consts[
# <index of publish code object in co_consts>
# ]
# )
# and checking all uniques LOAD_GLOBAL names, excluding builtins and
# getPublisherDeadlineValue, and including publish parameter default
# values.
ISkinnable,
IBrowserPage,
recordMetaData,
pubevents,
Redirect,
Retry,
call_object,
dont_publish_class,
endInteraction,
get_module_info,
mapply,
missing_name,
newInteraction,
notify,
publish,
setDefaultSkin,
sys,
urlparse,
noSecurityManager,
)
def publish(request, module_name, after_list, debug=0,
# Optimize:
call_object=call_object,
missing_name=missing_name,
dont_publish_class=dont_publish_class,
mapply=mapply,
):
(bobo_before, bobo_after, object, realm, debug_mode, err_hook,
validated_hook, transactions_manager)= get_module_info(module_name)
parents=None
response=None
try:
with getPublisherDeadlineValue(request):
notify(pubevents.PubStart(request))
# TODO pass request here once BaseRequest implements IParticipation
newInteraction()
request.processInputs()
request_get = request.get
response = request.response
# First check for "cancel" redirect:
if request_get('SUBMIT', '').strip().lower() == 'cancel':
cancel = request_get('CANCEL_ACTION', '')
if cancel:
# Relative URLs aren't part of the spec, but are accepted by
# some browsers.
for part, base in zip(urlparse(cancel)[:3],
urlparse(request['BASE1'])[:3]):
if not part:
continue
if not part.startswith(base):
cancel = ''
break
if cancel:
raise Redirect(cancel)
after_list[0] = bobo_after
if debug_mode:
response.debug_mode = debug_mode
if realm and not request.get('REMOTE_USER', None):
response.realm = realm
noSecurityManager()
if bobo_before is not None:
bobo_before()
# Get the path list.
# According to RFC1738 a trailing space in the path is valid.
path = request_get('PATH_INFO')
request['PARENTS'] = parents = [object]
if transactions_manager:
transactions_manager.begin()
object = request.traverse(path, validated_hook=validated_hook)
if IBrowserPage.providedBy(object):
request.postProcessInputs()
notify(pubevents.PubAfterTraversal(request))
if transactions_manager:
recordMetaData(object, request)
result = mapply(object, request.args, request,
call_object, 1,
missing_name,
dont_publish_class,
request, bind=1)
if result is not response:
response.setBody(result)
notify(pubevents.PubBeforeCommit(request))
if transactions_manager:
transactions_manager.commit()
notify(pubevents.PubSuccess(request))
endInteraction()
return response
except:
# save in order to give 'PubFailure' the original exception info
exc_info = sys.exc_info()
# DM: provide nicer error message for FTP
sm = None
if response is not None:
sm = getattr(response, "setMessage", None)
if sm is not None:
from asyncore import compact_traceback
cl, val = sys.exc_info()[:2]
sm('%s: %s %s' % (
getattr(cl, '__name__', cl), val,
debug_mode and compact_traceback()[-1] or ''))
# debug is just used by tests (has nothing to do with debug_mode!)
if not debug and err_hook is not None:
retry = False
if parents:
parents = parents[0]
try:
try:
with getPublisherDeadlineValue(request):
return err_hook(parents, request,
sys.exc_info()[0],
sys.exc_info()[1],
sys.exc_info()[2],
)
except Retry:
if not request.supports_retry():
with getPublisherDeadlineValue(request):
return err_hook(parents, request,
sys.exc_info()[0],
sys.exc_info()[1],
sys.exc_info()[2],
)
retry = True
finally:
# Note: 'abort's can fail.
# Nevertheless, we want end request handling.
try:
try:
notify(pubevents.PubBeforeAbort(
request, exc_info, retry))
finally:
if transactions_manager:
transactions_manager.abort()
finally:
endInteraction()
notify(pubevents.PubFailure(request, exc_info, retry))
# Only reachable if Retry is raised and request supports retry.
newrequest = request.retry()
request.close() # Free resources held by the request.
# Set the default layer/skin on the newly generated request
if ISkinnable.providedBy(newrequest):
setDefaultSkin(newrequest)
try:
return publish(newrequest, module_name, after_list, debug)
finally:
newrequest.close()
else:
# Note: 'abort's can fail.
# Nevertheless, we want end request handling.
try:
try:
notify(pubevents.PubBeforeAbort(request, exc_info, False))
finally:
if transactions_manager:
transactions_manager.abort()
finally:
endInteraction()
notify(pubevents.PubFailure(request, exc_info, False))
raise
Publish.publish = publish
except ImportError: # BBB Zope2
from ZPublisher import Publish, pubevents
from ZPublisher.Publish import (
# Produced using:
# dis.dis(
# compile(open(<this_file>, 'r').read(), 'foo', 'exec').co_consts[
......@@ -43,9 +243,8 @@ from ZPublisher.Publish import (
setDefaultSkin,
sys,
urlparse,
)
def publish(request, module_name, after_list, debug=0,
)
def publish(request, module_name, after_list, debug=0,
# Optimize:
call_object=call_object,
missing_name=missing_name,
......@@ -203,4 +402,4 @@ def publish(request, module_name, after_list, debug=0,
notify(PubFailure(request, exc_info, False))
raise
Publish.publish = publish
Publish.publish = publish
......@@ -16,26 +16,48 @@ import copy
import sys
import types
from RestrictedPython.RestrictionMutator import RestrictionMutator
try:
from RestrictedPython.transformer import FORBIDDEN_FUNC_NAMES
except:
# BBB
FORBIDDEN_FUNC_NAMES = frozenset(['printed',])
_MARKER = []
def checkNameLax(self, node, name=_MARKER):
"""Verifies that a name being assigned is safe.
def checkNameLax(self, node, name=_MARKER, allow_magic_methods=False):
"""Check names if they are allowed.
In ERP5 we are much more lax that than in Zope's original restricted
python and allow to using names starting with _, because we rely on
runtime checks to prevent access to forbidden attributes from objects.
We don't allow defining attributes ending with __roles__ though.
If ``allow_magic_methods is True`` names in `ALLOWED_FUNC_NAMES`
are additionally allowed although their names start with `_`.
"""
if name is None:
return
if name is _MARKER:
# we use same implementation for checkName and checkAttrName which access
# the name in different ways ( see RestrictionMutator 3.6.0 )
name = node.attrname
if name.endswith('__roles__'):
self.error(node, '"%s" is an invalid variable name because '
'it ends with "__roles__".' % name)
elif name in FORBIDDEN_FUNC_NAMES:
self.error(node, '"{name}" is a reserved name.'.format(name=name))
RestrictionMutator.checkName = RestrictionMutator.checkAttrName = checkNameLax
try:
from RestrictedPython.transformer import RestrictingNodeTransformer
RestrictingNodeTransformer.check_name = checkNameLax
except ImportError:
# BBB Restriced 3.6.0
from RestrictedPython.RestrictionMutator import RestrictionMutator
RestrictionMutator.checkName = RestrictionMutator.checkAttrName = checkNameLax
from Acquisition import aq_acquire
......@@ -49,18 +71,22 @@ from AccessControl.ZopeGuards import (safe_builtins, _marker, Unauthorized,
# TODO: add buffer/bytearray
def add_builtins(**kw):
assert not set(safe_builtins).intersection(kw)
assert not set(safe_builtins).intersection(kw), "%r intersect %r\n%r" %(safe_builtins, kw, set(safe_builtins).intersection(kw))
safe_builtins.update(kw)
del safe_builtins['dict']
del safe_builtins['list']
add_builtins(Ellipsis=Ellipsis, NotImplemented=NotImplemented,
dict=dict, list=list, set=set, frozenset=frozenset)
dict=dict, list=list)
if "set" not in safe_builtins: # BBB
add_builtins(set=set, frozenset=frozenset, slice=slice)
add_builtins(bin=bin, classmethod=classmethod, format=format, object=object,
property=property, slice=slice, staticmethod=staticmethod,
property=property, staticmethod=staticmethod,
super=super, type=type)
def guarded_next(iterator, default=_marker):
"""next(iterator[, default])
......@@ -81,7 +107,10 @@ def guarded_next(iterator, default=_marker):
if default is _marker:
raise
return default
add_builtins(next=guarded_next)
#if "next" not in safe_builtins: # BBB
# override the default next if exists
safe_builtins.update(next=guarded_next)
# add_builtins()
_safe_class_attribute_dict = {}
import inspect
......@@ -237,7 +266,7 @@ from AccessControl.ZopeGuards import _dict_white_list
# (closure) directly to ignore defaultdict like dict/list
from RestrictedPython.Guards import full_write_guard
ContainerAssertions[defaultdict] = _check_access_wrapper(defaultdict, _dict_white_list)
full_write_guard.func_closure[1].cell_contents.__self__[defaultdict] = True
#XXXfull_write_guard.func_closure[1].cell_contents.__self__[defaultdict] = True
ContainerAssertions[OrderedDict] = _check_access_wrapper(OrderedDict, _dict_white_list)
OrderedDict.__guarded_setitem__ = OrderedDict.__setitem__.__func__
......
......@@ -54,6 +54,11 @@ from ZPublisher.mapply import mapply
from ZPublisher.WSGIPublisher import call_object
from ZPublisher.WSGIPublisher import missing_name, WSGIResponse
try:
from ZServer.ZPublisher import Publish
isZope4 = True
except ImportError:
isZope4 = False
if sys.version_info >= (3, ):
_FILE_TYPES = (IOBase, )
......@@ -96,6 +101,7 @@ if 1: # upstream moved WSGIResponse to HTTPResponse.py
if lock:
self._locked_body = 1
if not isZope4:
WSGIResponse.setBody = setBody
def write(self, data):
......@@ -411,10 +417,17 @@ def load_app(module_info):
try:
yield (app, realm, debug_mode, validated_hook)
finally:
if transaction.manager._txn is not None:
if isZope4:
if transaction.manager.manager._txn is not None:
# Only abort a transaction, if one exists. Otherwise the
# abort creates a new transaction just to abort it.
transaction.abort()
else:
if getattr(transaction.manager, '_txn', None) is not None:
# Only abort a transaction, if one exists. Otherwise the
# abort creates a new transaction just to abort it.
transaction.abort()
app._p_jar.close()
......
......@@ -13,6 +13,7 @@
from Shared.DC.ZRDB.sqltest import *
from Shared.DC.ZRDB import sqltest
from DateTime import DateTime
from types import StringType
list_type_list = list, tuple, set, frozenset, dict
......@@ -50,7 +51,7 @@ if 1: # For easy diff with original
if type(v) is StringType:
if v[-1:]=='L':
v=v[:-1]
atoi(v)
int(v)
else: v=str(int(v))
except ValueError:
raise ValueError(
......@@ -58,7 +59,7 @@ if 1: # For easy diff with original
elif t=='float':
if not v and type(v) is StringType: continue
try:
if type(v) is StringType: atof(v)
if type(v) is StringType: float(v)
else: v=str(float(v))
except ValueError:
raise ValueError(
......@@ -92,7 +93,7 @@ if 1: # For easy diff with original
'No input was provided for <em>%s</em>' % name)
if len(vs) > 1:
vs=join(map(str,vs),', ')
vs = ', '.join(map(str, vs))
if self.op == '<>':
## Do the equivalent of 'not-equal' for a list,
## "a not in (b,c)"
......@@ -103,4 +104,11 @@ if 1: # For easy diff with original
return "%s %s %s" % (self.column, self.op, vs[0])
SQLTest.render = SQLTest.__call__ = render
sqltest.valid_type = (('int', 'float', 'string', 'nb', 'datetime') + tuple('datetime(%s)' % x for x in xrange(7))).__contains__
new_valid_types = (('int', 'float', 'string', 'nb', 'datetime') + tuple('datetime(%s)' % x for x in xrange(7)))
try:
# BBB
from Shared.DC.ZRDB.sqltest import valid_type
sqltest.valid_type = new_valid_types.__contains__
except ImportError:
sqltest.valid_types = new_valid_types
......@@ -83,11 +83,15 @@ def SQLVar_render(self, md):
% (t, self.__name__, v))
# Patched by yo. datetime is added.
new_valid_types = 'int', 'float', 'string', 'nb', 'datetime'
new_valid_types += tuple(map('datetime(%s)'.__mod__, xrange(7)))
try:
# BBB
from Shared.DC.ZRDB.sqlvar import valid_type
sqlvar.valid_type = new_valid_types.__contains__
except ImportError:
sqlvar.valid_types = new_valid_types
valid_type = 'int', 'float', 'string', 'nb', 'datetime'
valid_type += tuple(map('datetime(%s)'.__mod__, xrange(7)))
valid_type = valid_type.__contains__
SQLVar.render = SQLVar_render
SQLVar.__call__ = SQLVar_render
sqlvar.valid_type = valid_type
......@@ -141,7 +141,7 @@ class DummyMessageCatalog:
else:
return default
def translate(self, msgid, mapping=None, context=None,
target_language=None, default=None):
target_language=None, default=None, *args, **kw):
return default
class DummyLocalizer:
......
......@@ -28,7 +28,7 @@ from ComputedAttribute import ComputedAttribute
# FIXME: manage_renameObject hack needs these imports
from Acquisition import aq_base
from App.Dialogs import MessageDialog
from OFS.CopySupport import CopyError, eNotSupported
from OFS.CopySupport import CopyError
import sys
class Form:
......@@ -688,7 +688,7 @@ class ZMIForm(ObjectManager, PropertyManager, RoleManager, Item, Form):
action ='manage_main'))
ob=self._getOb(id)
if not ob.cb_isMoveable():
raise CopyError(eNotSupported % id)
raise CopyError('Not Supported')
self._verifyObjectPaste(ob)
try: ob._notifyOfCopyTo(self, op=1)
except: raise CopyError(MessageDialog(
......
......@@ -244,7 +244,7 @@ class HBTreeFolder2Tests(ERP5TypeTestCase):
h = HBTreeFolder2()
# whatever value, as long as it has an __of__
h._setOb('foo', HBTreeFolder2())
script = PythonScript('script')
script = PythonScript('test_script')
script.ZPythonScript_edit('h', dedent("""
for dummy in h.objectIds():
pass
......
......@@ -206,7 +206,9 @@ class MessageCatalog(LanguageManager, ObjectManager, SimpleItem):
def translate(self, msgid, mapping=None, context=None,
target_language=None, default=None):
target_language=None, default=None,
# zope i18n 4.7
msgid_plural=None, default_plural=None, number=None):
""" """
msgstr = self.gettext(msgid, lang=target_language, default=default)
# BBB support str in mapping by converting to unicode for
......
......@@ -27,7 +27,7 @@ from Acquisition import Implicit, aq_base
from Persistence import Persistent
from DocumentTemplate.DT_Util import InstanceDict, TemplateDict
from DocumentTemplate.DT_Util import Eval
from AccessControl.Permission import name_trans
from AccessControl.Permission import pname
from AccessControl.Permissions import import_export_objects, \
manage_zcatalog_entries
from .SQLCatalog import CatalogError
......@@ -1364,7 +1364,7 @@ InitializeClass(ZCatalog)
def p_name(name):
return '_' + string.translate(name, name_trans) + '_Permission'
return pname(name)
def absattr(attr):
if callable(attr): return attr()
......
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