From bf1fda008c81fe78d0521adc31ff756c2b8d340b Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Thu, 26 Sep 2024 19:59:51 +0200 Subject: [PATCH] integrator: Python3 fixes --- loops/integrator/README.txt | 37 ++++++++++---------- loops/integrator/collection.py | 40 ++++++--------------- loops/integrator/mail/collection.py | 28 +++------------ loops/integrator/mail/imap.py | 36 +++++-------------- loops/integrator/mail/interfaces.py | 27 +++------------ loops/integrator/mail/resource.py | 28 +++------------ loops/integrator/office/base.py | 28 +++------------ loops/integrator/put.py | 54 +++++++++-------------------- loops/integrator/source.py | 25 +++---------- loops/integrator/testsetup.py | 9 ++--- loops/resource.py | 2 +- 11 files changed, 81 insertions(+), 233 deletions(-) diff --git a/loops/integrator/README.txt b/loops/integrator/README.txt index 62b6532..c55dd6e 100644 --- a/loops/integrator/README.txt +++ b/loops/integrator/README.txt @@ -4,8 +4,6 @@ loops - Linked Objects for Organization and Processing Services Integration of external sources. - ($Id$) - Setting up a loops Site and Utilities ===================================== @@ -46,7 +44,7 @@ and methods of the external collect object. >>> from loops.integrator.collection import ExternalCollectionAdapter >>> tExternalCollection = concepts['extcollection'] >>> coll01 = addObject(concepts, Concept, 'coll01', - ... title=u'Collection One', conceptType=tExternalCollection) + ... title='Collection One', conceptType=tExternalCollection) >>> aColl01 = ExternalCollectionAdapter(coll01) An external collection carries a set of attributes that control the access @@ -58,7 +56,7 @@ to the external system: >>> aColl01.baseAddress = dataDir >>> aColl01.address = 'topics' - >>> aColl01.metaInfo = u'Photograph taken by...' + >>> aColl01.metaInfo = 'Photograph taken by...' >>> aColl01.overwriteMetaInfo is None True @@ -91,9 +89,9 @@ Let's now create the corresponding resource objects. 2 >>> xf1 = res[0] >>> xf1.__name__ - u'programming_beautifulprogram.pdf' + 'programming_beautifulprogram.pdf' >>> xf1.title - u'BeautifulProgram' + 'BeautifulProgram' >>> xf1.contentType 'application/pdf' @@ -115,8 +113,8 @@ Working with the External Collection >>> len(res) 2 >>> sorted((r.__name__, r.title, r._storageName) for r in res) - [(u'programming_beautifulprogram.pdf', u'BeautifulProgram', 'fullpath'), - (u'programming_zope_zope3.txt', u'zope3', 'fullpath')] + [('programming_beautifulprogram.pdf', 'BeautifulProgram', 'fullpath'), + ('programming_zope_zope3.txt', 'zope3', 'fullpath')] We may update the collection after having changed the storage params. This should also change the settings for existing objects if they still @@ -133,7 +131,7 @@ can be found. ('fullpath', {'subdirectory': '...programming'}, 'BeautifulProgram.pdf') >>> aXf1.metaInfo - u'Photograph taken by...' + 'Photograph taken by...' But if one of the referenced objects is not found any more it will be deleted. @@ -153,14 +151,14 @@ Mail Collections >>> tType = concepts['type'] >>> from loops.integrator.mail.interfaces import IMailCollection, IMailResource >>> tMailCollection = addAndConfigureObject(concepts, Concept, 'mailcollection', - ... title=u'Mail Collection', conceptType=tType, + ... title='Mail Collection', conceptType=tType, ... typeInterface=IMailCollection) >>> tMailResource = addAndConfigureObject(concepts, Concept, 'email', - ... title=u'Mail Resource', conceptType=tType, + ... title='Mail Resource', conceptType=tType, ... typeInterface=IMailResource) >>> mailColl = addObject(concepts, Concept, 'mails.user1', - ... title=u'My Mails (User1)', conceptType=tMailCollection) + ... title='My Mails (User1)', conceptType=tMailCollection) >>> from loops.integrator.mail.collection import MailCollectionAdapter >>> aMailColl = MailCollectionAdapter(mailColl) @@ -168,10 +166,10 @@ Mail Collections An external collection carries a set of attributes that control the access to the external system: - >>> aMailColl.userName = u'jim' + >>> aMailColl.userName = 'jim' >>> (aMailColl.providerName, aMailColl.baseAddress, aMailColl.address, ... aMailColl.pattern, aMailColl.userName) - (u'imap', None, None, None, u'jim') + ('imap', None, None, None, 'jim') >>> from loops.integrator.mail import testing @@ -187,9 +185,9 @@ to the external system: >>> aMail.date, aMail.sender, aMail.receiver, aMail.title (datetime.datetime(...), 'ceo@cy55.de', 'ceo@example.org', 'Blogging from Munich') >>> aMail.data - u'

