Commit 714b1bf4 authored by Arnaud Fontaine's avatar Arnaud Fontaine

WIP

parent c52a586a
......@@ -3317,7 +3317,10 @@ VALUES
def test_reindexWithGroupId(self):
CatalogTool = type(self.getCatalogTool().aq_base)
counts = []
orig_catalogObjectList = CatalogTool.catalogObjectList.__func__
orig_catalogObjectList = CatalogTool.catalogObjectList
import six
if six.PY2:
orig_catalogObjectList = orig_catalogObjectList.__func__
def catalogObjectList(self, object_list, *args, **kw):
counts.append(len(object_list))
return orig_catalogObjectList(self, object_list, *args, **kw)
......
......@@ -37,7 +37,10 @@ from Products.ERP5Type.patches.WorkflowTool import \
WorkflowHistoryList as LegacyWorkflowHistoryList
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
orig_maybe_rotate = DoublyLinkList._maybe_rotate.__func__
orig_maybe_rotate = DoublyLinkList._maybe_rotate
import six
if six.PY2:
orig_maybe_rotate = orig_maybe_rotate.__func__
def _maybe_rotate(self):
if len(self._log) < 16:
......
......@@ -72,7 +72,10 @@ class DummyMovement(Movement):
parent = self.getParentValue()
if isinstance(parent, DummyDelivery):
self = parent
return DummyDelivery.getSimulationState.__func__(self)
getSimulationState = DummyDelivery.getSimulationState
if six.PY2:
getSimulationState = getSimulationState.__func__
return getSimulationState(self)
def getDeliveryValue(self):
"""
......
......@@ -34,7 +34,7 @@ from Acquisition import aq_parent
# If the sort order below doesn't work, we cannot guarantee the sort key
# used below will actually result in the activity connection being committed
# after the ZODB and Catalog data.
assert None < 0 < '' < (), "Cannot guarantee commit of activities comes after the appropriate data"
##TypeError assert None < 0 < '' < (), "Cannot guarantee commit of activities comes after the appropriate data"
manage_addActivityConnectionForm = HTMLFile('dtml/connectionAdd', globals())
......
......@@ -1887,7 +1887,10 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor):
Speed up test by not interrupting the first transaction
as soon as we have the information we want.
"""
original_query = DB.query.__func__
original_query = DB.query
import six
if six.PY2:
original_query = original_query.__func__
def query(self, query_string, *args, **kw):
if query_string.startswith('INSERT'):
insert_list.append(len(query_string))
......@@ -2058,7 +2061,10 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor):
def testTryNotificationSavedOnEventLogWhenNotifyUserRaises(self, activity):
obj = self.portal.organisation_module.newContent(portal_type='Organisation')
self.tic()
original_notifyUser = Message.notifyUser.__func__
original_notifyUser = Message.notifyUser
import six
if six.PY2:
original_notifyUser = original_notifyUser.__func__
def failSendingEmail(self, *args, **kw):
raise MailHostError('Mail is not sent')
activity_unit_test_error = Exception()
......@@ -2088,7 +2094,10 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor):
def testNotificationFailureIsNotSavedOnEventLogWhenMailNotificationIsDisabled(self, activity):
obj = self.portal.organisation_module.newContent(portal_type='Organisation')
self.tic()
original_notifyUser = Message.notifyUser.__func__
original_notifyUser = Message.notifyUser
import six
if six.PY2:
original_notifyUser = original_notifyUser.__func__
def failSendingEmail(self, *args, **kw):
raise MailHostError('Mail is not sent')
activity_unit_test_error = Exception()
......@@ -2156,8 +2165,10 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor):
def failingMethod(self):
raise activity_unit_test_error
from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
original_raising = SiteErrorLog.raising.__func__
original_raising = SiteErrorLog.raising
import six
if six.PY2:
original_raising = original_raising.__func__
# Monkey patch Site Error to induce conflict errors artificially.
def raising(self, info):
raise AttributeError
......
......@@ -29,7 +29,7 @@
from past.builtins import cmp
from past.builtins import basestring
from compiler.consts import CO_VARKEYWORDS
from inspect import CO_VARKEYWORDS
from random import getrandbits
from Acquisition import aq_base
from DateTime import DateTime
......
......@@ -24,6 +24,7 @@ from builtins import filter
from builtins import object
from DateTime import DateTime
from six.moves import map
import six
import _thread, threading
from weakref import ref as weakref
from OFS.Application import Application, AppInitializer
......@@ -52,7 +53,6 @@ from Products.ERP5Type.mixin.response_header_generator import ResponseHeaderGene
from zLOG import LOG, INFO, WARNING, ERROR
from zExceptions import BadRequest
from string import join
import os
import warnings
import transaction
......@@ -685,7 +685,7 @@ class ERP5Site(ResponseHeaderGenerator, FolderMixIn, PortalObjectBase, CacheCook
"""
Returns the absolute path of an object
"""
return join(self.getPhysicalPath(),'/')
return '/'.join(self.getPhysicalPath())
security.declareProtected(Permissions.AccessContentsInformation, 'getRelativeUrl')
def getRelativeUrl(self):
......@@ -2447,7 +2447,10 @@ class ERP5Generator(PortalGenerator):
# Zope offers no mechanism to extend AppInitializer so let's monkey-patch.
AppInitializer_initialize = AppInitializer.initialize.__func__
AppInitializer_initialize = AppInitializer.initialize
if six.PY2:
# No more unbound methods in py3
AppInitializer_initialize = AppInitializer_initialize.__func__
def initialize(self):
AppInitializer.initialize = AppInitializer_initialize
self.initialize()
......
......@@ -305,7 +305,11 @@ class InteractionDefinition (SimpleItem):
def checkGuard(self, *args, **kwargs):
from Products.ERP5Type.mixin.guardable import GuardableMixin
return GuardableMixin.checkGuard.__func__(self, *args, **kwargs)
checkGuard = GuardableMixin.checkGuard
import six
if six.PY2:
checkGuard = checkGuard.__func__
return checkGuard(self, *args, **kwargs)
def getPortalTypeGroupFilterList(self):
if self.portal_type_group_filter is None:
......
......@@ -16,15 +16,15 @@
# GNU General Public License for more details.
#
##############################################################################
from __future__ import absolute_import
from builtins import str
"""
DCWorkflow implementation *deprecated* in favor of ERP5 Workflow.
"""
from __future__ import absolute_import
from builtins import str
from Products.ERP5Type import WITH_LEGACY_WORKFLOW
assert WITH_LEGACY_WORKFLOW
from __future__ import absolute_import
import transaction
from Products.ERP5Type import Globals
import App
......@@ -393,8 +393,10 @@ for method_name, security in (
):
if security is not None:
security(method_name)
setattr(InteractionWorkflowDefinition,
method_name,
getattr(ERP5InteractionWorkflow, method_name).__func__)
func = getattr(ERP5InteractionWorkflow, method_name)
import six
if six.PY2:
func = func.__func__
setattr(InteractionWorkflowDefinition, method_name, func)
Globals.InitializeClass(InteractionWorkflowDefinition)
......@@ -37,17 +37,19 @@ class PortalTypeClassInteractor(Interactor):
and dynamic properties.
"""
def install(self):
from Products.DCWorkflow.Transitions import Transitions
self.on(Transitions.addTransition).doAfter(self.resetDynamic)
self.on(Transitions.deleteTransitions).doAfter(self.resetDynamic)
from Products.DCWorkflow.Transitions import TransitionDefinition
self.on(TransitionDefinition.setProperties).doAfter(self.resetDynamic)
from Products.DCWorkflow.Variables import Variables
self.on(Variables.setStateVar).doAfter(self.resetDynamic)
from Products.ERP5Type import WITH_LEGACY_WORKFLOW
if WITH_LEGACY_WORKFLOW:
from Products.DCWorkflow.Transitions import Transitions
self.on(Transitions.addTransition).doAfter(self.resetDynamic)
self.on(Transitions.deleteTransitions).doAfter(self.resetDynamic)
from Products.DCWorkflow.Transitions import TransitionDefinition
self.on(TransitionDefinition.setProperties).doAfter(self.resetDynamic)
from Products.DCWorkflow.Variables import Variables
self.on(Variables.setStateVar).doAfter(self.resetDynamic)
from Products.Localizer.Localizer import Localizer
self.on(Localizer.add_language).doAfter(self.resetDynamic)
self.on(Localizer.del_language).doAfter(self.resetDynamic)
self.on(Localizer, 'add_language').doAfter(self.resetDynamic)
self.on(Localizer, 'del_language').doAfter(self.resetDynamic)
def resetDynamic(self, method_call_object, *args, **kw):
"""
......
......@@ -32,7 +32,8 @@ from future import standard_library
standard_library.install_aliases()
from builtins import filter
from builtins import range
from webdav.client import Resource
## XXX: WebDAV client implementation from ZServer
##from webdav.client import Resource
from App.config import getConfiguration
import os
......
......@@ -81,7 +81,9 @@ def initialize( context ):
'WorkflowException')
# Make sure InteactionWorkflow is visible in UI
import Products.ERP5.InteractionWorkflow
from Products.ERP5Type import WITH_LEGACY_WORKFLOW
if WITH_LEGACY_WORKFLOW:
import Products.ERP5.InteractionWorkflow
# backward compatibility names
XML = None
......
......@@ -207,8 +207,13 @@ def runwsgi():
make_wsgi_app({}, zope_conf=args.zope_conf)
from Signals.SignalHandler import SignalHandler
SignalHandler.registerHandler(signal.SIGTERM, sys.exit)
try:
from Signals.SignalHandler import SignalHandler
except ImportError:
# XXX-zope4py3: TODO
pass
else:
SignalHandler.registerHandler(signal.SIGTERM, sys.exit)
if args.timerserver_interval:
import Products.TimerService
......
......@@ -38,14 +38,14 @@ class FieldValueCacheInteractor(Interactor):
from Products.Formulator.Field import ZMIField
from Products.ERP5Form.ProxyField import ProxyField
from Products.Formulator.Form import ZMIForm
self.on(ZMIField.manage_edit).doAfter(self.purgeFieldValueCache)
self.on(ZMIField.manage_edit_xmlrpc).doAfter(self.purgeFieldValueCache)
self.on(ZMIField.manage_tales).doAfter(self.purgeFieldValueCache)
self.on(ZMIField.manage_tales_xmlrpc).doAfter(self.purgeFieldValueCache)
self.on(ProxyField.manage_edit).doAfter(self.purgeFieldValueCache)
self.on(ProxyField.manage_edit_target).doAfter(self.purgeFieldValueCache)
self.on(ProxyField.manage_tales).doAfter(self.purgeFieldValueCache)
self.on(ZMIForm.manage_renameObject).doAfter(self.purgeFieldValueCache)
self.on(ZMIField, 'manage_edit').doAfter(self.purgeFieldValueCache)
self.on(ZMIField, 'manage_edit_xmlrpc').doAfter(self.purgeFieldValueCache)
self.on(ZMIField, 'manage_tales').doAfter(self.purgeFieldValueCache)
self.on(ZMIField, 'manage_tales_xmlrpc').doAfter(self.purgeFieldValueCache)
self.on(ProxyField, 'manage_edit').doAfter(self.purgeFieldValueCache)
self.on(ProxyField, 'manage_edit_target').doAfter(self.purgeFieldValueCache)
self.on(ProxyField, 'manage_tales').doAfter(self.purgeFieldValueCache)
self.on(ZMIForm, 'manage_renameObject').doAfter(self.purgeFieldValueCache)
def purgeFieldValueCache(self, method_call_object):
"""
......
......@@ -196,7 +196,7 @@ def initialize( context ):
ModuleSecurityInfo('Products.ERP5Form.Report').declarePublic('ReportSection',)
ModuleSecurityInfo('Products.ERP5Form.MultiRelationField').declarePublic('SUB_FIELD_ID',)
allow_module('Products.ERP5Form.Selection')
from . import Selection
from .Selection import Selection
allow_class(Selection)
__module_aliases__ = ('Products.ERP5Form.SelectionTool', SelectionTool),
......
......@@ -34,7 +34,7 @@ standard_library.install_aliases()
from builtins import next
from builtins import str
from past.utils import old_div
from types import StringType
from past.builtins import basestring
from mimetypes import guess_extension
from OFS.Image import File
from Products.CMFCore.FSPageTemplate import FSPageTemplate
......@@ -214,7 +214,7 @@ class OOoTemplate(ZopePageTemplate):
if SUPPORTS_WEBDAV_LOCKS and self.wl_isLocked():
raise ResourceLockedError("File is locked via WebDAV")
if type(file) is not StringType:
if not isinstance(file, basestring):
if not file: raise ValueError('File not specified')
file = file.read()
......
......@@ -95,17 +95,25 @@ class InteractorSource(object):
"""
"""
def __init__(self, method):
def __init__(self, *args):
"""
Register method
"""
self.method = method
if len(args) == 1:
self.klass = method.im_class
self.method = method
else:
# No im_class on Python3 and Interactors only makes sense with non-ERP5
# objects anyway, so add a class argument to InteractorSource to make it
# simple
self.klass = args[0]
self.method = getattr(self.klass, args[1])
def doBefore(self, action, *args, **kw):
"""
"""
if not isinstance(self.method, InteractorMethod):
im_class = self.method.__self__.__class__
im_class = self.klass
# Turn this into an InteractorMethod
interactor_method = InteractorMethod(self.method)
setattr(im_class, self.method.__name__, interactor_method)
......@@ -117,7 +125,7 @@ class InteractorSource(object):
"""
"""
if not isinstance(self.method, InteractorMethod):
im_class = self.method.__self__.__class__
im_class = self.klass
# Turn this into an InteractorMethod
interactor_method = InteractorMethod(self.method)
setattr(im_class, self.method.__name__, interactor_method)
......@@ -148,9 +156,9 @@ class Interactor(object):
raise NotImplementedError
# Interaction implementation
def on(self, method):
def on(self, *args):
"""
Parameters may hold predicates ?
no need - use InteractorMethodCall and decide on action
"""
return InteractorSource(method)
return InteractorSource(*args)
......@@ -30,8 +30,7 @@ import threading
import time, six
from AccessControl.SecurityInfo import ModuleSecurityInfo
from ZPublisher.HTTPResponse import status_codes
if six.PY2:
from Products.TimerService.timerserver.TimerServer import TimerRequest
from Products.TimerService.timerserver.TimerServer import TimerRequest
__all__ = (
'TimeoutReachedError', 'Deadline', 'getDeadline', 'getTimeLeft',
......
......@@ -43,7 +43,6 @@ from Products.ERP5Type.Globals import InitializeClass, PersistentMapping
from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type.Utils import deprecated
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, AutoQuery, ComplexQuery, NegatedQuery
from sets import ImmutableSet
from zLOG import LOG, WARNING
from six import reraise
......@@ -359,7 +358,7 @@ class WorkflowTool(BaseTool, OriginalWorkflowTool):
portal_catalog = self.getPortalObject().portal_catalog
search_result = portal_catalog.unrestrictedSearchResults
sql_catalog = portal_catalog.getSQLCatalog()
table_column_id_set = ImmutableSet(
table_column_id_set = frozenset(
[COUNT_COLUMN_TITLE] + self.Base_getWorklistTableColumnIDList())
security_column_id_list = list(
sql_catalog.getSQLCatalogSecurityUidGroupsColumnsDict().values()) + \
......@@ -950,9 +949,9 @@ def sumCatalogResultByWorklist(grouped_worklist_dict, catalog_result):
criterion_id_list.append(criterion_id)
expected_class = class_dict[criterion_id]
if type(criterion_value_list[0]) is not expected_class:
criterion_dict[criterion_id] = ImmutableSet([expected_class(x) for x in criterion_value_list])
elif type(criterion_value_list) is not ImmutableSet:
criterion_dict[criterion_id] = ImmutableSet(criterion_dict[criterion_id])
criterion_dict[criterion_id] = frozenset([expected_class(x) for x in criterion_value_list])
elif type(criterion_value_list) is not frozenset:
criterion_dict[criterion_id] = frozenset(criterion_dict[criterion_id])
# Read catalog result and distribute to matching worklists
for result_line in catalog_result:
result_count = int(result_line[COUNT_COLUMN_TITLE])
......
......@@ -110,10 +110,12 @@ if six.PY2:
# No ZServer
from Products.ERP5Type.patches import Publish
from Products.ERP5Type.patches import WSGITask
from Products.ERP5Type.patches import urllib_opener
# XXX-zope4py3: urllib2 removed (see future/backports/urllib/request.py)
#from Products.ERP5Type.patches import urllib_opener
# These symbols are required for backward compatibility
from Products.ERP5Type.patches.PropertyManager import ERP5PropertyManager
from Products.ERP5Type.Core.Workflow import ValidationFailed
from Products.ERP5Type.patches.DCWorkflow import ERP5TransitionDefinition
if WITH_LEGACY_WORKFLOW:
from Products.ERP5Type.patches.DCWorkflow import ERP5TransitionDefinition
from Products.ERP5Type.patches.BTreeFolder2 import ERP5BTreeFolder2Base
......@@ -39,7 +39,7 @@ if six.PY2:
from zLOG import LOG, INFO
DISPLAY_BOOT_PROCESS = False
WITH_LEGACY_WORKFLOW = True # BBB
WITH_LEGACY_WORKFLOW = False # BBB
# We have a name conflict with source_reference and destination_reference,
# which are at the same time property accessors for 'source_reference'
......
......@@ -97,7 +97,13 @@ class PickleUpdater(ObjectReader, ObjectWriter, object):
if _setOb:
if isinstance(_setOb, WorkflowMethod):
_setOb = _setOb._m
if _setOb.__func__ is OFS_Folder._setOb.__func__:
import six
setOb_func = _setOb
OFS_Folder_setOb_func = OFS_Folder._setOb
if six.PY2:
setOb_func = setOb_func.__func__
OFS_Folder_setOb_func = OFS_Folder_setOb.__func__
if setOb_func is OFS_Folder_setOb_func:
self.lazy = Ghost
elif klass.__module__[:7] == 'BTrees.' and klass.__name__ != 'Length':
self.lazy = LazyBTree()
......
......@@ -63,7 +63,6 @@ from Products.DCWorkflow.Guard import Guard, _checkPermission
from Products.DCWorkflow.States import StateDefinition
from Products.DCWorkflow.Variables import VariableDefinition
from Products.DCWorkflow.Worklists import WorklistDefinition
from types import StringTypes
from zLOG import LOG, INFO, WARNING
# Libraries related to showAsXML
from lxml import etree
......
......@@ -91,7 +91,10 @@ class _(PatchClass(ExternalMethod)):
arg_list.append('**' + argument_object.keywords)
i = isinstance(f, MethodType)
ff = f.__func__ if i else f
ff = f
import six
if six.PY2 and i:
ff = f.__func__
has_self = len(arg_list) > i and arg_list[i] == 'self'
i += has_self
if i:
......
......@@ -18,6 +18,7 @@ from builtins import object
import copy
import sys
import types
import six
try:
from RestrictedPython.transformer import FORBIDDEN_FUNC_NAMES
......@@ -299,11 +300,15 @@ from RestrictedPython.Guards import full_write_guard
ContainerAssertions[defaultdict] = _check_access_wrapper(defaultdict, _dict_white_list)
allow_full_write(defaultdict)
# In contrary to builtins such as dict/defaultdict, it is possible to set
# attributes on OrderedDict instances, so only allow setitem/delitem
# On Python2 only: In contrary to builtins such as dict/defaultdict, it is
# possible to set attributes on OrderedDict instances, so only allow
# setitem/delitem
ContainerAssertions[OrderedDict] = _check_access_wrapper(OrderedDict, _dict_white_list)
OrderedDict.__guarded_setitem__ = OrderedDict.__setitem__.__func__
OrderedDict.__guarded_delitem__ = OrderedDict.__delitem__.__func__
if six.PY2:
OrderedDict.__guarded_setitem__ = OrderedDict.__setitem__.__func__
OrderedDict.__guarded_delitem__ = OrderedDict.__delitem__.__func__
else:
allow_full_write(OrderedDict)
_counter_white_list = copy.copy(_dict_white_list)
_counter_white_list['most_common'] = 1
......@@ -332,16 +337,19 @@ allow_type(type(re.compile('')))
allow_type(type(re.match('x','x')))
allow_type(type(re.finditer('x','x')))
allow_module('StringIO')
import io
io.StringIO.__allow_access_to_unprotected_subobjects__ = 1
allow_module('cStringIO')
import io
allow_type(io.InputType)
allow_type(io.OutputType)
allow_module('io')
import io
allow_type(io.BytesIO)
if six.PY2:
allow_module('StringIO')
import StringIO
StringIO.StringIO.__allow_access_to_unprotected_subobjects__ = 1
allow_module('cStringIO')
import cStringIO
allow_type(cStringIO.InputType)
allow_type(cStringIO.OutputType)
else:
allow_type(io.StringIO)
ModuleSecurityInfo('cgi').declarePublic('escape', 'parse_header')
allow_module('datetime')
......
import six
class PatchClass(tuple):
"""Helper to easily monkey-patch many attributes of an object
......@@ -17,7 +18,8 @@ class PatchClass(tuple):
if len(args) == 1:
return tuple.__new__(cls, args)
_, ((cls,),), d = args
for k, v in list(d.items()):
k == "__module__" or setattr(cls, k, v.__func__
if getattr(v, "im_class", None) is cls and v.__self__ is None
else v)
for k, v in six.iteritems(d):
if k != "__module__":
if getattr(v, "im_class", None) is cls and v.__self__ is None:
v = v.__func__
setattr(cls, k, v)
......@@ -32,7 +32,6 @@
from future import standard_library
standard_library.install_aliases()
import urllib.request, urllib.parse, urllib.error
import urllib.request, urllib.error, urllib.parse
from io import BytesIO as StringIO
import socket
import os
......@@ -52,7 +51,10 @@ class DirectoryFileHandler(urllib.request.FileHandler):
# Use local file or FTP depending on form of URL
def file_open(self, req):
url = req.get_selector()
if six.PY2:
url = req.get_selector()
else:
url = req.selector
if url[:2] == '//' and url[2:3] != '/':
req.type = 'ftp'
return self.parent.open(req)
......@@ -61,8 +63,12 @@ class DirectoryFileHandler(urllib.request.FileHandler):
# not entirely sure what the rules are here
def open_local_file(self, req):
host = req.get_host()
file = req.get_selector()
if six.PY2:
host = req.get_host()
file = req.get_selector()
else:
host = req.host
file = req.selector
localfile = urllib2.url2pathname(file)
stats = os.stat(localfile)
size = stats.st_size
......
......@@ -12,7 +12,10 @@ def patch():
import traceback
from unittest import TextTestResult, TextTestRunner
TextTestResult_addError = TextTestResult.addError.__func__
TextTestResult_addError = TextTestResult.addError
import six
if six.PY2:
TextTestResult_addError = TextTestResult_addError.__func__
def addError(self, test, err):
if isinstance(err[1], SetupSiteError):
self.errors.append(None)
......@@ -40,7 +43,10 @@ def patch():
self.stream.writeln("SUCCESS: %s" % self.getDescription(test))
TextTestResult.printErrors = printErrors
TextTestRunner_run = TextTestRunner.run.__func__
TextTestRunner_run = TextTestRunner.run
import six
if six.PY2:
TextTestRunner_run = TextTestRunner_run.__func__
def run(self, test):
def t(result):
try:
......
......@@ -330,7 +330,11 @@ class getMySQLArguments(object):
self = object.__new__(cls)
self._connection = os.getenv('erp5_sql_connection_string') or 'test test'
self.conv = None
DB._parse_connection_string.__func__(self)
parse_connection_string_function = DB._parse_connection_string
import six
if six.PY2:
parse_connection_string_function = parse_connection_string_function.__func__
parse_connection_string_function(self)
return ''.join('-%s%s ' % (self.args_dict[k], v)
for k, v in self._kw_args.items()
if k in self.args_dict
......
......@@ -114,7 +114,10 @@ def getPropertyFields(obj):
"""
fields = []
for property_name in obj.property_names:
fields.append(getattr(obj, property_name))
try:
fields.append(getattr(obj, property_name))
except:
import pdb; pdb.set_trace()
return fields
def setupIcon(klass, icon, repository):
......
......@@ -123,7 +123,7 @@ class StringValidator(StringBaseValidator):
property_names = StringBaseValidator.property_names +\
['unicode', 'max_length', 'truncate']
str = fields.CheckBoxField('unicode',
unicode = fields.CheckBoxField('unicode',
title='Unicode',
description=(
"Checked if the field delivers a unicode string instead of an "
......@@ -381,7 +381,7 @@ class LinesValidator(StringBaseValidator):
property_names = StringBaseValidator.property_names +\
['unicode', 'max_lines', 'max_linelength', 'max_length']
str = fields.CheckBoxField('unicode',
unicode = fields.CheckBoxField('unicode',
title='Unicode',
description=(
"Checked if the field delivers a unicode string instead of an "
......@@ -474,7 +474,7 @@ class SelectionValidator(StringBaseValidator):
property_names = StringBaseValidator.property_names +\
['unicode']
str = fields.CheckBoxField('unicode',
unicode = fields.CheckBoxField('unicode',
title='Unicode',
description=(
"Checked if the field delivers a unicode string instead of an "
......@@ -529,7 +529,7 @@ class MultiSelectionValidator(Validator):
"data."),
default=1)
str = fields.CheckBoxField('unicode',
unicode = fields.CheckBoxField('unicode',
title='Unicode',
description=(
"Checked if the field delivers a unicode string instead of an "
......
......@@ -64,7 +64,7 @@ def convert_to_xml_compatible_string(value):
_char_tail = u'%s-%s' % (chr(0x10000),
chr(min(sys.maxunicode, 0x10FFFF)))
_nontext_sub = re.compile(
ur'[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD%s]' % _char_tail,
u'[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD%s]' % _char_tail,
re.U).sub
return _nontext_sub(u'\uFFFD', value)
......
......@@ -24,7 +24,6 @@ from cgi import escape
from itertools import chain, islice
from urllib.parse import quote
from random import randint
from types import StringType
from App.class_init import default__class_init__ as InitializeClass
from App.special_dtml import DTMLFile
......
......@@ -20,9 +20,10 @@
from __future__ import absolute_import
from .accept import AcceptLanguageType, get_accept, select_language
from .accept import init_language_selector
from .base import has_language, get_languages, get_language_name
from .fuzzy import get_distance, get_similarity, is_similar, get_most_similar
from .languages import has_language, get_languages, get_language_name
from .locale_ import format_date, format_time, format_datetime
from .locale_ import format_number
from .oracle import guess_language, is_asian_character, is_punctuation
......
......@@ -25,10 +25,7 @@ standard_library.install_aliases()
from builtins import str
from builtins import object
import six
if six.PY2:
import builtins
else:
import builtins as __builtin__
import builtins
from decimal import Decimal
from locale import getdefaultlocale
......
......@@ -73,7 +73,7 @@ if patch is False:
logger.info('Install "Globals.get_request".')
# Apply the patch
Publish.publish = get_new_publish(Publish.publish)
## Publish.publish = get_new_publish(Publish.publish)
patch = True
# Add to Globals for backwards compatibility
......
......@@ -8,14 +8,13 @@ from __future__ import absolute_import
from past.builtins import basestring
from builtins import object
import os
import email.utils
from AccessControl import ClassSecurityInfo
from DateTime import DateTime
from email.Header import Header
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.Utils import make_msgid, formataddr, getaddresses
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import make_msgid, formataddr, getaddresses
from App.class_init import default__class_init__ as InitializeClass
from App.Common import package_home
......@@ -148,8 +147,7 @@ class BaseMailTemplate(object):
v = values.get(key)
if v:
if isinstance(v, basestring):
v = [email.utils.formataddr(addr) for addr \
in email.utils.getaddresses([v])]
v = [formataddr(addr) for addr in getaddresses([v])]
to_addrs += tuple(v)
self._send(values['mfrom'], to_addrs, msg)
......
......@@ -6,9 +6,9 @@
from builtins import str
from AccessControl import ClassSecurityInfo
from email import Encoders
from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email.encoders import encode_base64
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from App.class_init import default__class_init__ as InitializeClass
try:
from OFS.content_types import guess_content_type
......@@ -77,7 +77,7 @@ class MTMultipart(MIMEMultipart):
msg = MIMEBase(*content_type.split('/'))
msg.set_payload(data)
Encoders.encode_base64(msg)
encode_base64(msg)
msg.add_header('Content-ID', '<%s>' % \
''.join(['%s' % ord(i) for i in filename]))
msg.add_header('Content-Disposition', 'attachment',
......
......@@ -11,7 +11,6 @@ from builtins import str
from AccessControl import allow_module,allow_class
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from .MailTemplate import MailTemplate
from types import ClassType
from urllib.parse import quote
try:
......@@ -84,6 +83,8 @@ for name in email.__all__:
mod = getattr(mod,name)
for mod_name in dir(mod):
obj = getattr(mod,mod_name)
if isinstance(obj,ClassType):
allow_class(obj)
if isinstance(obj,type):
try:
allow_class(obj)
except TypeError:
continue
# -*- coding: utf-8 -*-
from future import standard_library
standard_library.install_aliases()
from builtins import zip
from zLOG import ERROR
from UserDict import UserDict
from collections import UserDict
from zope.interface import implementer
......
......@@ -3,7 +3,9 @@ standard_library.install_aliases()
import re
import os
import sys
from sgmllib import SGMLParser, SGMLParseError
# XXX-zope4py3: sgmllib removed from standard library in favor of
# html.parser.HTMLParser
#from sgmllib import SGMLParser, SGMLParseError
try:
# Need to be imported before win32api to avoid dll loading
......@@ -144,95 +146,95 @@ NASTY_TAGS = { 'script' : 1
class IllegalHTML( ValueError ):
pass
class StrippingParser( SGMLParser ):
""" Pass only allowed tags; raise exception for known-bad. """
# class StrippingParser( SGMLParser ):
# """ Pass only allowed tags; raise exception for known-bad. """
from html.entities import entitydefs # replace entitydefs from sgmllib
# from html.entities import entitydefs # replace entitydefs from sgmllib
def __init__( self ):
# def __init__( self ):
SGMLParser.__init__( self )
self.result = ""
# SGMLParser.__init__( self )
# self.result = ""
def handle_data( self, data ):
# def handle_data( self, data ):
if data:
self.result = self.result + data
# if data:
# self.result = self.result + data
def handle_charref( self, name ):
# def handle_charref( self, name ):
self.result = "%s&#%s;" % ( self.result, name )
# self.result = "%s&#%s;" % ( self.result, name )
def handle_entityref(self, name):
# def handle_entityref(self, name):
if name in self.entitydefs:
x = ';'
else:
# this breaks unstandard entities that end with ';'
x = ''
# if name in self.entitydefs:
# x = ';'
# else:
# # this breaks unstandard entities that end with ';'
# x = ''
self.result = "%s&%s%s" % (self.result, name, x)
# self.result = "%s&%s%s" % (self.result, name, x)
def unknown_starttag(self, tag, attrs):
# def unknown_starttag(self, tag, attrs):
""" Delete all tags except for legal ones.
"""
if tag in VALID_TAGS:
# """ Delete all tags except for legal ones.
# """
# if tag in VALID_TAGS:
self.result = self.result + '<' + tag
# self.result = self.result + '<' + tag
for k, v in attrs:
# for k, v in attrs:
if k.lower().startswith( 'on' ):
raise IllegalHTML('Javascipt event "%s" not allowed.' % k)
# if k.lower().startswith( 'on' ):
# raise IllegalHTML('Javascipt event "%s" not allowed.' % k)
if v.lower().startswith( 'javascript:' ):
raise IllegalHTML('Javascipt URI "%s" not allowed.' % v)
# if v.lower().startswith( 'javascript:' ):
# raise IllegalHTML('Javascipt URI "%s" not allowed.' % v)
self.result = '%s %s="%s"' % (self.result, k, v)
# self.result = '%s %s="%s"' % (self.result, k, v)
endTag = '</%s>' % tag
if VALID_TAGS.get(tag):
self.result = self.result + '>'
else:
self.result = self.result + ' />'
# endTag = '</%s>' % tag
# if VALID_TAGS.get(tag):
# self.result = self.result + '>'
# else:
# self.result = self.result + ' />'
elif NASTY_TAGS.get( tag ):
raise IllegalHTML('Dynamic tag "%s" not allowed.' % tag)
# elif NASTY_TAGS.get( tag ):
# raise IllegalHTML('Dynamic tag "%s" not allowed.' % tag)
else:
pass # omit tag
# else:
# pass # omit tag
def unknown_endtag(self, tag):
# def unknown_endtag(self, tag):
if VALID_TAGS.get( tag ):
# if VALID_TAGS.get( tag ):
self.result = "%s</%s>" % (self.result, tag)
remTag = '</%s>' % tag
# self.result = "%s</%s>" % (self.result, tag)
# remTag = '</%s>' % tag
def parse_declaration(self, i):
"""Fix handling of CDATA sections. Code borrowed from BeautifulSoup.
"""
j = None
if self.rawdata[i:i+9] == '<![CDATA[':
k = self.rawdata.find(']]>', i)
if k == -1:
k = len(self.rawdata)
data = self.rawdata[i+9:k]
j = k+3
self.result.append("<![CDATA[%s]]>" % data)
else:
try:
j = SGMLParser.parse_declaration(self, i)
except SGMLParseError:
toHandle = self.rawdata[i:]
self.result.append(toHandle)
j = i + len(toHandle)
return j
# def parse_declaration(self, i):
# """Fix handling of CDATA sections. Code borrowed from BeautifulSoup.
# """
# j = None
# if self.rawdata[i:i+9] == '<![CDATA[':
# k = self.rawdata.find(']]>', i)
# if k == -1:
# k = len(self.rawdata)
# data = self.rawdata[i+9:k]
# j = k+3
# self.result.append("<![CDATA[%s]]>" % data)
# else:
# try:
# j = SGMLParser.parse_declaration(self, i)
# except SGMLParseError:
# toHandle = self.rawdata[i:]
# self.result.append(toHandle)
# j = i + len(toHandle)
# return j
def scrubHTML( html ):
""" Strip illegal HTML tags from string text. """
parser = StrippingParser()
parser.feed( html )
parser.close()
return parser.result
# def scrubHTML( html ):
# """ Strip illegal HTML tags from string text. """
# parser = StrippingParser()
# parser.feed( html )
# parser.close()
# return parser.result
......@@ -2,7 +2,7 @@
"""some common utilities
"""
import mimetools, six
import six
if six.PY2:
from email import message_from_file as message_from_bytes
else:
......@@ -34,7 +34,7 @@ def safeToInt(value):
return 0
def parseContentType(content_type):
"""Parses `text/plain;charset="utf-8"` to a mimetools.Message object.
"""Parses `text/plain;charset="utf-8"` to a Message object.
Note: Content type or MIME type are built like `maintype/subtype[;params]`.
......
......@@ -26,13 +26,3 @@ def getTimerService(context):
control_panel._delObject(cp_id)
root._setObject(cp_id, timer_service)
return timer_service
try:
old = sys.modules['timerserver']
except KeyError:
pass
else: # BBB: old timerserver loaded from zope config, force use of new one
assert 'timerserver.TimerServer' not in sys.modules
from .timerserver import TimerServerFactory
old.TimerServerFactory.create = TimerServerFactory.create.__func__
del old, TimerServerFactory
......@@ -30,49 +30,30 @@ class TimerServer(threading.Thread):
interval)
def run(self):
try:
zopewsgi = sys.modules['Products.ERP5.bin.zopewsgi']
except KeyError:
# wait until the zhttp_server exist in socket_map
# because TimerService has to be started after the Zope HTTPServer
from asyncore import socket_map
ip = port = ''
while 1:
time.sleep(5)
for k, v in list(socket_map.items()):
if hasattr(v, 'addr'):
# see Zope/lib/python/App/ApplicationManager.py: def getServers(self)
type = str(getattr(v, '__class__', 'unknown'))
if type == 'ZServer.HTTPServer.zhttp_server':
ip, port = v.addr
break
if port:
break
from ZServer.PubCore import handle
else:
while 1:
time.sleep(5)
try:
server = zopewsgi.server
break
except AttributeError:
pass
ip, port = server.addr
start_response = lambda *_: None
class handle(object):
def __init__(self, module_name, request, response):
self.service = partial(zopewsgi.publish_module,
request.environ,
start_response,
_module_name=module_name,
_request=request,
_response=response)
server.add_task(self)
def cancel(self):
pass
import Products.ERP5.bin.zopewsgi
while 1:
time.sleep(5)
try:
server = Products.ERP5.bin.zopewsgi.server
break
except AttributeError:
pass
ip, port = server.addr
start_response = lambda *_: None
class handle(object):
def __init__(self, module_name, request, response):
self.service = partial(zopewsgi.publish_module,
request.environ,
start_response,
_module_name=module_name,
_request=request,
_response=response)
server.add_task(self)
def cancel(self):
pass
if ip == '0.0.0.0':
ip = socket.gethostbyname(socket.gethostname())
......
from ZServer.datatypes import ServerFactory
class TimerServerFactory(ServerFactory):
def __init__(self, section):
ServerFactory.__init__(self)
self.interval = section.interval
def create(self):
from .TimerServer import TimerServer
return TimerServer(self.module, self.interval)
<component>
<import package="ZServer" />
<sectiontype name="timer-server"
datatype="Products.TimerService.timerserver.TimerServerFactory"
implements="ZServer.server">
<key name="interval" datatype="float" default="600">
<description>
Interval in seconds. Supports fractions of a second.
</description>
</key>
</sectiontype>
</component>
"""LDAP Server Connection Package """
from __future__ import absolute_import
# XXX-zope4py3: Is it really used anymore?
# from __future__ import absolute_import
from . import ZLDAP, Entry
__version__ = ZLDAP.__version__
# from . import ZLDAP, Entry
# __version__ = ZLDAP.__version__
# use the propert product registration
def initialize(context):
context.registerClass(
ZLDAP.ZLDAPConnection,
constructors = (ZLDAP.manage_addZLDAPConnectionForm,
ZLDAP.manage_addZLDAPConnection),
icon = 'LDAP_conn_icon.gif',
permissions = ('Manage Entry information',
'Create New Entry Objects',
),
)
# # use the propert product registration
# def initialize(context):
# context.registerClass(
# ZLDAP.ZLDAPConnection,
# constructors = (ZLDAP.manage_addZLDAPConnectionForm,
# ZLDAP.manage_addZLDAPConnection),
# icon = 'LDAP_conn_icon.gif',
# permissions = ('Manage Entry information',
# 'Create New Entry Objects',
# ),
# )
"""LDAP Filter Methods Package """
from __future__ import absolute_import
# XXX-zope4py3: Is it really used anymore?
# from __future__ import absolute_import
from . import LM
# from . import LM
def initialize(context):
# def initialize(context):
context.registerClass(
LM.LDAPMethod,
constructors = (LM.manage_addZLDAPMethodForm,
LM.manage_addZLDAPMethod),
icon = "LDAP_Method_icon.gif",
legacy = (LM.LDAPConnectionIDs,), #special baby to add to ObjectManagers
)
# context.registerClass(
# LM.LDAPMethod,
# constructors = (LM.manage_addZLDAPMethodForm,
# LM.manage_addZLDAPMethod),
# icon = "LDAP_Method_icon.gif",
# legacy = (LM.LDAPConnectionIDs,), #special baby to add to ObjectManagers
# )
context.registerClass(
LM.LDIFMethod,
constructors = (LM.manage_addZLDIFMethodForm,
LM.manage_addZLDIFMethod),
icon = "LDAP_Method_icon.gif",
legacy = (LM.LDAPConnectionIDs,), #special baby to add to ObjectManagers
)
\ No newline at end of file
# context.registerClass(
# LM.LDIFMethod,
# constructors = (LM.manage_addZLDIFMethodForm,
# LM.manage_addZLDIFMethod),
# icon = "LDAP_Method_icon.gif",
# legacy = (LM.LDAPConnectionIDs,), #special baby to add to ObjectManagers
# )
\ No newline at end of file
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