Commit 48212534 authored by Julien Muchembled's avatar Julien Muchembled

Drop support for Zope 2.8

Checked following occurrences in comments:
- "Python 2.[456]"
- "Zope 2.[891]"
- "BBB"
- "BACK"

Checked uses of:
- email, hashlib, numpy & tarfile (modules)
- ImportError
- string.Template
- suppress_events (parameter of _setObject)

Excluded:
- some forked modules (MailTemplates, PortalTransforms...)
- some i18n compatibility code
parent 7c9313f0
......@@ -30,7 +30,6 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.Document.Ticket import Ticket
from Products.ERP5.mixin.encrypted_password import EncryptedPasswordMixin
from Products.CMFCore.utils import getToolByName
try:
from Products import PluggableAuthService
from Products.ERP5Security.ERP5UserManager import ERP5UserManager
......
402
\ No newline at end of file
403
\ No newline at end of file
......@@ -28,7 +28,7 @@
from PIL import ImageFont, Image, ImageDraw, ImageFilter
from random import randrange, uniform
from string import zfill
from md5 import md5
from hashlib import md5
from tempfile import NamedTemporaryFile
import sys, os
import commands
......
......@@ -37,8 +37,8 @@ from zLOG import LOG
import transaction
import random
import email
from email.Header import decode_header, make_header
from email.Utils import parseaddr
from email.header import decode_header, make_header
from email.utils import parseaddr
class TestEGovMixin(SecurityTestCase):
"""Usefull methods for eGov Unit Tests."""
......
756
\ No newline at end of file
757
\ No newline at end of file
......@@ -53,16 +53,10 @@ def getActionTitleListFromAllActionProvider(portal):
from StringIO import StringIO
try:
from TAL.HTMLTALParser import HTMLTALParser
from TAL.TALParser import TALParser
from TAL.TALGenerator import TALGenerator
from TAL.DummyEngine import name_match
except ImportError:
from zope.tal.htmltalparser import HTMLTALParser
from zope.tal.talparser import TALParser
from zope.tal.talgenerator import TALGenerator
from zope.tal.dummyengine import name_match
from zope.tal.htmltalparser import HTMLTALParser
from zope.tal.talparser import TALParser
from zope.tal.talgenerator import TALGenerator
from zope.tal.dummyengine import name_match
def findStaticTranslationText(page_template, func_name_list):
def iterate(node, target_name, function):
if type(node) is list:
......@@ -131,12 +125,8 @@ def findStaticTranslationText(page_template, func_name_list):
#
# Utility class for findStaticTranslationText
#
try:
from TAL.TALInterpreter import TALInterpreter
from TAL.DummyEngine import DummyEngine
except ImportError:
from zope.tal.talinterpreter import TALInterpreter
from zope.tal.dummyengine import DummyEngine
from zope.tal.talinterpreter import TALInterpreter
from zope.tal.dummyengine import DummyEngine
class MyDummyEngine(DummyEngine):
def evaluate(self, expression):
......
......@@ -56,11 +56,7 @@ trust_dict=dict((x, request[x]) for x in (\n
\n
context.getVcsTool().acceptSSLServer(trust_dict, True)\n
\n
try:\n
traverseName = request.traverseName\n
except AttributeError: # BBB: Zope2.8\n
return request.traverse(\'%s/%s\' % (context.getPath(), caller))(**dict(caller_kw))\n
return traverseName(context, caller)(**caller_kw)\n
return request.traverseName(context, caller)(**caller_kw)\n
</string> </value>
</item>
<item>
......
......@@ -52,12 +52,7 @@
<key> <string>_body</string> </key>
<value> <string>context.getVcsTool().setLogin(auth, user, password)\n
\n
request = context.REQUEST\n
try:\n
traverseName = request.traverseName\n
except AttributeError: # BBB: Zope2.8\n
return request.traverse(\'%s/%s\' % (context.getPath(), caller))(**dict(caller_kw))\n
return traverseName(context, caller)(**caller_kw)\n
return context.REQUEST.traverseName(context, caller)(**caller_kw)\n
</string> </value>
</item>
<item>
......
662
\ No newline at end of file
663
\ No newline at end of file
import feedparser, md5, urllib2, socket
import feedparser, urllib2, socket
from hashlib import md5
def getRssDataAsDict(self, url, username=None, password=None):
result = {}
translate = self.Base_translateString
......@@ -46,7 +47,7 @@ def getRssDataAsDict(self, url, username=None, password=None):
entry_dict['title'] = entry['title']
entry_dict['link'] = entry['link']
entry_dict['other_links'] = [x['href'] for x in entry['links']]
entry_dict['md5'] = md5.new(entry['link']).hexdigest()
entry_dict['md5'] = md5(entry['link']).hexdigest()
entry_dict['content'] = entry.get('summary', '')
entry_dict['date'] = entry.get('updated', None)
entry_dict['img'] = [x['href'] for x in entry.get('enclosures', [])]
......
730
\ No newline at end of file
731
\ No newline at end of file
......@@ -28,6 +28,7 @@
##############################################################################
from AccessControl import ClassSecurityInfo
from AccessControl.AuthEncoding import pw_encrypt, pw_validate
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.XMLObject import XMLObject
......@@ -38,17 +39,6 @@ try:
except ImportError:
PluggableAuthService = None
try:
from AccessControl.AuthEncoding import pw_encrypt
except ImportError:
pw_encrypt = lambda pw:pw
try:
from AccessControl.AuthEncoding import pw_validate
except ImportError:
pw_validate = lambda reference, attempt: reference == attempt
#class Person(Node, XMLObject):
class PsjPerson(XMLObject):
"""
......
936
\ No newline at end of file
937
\ No newline at end of file
......@@ -27,7 +27,7 @@
##############################################################################
import cPickle, sys
from hashlib import sha1 as sha_new
from hashlib import sha1
from DateTime import DateTime
from zLOG import LOG, WARNING, ERROR
from ZODB.POSException import ConflictError
......@@ -261,7 +261,7 @@ class Queue:
# is true in Python. This is important, because dtml-if assumes that an empty
# string is false, so we must use a non-empty string for this.
return 'none'
return sha_new(repr(order_validation_item_list)).hexdigest()
return sha1(repr(order_validation_item_list)).hexdigest()
def getMessageList(self, activity_tool, processing_node=None,**kw):
return []
......
......@@ -421,12 +421,8 @@ class SQLBase:
# should they be just made available again ?
if uid_to_duplicate_uid_list_dict is not None:
make_available_uid_list += uid_to_duplicate_uid_list_dict.get(uid, ())
# BACK: Only exceptions can be classes in Python 2.6.
# Once we drop support for Python 2.4,
# please, remove the "type(m.exc_type) is type(ConflictError)" check
# and leave only the "issubclass(m.exc_type, ConflictError)" check.
if type(m.exc_type) is type(ConflictError) and \
m.conflict_retry and issubclass(m.exc_type, ConflictError):
if (m.exc_type and # m.exc_type may be None
m.conflict_retry and issubclass(m.exc_type, ConflictError)):
delay_uid_list.append(uid)
else:
max_retry = m.max_retry
......
......@@ -78,10 +78,7 @@ except ImportError:
def getTimerService(self):
pass
try:
from traceback import format_list, extract_stack
except ImportError:
format_list = extract_stack = None
from traceback import format_list, extract_stack
# minimal IP:Port regexp
NODE_RE = re.compile('^\d+\.\d+\.\d+\.\d+:\d+$')
......@@ -356,11 +353,6 @@ Exception: %s %s
self.user_name, path, self.method_id, self.args, self.kw,
call_traceback, self.exc_type, self.exc_value, self.traceback)
if isinstance(mail_text, unicode):
# __traceback_info__ can turn the tracebacks into unicode strings, but
# MailHost.send (in Zope 2.8) will not be able to parse headers if the
# mail_text is passed as a unicode.
mail_text = mail_text.encode('utf8')
try:
activity_tool.MailHost.send( mail_text )
except (socket.error, MailHostError), message:
......
......@@ -32,14 +32,8 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Testing.ZopeTestCase.PortalTestCase import PortalTestCase
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
import transaction
try:
from transaction import get as get_transaction
except ImportError:
pass
class TestCMFCategory(ERP5TypeTestCase):
# Different variables used for this test
......@@ -368,13 +362,13 @@ class TestCMFCategory(ERP5TypeTestCase):
p2 = self.getPersonModule()._getOb(self.id2)
o1 = self.getOrganisationModule()._getOb(self.id1)
p1.setGenderValue(o1)
get_transaction().commit()
transaction.commit()
self.tic() # This is required
self.assertEqual(p1.getGenderValue(),o1)
self.assertEqual(o1.getGenderRelatedValueList(),[p1])
p2.setGenderValue(o1) # reindex implicit
get_transaction().commit()
transaction.commit()
self.tic()
self.assertEqual(len(o1.getGenderRelatedValueList()),2)
......@@ -386,12 +380,12 @@ class TestCMFCategory(ERP5TypeTestCase):
p1 = self.getPersonModule()._getOb(self.id1)
p1.setRegion('europe/west/france')
get_transaction().commit()
transaction.commit()
self.tic()
west = self.portal.portal_categories.resolveCategory('region/europe/west')
west.setId("ouest")
get_transaction().commit()
transaction.commit()
self.tic()
self.assertEqual(west,
......@@ -406,14 +400,14 @@ class TestCMFCategory(ERP5TypeTestCase):
p1 = self.getPersonModule()._getOb(self.id1)
p1.setRegion('europe/west/france')
get_transaction().commit()
transaction.commit()
self.tic()
europe = self.portal.portal_categories.resolveCategory('region/europe')
west = europe.west
cb_data = europe.manage_cutObjects(['west'])
self.portal.portal_categories.region.manage_pasteObjects(cb_data)
get_transaction().commit()
transaction.commit()
self.tic()
self.assertEqual(west,
......@@ -428,14 +422,14 @@ class TestCMFCategory(ERP5TypeTestCase):
p1 = self.getPersonModule()._getOb(self.id1)
p1.setRegion('europe/west/france')
get_transaction().commit()
transaction.commit()
self.tic()
europe = self.portal.portal_categories.resolveCategory('region/europe')
west = europe.west
cb_data = europe.manage_copyObjects(['west'])
self.portal.portal_categories.region.manage_pasteObjects(cb_data)
get_transaction().commit()
transaction.commit()
self.tic()
self.assertEqual(west,
......@@ -524,7 +518,7 @@ class TestCMFCategory(ERP5TypeTestCase):
pc = self.getCategoriesTool()
bc = pc.newContent(portal_type='Base Category', id='related_value_test')
self.failUnless(bc is not None)
get_transaction().commit()
transaction.commit()
self.tic()
# A newly created base category should be referred to only by itself
value_list = pc.getRelatedValueList(bc)
......@@ -532,7 +526,7 @@ class TestCMFCategory(ERP5TypeTestCase):
c = bc.newContent(portal_type='Category', id='1')
self.failUnless(c is not None)
get_transaction().commit()
transaction.commit()
self.tic()
value_list = pc.getRelatedValueList(bc)
# Now the base category should be referred to by itself and this sub category
......@@ -546,7 +540,7 @@ class TestCMFCategory(ERP5TypeTestCase):
org = self.portal.organisation_module.newContent(
id='organisation_test',
destination='person_module/person_test')
get_transaction().commit()
transaction.commit()
self.tic()
self.assertEquals(person.getDefaultDestinationRelated(),
'organisation_module/organisation_test' )
......@@ -561,7 +555,7 @@ class TestCMFCategory(ERP5TypeTestCase):
obj = self.getOrganisationModule().newContent(
portal_type = 'Organisation')
obj.setCategoryList(['test_base_cat/test_cat'])
get_transaction().commit()
transaction.commit()
self.tic()
self.assert_(obj in [x.getObject() for x in test.getCategoryMemberValueList()])
......@@ -594,7 +588,7 @@ class TestCMFCategory(ERP5TypeTestCase):
organisation = self.getOrganisationModule().newContent(
portal_type='Organisation', region='west/france')
get_transaction().commit()
transaction.commit()
self.tic()
self.assertEquals([x.getObject() for x in
......@@ -938,7 +932,7 @@ class TestCMFCategory(ERP5TypeTestCase):
bc = self.portal.portal_categories.newContent(
portal_type='Base Category',
id='first_id')
get_transaction().commit()
transaction.commit()
self.tic()
bc.setId('new_id')
self.assertEquals('new_id', bc.getId())
......@@ -953,7 +947,7 @@ class TestCMFCategory(ERP5TypeTestCase):
self.assertNotEquals(line, None)
cell = line.newContent(id='baz', portal_type='Sale Order Cell')
self.assertNotEquals(cell, None)
get_transaction().commit()
transaction.commit()
self.tic()
for relative_url, value in (
......@@ -983,7 +977,7 @@ class TestCMFCategory(ERP5TypeTestCase):
#First remove Base Category
self.portal.portal_categories.manage_delObjects(['region'])
obj = self.portal.person_module.newContent(portal_type='Person')
get_transaction().commit()
transaction.commit()
try:
#Setters
self.assertRaises(AttributeError, getattr, obj, 'setRegion')
......@@ -999,7 +993,7 @@ class TestCMFCategory(ERP5TypeTestCase):
finally:
#add Base Category
self.portal.portal_categories.newContent(id='region', portal_type='Base Category')
get_transaction().commit()
transaction.commit()
#check Method exists after base_category creation
#Setters
self.assertTrue(getattr(obj, 'setRegion') is not None)
......
......@@ -26,10 +26,7 @@
#
##############################################################################
try:
from numpy import shape, array
except ImportError:
from Numeric import shape, array
from numpy import shape, array
MODEL_HEAD = """
/* The number of samples. */
......
......@@ -27,7 +27,7 @@
#
##############################################################################
import fnmatch, gc, glob, imp, os, re, shutil, sys, time
import fnmatch, gc, glob, imp, os, re, shutil, sys, time, tarfile
from Shared.DC.ZRDB import Aqueduct
from Shared.DC.ZRDB.Connection import Connection as RDBConnection
from Products.ERP5Type.DiffUtils import DiffFile
......@@ -80,7 +80,6 @@ from gzip import GzipFile
from lxml.etree import parse
from xml.sax.saxutils import escape
from Products.CMFCore.Expression import Expression
from Products.ERP5Type import tarfile
from urllib import quote, unquote
from difflib import unified_diff
import posixpath
......@@ -2737,22 +2736,15 @@ class ActionTemplateItem(ObjectTemplateItem):
return obj._exportOldAction(action)
def _getPortalToolActionCopy(self, obj, context, value):
try:
from Products.CMFCore.interfaces import IActionProvider
except ImportError:
# BACK:
# we still don't load ZCML on tests on 2.8, but on 2.8 actions from other
# tools are not redirected to portal_actions
pass
else:
if not IActionProvider.providedBy(obj):
# look for the action in portal_actions, instead of the original object
LOG('Products.ERP5.Document.BusinessTemplate', WARNING,
'Redirected action export',
'Attempted to retrieve action %r from %r which is no longer an '
'IActionProvided. Retrieving action from portal_actions instead' %
(value, obj.getId()))
obj = context.getPortalObject().portal_actions
from Products.CMFCore.interfaces import IActionProvider
if not IActionProvider.providedBy(obj):
# look for the action in portal_actions, instead of the original object
LOG('Products.ERP5.Document.BusinessTemplate', WARNING,
'Redirected action export',
'Attempted to retrieve action %r from %r which is no longer an '
'IActionProvided. Retrieving action from portal_actions instead' %
(value, obj.getId()))
obj = context.getPortalObject().portal_actions
id_id = 'id'
for action in obj.listActions():
if getattr(action, id_id, None) == value:
......@@ -2815,23 +2807,16 @@ class ActionTemplateItem(ObjectTemplateItem):
# Following code is for actions outside Types Tool.
# It will be removed when they are also converted to ERP5 actions.
try:
from Products.CMFCore.interfaces import IActionProvider
except ImportError:
# BACK:
# we still don't load ZCML on tests on 2.8, but on 2.8 we don't
# need to redirect actions to portal_actions.
pass
else:
if not IActionProvider.providedBy(container):
# some tools stopped being ActionProviders in CMF 2.x. Drop the
# action into portal_actions.
LOG('Products.ERP5.Document.BusinessTemplate', WARNING,
'Redirected action import',
'Attempted to store action %r in %r which is no longer an '
'IActionProvided. Storing action on portal_actions instead' %
(id, path))
container = p.portal_actions
from Products.CMFCore.interfaces import IActionProvider
if not IActionProvider.providedBy(container):
# some tools stopped being ActionProviders in CMF 2.x. Drop the
# action into portal_actions.
LOG('Products.ERP5.Document.BusinessTemplate', WARNING,
'Redirected action import',
'Attempted to store action %r in %r which is no longer an '
'IActionProvided. Storing action on portal_actions instead' %
(id, path))
container = p.portal_actions
obj, action = container, obj
action_list = obj.listActions()
for index in range(len(action_list)):
......
......@@ -53,8 +53,8 @@ except ImportError:
"""
from email import message_from_string
from email.Header import decode_header, HeaderParseError
from email.Utils import parsedate_tz, mktime_tz
from email.header import decode_header, HeaderParseError
from email.utils import parsedate_tz, mktime_tz
DEFAULT_TEXT_FORMAT = 'text/html'
COMMASPACE = ', '
......
......@@ -35,12 +35,11 @@ from Products.ERP5Type.Core.Predicate import Predicate
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin
# On Python 2.4, this dictionary doesn't include ROUND_05UP
ROUNDING_OPTION_DICT = dict((name, value)
for name, value in decimal.__dict__.items()
if name.startswith('ROUND_'))
# On Python >= 2.6, we could compute a value based on sys.float_info.epsilon
# XXX: We could compute a value based on sys.float_info.epsilon
DEFAULT_PRECISION = 1e-12
class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin):
......@@ -173,9 +172,7 @@ class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin):
value=relative_tolerance_max))
def _round(self, value):
# on Python 2.4, looking up 'ROUND_05UP' will return ROUND_DOWN here
rounding_option = ROUNDING_OPTION_DICT.get(self.getDecimalRoundingOption(),
decimal.ROUND_DOWN)
rounding_option = ROUNDING_OPTION_DICT[self.getDecimalRoundingOption()]
exponent = decimal.Decimal(self.getDecimalExponent())
# In Python 2.7, the str() below will no longer be necessary
result = decimal.Decimal(str(value)).quantize(exponent,
......
......@@ -28,7 +28,7 @@
##############################################################################
import StringIO
from hashlib import md5 as md5_new
from hashlib import md5
from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Cache import CachingMethod
from Products.ERP5Type import Permissions, PropertySheet
......@@ -431,7 +431,7 @@ class PDFTypeInformation(ERP5TypeInformation):
generateParsedScribus = CachingMethod(generateParsedScribus,
('PDFTypeInformation_generateParsedScribus',
md5_new(scribus_form.getData()).digest()),
md5(scribus_form.getData()).digest()),
cache_factory='dms_cache_factory')
return generateParsedScribus()
......@@ -544,7 +544,7 @@ class PDFTypeInformation(ERP5TypeInformation):
return form
#generateERP5Form = CachingMethod(generateERP5Form,
# ('PDFTypeInformation_generateERP5Form',
# md5_new(self.getDefaultScribusFormValue().getData()).digest()),
# md5(self.getDefaultScribusFormValue().getData()).digest()),
# cache_factory='dms_cache_factory')
return generateERP5Form().__of__(self)
......@@ -594,7 +594,7 @@ class PDFTypeInformation(ERP5TypeInformation):
generateERP5FormCSS = CachingMethod(generateERP5FormCSS,
('PDFTypeInformation_generateERP5FormCSS',
md5_new(self.getDefaultScribusFormValue().getData()).digest()),
md5(self.getDefaultScribusFormValue().getData()).digest()),
cache_factory='dms_cache_factory')
self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/css')
return generateERP5FormCSS()
......
......@@ -38,14 +38,11 @@ from Products.ERP5Type.WebDAVSupport import TextContent
import re
from Products.ERP5.Document.Document import VALID_IMAGE_FORMAT_LIST
import cStringIO
from string import Template
# Mixin Import
from Products.ERP5.mixin.cached_convertable import CachedConvertableMixin
from Products.ERP5.mixin.base_convertable import BaseConvertableFileMixin
try:
from string import Template
except ImportError:
from Products.ERP5Type.patches.string import Template
from Products.ERP5Type.Utils import guessEncodingFromText
from lxml import html as etree_html
......
......@@ -187,7 +187,6 @@ class ReferCheckerBeforeTraverseHook:
'request : "%s"' % http_url)
response.unauthorized()
import ZODB
class _site(threading.local):
"""Class for getting and setting the site in the thread global namespace
......@@ -198,15 +197,13 @@ class _site(threading.local):
self = threading.local.__new__(cls)
return self.__get, self.__set
def __get(self, REQUEST=None,
# XXX Compatibility code (ZODB >= 3.9 has no __version__ anymore)
__opened='_opened'[getattr(ZODB, '__version__', '3.9') >= '3.9':]):
def __get(self, REQUEST=None):
"""Returns the currently processed site, optionally wrapped in a request
"""
while True:
app, site_id = self.site[-1]
app = app()
if getattr(app._p_jar, __opened):
if app._p_jar.opened:
if REQUEST is None:
return getattr(app, site_id)
return getattr(app.__of__(RequestContainer(REQUEST=REQUEST)), site_id)
......@@ -346,8 +343,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
return self
def manage_beforeDelete(self, item, container):
# On Zope 2.8, skin is setup during Acquisition (in the .__of__() method).
# On Zope 2.12, skin is setup during __before_publishing_traverse__, which
# skin is setup during __before_publishing_traverse__, which
# doesn't happen when the object is being deleted from the management
# interface, but we need it to be set for portal_activities when we're
# being deleted.
......@@ -1864,17 +1860,11 @@ class ERP5Generator(PortalGenerator):
# Remove unused default actions
def removeActionsFromTool(tool, remove_list):
try:
from Products.CMFCore.interfaces import IActionProvider
if not IActionProvider.providedBy(tool):
# On CMF 2.x, some tools (portal_membership)
# are no longer action providers
return
except ImportError:
# BACK: Currently ERP5 tests don't load ZCML which is needed by the
# above import on CMF 1.5. This "try" should be removed when ERP5 tests
# start loading ZCML.
pass
from Products.CMFCore.interfaces import IActionProvider
if not IActionProvider.providedBy(tool):
# On CMF 2.x, some tools (portal_membership)
# are no longer action providers
return
action_id_list = [i.id for i in tool.listActions()]
remove_index_list = []
for i in remove_list:
......@@ -1911,26 +1901,14 @@ class ERP5Generator(PortalGenerator):
"""Semi-manually create DirectoryViews since CMFDefault 2.X no longer
registers the "skins" directory, only its subdirectories, making it
unusable with Products.CMFCore.DirectoryView.addDirectoryViews."""
from Products.CMFCore.DirectoryView import createDirectoryView
try:
from Products.CMFCore.DirectoryView import _generateKey
def generateKey(package, subdir):
return _generateKey(package.__name__, subdir)
except ImportError:
# Means we're still on CMF 1.x, were they generate the DirectoryView
# key using minimalpath
# ( see Products.CMFCore.DirectoryView.addDirectoryViews() )
from Products.CMFCore.DirectoryView import minimalpath
def generateKey(package, subdir):
package_path = os.path.dirname(package.__file__)
return minimalpath(os.path.join(package_path, subdir))
from Products.CMFCore.DirectoryView import createDirectoryView, _generateKey
import Products.CMFDefault
ps = p.portal_skins
# get the layer directories actually present
for cmfdefault_skin_layer in self.CMFDEFAULT_FOLDER_LIST:
reg_key = generateKey(Products.CMFDefault,
'skins/' + cmfdefault_skin_layer)
reg_key = _generateKey(Products.CMFDefault.__name__,
'skins/' + cmfdefault_skin_layer)
createDirectoryView(ps, reg_key)
def setupDefaultSkins(self, p):
......
......@@ -6,16 +6,9 @@ import csv
from Products.CMFCore.utils import expandpath
from zLOG import LOG
from App.config import getConfiguration
try:
from App.config import getConfiguration
except ImportError:
getConfiguration = None
if getConfiguration is None:
data_dir = '/var/lib/zope/data'
else:
data_dir = getConfiguration().instancehome + '/data'
data_dir = os.path.join(getConfiguration().instancehome, 'data')
fs_skin_spec = ('ERP5 Filesystem Formulator Form',
'ERP5 Filesystem PDF Template',
......
......@@ -4,13 +4,8 @@
# have to be patched with a manage_FTPget wich contains
# a section <dtml-comment></dtml-comment>
#instance_home = getConfiguration().instancehome
# Zope 2.6.x does not have App.Config
try:
from App.config import getConfiguration
except ImportError:
getConfiguration = None
import os
from App.config import getConfiguration
fs_skin_ids = ('fs_erp5_core', 'fs_erp5_trade', 'fs_erp5_accounting', 'fs_erp5_crm')
fs_skin_spec = ('ERP5 Filesystem Formulator Form',
......@@ -19,10 +14,7 @@ fs_skin_spec = ('ERP5 Filesystem Formulator Form',
'Filesystem Page Template',
'Filesystem Script (Python)',
'Filesystem Z SQL Method')
if getConfiguration is None:
fs_skin_dir = '/var/lib/zope/Products'
else:
fs_skin_dir = getConfiguration().instancehome + '/Products'
fs_skin_dir = os.path.join(getConfiguration().instancehome, 'Products')
zodb_skin_ids = ('erp5_core', 'erp5_trade', 'erp5_accounting', 'erp5_crm')
zodb_skin_spec = ('ERP5 Form', 'ERP5 PDF Template', 'Page Template', 'Script', 'Script (Python)','Z SQL Method')
......
......@@ -19,6 +19,7 @@ import urllib2, os, dircache, urllib
from StringIO import StringIO
from urllib2 import FileHandler, url2pathname, addinfourl, URLError
import mimetypes, mimetools
from email.utils import formatdate
class DirectoryFileHandler(FileHandler):
"""
......@@ -37,13 +38,12 @@ class DirectoryFileHandler(FileHandler):
# not entirely sure what the rules are here
def open_local_file(self, req):
import email.Utils
host = req.get_host()
file = req.get_selector()
localfile = url2pathname(file)
stats = os.stat(localfile)
size = stats.st_size
modified = email.Utils.formatdate(stats.st_mtime, usegmt=True)
modified = formatdate(stats.st_mtime, usegmt=True)
mtype = mimetypes.guess_type(file)[0]
headers = mimetools.Message(StringIO(
'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
......
......@@ -31,6 +31,7 @@ import os
import sys
import tempfile
import json
import tarfile
from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Globals import InitializeClass, DTMLFile
from Products.ERP5Type.Tool.BaseTool import BaseTool
......@@ -42,7 +43,6 @@ from Products.ERP5Type.Utils import _setSuperSecurityManager
from App.config import getConfiguration
from AccessControl import Unauthorized
from Products.ERP5Type.Cache import CachingMethod
from Products.ERP5Type import tarfile
from cgi import escape
import logging
......
......@@ -35,13 +35,13 @@ from AccessControl import ModuleSecurityInfo
from Products.ERP5 import _dtmldir
from mimetypes import guess_type
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email.MIMEAudio import MIMEAudio
from email.MIMEImage import MIMEImage
from email.Header import make_header
from email import Encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.audio import MIMEAudio
from email.mime.image import MIMEImage
from email.header import make_header
from email import encoders
class ConversionError(Exception): pass
class MimeTypeException(Exception): pass
......@@ -168,7 +168,7 @@ def buildEmailMessage(from_url, to_url, msg=None,
# encode non-plaintext attachment in base64
part = MIMEBase(major, minor)
part.set_payload(attachment['content'])
Encoders.encode_base64(part)
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment',
filename=attachment_name)
......
......@@ -36,7 +36,7 @@ from Products.ERP5Type import Permissions
from Products.ERP5 import _dtmldir
from zLOG import LOG, INFO
import time, random
from hashlib import md5 as md5_new
from hashlib import md5
from DateTime import DateTime
from Products.ERP5Type.Message import translateString
from Products.ERP5Type.Globals import PersistentMapping
......@@ -214,9 +214,7 @@ class PasswordTool(BaseTool):
# if we can't get a network address, just imagine one
a = random.random()*100000000000000000L
data = ' '.join((str(t), str(r), str(a), str(args)))
data = md5_new(data).hexdigest()
return data
return md5(data).hexdigest()
def resetPassword(self, reset_key=None, REQUEST=None):
"""
......
......@@ -39,10 +39,7 @@ from Products.ERP5 import _dtmldir
from zLOG import LOG, PROBLEM
from Products.ERP5.Capacity.GLPK import solve
try:
from numpy import zeros, resize
except ImportError:
from Numeric import zeros, resize
from numpy import zeros, resize
from DateTime import DateTime
from Products.ERP5 import DeliverySolver
......
......@@ -33,6 +33,7 @@ from App.config import getConfiguration
import os
import shutil
import sys
import tarfile
from Acquisition import Implicit, Explicit
from AccessControl import ClassSecurityInfo
......@@ -40,7 +41,7 @@ from Products.CMFActivity.ActiveResult import ActiveResult
from Products.ERP5Type.Globals import InitializeClass, DTMLFile, PersistentMapping
from Products.ERP5Type.DiffUtils import DiffFile
from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type import Permissions, tarfile
from Products.ERP5Type import Permissions
from Products.ERP5.Document.BusinessTemplate import BusinessTemplateMissingDependency
from Acquisition import aq_base
from tempfile import mkstemp, mkdtemp
......
......@@ -116,18 +116,13 @@ class TrashTool(BaseTool):
try:
backup = connection.importFile(copy)
backup.isIndexable = ConstantGetter('isIndexable', value=False)
try:
# the isIndexable setting above avoids the recursion of
# manage_afterAdd on
# Products.ERP5Type.CopySupport.CopySupport.manage_afterAdd()
# but not on event subscribers, so we need to suppress_events,
# otherwise subobjects will be reindexed
backup_object_container._setObject(object_id, backup,
suppress_events=True)
except TypeError:
# BACK: On Zope 2.8. _setObject does not accept "suppress_events"
# remove when we drop support
backup_object_container._setObject(object_id, backup)
# the isIndexable setting above avoids the recursion of
# manage_afterAdd on
# Products.ERP5Type.CopySupport.CopySupport.manage_afterAdd()
# but not on event subscribers, so we need to suppress_events,
# otherwise subobjects will be reindexed
backup_object_container._setObject(object_id, backup,
suppress_events=True)
except (AttributeError, ImportError):
# XXX we can go here due to formulator because attribute
# field_added doesn't not exists on parent if it is a Trash
......
......@@ -33,7 +33,6 @@
import tarfile
import os
import os.path
import sys
import tempfile
import shutil
......@@ -66,7 +65,7 @@ def readProperty(property_dict, property_name, property_file):
try:
text = property_file.read()
if property_name.endswith('_list'):
property_dict[property_name[:-5]] = text and text.split('\n') or []
property_dict[property_name[:-5]] = text.splitlines()
else:
property_dict[property_name] = text
finally:
......@@ -118,12 +117,9 @@ def generateInformation(fd):
property_dict = readBusinessTemplateDirectory(file)
else:
continue
property_id_list = property_dict.keys()
property_id_list.sort()
os.write(fd, ' <template id="%s">\n' % (file,))
for property_id in property_id_list:
property_value = property_dict[property_id]
if type(property_value) == type(''):
for property_id, property_value in sorted(property_dict.items()):
if type(property_value) is str:
os.write(fd, ' <%s>%s</%s>\n' % (
property_id, cgi.escape(property_value), property_id))
else:
......@@ -140,143 +136,24 @@ def main():
else:
dir_list = sys.argv[1:]
cur_umask = os.umask(0666)
os.umask(cur_umask)
cwd = os.getcwd()
for d in dir_list:
os.chdir(d)
fd, path = tempfile.mkstemp()
try:
fd, path = tempfile.mkstemp(dir='.')
try:
generateInformation(fd)
os.fchmod(fd, 0666 & ~cur_umask)
os.rename(path, 'bt5list')
except:
os.remove(path)
raise
finally:
os.close(fd)
except:
os.remove(path)
raise
else:
shutil.move(path, 'bt5list')
cur_umask = os.umask(0666)
os.chmod('bt5list', 0666 & ~cur_umask)
os.umask(cur_umask)
os.chdir(cwd)
# monkey patch tarfile library if python version is 2.4.
if sys.version_info[0:2] == (2, 4):
from tarfile import BLOCKSIZE, GNUTYPE_SPARSE, SUPPORTED_TYPES, TarFile, \
TarInfo, calc_chksum, normpath, nts
def frombuf(cls, buf):
"""Construct a TarInfo object from a 512 byte string buffer.
"""
tarinfo = cls()
tarinfo.name = nts(buf[0:100])
tarinfo.mode = int(buf[100:108], 8)
tarinfo.uid = int(buf[108:116],8)
tarinfo.gid = int(buf[116:124],8)
# There are two possible codings for the size field we
# have to discriminate, see comment in tobuf() below.
if buf[124] != chr(0200):
tarinfo.size = long(buf[124:136], 8)
else:
tarinfo.size = 0L
for i in range(11):
tarinfo.size <<= 8
tarinfo.size += ord(buf[125 + i])
tarinfo.mtime = long(buf[136:148], 8)
tarinfo.chksum = int(buf[148:156], 8)
tarinfo.type = buf[156:157]
tarinfo.linkname = nts(buf[157:257])
tarinfo.uname = nts(buf[265:297])
tarinfo.gname = nts(buf[297:329])
try:
tarinfo.devmajor = int(buf[329:337], 8)
tarinfo.devminor = int(buf[337:345], 8)
except ValueError:
tarinfo.devmajor = tarinfo.devmajor = 0
tarinfo.prefix = buf[345:500]
# The prefix field is used for filenames > 100 in
# the POSIX standard.
# name = prefix + '/' + name
if tarinfo.type != GNUTYPE_SPARSE:
tarinfo.name = normpath(os.path.join(nts(tarinfo.prefix), tarinfo.name))
# Directory names should have a '/' at the end.
if tarinfo.isdir() and tarinfo.name[-1:] != "/":
tarinfo.name += "/"
return tarinfo
TarInfo.frombuf = classmethod(frombuf)
def next(self):
"""Return the next member of the archive as a TarInfo object, when
TarFile is opened for reading. Return None if there is no more
available.
"""
self._check("ra")
if self.firstmember is not None:
m = self.firstmember
self.firstmember = None
return m
# Read the next block.
self.fileobj.seek(self.offset)
while True:
buf = self.fileobj.read(BLOCKSIZE)
if not buf:
return None
try:
tarinfo = TarInfo.frombuf(buf)
except ValueError:
if self.ignore_zeros:
if buf.count(NUL) == BLOCKSIZE:
adj = "empty"
else:
adj = "invalid"
self._dbg(2, "0x%X: %s block" % (self.offset, adj))
self.offset += BLOCKSIZE
continue
else:
# Block is empty or unreadable.
if self.offset == 0:
# If the first block is invalid. That does not
# look like a tar archive we can handle.
raise ReadError,"empty, unreadable or compressed file"
return None
break
# We shouldn't rely on this checksum, because some tar programs
# calculate it differently and it is merely validating the
# header block. We could just as well skip this part, which would
# have a slight effect on performance...
if tarinfo.chksum != calc_chksum(buf):
self._dbg(1, "tarfile: Bad Checksum %r" % tarinfo.name)
# Set the TarInfo object's offset to the current position of the
# TarFile and set self.offset to the position where the data blocks
# should begin.
tarinfo.offset = self.offset
self.offset += BLOCKSIZE
# Check if the TarInfo object has a typeflag for which a callback
# method is registered in the TYPE_METH. If so, then call it.
if tarinfo.type in self.TYPE_METH:
return self.TYPE_METH[tarinfo.type](self, tarinfo)
tarinfo.offset_data = self.offset
if tarinfo.isreg() or tarinfo.type not in SUPPORTED_TYPES:
# Skip the following data blocks.
self.offset += self._block(tarinfo.size)
if tarinfo.isreg() and tarinfo.name[:-1] == "/":
# some old tar programs don't know DIRTYPE
tarinfo.type = DIRTYPE
self.members.append(tarinfo)
return tarinfo
TarFile.next = next
finally:
os.chdir(cwd)
if __name__ == "__main__":
main()
......@@ -27,7 +27,7 @@
#
##############################################################################
from hashlib import md5 as md5_new
from hashlib import md5
import string
from Acquisition import aq_base
......@@ -47,7 +47,7 @@ def hashPdataObject(pdata_object):
"""Pdata objects are iterable, use this feature strongly
to minimize memory footprint.
"""
md5_hash = md5_new()
md5_hash = md5()
next = pdata_object
while next is not None:
md5_hash.update(next.data)
......@@ -134,11 +134,11 @@ class CachedConvertableMixin:
size = len(cached_value)
elif isinstance(data, OFSImage):
cached_value = data
conversion_md5 = md5_new(str(data.data)).hexdigest()
conversion_md5 = md5(str(data.data)).hexdigest()
size = len(data.data)
elif isinstance(data, (str, unicode,)):
cached_value = data
conversion_md5 = md5_new(cached_value).hexdigest()
conversion_md5 = md5(cached_value).hexdigest()
size = len(cached_value)
elif isinstance(data, dict):
# Dict instance are used to store computed metadata
......@@ -249,7 +249,7 @@ class CachedConvertableMixin:
if isinstance(data, Pdata):
self._setContentMd5(hashPdataObject(aq_base(data)))
else:
self._setContentMd5(md5_new(data).hexdigest()) # Reindex is useless
self._setContentMd5(md5(data).hexdigest()) # Reindex is useless
else:
self._setContentMd5(None)
......
......@@ -30,22 +30,13 @@
##############################################################################
import zope.interface
from AccessControl import ClassSecurityInfo
from AccessControl.AuthEncoding import pw_encrypt, pw_validate
from Acquisition import aq_base
from Products.ERP5Type import Permissions, interfaces
from Products.ERP5Type.Globals import PersistentMapping
from Products.CMFCore.utils import _checkPermission
from Products.CMFCore.exceptions import AccessControl_Unauthorized
try:
from AccessControl.AuthEncoding import pw_encrypt
except ImportError:
pw_encrypt = lambda pw:pw
try:
from AccessControl.AuthEncoding import pw_validate
except ImportError:
pw_validate = lambda reference, attempt: reference == attempt
class EncryptedPasswordMixin:
# Declarative security
......
......@@ -125,8 +125,7 @@ class PropertyRecordableMixin:
which recorded properties in its context.
"""
context = self.asContext()
# BBB: cast to dict is required for Python < 2.6
context.edit(**dict(self._getRecordedPropertyDict(())))
context.edit(**self._getRecordedPropertyDict(()))
return context
def _getRecordedPropertyDict(self, *args):
......
......@@ -311,7 +311,7 @@ class TestBug(ERP5TypeTestCase):
last_message = self.portal.MailHost._last_message
self.assertNotEquals((), last_message)
mfrom, mto, messageText = last_message
from email.Parser import Parser
from email.parser import Parser
p = Parser()
m = p.parsestr(messageText)
self.assertTrue('Re-assign!' in m.get_payload()[0].get_payload(decode=True))
......
......@@ -28,8 +28,6 @@
import unittest
import os
import email.Header
import transaction
from Products.CMFCore.WorkflowCore import WorkflowException
......@@ -39,10 +37,11 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase,\
from Products.ERP5OOo.tests.testIngestion import FILENAME_REGULAR_EXPRESSION
from Products.ERP5OOo.tests.testIngestion import REFERENCE_REGULAR_EXPRESSION
from Products.ERP5Type.tests.backportUnittest import expectedFailure
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
from email.header import decode_header
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders, message_from_string
def makeFilePath(name):
return os.path.join(os.path.dirname(__file__), 'test_data', 'crm_emails', name)
......@@ -632,7 +631,7 @@ class TestCRMMailIngestion(BaseTestCRM):
return object_list[-1]
portal = self.portal
message = email.message_from_string(self._readTestData('simple'))
message = message_from_string(self._readTestData('simple'))
message.replace_header('subject', 'Visit:Company A')
data = message.as_string()
self._ingestMail(data=data)
......@@ -641,7 +640,7 @@ class TestCRMMailIngestion(BaseTestCRM):
document = getLastCreatedEvent(portal.event_module)
self.assertEqual(document.getPortalType(), 'Visit')
message = email.message_from_string(self._readTestData('simple'))
message = message_from_string(self._readTestData('simple'))
message.replace_header('subject', 'Fax:Company B')
data = message.as_string()
self._ingestMail(data=data)
......@@ -650,7 +649,7 @@ class TestCRMMailIngestion(BaseTestCRM):
document = getLastCreatedEvent(portal.event_module)
self.assertEqual(document.getPortalType(), 'Fax Message')
message = email.message_from_string(self._readTestData('simple'))
message = message_from_string(self._readTestData('simple'))
message.replace_header('subject', 'TEST:Company B')
data = message.as_string()
self._ingestMail(data=data)
......@@ -659,7 +658,7 @@ class TestCRMMailIngestion(BaseTestCRM):
document = getLastCreatedEvent(portal.event_module)
self.assertEqual(document.getPortalType(), 'Mail Message')
message = email.message_from_string(self._readTestData('simple'))
message = message_from_string(self._readTestData('simple'))
message.replace_header('subject', 'visit:Company A')
data = message.as_string()
self._ingestMail(data=data)
......@@ -668,7 +667,7 @@ class TestCRMMailIngestion(BaseTestCRM):
document = getLastCreatedEvent(portal.event_module)
self.assertEqual(document.getPortalType(), 'Visit')
message = email.message_from_string(self._readTestData('simple'))
message = message_from_string(self._readTestData('simple'))
message.replace_header('subject', 'phone:Company B')
data = message.as_string()
self._ingestMail(data=data)
......@@ -677,7 +676,7 @@ class TestCRMMailIngestion(BaseTestCRM):
document = portal.event_module[portal.event_module.objectIds()[-1]]
self.assertEqual(document.getPortalType(), 'Phone Call')
message = email.message_from_string(self._readTestData('simple'))
message = message_from_string(self._readTestData('simple'))
message.replace_header('subject', 'LETTER:Company C')
data = message.as_string()
self._ingestMail(data=data)
......@@ -686,7 +685,7 @@ class TestCRMMailIngestion(BaseTestCRM):
document = getLastCreatedEvent(portal.event_module)
self.assertEqual(document.getPortalType(), 'Letter')
message = email.message_from_string(self._readTestData('simple'))
message = message_from_string(self._readTestData('simple'))
body = message.get_payload()
message.set_payload('Visit:%s' % body)
data = message.as_string()
......@@ -696,7 +695,7 @@ class TestCRMMailIngestion(BaseTestCRM):
document = getLastCreatedEvent(portal.event_module)
self.assertEqual(document.getPortalType(), 'Visit')
message = email.message_from_string(self._readTestData('simple'))
message = message_from_string(self._readTestData('simple'))
body = message.get_payload()
message.set_payload('PHONE CALL:%s' % body)
data = message.as_string()
......@@ -800,7 +799,7 @@ class TestCRMMailIngestion(BaseTestCRM):
message.attach(MIMEText('text plain content', _charset='utf-8'))
part = MIMEBase('text', 'html')
part.set_payload(html_message)
Encoders.encode_base64(part)
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment',
filename=html_filename)
......@@ -901,10 +900,9 @@ class TestCRMMailSend(BaseTestCRM):
self.assertEquals('"Me," <me@erp5.org>', mfrom)
self.assertEquals(['"Recipient," <recipient@example.com>'], mto)
self.assertEquals(event.getTextContent(), text_content)
message = email.message_from_string(messageText)
message = message_from_string(messageText)
self.assertEquals('A Mail',
email.Header.decode_header(message['Subject'])[0][0])
self.assertEquals('A Mail', decode_header(message['Subject'])[0][0])
part = None
for i in message.get_payload():
if i.get_content_type()=='text/plain':
......@@ -1011,7 +1009,7 @@ class TestCRMMailSend(BaseTestCRM):
self.assertEquals('"Me," <me@erp5.org>', mfrom)
self.assertEquals(['"Recipient," <recipient@example.com>'], mto)
message = email.message_from_string(messageText)
message = message_from_string(messageText)
part = None
for i in message.get_payload():
if i.get_content_type()=='text/html':
......@@ -1055,10 +1053,9 @@ class TestCRMMailSend(BaseTestCRM):
self.assertEquals('"Me," <me@erp5.org>', mfrom)
self.assertEquals(['"Recipient," <recipient@example.com>'], mto)
message = email.message_from_string(messageText)
message = message_from_string(messageText)
self.assertEquals('Héhé',
email.Header.decode_header(message['Subject'])[0][0])
self.assertEquals('Héhé', decode_header(message['Subject'])[0][0])
part = None
for i in message.get_payload():
if i.get_content_type()=='text/plain':
......@@ -1098,7 +1095,7 @@ class TestCRMMailSend(BaseTestCRM):
mail_text = event.send(download=True)
# Check mail text.
message = email.message_from_string(mail_text)
message = message_from_string(mail_text)
part = None
for i in message.get_payload():
if i.get_content_type()=='text/plain':
......@@ -1146,7 +1143,7 @@ class TestCRMMailSend(BaseTestCRM):
mail_text = event.send(download=True)
# Check mail text.
message = email.message_from_string(mail_text)
message = message_from_string(mail_text)
part = None
for i in message.get_payload():
if i.get_content_type()=='text/plain':
......@@ -1193,7 +1190,7 @@ class TestCRMMailSend(BaseTestCRM):
mail_text = event.send(download=True)
# Check mail text.
message = email.message_from_string(mail_text)
message = message_from_string(mail_text)
part = None
for i in message.get_payload():
if i.get_content_type()=='text/plain':
......@@ -1241,7 +1238,7 @@ class TestCRMMailSend(BaseTestCRM):
mail_text = event.send(download=True)
# Check mail text.
message = email.message_from_string(mail_text)
message = message_from_string(mail_text)
part = None
for i in message.get_payload():
if i.get_content_type()=='text/plain':
......@@ -1289,7 +1286,7 @@ class TestCRMMailSend(BaseTestCRM):
mail_text = event.send(download=True)
# Check mail text.
message = email.message_from_string(mail_text)
message = message_from_string(mail_text)
part = None
for i in message.get_payload():
if i.get_content_type()=='text/plain':
......@@ -1388,7 +1385,7 @@ class TestCRMMailSend(BaseTestCRM):
mail_text = event.send(download=True)
# Check mail text.
message = email.message_from_string(mail_text)
message = message_from_string(mail_text)
part = None
for i in message.get_payload():
if i.get_content_type()=='text/plain':
......@@ -1447,7 +1444,7 @@ class TestCRMMailSend(BaseTestCRM):
mail_text = event.send(download=True)
# Check mail text.
message = email.message_from_string(mail_text)
message = message_from_string(mail_text)
part = None
for i in message.get_payload():
if i.get_content_type()=='text/plain':
......
......@@ -28,7 +28,7 @@
##############################################################################
import unittest
import md5
from hashlib import md5
import pprint
import transaction
......@@ -38,16 +38,7 @@ from Testing import ZopeTestCase
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import DummyTranslationService
try:
# BACK: Zope 2.8
# When we drop support, refactor the tests to use the i18n utilities
# directly
from Products.PageTemplates.GlobalTranslationService import \
setGlobalTranslationService
def unregister_translation_domain_fallback():
"""dummy function to keep the beforeTearDown() code neat"""
except ImportError:
if 1: # BBB
# Zope 2.12, simulate setting the globalTranslationService with
# zope.i18n utilities
import zope.interface
......@@ -425,7 +416,7 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
'test_selection', dict(uids=uid_list))
transaction.commit()
self.tic()
md5_string = md5.new(str(sorted([str(x) for x in uid_list]))).hexdigest()
md5_string = md5(str(sorted(map(str, uid_list)))).hexdigest()
redirect = module.Folder_delete(selection_name='test_selection',
uids=uid_list,
md5_object_uid_list=md5_string)
......@@ -451,7 +442,7 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
uid_list = [obj.getUid()]
self.portal.portal_selections.setSelectionParamsFor(
'test_selection', dict(uids=uid_list))
md5_string = md5.new(str(sorted(str(x) for x in uid_list))).hexdigest()
md5_string = md5(str(sorted(map(str, uid_list)))).hexdigest()
redirect = obj.getParentValue().Folder_delete(uids=uid_list,
selection_name='test_selection', md5_object_uid_list=md5_string)
self.assertTrue(('Sorry, 1 item is in use.', 'Deleted.')[assert_deleted]
......@@ -484,7 +475,7 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
self.tic()
self.assertEquals([document_1],
self.portal.portal_categories.getRelatedValueList(document_2))
md5_string = md5.new(str(sorted([str(x) for x in uid_list]))).hexdigest()
md5_string = md5(str(sorted(map(str, uid_list)))).hexdigest()
document_1.manage_permission('View', [], acquire=0)
document_1.manage_permission('Access contents information', [], acquire=0)
......
......@@ -32,8 +32,8 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import DummyMailHost
from Products.ERP5Type.tests.Sequence import SequenceList
import email, re
from email.Header import decode_header, make_header
from email.Utils import parseaddr
from email.header import decode_header, make_header
from email.utils import parseaddr
import transaction
import cgi
from urlparse import urlparse
......
......@@ -35,8 +35,8 @@ from AccessControl.SecurityManagement import getSecurityManager
from Products.ERP5Type.tests.Sequence import SequenceList
from Products.ERP5Type.tests.utils import DummyMailHost
import email
from email.Header import decode_header, make_header
from email.Utils import parseaddr
from email.header import decode_header, make_header
from email.utils import parseaddr
# Copied from ERP5Type/patches/CMFMailIn.py
def decode_email(file):
......
......@@ -26,7 +26,7 @@
##############################################################################
import os
from Products.ERP5Type import tarfile
import tarfile
import xml.parsers.expat
import xml.dom.minidom
from urllib import url2pathname
......
......@@ -39,14 +39,8 @@ from Products.ERP5Banking.BaobabMixin import BaobabMixin
# Import classes to monkey-patch
# XXX All patches must be moved in a Business Template !!
try:
from Products.ERP5Type import dynamic
except ImportError:
from Products.ERP5Type.Document.Currency import Currency
from Products.ERP5Type.Document.DeliveryCell import DeliveryCell
else:
from Products.ERP5.Document.Currency import Currency
from Products.ERP5.Document.DeliveryCell import DeliveryCell
from Products.ERP5.Document.Currency import Currency
from Products.ERP5.Document.DeliveryCell import DeliveryCell
class BankingOperation(BaobabMixin, AccountingTransaction):
......
......@@ -47,10 +47,6 @@ from Products.CMFActivity.Errors import ActivityFlushError
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
from Products.ERP5Type.tests.backportUnittest import expectedFailure
try:
from transaction import get as get_transaction
except ImportError:
pass
import transaction
from OFS.ObjectManager import ObjectManager
......
......@@ -38,7 +38,7 @@ from Products.Formulator.TALESField import TALESField
import CaptchasDotNet
import string
import random
import md5
from hashlib import md5
import time
from zope.interface import Interface
from zope.interface import implements
......@@ -79,7 +79,7 @@ class CaptchasDotNetProvider(object):
def getHTML(self, field, captcha_key):
image_generator = self.getImageGenerator(field)
return image_generator.image(captcha_key, "__captcha_" + md5.new(captcha_key).hexdigest())
return image_generator.image(captcha_key, "__captcha_" + md5(captcha_key).hexdigest())
# dynamic fields
_dynamic_property_list = [dict(id='captcha_dot_net_client',
......@@ -202,15 +202,14 @@ class CaptchaWidget(Widget.TextWidget):
provider = CaptchaProviderFactory.getProvider(captcha_type)
(captcha_key, captcha_answer) = provider.generate(field)
portal_sessions = field.getPortalObject().portal_sessions
while not(self.add_captcha(portal_sessions, md5.new(captcha_key).hexdigest(), captcha_answer)):
while not self.add_captcha(portal_sessions, md5(captcha_key).hexdigest(), captcha_answer):
(captcha_key, captcha_answer) = provider.generate(field)
captcha_field = provider.getHTML(field, captcha_key)
key_field = Widget.render_element("input",
type="hidden",
name="__captcha_" + key + "__",
value=md5.new(captcha_key).hexdigest()
)
value=md5(captcha_key).hexdigest())
splitter = "<br />"
answer = Widget.render_element("input",
type="text",
......
......@@ -28,7 +28,7 @@
#
#---------------------------------------------------------------------
import md5
from hashlib import md5
import random
class CaptchasDotNet:
......@@ -132,7 +132,7 @@ class CaptchasDotNet:
encryption_base = self.__secret + random
if (password_alphabet != "abcdefghijklmnopqrstuvwxyz") or (password_length != 6):
encryption_base += ":" + password_alphabet + ":" + str(password_length)
digest = md5.new (encryption_base).digest ()
digest = md5(encryption_base).digest()
# Compute password
correct_password = ''
......
......@@ -50,7 +50,7 @@ from Products.ERP5Type.Globals import InitializeClass, get_request
from Products.PythonScripts.Utility import allow_class
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from warnings import warn
from hashlib import md5 as md5_new
from hashlib import md5
import cgi
DEFAULT_LISTBOX_DISPLAY_STYLE = 'table'
......@@ -2569,7 +2569,7 @@ class ListBoxHTMLRenderer(ListBoxRenderer):
if checked_uid_list is not None:
checked_uid_list = [str(uid) for uid in checked_uid_list]
checked_uid_list.sort()
md5_string = md5_new(str(checked_uid_list)).hexdigest()
md5_string = md5(str(checked_uid_list)).hexdigest()
else:
md5_string = None
......
......@@ -29,11 +29,7 @@
from OFS.Image import File
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.ERP5Type import PropertySheet, Permissions
from Products.PageTemplates.Expressions import getEngine
try:
from Products.PageTemplates.TALES import SafeMapping
except ImportError:
from Products.PageTemplates.Expressions import SafeMapping
from Products.PageTemplates.Expressions import getEngine, SafeMapping
from urllib import quote
from Products.ERP5Type.Globals import InitializeClass, PersistentMapping, DTMLFile
......
......@@ -219,14 +219,7 @@ if ReportTool:
from Products.CMFReportTool.RenderPDF.Parser import TemplateParser,DocumentParser
try:
# Zope 2.10 and later.
from Products.PageTemplates.Expressions import boboAwareZopeTraverse
except ImportError:
# Zope 2.9 and earlier.
boboAwareZopeTraverse = None
from Products.PageTemplates.Expressions import restrictedTraverse
from Products.PageTemplates.Expressions import boboAwareZopeTraverse
from StringIO import StringIO
import xml.dom.minidom
import urllib,os.path
......@@ -239,12 +232,9 @@ if ReportTool:
def handleZODB(self,path):
path = path.split('/')
if boboAwareZopeTraverse is None:
obj = restrictedTraverse(self.context,path,getSecurityManager())
else:
# XXX only the request should be required, but this looks ad-hoc..
econtext = dict(request=self.context.REQUEST)
obj = boboAwareZopeTraverse(self.context, path, econtext)
# XXX only the request should be required, but this looks ad-hoc..
econtext = dict(request=self.context.REQUEST)
obj = boboAwareZopeTraverse(self.context, path, econtext)
# check type and e.g. call object if script ...
......@@ -276,12 +266,9 @@ if ReportTool:
def zodb_open(self, req):
path = req.get_selector()
path = path.split('/')
if boboAwareZopeTraverse is None:
obj = restrictedTraverse(self.context,path,getSecurityManager())
else:
# XXX only the request should be required, but this looks ad-hoc..
econtext = dict(request=self.context.REQUEST)
obj = boboAwareZopeTraverse(self.context, path, econtext)
# XXX only the request should be required, but this looks ad-hoc..
econtext = dict(request=self.context.REQUEST)
obj = boboAwareZopeTraverse(self.context, path, econtext)
# check type and e.g. call object if script ...
if callable(obj):
......
......@@ -41,7 +41,7 @@ from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from Products.ERP5Form import _dtmldir
from Products.ERP5Form.Selection import Selection, DomainSelection
from ZPublisher.HTTPRequest import FileUpload
from hashlib import md5 as md5_new
from hashlib import md5
import string, re
from time import time
from random import random
......@@ -1174,7 +1174,7 @@ class SelectionTool( BaseTool, SimpleItem ):
# convert each element to a string.
object_uid_list = [str(x) for x in object_uid_list]
object_uid_list.sort()
new_md5_string = md5_new(str(object_uid_list)).hexdigest()
new_md5_string = md5(str(object_uid_list)).hexdigest()
return md5_string != new_md5_string
......@@ -1414,7 +1414,7 @@ class SelectionTool( BaseTool, SimpleItem ):
if user_id == 'Anonymous User' and self.getAnonymousStorage() is not None:
anonymous_uid = self.REQUEST.get('anonymous_uid', None)
if anonymous_uid is None:
anonymous_uid = md5_new('%s.%s' % (time(), random())).hexdigest()
anonymous_uid = md5('%s.%s' % (time(), random())).hexdigest()
self.REQUEST['anonymous_uid'] = anonymous_uid
user_id = 'Anonymous:%s' % anonymous_uid
tv['_user_id'] = user_id
......@@ -1581,15 +1581,10 @@ class SelectionPersistentMapping(PersistentMapping):
return 1
def _p_resolveConflict(self, oldState, savedState, newState):
# BUG: we should not modify newState
# update keys that only savedState has
oldState = newState
# dict returned by PersistentMapping.__getstate__ contains the data
# under '_container' key in zope 2.7 and 'data' in zope 2.8
if 'data' in oldState:
oldState['data'].update(savedState['data'])
else:
oldState['_container'].update(savedState['_container'])
return oldState
newState['data'].update(savedState['data'])
return newState
class TreeListLine:
......
......@@ -580,11 +580,8 @@ class TestProxyField(ERP5TypeTestCase):
ERP5Form('Base_viewProxyFieldLibrary', 'Proxys'))
self.container._setObject('Base_view',
ERP5Form('Base_view', 'View'))
try:
from Products.CMFCore.tests.base.utils import _setUpDefaultTraversable
_setUpDefaultTraversable()
except ImportError:
pass # On Zope 2.8, remove when we no longer support it
from Products.CMFCore.tests.base.utils import _setUpDefaultTraversable
_setUpDefaultTraversable()
def addField(self, form, id, title, field_type):
......
......@@ -28,14 +28,7 @@
import unittest
import os
try:
from zope.app.testing.placelesssetup import PlacelessSetup
except ImportError:
# BACK: Zope 2.8. Remove when we no longer support it
from zope.component.tests.placelesssetup import PlacelessSetup
from zope.app.testing.placelesssetup import PlacelessSetup
from Products.ERP5Form.PDFForm import PDFForm
from Products.ERP5.Document.Document import Document
......@@ -51,11 +44,8 @@ class TestPDFForm(PlacelessSetup, unittest.TestCase):
"""Creates a PDFForm, and a document on which the PDF form is rendered.
"""
super(TestPDFForm, self).setUp()
try:
from Products.CMFCore.tests.base.utils import _setUpDefaultTraversable
_setUpDefaultTraversable()
except ImportError:
pass # On Zope 2.8, remove when we no longer support it
from Products.CMFCore.tests.base.utils import _setUpDefaultTraversable
_setUpDefaultTraversable()
self.document = Document('doc_id')
pdf_file = open(os.path.join(os.path.dirname(__file__),
'data', 'test_1.pdf'), 'rb')
......
......@@ -34,10 +34,7 @@ from AccessControl import ClassSecurityInfo
from AccessControl import Unauthorized
from OFS.Image import Pdata
from OFS.Image import File as OFSFile
try:
from OFS.content_types import guess_content_type
except ImportError:
from zope.contenttype import guess_content_type
from zope.contenttype import guess_content_type
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.Cache import CachingMethod
......
......@@ -36,10 +36,7 @@ from Products.CMFCore.FSPageTemplate import FSPageTemplate
from Products.CMFCore.DirectoryView import registerFileExtension, registerMetaType
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
try:
from TAL.TALInterpreter import FasterStringIO
except ImportError:
from zope.tal.talinterpreter import FasterStringIO
from zope.tal.talinterpreter import FasterStringIO
from Products.ERP5Type import PropertySheet
from urllib import quote
from Products.ERP5Type.Globals import InitializeClass, DTMLFile, get_request
......@@ -48,10 +45,7 @@ from Acquisition import aq_base
from AccessControl import ClassSecurityInfo
from OOoUtils import OOoBuilder
from zipfile import ZipFile, ZIP_DEFLATED
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
from cStringIO import StringIO
import re
import itertools
......@@ -111,30 +105,26 @@ class OOoTemplateStringIO(FasterStringIO):
s = s.encode('utf-8')
FasterStringIO.write(self, s)
try:
from Products.PageTemplates.Expressions import ZopeContext, createZopeEngine
except ImportError:
# BACK: remove when we drop support for Zope 2.8
_engine = None
else:
# On Zope 2.12, we need an engine to decode non-unicode-strings for us
class OOoContext(ZopeContext):
""" ZopeContext variant that ALWAYS converts standard strings through utf-8,
as needed by OpenOffice, ignoring the preferred encodings in the request.
"""
def _handleText(self, text, expr):
if isinstance(text, str):
# avoid calling the IUnicodeEncodingConflictResolver utility
return unicode(text, 'utf-8')
return ZopeContext._handleText(self, text, expr)
def createOOoZopeEngine():
e = createZopeEngine()
e._create_context = OOoContext
return e
_engine = createOOoZopeEngine()
from Products.PageTemplates.Expressions import ZopeContext, createZopeEngine
# On recent Zope, we need an engine to decode non-unicode-strings for us
class OOoContext(ZopeContext):
""" ZopeContext variant that ALWAYS converts standard strings through utf-8,
as needed by OpenOffice, ignoring the preferred encodings in the request.
"""
def _handleText(self, text, expr):
if isinstance(text, str):
# avoid calling the IUnicodeEncodingConflictResolver utility
return unicode(text, 'utf-8')
return ZopeContext._handleText(self, text, expr)
def createOOoZopeEngine():
e = createZopeEngine()
e._create_context = OOoContext
return e
_engine = createOOoZopeEngine()
class OOoTemplate(ZopePageTemplate):
"""
......@@ -208,20 +198,13 @@ class OOoTemplate(ZopePageTemplate):
self.OLE_documents_zipstring = None
self.ooo_xml_file_id = xml_file_id
if _engine is not None:
# Zope 2.12 relies on the ZTK implementation of page templates,
# passing it a special expression evaluation context that converts strings
# to unicode in the presence of the proper request headers.
# Here we do the same, but forcing utf-8 conversion insteado of expecting
# request headers.
def pt_getEngine(self):
return _engine
else:
# BACK: Remove when we drop support for Zope 2.8!
# Every OOoTemplate uses UTF-8 or Unicode, so a special StringIO class
# must be used, which does not care about response.
def StringIO(self):
return OOoTemplateStringIO()
# Recent Zope relies on the ZTK implementation of page templates,
# passing it a special expression evaluation context that converts strings
# to unicode in the presence of the proper request headers.
# Here we do the same, but forcing utf-8 conversion insteado of expecting
# request headers.
def pt_getEngine(self):
return _engine
def pt_upload(self, REQUEST, file=''):
"""Replace the document with the text in file."""
......
......@@ -38,10 +38,7 @@ from xml.dom import Node
from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Globals import InitializeClass, get_request
from zipfile import ZipFile, ZIP_DEFLATED
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
from cStringIO import StringIO
import imghdr
import random
from Products.ERP5Type import Permissions
......
......@@ -16,13 +16,7 @@ from lxml.etree import ParseError, Element
from lxml.etree import SubElement
from urllib import unquote
from urlparse import urlparse
try:
# Python >= 2.6
from urlparse import parse_qsl
except ImportError:
from cgi import parse_qsl
from urlparse import parse_qsl, urlparse
# XXX Must be replaced by portal_data_adapters soon
from Products.ERP5OOo.Document.OOoDocument import OOoServerProxy
......
......@@ -32,10 +32,7 @@ from urllib import quote, unquote
from DateTime import DateTime
from zLOG import LOG, PROBLEM
from Products.ERP5Type.Globals import InitializeClass
try:
from zope.interface import Interface
except ImportError:
from Products.PluggableAuthService.utils import Interface
from zope.interface import Interface
from AccessControl import ClassSecurityInfo
from AccessControl.SecurityManagement import getSecurityManager,\
......
......@@ -17,6 +17,7 @@
from Products.ERP5Type.Globals import InitializeClass
from AccessControl import ClassSecurityInfo
from AccessControl.AuthEncoding import pw_validate
from AccessControl.SecurityManagement import getSecurityManager,\
setSecurityManager, newSecurityManager
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
......@@ -32,11 +33,6 @@ import sys
from DateTime import DateTime
from zLOG import LOG, PROBLEM
try :
from AccessControl.AuthEncoding import pw_validate
except ImportError:
pw_validate = lambda reference, attempt: reference == attempt
# This user is used to bypass all security checks.
SUPER_USER = '__erp5security-=__'
......
......@@ -33,8 +33,8 @@ from Products.ERP5Type.Utils import deprecated
from Products.ERP5Type.XMLExportImport import MARSHALLER_NAMESPACE_URI
from Products.CMFCore.utils import getToolByName
from DateTime.DateTime import DateTime
from email.MIMEBase import MIMEBase
from email import Encoders
from email.mime.base import MIMEBase
from email import encoders
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, interfaces
from Products.ERP5Type.Globals import PersistentMapping
......@@ -418,7 +418,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if keyword == 'binary_data':
#LOG('ERP5Conduit.getFormatedArgs', DEBUG, 'binary_data keyword: %s' % str(keyword))
msg = MIMEBase('application','octet-stream')
Encoders.encode_base64(msg)
encoders.encode_base64(msg)
msg.set_payload(data)
data = msg.get_payload(decode=True)
new_args[keyword] = data
......
......@@ -35,7 +35,7 @@ from Products.ERP5Type import PropertySheet
from zLOG import LOG, DEBUG, INFO
from Products.ERP5SyncML.Utils import PdataHelper
import md5
from hashlib import md5
_MARKER = []
......@@ -134,7 +134,7 @@ class SyncMLSignature(XMLObject):
"""
if isinstance(xml_string, unicode):
xml_string = xml_string.encode('utf-8')
return ((md5.new(xml_string).hexdigest()) == self.getContentMd5())
return md5(xml_string).hexdigest() == self.getContentMd5()
security.declareProtected(Permissions.ModifyPortalContent, 'setPartialData')
def setPartialData(self, value):
......
......@@ -29,15 +29,7 @@
# Required modules - some modules are imported later to prevent circular deadlocks
import persistent
try:
# Python 2.5 or later
from hashlib import md5 as md5_new
from hashlib import sha1 as sha_new
except ImportError:
# Python 2.4
from md5 import new as md5_new
from sha import new as sha_new
from hashlib import md5
#####################################################
# Avoid importing from (possibly unpatched) Globals
......@@ -146,7 +138,7 @@ class PdataHelper(persistent.Persistent):
def _digest_md5_hash_from_pdata(self, pdata):
"""Compute hash part by part
"""
md5_hash = md5_new()
md5_hash = md5()
next = pdata
while next is not None:
md5_hash.update(next.data)
......
......@@ -41,7 +41,7 @@ import random
import urlparse
import hmac
import binascii
from hashlib import sha1
CONSUMER_KEY = "e90f5a97ec5cecd1"
......@@ -434,12 +434,7 @@ class OAuthSignatureMethod_HMAC_SHA1(OAuthSignatureMethod):
token)
# HMAC object.
try:
import hashlib # 2.5
hashed = hmac.new(key, raw, hashlib.sha1)
except:
import sha # Deprecated
hashed = hmac.new(key, raw, sha)
hashed = hmac.new(key, raw, sha1)
# Calculate the digest base 64.
return binascii.b2a_base64(hashed.digest())[:-1]
......
......@@ -3666,20 +3666,12 @@ class Base( CopyContainer,
InitializeClass(Base)
try:
from Products.CMFCore.interfaces import IContentish
except ImportError:
# We're on CMF 1.5 where the IContentish is not yet bridged as a Zope3
# interface, so no need to worry about events here. Remove this "try:" once
# we abandon Zope 2.8
def removeIContentishInterface(cls):
pass
else:
# suppress CMFCore event machinery from trying to reindex us through events
# by removing Products.CMFCore.interfaces.IContentish interface.
# We reindex ourselves in manage_afterAdd thank you very much.
def removeIContentishInterface(cls):
classImplementsOnly(cls, implementedBy(cls) - IContentish)
from Products.CMFCore.interfaces import IContentish
# suppress CMFCore event machinery from trying to reindex us through events
# by removing Products.CMFCore.interfaces.IContentish interface.
# We reindex ourselves in manage_afterAdd thank you very much.
def removeIContentishInterface(cls):
classImplementsOnly(cls, implementedBy(cls) - IContentish)
removeIContentishInterface(Base)
......@@ -3730,7 +3722,7 @@ class TempBase(Base):
security.declarePublic('edit')
# Persistence.Persistent is one of the superclasses of TempBase, and on Zope2.8
# it's __class_init__ method is InitializeClass. This is not the case on
# its __class_init__ method is InitializeClass. This is not the case on
# Zope2.12 which requires us to call InitializeClass manually, otherwise
# allow_class(TempBase) in ERP5Type/Document/__init__.py will trample our
# ClassSecurityInfo with one that doesn't declare our public methods
......
......@@ -16,9 +16,6 @@ class ConflictFreeLog(Persistent):
def __len__(self):
return self._tail_count + len(self._log)
if not hasattr(Persistent, '_p_estimated_size'): # BBB: Zope 2.8
_p_estimated_size = property(lambda self: len(self._log) * 64)
def _maybe_rotate(self):
if self._p_estimated_size < self._bucket_size:
self._p_changed = 1
......
......@@ -37,13 +37,7 @@ class TimeoutTransport(SafeTransport):
def __init__(self, timeout=None, scheme='http'):
self._timeout = timeout
self._scheme = scheme
# On Python 2.6, .__init__() of Transport and SafeTransport must be called
# to set up the ._use_datetime attribute.
# sigh... too bad we can't use super() here, as SafeTransport is not
# a new-style class (as of Python 2.4 to 2.6)
# remove the gettattr below when we drop support for Python 2.4
super__init__ = getattr(SafeTransport, '__init__', lambda self: None)
super__init__(self)
SafeTransport.__init__(self)
def send_content(self, connection, request_body):
try:
......
......@@ -29,11 +29,7 @@
from Products.ERP5Type.Globals import InitializeClass, Persistent
from AccessControl import ClassSecurityInfo
from Products.PythonScripts.Utility import allow_class
try:
from Products.PageTemplates.GlobalTranslationService import getGlobalTranslationService
# on Zope 2.8
except ImportError:
# on Zope 2.12, though we should try to see if it works on 2.8 as well
if 1: # BBB
import zLOG, sys
zLOG.LOG('Products.ERP5Type.Messages',
zLOG.INFO,
......@@ -86,12 +82,7 @@ except ImportError:
from Products.ERP5Type import Globals
from cPickle import dumps, loads
try:
from string import Template
except ImportError:
from Products.ERP5Type.patches.string import Template
from string import Template
from base64 import b64encode, b64decode
class Message(Persistent):
......
......@@ -393,12 +393,7 @@ OldRoleInformation.RoleInformation = SimpleItem
def _eventLessSetObject(container):
_setObject = container._setObject
def wrapper(*args, **kw):
try:
return _setObject(suppress_events=True, *args, **kw)
except TypeError:
return _setObject(*args, **kw)
return wrapper
return lambda *args, **kw: _setObject(suppress_events=True, *args, **kw)
class OldTypesTool(OFSFolder):
......
......@@ -30,10 +30,7 @@ from AccessControl.User import UnrestrictedUser
from AccessControl.SpecialUsers import system
from AccessControl.SecurityManagement import getSecurityManager, \
newSecurityManager, setSecurityManager
try:
from Zope2 import app
except ImportError:
from Zope import app
from Zope2 import app
from Products.ERP5Type.Utils import simple_decorator
class PrivilegedUser(UnrestrictedUser):
......
......@@ -213,9 +213,7 @@ def _showwarning(message, category, filename, lineno, file=None, line=None):
LOG("%s:%u %s: %s" % (filename, lineno, category.__name__, message),
WARNING, '')
else:
# BACK: In Python 2.6 we need to pass along the "line" parameter to
# formatwarning(). For now we don't to keep backward compat with Python 2.4
file.write(warnings.formatwarning(message, category, filename, lineno))
file.write(warnings.formatwarning(message, category, filename, lineno, line))
warnings.showwarning = _showwarning
def deprecated(message=''):
......
......@@ -19,12 +19,6 @@ from Acquisition import aq_parent, aq_inner, aq_base
from AccessControl import ClassSecurityInfo, ModuleSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint
from Products.CMFCore.PortalContent import ResourceLockedError
try:
from Products.CMFCore.PortalContent import NoWL
except ImportError:
# NoWL has been 0 for a long time now
NoWL = 0
from Products.CMFCore.utils import getToolByName
from Products.CMFDefault.utils import parseHeadersBody
from Products.CMFDefault.utils import html_headcheck
......@@ -120,9 +114,8 @@ class TextContent:
security.declareProtected(Permissions.ModifyPortalContent, 'PUT')
def PUT(self, REQUEST, RESPONSE):
""" Handle HTTP (and presumably FTP?) PUT requests """
if not NoWL:
self.dav__init(REQUEST, RESPONSE)
self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
self.dav__init(REQUEST, RESPONSE)
self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
body = REQUEST.get('BODY', '')
try:
......@@ -201,12 +194,7 @@ class TextContent:
return len(self.manage_FTPget())
from webdav.common import Locked, PreconditionFailed
try:
from webdav.interfaces import IWriteLock
providesIWriteLock = IWriteLock.providedBy
except ImportError: # BBB: Zope 2.8
from webdav.WriteLockInterface import WriteLockInterface
providesIWriteLock = WriteLockInterface.isImplementedBy
from webdav.interfaces import IWriteLock
from webdav.NullResource import NullResource
NullResource_PUT = NullResource.PUT
......@@ -222,7 +210,7 @@ def PUT(self, REQUEST, RESPONSE):
parent = self.__parent__
ifhdr = REQUEST.get_header('If', '')
if providesIWriteLock(parent) and parent.wl_isLocked():
if IWriteLock.providedBy(parent) and parent.wl_isLocked():
if ifhdr:
parent.dav__simpleifhandler(REQUEST, RESPONSE, col=1)
else:
......
......@@ -36,14 +36,6 @@ from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
# ERP5 workflow factory definitions
_workflow_factories = {}
try:
from Products.CMFCore.WorkflowTool import addWorkflowFactory as baseAddWorkflowFactory
# We're on CMF 1.5
except ImportError:
# We're on CMF 2
def baseAddWorkflowFactory(factory, id, tittle):
pass
def addWorkflowFactory(factory, id, title):
"""addWorkflowFactory replacement
......@@ -63,8 +55,6 @@ def addWorkflowFactory(factory, id, title):
'id': id,
'title': title,
}
# register with CMF 1 if it's still there
baseAddWorkflowFactory(factory, id, title)
# Workflow Creation DTML
manage_addWorkflowFormDtml = HTMLFile('dtml/addWorkflow', globals())
......
......@@ -30,8 +30,6 @@
from Acquisition import aq_base, aq_inner
from cStringIO import StringIO
from email.MIMEBase import MIMEBase
from email import Encoders
from pickle import Pickler, EMPTY_DICT, MARK, DICT, PyStringMap, DictionaryType
from xml.sax.saxutils import escape, unescape
from lxml import etree
......
......@@ -63,14 +63,9 @@ from Products.ERP5Type.patches import StateChangeInfoPatch
from Products.ERP5Type.patches import transforms
from Products.ERP5Type.patches import OFSPdata
from Products.ERP5Type.patches import make_hidden_input
from Products.ERP5Type.patches import ClientStorage
from Products.ERP5Type.patches import DemoStorage
from Products.ERP5Type.patches import unicodeconflictresolver
from Products.ERP5Type.patches import ZODBConnection
# BACK: Forward Compatibility with Zope 2.12 or CMF 2.2. Remove when we've
# dropped support for older versions.
from Products.ERP5Type.patches import TransactionAddBeforeCommitHook
from Products.ERP5Type.patches import ZopePageTemplate
from Products.ERP5Type.patches import ZopePageTemplateUtils
from Products.ERP5Type.patches import OFSHistory
from Products.ERP5Type.patches import OFSItem
......
......@@ -187,11 +187,3 @@ ModuleSecurityInfo('Products.ERP5Type.Constraint').declarePublic('PropertyTypeVa
ModuleSecurityInfo('Products.ERP5Type.collections').declarePublic('OrderedDict')
ModuleSecurityInfo('Products.ERP5Type.DiffUtils').declarePublic('DiffFile')
ModuleSecurityInfo('pprint').declarePublic('pformat', 'pprint')
if sys.version_info[0:2] == (2, 4):
# Use our own tarfile if we got the buggy Python 2.4 version
# BACK: drop once we remove support for Python 2.4
import _tarfile as tarfile
else:
import tarfile
This diff is collapsed.
......@@ -354,10 +354,7 @@ def synchronizeDynamicModules(context, force=False):
tool = getattr(portal, tool_id, None)
if tool is None:
tool = tool_class()
try:
portal._setObject(tool_id, tool, set_owner=False, suppress_events=True)
except TypeError:
portal._setObject(tool_id, tool, set_owner=False)
portal._setObject(tool_id, tool, set_owner=False, suppress_events=True)
tool = getattr(portal, tool_id)
elif tool._isBootstrapRequired():
migrate = True
......
......@@ -28,16 +28,8 @@
"""Types Tool Interfaces.
"""
from zope.interface import Interface
from zope.interface import Attribute
try:
from Products.CMFCore.interfaces import ITypesTool as ICMFCoreTypesTool
except ImportError:
# on CMF 1.5, this interface is generated by Five, and is not available at
# this point
class ICMFCoreTypesTool(Interface):
pass
from Products.CMFCore.interfaces import ITypesTool as ICMFCoreTypesTool
class ITypesTool(ICMFCoreTypesTool):
"""ERP5Type's types tool.
......
......@@ -159,7 +159,7 @@ ActionInformation.getMapping = getMapping
PatchedActionInformation = ActionInformation
try:
if 1:
from Products.CMFCore.ActionInformation import ActionInfo
original_init = ActionInfo.__init__
......@@ -181,6 +181,3 @@ try:
self.data['name'] = self['title']
ActionInfo.__init__ = __init__
except ImportError:
pass
......@@ -17,13 +17,7 @@ import logging
logger = logging.getLogger(__name__)
from Products.CMFCore.ActionsTool import ActionsTool
try:
from Products.CMFCore.interfaces import IActionProvider
IActionProvider_providedBy = IActionProvider.providedBy
except ImportError:
# XXX Do not initialize ZCML in unit tests on Zope 2.8 for the moment
from Products.CMFCore.ActionsTool import IActionProvider
IActionProvider_providedBy = IActionProvider.isImplementedBy
from Products.CMFCore.interfaces import IActionProvider
def migrateNonProviders(portal_actions):
portal_actions_path = '/'.join(portal_actions.getPhysicalPath())
......@@ -38,9 +32,8 @@ def migrateNonProviders(portal_actions):
portal_actions._actions += provider._actions
del provider._actions
if (getattr(provider, 'listActionInfos', None) is None and
getattr(provider, '_listActionInfos', None) is None and
getattr(provider, 'getActionListFor', None) is None and
not(IActionProvider_providedBy(provider))):
not(IActionProvider.providedBy(provider))):
action_providers.remove(provider_name)
portal_actions.action_providers = tuple(action_providers)
......@@ -70,14 +63,8 @@ def listFilteredActionsFor(self, object=None):
actions.extend(action.cook(ec)
for action in provider.getActionListFor(object)
if action.test(ec))
elif IActionProvider_providedBy(provider):
elif IActionProvider.providedBy(provider):
actions.extend( provider.listActionInfos(object=object) )
elif getattr(provider, '_listActionInfos', None) is not None:
# BACK: drop this clause and the 'else' clause below when we
# drop CMF 1.5
# for Action Providers written for CMF versions before 1.5
actions.extend( self._listActionInfos(provider, object) )
else:
# This should only be triggered once
# We're in 2.12 and we need to migrate objects that are no longer
......
......@@ -12,7 +12,6 @@
#
##############################################################################
#from Products.CMFCore.PortalFolder import PortalFolder
#from Products.CMFCore.PortalFolder import PortalFolder
try:
from Products.CMFCore.CMFBTreeFolder import CMFBTreeFolder
......
......@@ -14,11 +14,6 @@
from Products.CMFCore import Skinnable
from Products.CMFCore.Skinnable import SKINDATA, SkinnableObjectManager
try:
from Products.CMFCore.Skinnable import superGetAttr
except ImportError:
# Removed on CMFCore 2.x
superGetAttr = None
from thread import get_ident
from zLOG import LOG, WARNING, DEBUG
......@@ -117,9 +112,7 @@ def CMFCoreSkinnableSkinnableObjectManager___getattr__(self, name):
LOG('__getattr__', WARNING, 'Skin folder %s is in selection list '\
'but does not exist.' % (candidate_folder_id, ))
ignore[name] = None
if superGetAttr is None:
raise AttributeError, name
return superGetAttr(self, name)
raise AttributeError(name)
def CMFCoreSkinnableSkinnableObjectManager_changeSkin(self, skinname, REQUEST=None):
'''
......
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# Copyright (c) 2010 Nexedi SARL and Contributors. All Rights Reserved.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
# This is a backport of http://svn.zope.org/?rev=106514&view=rev for Zope 2.8.
try:
from ThreadedAsync import LoopCallback
except ImportError:
pass # nothing to do for recent Zope
else:
# Switch Zope 2.8 to async I/O for ZEO client storages
import Lifetime
Lifetime_lifetime_loop = Lifetime.lifetime_loop
def lifetime_loop():
from asyncore import socket_map as map
LoopCallback._loop_lock.acquire()
try:
LoopCallback._looping = map
while LoopCallback._loop_callbacks:
cb, args, kw = LoopCallback._loop_callbacks.pop()
cb(map, *args, **(kw or {}))
finally:
LoopCallback._loop_lock.release()
return Lifetime_lifetime_loop()
Lifetime.lifetime_loop = lifetime_loop
# Prevent invalidations from being processed out of order
from ZEO.ClientStorage import ClientStorage
def tpc_finish(self, txn, f=None):
"""Storage API: finish a transaction."""
if txn is not self._transaction:
return
self._load_lock.acquire()
try:
if self._midtxn_disconnect:
raise ClientDisconnected(
'Calling tpc_finish() on a disconnected transaction')
# The calls to tpc_finish() and _update_cache() should
# never run currently with another thread, because the
# tpc_cond condition variable prevents more than one
# thread from calling tpc_finish() at a time.
# <patch/>
self._lock.acquire() # for atomic processing of invalidations
try:
tid = self._server.tpc_finish(id(txn)) # <patch/>
self._update_cache(tid)
if f is not None:
f(tid)
finally:
self._lock.release()
r = self._check_serials()
assert r is None or len(r) == 0, "unhandled serialnos: %s" % r
finally:
self._load_lock.release()
self.end_transaction()
ClientStorage.tpc_finish = tpc_finish
from ZODB.Connection import Connection
def invalidate(self, tid, oids):
"""Notify the Connection that transaction 'tid' invalidated oids."""
self._inv_lock.acquire()
try:
if self._txn_time is None:
self._txn_time = tid
# <patch>
elif tid < self._txn_time:
raise AssertionError("invalidations out of order, %r < %r"
% (tid, self._txn_time))
# </patch>
self._invalidated.update(oids)
finally:
self._inv_lock.release()
Connection.invalidate = invalidate
......@@ -215,11 +215,7 @@ def DA__call__(self, REQUEST=None, __ick__=None, src__=0, test__=0, **kw):
if src__: return query
if self.cache_time_ > 0 and self.max_cache_ > 0:
try:
result=self._cached_result(DB__, (query, self.max_rows_))
except TypeError:
# Zope > 2.9
result=self._cached_result(DB__, query, self.max_rows_, c)
result=self._cached_result(DB__, query, self.max_rows_, c)
else:
try:
# if 'portal_ids' in query:
......
......@@ -34,14 +34,7 @@ SyntaxError, DateError, TimeError, localtime, time
STATE_KEY = 'str'
try:
original_DateTime__setstate__ = DateTimeKlass.__setstate__
except AttributeError:
# BBB: Running on Zope < 2.11
def original_DateTime__setstate__(self, state):
dikt = self.__dict__
dikt.clear()
dikt.update(state)
original_DateTime__setstate__ = DateTimeKlass.__setstate__
def DateTime__setstate__(self, state):
self.__dict__.clear()
......
......@@ -16,10 +16,7 @@
from ZODB.DemoStorage import DemoStorage
from ZODB.ConflictResolution import tryToResolveConflict, ResolvedSerial
try:
loadEx = DemoStorage.loadEx
except AttributeError: # Zope 2.12
if 1:
##
# Implement conflict resolution for DemoStorage
#
......@@ -56,131 +53,3 @@ except AttributeError: # Zope 2.12
return self.changes.store(oid, serial, data, '', transaction)
DemoStorage.store = store
else: # Zope 2.8
##
# Fix bug in DemoStorage.loadEx (it uses 'load' instead of 'loadEx')
#
DemoStorage.loadEx = lambda *args: (loadEx(*args) + ('',))[:3]
##
# Implement conflict resolution for DemoStorage
#
from ZODB import POSException
# copied from ZODB/DemoStorage.py and patched
def store(self, oid, serial, data, version, transaction):
if transaction is not self._transaction:
raise POSException.StorageTransactionError(self, transaction)
self._lock_acquire()
try:
old = self._index.get(oid, None)
if old is None:
# Hm, nothing here, check the base version:
if self._base:
try:
p, tid = self._base.load(oid, '')
except KeyError:
pass
else:
old = oid, None, None, p, tid
nv=None
if old:
oid, pre, vdata, p, tid = old
if vdata:
if vdata[0] != version:
raise POSException.VersionLockError, oid
nv=vdata[1]
else:
nv=old
if serial != tid:
# <patch>
rdata = tryToResolveConflict(self, oid, tid, serial, data)
if rdata is None:
raise POSException.ConflictError(
oid=oid, serials=(tid, serial), data=data)
data = rdata
# </patch>
r = [oid, old, version and (version, nv) or None, data, self._tid]
self._tindex.append(r)
s=self._tsize
s=s+72+(data and (16+len(data)) or 4)
if version: s=s+32+len(version)
if self._quota is not None and s > self._quota:
raise POSException.StorageError, (
'''<b>Quota Exceeded</b><br>
The maximum quota for this demonstration storage
has been exceeded.<br>Have a nice day.''')
finally: self._lock_release()
# <patch>
if old and serial != tid:
return ResolvedSerial
# </patch>
return self._tid
DemoStorage.store = store
def loadSerial(self, oid, serial):
# XXX should I use self._lock_acquire and self._lock_release ?
pre = self._index.get(oid)
while pre:
oid, pre, vdata, p, tid = pre
if tid == serial:
return p
return self._base.loadSerial(oid, serial)
DemoStorage.loadSerial = loadSerial
def loadBefore(self, oid, tid):
# XXX should I use self._lock_acquire and self._lock_release ?
end_time = None
pre = self._index.get(oid)
while pre:
oid, pre, vdata, p, start_time = pre
if start_time < tid:
return p, start_time, end_time
end_time = start_time
base = self._base.loadBefore(oid, tid)
if base:
p, start_time, base_end_time = base
return p, start_time, base_end_time or end_time
DemoStorage.loadBefore = loadBefore
from persistent.TimeStamp import TimeStamp
def history(self, oid, version=None, length=1, filter=None):
assert not version
self._lock_acquire()
try:
r = []
pre = self._index.get(oid)
while length and pre:
oid, pre, vdata, p, tid = pre
assert vdata is None
d = {'tid': tid, 'size': len(p), 'version': '',
'time': TimeStamp(tid).timeTime()}
if filter is None or filter(d):
r.append(d)
length -= 1
if length:
try:
self._base.modifiedInVersion(oid)
except POSException.POSKeyError:
pass
else:
r += self._base.history(oid, version, length, filter)
return r
finally:
self._lock_release()
DemoStorage.history = history
......@@ -12,13 +12,7 @@
#
##############################################################################
# Template() is a new method of python 2.4, that's why we have the string.py
# file in patches directory.
try:
from string import Template
except ImportError:
from Products.ERP5Type.patches.string import Template
from string import Template
from itools import i18n
from Products.ERP5Type.Message import Message
from zLOG import LOG, ERROR
......@@ -89,31 +83,10 @@ def Localizer_translate(self, domain, msgid, lang=None, mapping=None, *args, **k
translated_str = Template(translated_str).substitute(unicode_mapping)
return translated_str
# BACK: This method is not used in Zope 2.12. Drop when we drop support for
# Zope 2.8
def GlobalTranslationService_translate(self, domain, msgid, *args, **kw):
context = kw.get('context')
if context is None:
# Placeless!
return msgid
localizer = getattr(context.getPortalObject(), 'Localizer', None)
if localizer is None:
LOG('ERP5Type.patches.Localizer', ERROR, 'could not find a Localizer '
'object in acquisition context, message will not be translated')
return msgid
return localizer.translate(domain, msgid, *args, **kw)
# Apply the monkey patch.
from Products.Localizer.Localizer import Localizer
Localizer.translate = Localizer_translate
Localizer.translate__roles__ = None # public
try:
from Products.Localizer import GlobalTranslationService
GlobalTranslationService.translate = GlobalTranslationService_translate
except ImportError:
pass
# Fix MessageCatalog's manage_export that fails with unicode strings
from Products.Localizer.MessageCatalog import MessageCatalog
......@@ -273,12 +246,9 @@ Localizer.InitializeClass(Localizer.Localizer)
# BACK: Can't write a configure.zcml that works on both Zope 2.8 and Zope 2.12
# So we monkeypatch the subscriber instead. When we drop support for Zope 2.8
# write a proper subscriber for MessageCatalog and IObjectMovedEvent
try:
if 1:
from Products.Localizer.MessageCatalog import (MessageCatalog_moved as
MessageCatalog_moved_orig)
except ImportError:
pass # Zope 2.8
else:
from zope.component import getSiteManager
from zope.i18n.interfaces import ITranslationDomain
import Products.Localizer.MessageCatalog
......
......@@ -32,11 +32,7 @@ def ObjectManager_importObjectFromFile(self, filepath, verify=1, set_owner=1, id
id=ob.id
if hasattr(id, 'im_func'): id=id()
if getZopeVersion()[1] >= 10:
# only in Zope > 2.10
self._setObject(id, ob, set_owner=set_owner, suppress_events=suppress_events)
else:
self._setObject(id, ob, set_owner=set_owner)
self._setObject(id, ob, set_owner=set_owner, suppress_events=suppress_events)
# try to make ownership implicit if possible in the context
# that the object was imported into.
......@@ -46,9 +42,3 @@ def ObjectManager_importObjectFromFile(self, filepath, verify=1, set_owner=1, id
return ob
ObjectManager._importObjectFromFile=ObjectManager_importObjectFromFile
# BACK: allow using 'some_id in folder' construct in 2.8
def ObjectManager_contains(self, name):
return name in self.objectIds()
if '__contains__' not in ObjectManager.__dict__:
ObjectManager.__contains__ = ObjectManager_contains
......@@ -13,7 +13,7 @@
##############################################################################
# AttrDict patch for more dict-like methods.
try:
if 1:
from App.ProductContext import AttrDict
def AttrDict_getitem(self, name):
......@@ -35,5 +35,3 @@ try:
AttrDict.has_key = AttrDict_has_key
AttrDict.items = AttrDict_items
AttrDict.keys = AttrDict_keys
except ImportError:
pass
......@@ -29,21 +29,3 @@ def TM__register(self):
#except: pass
TM._register = TM__register
if getattr(TM, 'setSortKey', None) is None:
# BACK: We're not yet on Zope 2.12, patch in the sort_key setting method
# remove this part when we drop support for earlier versions.
def setSortKey(self, sort_key):
self._sort_key = sort_key
def sortKey(self, *ignored):
""" The sortKey method is used by the transaction subsystem to have a
known commit order for lock acquisition.
"""
return self._sort_key
TM._sort_key = 1
TM.setSortKey = setSortKey
TM.sortKey = sortKey
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
# Copyright (c) 2009 Nexedi SARL and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
from transaction._transaction import Transaction
if not hasattr(Transaction, 'addBeforeCommitHook'):
def Transaction_addBeforeCommitHook(self, hook, args=(), kws=None):
if kws is None:
kws = {}
self.beforeCommitHook(hook, *args, **kws)
import logging
logger = logging.getLogger(__name__)
logger.info("Patching Transaction with forward compatibility for "
".addBeforeCommitHook()")
Transaction.addBeforeCommitHook = Transaction_addBeforeCommitHook
......@@ -807,13 +807,9 @@ class WorkflowMethod( Method ):
res = wf.wrapWorkflowMethod(instance, self._id, self._m,
(instance,) + args, kw)
try:
from Products.CMFCore.WorkflowCore import WorkflowMethod
except ImportError:
from Products.CMFCore import WorkflowCore
# We're on CMF 2, where WorkflowMethod has been removed from CMFCore
#WorkflowCore.WorkflowMethod = WorkflowMethod
WorkflowCore.WorkflowAction = WorkflowMethod
from Products.CMFCore import WorkflowCore
# BBB: WorkflowMethod has been removed from CMFCore 2
WorkflowCore.WorkflowAction = WorkflowMethod
def _jumpToStateFor(self, ob, state_id, wf_id=None, *args, **kw):
"""Inspired from doActionFor.
......
......@@ -14,15 +14,11 @@
# Make sure the xml export will be ordered
import re
from ZODB.utils import u64, p64
from Shared.DC.xml import ppml
from base64 import encodestring
from cStringIO import StringIO
try:
from ZODB.serialize import referencesf
except ImportError:
from ZODB.referencesf import referencesf
from ZODB.serialize import referencesf
from ZODB.ExportImport import TemporaryFile
from pickle import Pickler, EMPTY_DICT, MARK, DICT
from cPickle import loads, dumps
......@@ -62,53 +58,6 @@ class OrderedPickler(Pickler):
if not PyStringMap is None:
dispatch[PyStringMap] = save_dict
# ExtensionClass.Base.__getnewargs__ XML simplification
# BBB: Remove this whole section of code (and its invocation below) once
# we drop support for Zope 2.8 (i.e. once Base drops __getnewargs__)
from ExtensionClass import Base
Base__getnewargs__ = getattr(Base, '__getnewargs__', None)
if Base__getnewargs__ is None:
is_old_btree = lambda pickle: None
def getCleanClass(classdef):
return classdef
else:
is_old_btree = re.compile('cBTrees\\._(..)BTree\n(\\1)BTree\n').match
def getCleanClass(classdef):
if isinstance(classdef, tuple):
pureclass, newargs = classdef
if (newargs == () and
not isinstance(pureclass, tuple) and
getattr(pureclass, '__getnewargs__', None) is Base__getnewargs__):
return pureclass
return classdef
# END ExtensionClass.Base.__getnewargs__ XML simplification
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
PICKLE_CLEANERS = {}
def cleaner_for(classdef):
def wrapper(func):
PICKLE_CLEANERS[classdef] = func
return func
return wrapper
# BBB: Remove this cleaner when we drop support for Zope 2.8
@cleaner_for(ZopePageTemplate)
def cleanup_ZopePageTemplate(state):
if isinstance(state.get('_text'), str):
state['_text'] = unicode(state['_text'], 'utf-8')
state['output_encoding'] = 'utf-8'
if isinstance(state.get('title'), str):
state['title'] = unicode(state['title'], 'utf-8')
def cleanupState(classdef, state):
classdef = getCleanClass(classdef)
cleanupState = PICKLE_CLEANERS.get(classdef, lambda state: None)
cleanupState(state)
return classdef, state
def reorderPickle(jar, p):
from ZODB.ExportImport import Ghost, Unpickler, Pickler, StringIO, persistent_id
......@@ -134,7 +83,6 @@ def reorderPickle(jar, p):
Ghost=Ghost(ooid)
return Ghost
# Reorder pickle by doing I/O
pfile = StringIO(p)
unpickler=Unpickler(pfile)
......@@ -146,12 +94,9 @@ def reorderPickle(jar, p):
classdef = unpickler.load()
obj = unpickler.load()
classdef, obj = cleanupState(classdef, obj)
pickler.dump(classdef)
pickler.dump(obj)
p=newp.getvalue()
if is_old_btree(p):
p = p.replace('_','',1)
return obj, p
def _mapOid(id_mapping, oid):
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# Leonardo Rochael Almeida <leonardo@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
##############################################################################
# BBB: This whole file is unnecessary once we drop support for Zope 2.8
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
marker = object()
if getattr(ZopePageTemplate, 'output_encoding', marker) is marker:
# pre-Zope 2.10, non-unicode Zope Page Templates.
# downgrade source code and title to utf-8 for compatibility
def __setstate__(self, state):
# Perform on-the-fly migration from unicode.
if isinstance(state.get('_text'), unicode):
state['_text'] = state['_text'].encode('utf-8')
if isinstance(state.get('title'), unicode):
state['title'] = state['title'].encode('utf-8')
ZopePageTemplate.inheritedAttribute('__setstate__')(self, state)
ZopePageTemplate.__setstate__ = __setstate__
......@@ -20,17 +20,7 @@
# FOR A PARTICULAR PURPOSE
##############################################################################
NEED_PATCH = False
try:
from Products.PageTemplates.utils import convertToUnicode
except ImportError:
# Not present in Zope 2.8
pass
else:
try:
convertToUnicode(u'')
except TypeError:
NEED_PATCH = True
from Products.PageTemplates.utils import convertToUnicode
def patched_convertToUnicode(source, content_type, preferred_encodings):
""" Convert 'source' to unicode.
......@@ -64,8 +54,9 @@ def patched_convertToUnicode(source, content_type, preferred_encodings):
return unicode(source), None
if NEED_PATCH:
try:
convertToUnicode(u'', 'text/xml', ())
except TypeError:
# We need to monkey patch in-place, as it is a top-level function and
# already imported in other places.
convertToUnicode.func_code = patched_convertToUnicode.func_code
......@@ -13,8 +13,7 @@
##############################################################################
"""
Backport fix from https://bugs.launchpad.net/zope2/+bug/143768 for Zope2.8
Also, close properly the <input /> tag
Close properly the <input /> tag
"""
import ZTUtils.Zope
......
......@@ -734,9 +734,8 @@ class Tuple(Sequence): pass
ppml.Tuple = Tuple
# not a patch, but imported and used directly by
# Products.ERP5.Document.BusinessTemplate. It is a copy of
# from OFS.XMLExportImport.importXML from Zope 2.12
# Copied from OFS.XMLExportImport.importXML (of Zope 2.12)
# Imported and used directly by Products.ERP5.Document.BusinessTemplate
def importXML(jar, file, clue=''):
from OFS.XMLExportImport import save_record, save_zopedata, start_zopedata
from tempfile import TemporaryFile
......@@ -751,12 +750,13 @@ def importXML(jar, file, clue=''):
F.start_handlers['ZopeData'] = start_zopedata
F.binary=1
F.file=outfile
# <patch>
# Our BTs XML files don't declare encoding but have accented chars in them
# So we have to declare an encoding but not use unicode, so the unpickler
# can deal with the utf-8 strings directly
p=xml.parsers.expat.ParserCreate('utf-8')
p.returns_unicode = False
# </patch>
p.CharacterDataHandler=F.handle_data
p.StartElementHandler=F.unknown_starttag
p.EndElementHandler=F.unknown_endtag
......
......@@ -26,81 +26,7 @@
#
##############################################################################
import os, sys, types
if sys.version_info < (2, 5):
import __builtin__, imp
def all(iterable):
"""
Return True if bool(x) is True for all values x in the iterable.
"""
for x in iterable:
if not x:
return False
return True
__builtin__.all = all
def any(iterable):
"""
Return True if bool(x) is True for any x in the iterable.
"""
for x in iterable:
if x:
return True
return False
__builtin__.any = any
import md5, sha
sys.modules['hashlib'] = hashlib = imp.new_module('hashlib')
hashlib.md5 = md5.new
hashlib.sha1 = sha.new
import email.Utils
sys.modules['email.utils'] = email.Utils
# A business template exported by Python 2.4 may contain:
# <klass>
# <global id="xxx" name="_compile" module="sre"/>
# </klass>
#
# A business template exported by Python 2.6 may contain:
# <klass>
# <global id="xxx" name="_compile" module="re"/>
# </klass>
#
# Python 2.6 provides 'sre._compile', but Python 2.4 does not provide
# 're._compile', so we provide re._compile here for the backward
# compatilibility.
import re, sre
re._compile = sre._compile
# Monkey-patch pprint to sort keys of dictionaries
class _ordered_dict(dict):
def iteritems(self):
return sorted(self.items())
import pprint as _pprint
orig_safe_repr = _pprint._safe_repr
def _safe_repr(object, context, maxlevels, level):
if type(object) is dict:
object = _ordered_dict(object)
return orig_safe_repr(object, context, maxlevels, level)
_pprint._safe_repr = _safe_repr
if sys.version_info < (2, 6):
try:
import simplejson as json
except ImportError, missing_simplejson:
class dummy(types.ModuleType):
def __getattr__(self, name):
raise missing_simplejson
json = dummy('dummy_json')
sys.modules['json'] = json
import os, sys
if sys.version_info < (2, 7):
......@@ -115,7 +41,7 @@ if sys.version_info < (2, 7):
if 1:
# Speed up email parsing (see also http://bugs.python.org/issue1243730)
from email import Parser as parser, FeedParser as feedparser # BBB
from email import parser, feedparser
NLCRE_crack_split = feedparser.NLCRE_crack.split
def push(self, data):
......
This diff is collapsed.
......@@ -23,14 +23,10 @@ from logging import getLogger
import traceback
logger = getLogger(__name__)
try:
from Products.PageTemplates.unicodeconflictresolver \
from Products.PageTemplates.unicodeconflictresolver \
import PreferredCharsetResolver
except ImportError:
# do nothing for Zope-2.8
pass
else:
def PreferredCharsetResolver_resolve(context, text, expression):
def PreferredCharsetResolver_resolve(context, text, expression):
# Since we use UTF-8 only in PageTemplate, it is enough here. It is
# faster than the original implementation, and it is compatible with
# requests that do not contain Accept-Charset header.
......@@ -42,5 +38,4 @@ else:
(e, text, tb_info))
result = unicode(text, 'utf-8', 'replace')
return result
PreferredCharsetResolver.resolve = PreferredCharsetResolver_resolve
PreferredCharsetResolver.resolve = PreferredCharsetResolver_resolve
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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