Blogging from ...
\n' + '

Blogging from ...
\n' >>> aMail.externalAddress - u'imap://jim@.../20081208171745.e4ce2xm96cco80cg@cy55.de' + 'imap://jim@.../20081208171745.e4ce2xm96cco80cg@cy55.de' Uploading Resources with HTTP PUT Requests @@ -217,9 +215,9 @@ Uploading Resources with HTTP PUT Requests *** resources.PUT .data local/user/filesystem/testing/data/file1.txt >>> getName(resource) - u'local_user_filesystem_testing_data_file1.txt' + 'local_user_filesystem_testing_data_file1.txt' >>> resource.title - u'file1' + 'file1' Extracting Document Properties from MS Office Files @@ -234,7 +232,7 @@ Extracting Document Properties from MS Office Files 23561... >>> officeFile = addAndConfigureObject(resources, Resource, 'test.docx', - ... title=u'Example Word File', resourceType=tOfficeFile, + ... title='Example Word File', resourceType=tOfficeFile, ... storageParams=dict(subdirectory=path)) >>> aOfficeFile = adapted(officeFile) >>> aOfficeFile.externalAddress = 'example.docx' @@ -245,6 +243,7 @@ Extracting Document Properties from MS Office Files Clean up: >>> shutil.copy(fn + '.sav', fn) + '.../example.docx' Fin de partie diff --git a/loops/integrator/collection.py b/loops/integrator/collection.py index b33fe4f..bbe3dfc 100644 --- a/loops/integrator/collection.py +++ b/loops/integrator/collection.py @@ -1,23 +1,6 @@ -# -# Copyright (c) 2012 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.integrator.collection -""" -Concept adapter(s) for external collections, e.g. a directory in the +""" Concept adapter(s) for external collections, e.g. a directory in the file system. """ @@ -26,15 +9,15 @@ from logging import getLogger import os, re, stat import transaction -from zope.app.container.interfaces import INameChooser -from zope.app.container.contained import ObjectRemovedEvent +from zope.container.interfaces import INameChooser +from zope.container.contained import ObjectRemovedEvent from zope.cachedescriptors.property import Lazy from zope import component from zope.component import adapts from zope.contenttype import guess_content_type from zope.event import notify from zope.lifecycleevent import ObjectModifiedEvent -from zope.interface import implements, Attribute +from zope.interface import implementer, Attribute from zope.schema.interfaces import IField from zope.traversing.api import getName, getParent @@ -56,12 +39,12 @@ TypeInterfaceSourceList.typeInterfaces += (IExternalCollection,) logger = getLogger('loops.integrator.collection') +@implementer(IExternalCollection) class ExternalCollectionAdapter(AdapterBase): """ A concept adapter for accessing an external collection. May delegate access to a named utility. """ - implements(IExternalCollection) adapts(IConcept) _adapterAttributes = AdapterBase._adapterAttributes + ( @@ -84,16 +67,16 @@ class ExternalCollectionAdapter(AdapterBase): if self.useVersioning: for obj in old.values(): for vaddr, vobj, vid in self.getVersions(obj): - print '###', vaddr, vobj, vid + print('###', vaddr, vobj, vid) versions.add(vaddr) new = [] oldFound = set([]) provider = component.getUtility(IExternalCollectionProvider, name=self.providerName or '') - #print '*** old', old, versions, self.lastUpdated + #print('*** old', old, versions, self.lastUpdated) changeCount = 0 for addr, mdate in provider.collect(self): - #print '***', addr, mdate + #print('***', addr, mdate) if addr in versions: continue if addr in old: @@ -170,12 +153,11 @@ class ExternalCollectionAdapter(AdapterBase): if IVersionable(v).parent is not None] +@implementer(IExternalCollectionProvider) class DirectoryCollectionProvider(object): """ A utility that provides access to files in a directory. """ - implements(IExternalCollectionProvider) - extFileTypeMapping = { 'image/*': 'media_asset', '*/*': 'extfile', @@ -256,7 +238,7 @@ class DirectoryCollectionProvider(object): base, ext = title.rsplit('.', 1) if ext.lower() in mimetypes.extensions.values(): title = base - if not isinstance(title, unicode): + if isinstance(title, bytes): try: title = title.decode('UTF-8') except UnicodeDecodeError: diff --git a/loops/integrator/mail/collection.py b/loops/integrator/mail/collection.py index 89ee170..f9011cd 100644 --- a/loops/integrator/mail/collection.py +++ b/loops/integrator/mail/collection.py @@ -1,32 +1,13 @@ -# -# Copyright (c) 2009 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.integrator.mail.collection -""" -Concept adapter(s) for external collections, e.g. a directory in the +""" Concept adapter(s) for external collections, e.g. a directory in the file system. - -$Id$ """ from zope.cachedescriptors.property import Lazy from zope import component from zope.component import adapts -from zope.interface import implements +from zope.interface import implementer from loops.integrator.collection import ExternalCollectionAdapter from loops.integrator.mail.interfaces import IMailCollection @@ -36,13 +17,12 @@ from loops.type import TypeInterfaceSourceList TypeInterfaceSourceList.typeInterfaces += (IMailCollection,) +@implementer(IMailCollection) class MailCollectionAdapter(ExternalCollectionAdapter): """ A concept adapter for accessing a mail collection. May delegate access to a named utility. """ - implements(IMailCollection) - _adapterAttributes = ExternalCollectionAdapter._adapterAttributes + ( 'providerName', '_collectedObjects') _contextAttributes = list(IMailCollection) diff --git a/loops/integrator/mail/imap.py b/loops/integrator/mail/imap.py index 84a7326..f581023 100644 --- a/loops/integrator/mail/imap.py +++ b/loops/integrator/mail/imap.py @@ -1,42 +1,23 @@ -# -# Copyright (c) 2010 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.integrator.mail.imap -""" -Concept adapter(s) for external collections, e.g. a directory in the +""" Concept adapter(s) for external collections, e.g. a directory in the file system. - -$Id$ """ from datetime import datetime -import email, email.Header +import email, email.header, email.utils from logging import getLogger import os import time -from zope.app.container.interfaces import INameChooser from zope.cachedescriptors.property import Lazy from zope import component from zope.component import adapts +from zope.container.interfaces import INameChooser from zope.event import notify from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent from zope.event import notify -from zope.interface import implements +from zope.interface import implementer from zope.traversing.api import getName, getParent from loops.common import AdapterBase, adapted @@ -47,12 +28,11 @@ from loops.resource import Resource from loops.setup import addAndConfigureObject +@implementer(IExternalCollectionProvider) class IMAPCollectionProvider(object): """ A utility that provides access to an IMAP folder. """ - implements(IExternalCollectionProvider) - def collect(self, client): client._collectedObjects = {} hostName = client.baseAddress @@ -90,7 +70,7 @@ class IMAPCollectionProvider(object): #raw_date = msg['Date'].rsplit(' ', 1)[0] #fmt = '%a, %d %b %Y %H:%M:%S' #date = datetime(*(time.strptime(raw_date, fmt)[0:6])) - date = datetime(*(email.Utils.parsedate(msg['Date'])[0:6])) + date = datetime(*(email.utils.parsedate(msg['Date'])[0:6])) parts = getPayload(msg) if 'html' in parts: text = '




'.join(parts['html']) @@ -117,7 +97,7 @@ class IMAPCollectionProvider(object): def decodeHeader(h): result = [] - for v, dec in email.Header.decode_header(h): + for v, dec in email.header.decode_header(h): if dec: v = v.decode(dec) result.append(v) diff --git a/loops/integrator/mail/interfaces.py b/loops/integrator/mail/interfaces.py index 7a1935b..f71e255 100644 --- a/loops/integrator/mail/interfaces.py +++ b/loops/integrator/mail/interfaces.py @@ -1,25 +1,6 @@ -# -# Copyright (c) 2009 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.integrator.mail.interfaces -""" -Integrator interfaces for email representation. - -$Id$ +""" Integrator interfaces for email representation. """ from zope.interface import Interface, Attribute @@ -69,8 +50,8 @@ class IMailResource(ITextDocument): title=_(u'External Address'), description=_(u'The full address of the email in the external ' u'email system.'), - default='', - missing_value='', + default=b'', + missing_value=b'', required=False) sender = schema.TextLine( title=_(u'Sender'), diff --git a/loops/integrator/mail/resource.py b/loops/integrator/mail/resource.py index 6def733..b943d25 100644 --- a/loops/integrator/mail/resource.py +++ b/loops/integrator/mail/resource.py @@ -1,31 +1,12 @@ -# -# Copyright (c) 2009 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.integrator.mail.resouurce -""" -Adapter for mail resources. - -$Id$ +""" Adapter for mail resources. """ from zope.cachedescriptors.property import Lazy from zope import component from zope.component import adapts -from zope.interface import implements +from zope.interface import implementer from loops.integrator.mail.interfaces import IMailResource from loops.resource import TextDocumentAdapter @@ -35,11 +16,10 @@ from loops.type import TypeInterfaceSourceList TypeInterfaceSourceList.typeInterfaces += (IMailResource,) +@implementer(IMailResource) class MailResource(TextDocumentAdapter): """ A concept adapter for accessing a mail collection. May delegate access to a named utility. """ - implements(IMailResource) - _contextAttributes = list(IMailResource) diff --git a/loops/integrator/office/base.py b/loops/integrator/office/base.py index 6271d9f..88d9b30 100644 --- a/loops/integrator/office/base.py +++ b/loops/integrator/office/base.py @@ -1,23 +1,6 @@ -# -# Copyright (c) 2014 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.integrator.office.base -""" -Resource adapter(s) for MS Office files. +""" Resource adapter(s) for MS Office files. """ from datetime import date, datetime, timedelta @@ -30,7 +13,7 @@ from zipfile import ZipFile, BadZipfile from zope.cachedescriptors.property import Lazy from zope import component from zope.component import adapts -from zope.interface import implements +from zope.interface import implementer from zope.traversing.api import getName, getParent from cybertools.storage.interfaces import IExternalStorage @@ -45,13 +28,12 @@ from loops.versioning.interfaces import IVersionable TypeInterfaceSourceList.typeInterfaces += (IOfficeFile,) +@implementer(IOfficeFile) class OfficeFile(ExternalFileAdapter): """ An external file that references a MS Office (2007/2010) file. It provides access to the document content and properties. """ - implements(IOfficeFile) - _adapterAttributes = (ExternalFileAdapter._adapterAttributes + ('documentPropertiesAccessible',)) @@ -98,7 +80,7 @@ class OfficeFile(ExternalFileAdapter): try: zf = ZipFile(fn, 'r') self.documentPropertiesAccessible = True - except (IOError, BadZipfile), e: + except (IOError, BadZipfile) as e: from logging import getLogger self.logger.warn(e) self.documentPropertiesAccessible = False diff --git a/loops/integrator/put.py b/loops/integrator/put.py index dd2d04c..bdf0d68 100644 --- a/loops/integrator/put.py +++ b/loops/integrator/put.py @@ -1,37 +1,18 @@ -# -# Copyright (c) 2007 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.integrator.put -""" -Traversal adapter for PUT requests, e.g. coming from loops.agent. - -$Id$ +""" Traversal adapter for PUT requests, e.g. coming from loops.agent. """ from zope import interface, component -from zope.interface import implements -from zope.component import adapts -from zope.app.catalog.interfaces import ICatalog -from zope.app.container.interfaces import INameChooser -from zope.app.container.traversal import ContainerTraverser, ItemTraverser -from zope.contenttype import guess_content_type from zope.cachedescriptors.property import Lazy +from zope.catalog.interfaces import ICatalog +from zope.component import adapts +from zope.container.interfaces import INameChooser +from zope.container.traversal import ContainerTraverser, ItemTraverser +from zope.contenttype import guess_content_type from zope.event import notify from zope.filerepresentation.interfaces import IWriteFile +from zope.interface import implementer from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent from zope.publisher.interfaces import IPublishTraverse @@ -42,9 +23,9 @@ from loops.interfaces import IResourceManager from loops.resource import Resource +@implementer(IPublishTraverse) class ResourceManagerTraverser(ItemTraverser): - implements(IPublishTraverse) adapts(IResourceManager) def publishTraverse(self, request, name): @@ -61,8 +42,8 @@ class ResourceManagerTraverser(ItemTraverser): for i in range(len(stack)): # prevent further traversal stack.pop() - #print '*** resources.PUT', name, path, machine, user, app - print '*** resources.PUT', name, path + #print('*** resources.PUT', name, path, machine, user, app) + print('*** resources.PUT', name, path) resource = self.findResource(path) if resource is None: resource = self.createResource(path) @@ -118,9 +99,11 @@ class ResourceManagerTraverser(ItemTraverser): base, ext = name.rsplit('.', 1) if ext.lower() in mimetypes.extensions.values(): name = base - return name.decode('UTF-8') + return name + #return name.decode('UTF-8') +@implementer(IWriteFile) class MetadataProxy(object): """ Processes a metadata file for an associated resource. """ @@ -128,19 +111,16 @@ class MetadataProxy(object): def __init__(self, resource): self.resource = resource - implements(IWriteFile) - def write(self, text): # TODO: provide/change concept assignments based on metadata - print '*** metadata', repr(text) + print('*** metadata', repr(text)) +@implementer(IWriteFile) class DummyResource(object): """ Just for testing """ - implements(IWriteFile) - def write(self, text): - print '*** content', repr(text) + print('*** content', repr(text)) diff --git a/loops/integrator/source.py b/loops/integrator/source.py index 74bcfb1..2b18ce5 100644 --- a/loops/integrator/source.py +++ b/loops/integrator/source.py @@ -1,28 +1,11 @@ -# -# Copyright (c) 2017 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +# loops.integrator.source -""" -Managing information form objects provided by external sources, e.g. loops.agent. +""" Managing information form objects provided by external sources, e.g. loops.agent. """ from persistent.mapping import PersistentMapping from zope import interface, component -from zope.interface import implements +from zope.interface import implementer from zope.component import adapts from loops.common import adapted, AdapterBase @@ -33,9 +16,9 @@ from loops.integrator.interfaces import IExternalSourceInfo sourceInfoAttrName = '__loops_integrator_sourceinfo__' +@implementer(IExternalSourceInfo) class ExternalSourceInfo(object): - implements(IExternalSourceInfo) adapts(ILoopsObject) def __init__(self, context): diff --git a/loops/integrator/testsetup.py b/loops/integrator/testsetup.py index bd94aef..14ee81e 100644 --- a/loops/integrator/testsetup.py +++ b/loops/integrator/testsetup.py @@ -1,11 +1,12 @@ -""" -Set up a loops site for testing. +# loops.integrator.testsetup + +""" Set up a loops site for testing. """ import os from zope import component -from zope.app.catalog.interfaces import ICatalog -from zope.app.catalog.field import FieldIndex +from zope.catalog.interfaces import ICatalog +from zope.catalog.field import FieldIndex from cybertools.storage.interfaces import IExternalStorage from cybertools.storage.filesystem import fullPathStorage diff --git a/loops/resource.py b/loops/resource.py index 8e8b857..863c0f4 100644 --- a/loops/resource.py +++ b/loops/resource.py @@ -276,7 +276,7 @@ class Resource(Image, Contained): if newAdapted is not None and newOptions.get('storage') != oldAdapted.storageName: data = oldAdapted.data #print 'data', data - oldAdapted.data = '' # clear old storage + oldAdapted.data = b'' # clear old storage context._storageName = None # let's take storage from new type options context._storageParams = None # " if data: # do not write empty files