integrator: Python3 fixes

This commit is contained in:
Helmut Merz 2024-09-26 19:59:51 +02:00
parent 5e5e9aedfc
commit bf1fda008c
11 changed files with 81 additions and 233 deletions

View file

@ -4,8 +4,6 @@ loops - Linked Objects for Organization and Processing Services
Integration of external sources. Integration of external sources.
($Id$)
Setting up a loops Site and Utilities Setting up a loops Site and Utilities
===================================== =====================================
@ -46,7 +44,7 @@ and methods of the external collect object.
>>> from loops.integrator.collection import ExternalCollectionAdapter >>> from loops.integrator.collection import ExternalCollectionAdapter
>>> tExternalCollection = concepts['extcollection'] >>> tExternalCollection = concepts['extcollection']
>>> coll01 = addObject(concepts, Concept, 'coll01', >>> coll01 = addObject(concepts, Concept, 'coll01',
... title=u'Collection One', conceptType=tExternalCollection) ... title='Collection One', conceptType=tExternalCollection)
>>> aColl01 = ExternalCollectionAdapter(coll01) >>> aColl01 = ExternalCollectionAdapter(coll01)
An external collection carries a set of attributes that control the access An external collection carries a set of attributes that control the access
@ -58,7 +56,7 @@ to the external system:
>>> aColl01.baseAddress = dataDir >>> aColl01.baseAddress = dataDir
>>> aColl01.address = 'topics' >>> aColl01.address = 'topics'
>>> aColl01.metaInfo = u'Photograph taken by...' >>> aColl01.metaInfo = 'Photograph taken by...'
>>> aColl01.overwriteMetaInfo is None >>> aColl01.overwriteMetaInfo is None
True True
@ -91,9 +89,9 @@ Let's now create the corresponding resource objects.
2 2
>>> xf1 = res[0] >>> xf1 = res[0]
>>> xf1.__name__ >>> xf1.__name__
u'programming_beautifulprogram.pdf' 'programming_beautifulprogram.pdf'
>>> xf1.title >>> xf1.title
u'BeautifulProgram' 'BeautifulProgram'
>>> xf1.contentType >>> xf1.contentType
'application/pdf' 'application/pdf'
@ -115,8 +113,8 @@ Working with the External Collection
>>> len(res) >>> len(res)
2 2
>>> sorted((r.__name__, r.title, r._storageName) for r in res) >>> sorted((r.__name__, r.title, r._storageName) for r in res)
[(u'programming_beautifulprogram.pdf', u'BeautifulProgram', 'fullpath'), [('programming_beautifulprogram.pdf', 'BeautifulProgram', 'fullpath'),
(u'programming_zope_zope3.txt', u'zope3', 'fullpath')] ('programming_zope_zope3.txt', 'zope3', 'fullpath')]
We may update the collection after having changed the storage params. We may update the collection after having changed the storage params.
This should also change the settings for existing objects if they still This should also change the settings for existing objects if they still
@ -133,7 +131,7 @@ can be found.
('fullpath', {'subdirectory': '...programming'}, 'BeautifulProgram.pdf') ('fullpath', {'subdirectory': '...programming'}, 'BeautifulProgram.pdf')
>>> aXf1.metaInfo >>> 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. 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'] >>> tType = concepts['type']
>>> from loops.integrator.mail.interfaces import IMailCollection, IMailResource >>> from loops.integrator.mail.interfaces import IMailCollection, IMailResource
>>> tMailCollection = addAndConfigureObject(concepts, Concept, 'mailcollection', >>> tMailCollection = addAndConfigureObject(concepts, Concept, 'mailcollection',
... title=u'Mail Collection', conceptType=tType, ... title='Mail Collection', conceptType=tType,
... typeInterface=IMailCollection) ... typeInterface=IMailCollection)
>>> tMailResource = addAndConfigureObject(concepts, Concept, 'email', >>> tMailResource = addAndConfigureObject(concepts, Concept, 'email',
... title=u'Mail Resource', conceptType=tType, ... title='Mail Resource', conceptType=tType,
... typeInterface=IMailResource) ... typeInterface=IMailResource)
>>> mailColl = addObject(concepts, Concept, 'mails.user1', >>> 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 >>> from loops.integrator.mail.collection import MailCollectionAdapter
>>> aMailColl = MailCollectionAdapter(mailColl) >>> aMailColl = MailCollectionAdapter(mailColl)
@ -168,10 +166,10 @@ Mail Collections
An external collection carries a set of attributes that control the access An external collection carries a set of attributes that control the access
to the external system: to the external system:
>>> aMailColl.userName = u'jim' >>> aMailColl.userName = 'jim'
>>> (aMailColl.providerName, aMailColl.baseAddress, aMailColl.address, >>> (aMailColl.providerName, aMailColl.baseAddress, aMailColl.address,
... aMailColl.pattern, aMailColl.userName) ... aMailColl.pattern, aMailColl.userName)
(u'imap', None, None, None, u'jim') ('imap', None, None, None, 'jim')
>>> from loops.integrator.mail import testing >>> from loops.integrator.mail import testing
@ -187,9 +185,9 @@ to the external system:
>>> aMail.date, aMail.sender, aMail.receiver, aMail.title >>> aMail.date, aMail.sender, aMail.receiver, aMail.title
(datetime.datetime(...), 'ceo@cy55.de', 'ceo@example.org', 'Blogging from Munich') (datetime.datetime(...), 'ceo@cy55.de', 'ceo@example.org', 'Blogging from Munich')
>>> aMail.data >>> aMail.data
u'<p><b>Blogging from ...</b><br />\n' '<p><b>Blogging from ...</b><br />\n'
>>> aMail.externalAddress >>> aMail.externalAddress
u'imap://jim@.../20081208171745.e4ce2xm96cco80cg@cy55.de' 'imap://jim@.../20081208171745.e4ce2xm96cco80cg@cy55.de'
Uploading Resources with HTTP PUT Requests 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 *** resources.PUT .data local/user/filesystem/testing/data/file1.txt
>>> getName(resource) >>> getName(resource)
u'local_user_filesystem_testing_data_file1.txt' 'local_user_filesystem_testing_data_file1.txt'
>>> resource.title >>> resource.title
u'file1' 'file1'
Extracting Document Properties from MS Office Files Extracting Document Properties from MS Office Files
@ -234,7 +232,7 @@ Extracting Document Properties from MS Office Files
23561... 23561...
>>> officeFile = addAndConfigureObject(resources, Resource, 'test.docx', >>> officeFile = addAndConfigureObject(resources, Resource, 'test.docx',
... title=u'Example Word File', resourceType=tOfficeFile, ... title='Example Word File', resourceType=tOfficeFile,
... storageParams=dict(subdirectory=path)) ... storageParams=dict(subdirectory=path))
>>> aOfficeFile = adapted(officeFile) >>> aOfficeFile = adapted(officeFile)
>>> aOfficeFile.externalAddress = 'example.docx' >>> aOfficeFile.externalAddress = 'example.docx'
@ -245,6 +243,7 @@ Extracting Document Properties from MS Office Files
Clean up: Clean up:
>>> shutil.copy(fn + '.sav', fn) >>> shutil.copy(fn + '.sav', fn)
'.../example.docx'
Fin de partie Fin de partie

View file

@ -1,23 +1,6 @@
# # loops.integrator.collection
# 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
#
""" """ 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. file system.
""" """
@ -26,15 +9,15 @@ from logging import getLogger
import os, re, stat import os, re, stat
import transaction import transaction
from zope.app.container.interfaces import INameChooser from zope.container.interfaces import INameChooser
from zope.app.container.contained import ObjectRemovedEvent from zope.container.contained import ObjectRemovedEvent
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope import component from zope import component
from zope.component import adapts from zope.component import adapts
from zope.contenttype import guess_content_type from zope.contenttype import guess_content_type
from zope.event import notify from zope.event import notify
from zope.lifecycleevent import ObjectModifiedEvent 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.schema.interfaces import IField
from zope.traversing.api import getName, getParent from zope.traversing.api import getName, getParent
@ -56,12 +39,12 @@ TypeInterfaceSourceList.typeInterfaces += (IExternalCollection,)
logger = getLogger('loops.integrator.collection') logger = getLogger('loops.integrator.collection')
@implementer(IExternalCollection)
class ExternalCollectionAdapter(AdapterBase): class ExternalCollectionAdapter(AdapterBase):
""" A concept adapter for accessing an external collection. """ A concept adapter for accessing an external collection.
May delegate access to a named utility. May delegate access to a named utility.
""" """
implements(IExternalCollection)
adapts(IConcept) adapts(IConcept)
_adapterAttributes = AdapterBase._adapterAttributes + ( _adapterAttributes = AdapterBase._adapterAttributes + (
@ -84,16 +67,16 @@ class ExternalCollectionAdapter(AdapterBase):
if self.useVersioning: if self.useVersioning:
for obj in old.values(): for obj in old.values():
for vaddr, vobj, vid in self.getVersions(obj): for vaddr, vobj, vid in self.getVersions(obj):
print '###', vaddr, vobj, vid print('###', vaddr, vobj, vid)
versions.add(vaddr) versions.add(vaddr)
new = [] new = []
oldFound = set([]) oldFound = set([])
provider = component.getUtility(IExternalCollectionProvider, provider = component.getUtility(IExternalCollectionProvider,
name=self.providerName or '') name=self.providerName or '')
#print '*** old', old, versions, self.lastUpdated #print('*** old', old, versions, self.lastUpdated)
changeCount = 0 changeCount = 0
for addr, mdate in provider.collect(self): for addr, mdate in provider.collect(self):
#print '***', addr, mdate #print('***', addr, mdate)
if addr in versions: if addr in versions:
continue continue
if addr in old: if addr in old:
@ -170,12 +153,11 @@ class ExternalCollectionAdapter(AdapterBase):
if IVersionable(v).parent is not None] if IVersionable(v).parent is not None]
@implementer(IExternalCollectionProvider)
class DirectoryCollectionProvider(object): class DirectoryCollectionProvider(object):
""" A utility that provides access to files in a directory. """ A utility that provides access to files in a directory.
""" """
implements(IExternalCollectionProvider)
extFileTypeMapping = { extFileTypeMapping = {
'image/*': 'media_asset', 'image/*': 'media_asset',
'*/*': 'extfile', '*/*': 'extfile',
@ -256,7 +238,7 @@ class DirectoryCollectionProvider(object):
base, ext = title.rsplit('.', 1) base, ext = title.rsplit('.', 1)
if ext.lower() in mimetypes.extensions.values(): if ext.lower() in mimetypes.extensions.values():
title = base title = base
if not isinstance(title, unicode): if isinstance(title, bytes):
try: try:
title = title.decode('UTF-8') title = title.decode('UTF-8')
except UnicodeDecodeError: except UnicodeDecodeError:

View file

@ -1,32 +1,13 @@
# # loops.integrator.mail.collection
# 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
#
""" """ 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. file system.
$Id$
""" """
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope import component from zope import component
from zope.component import adapts from zope.component import adapts
from zope.interface import implements from zope.interface import implementer
from loops.integrator.collection import ExternalCollectionAdapter from loops.integrator.collection import ExternalCollectionAdapter
from loops.integrator.mail.interfaces import IMailCollection from loops.integrator.mail.interfaces import IMailCollection
@ -36,13 +17,12 @@ from loops.type import TypeInterfaceSourceList
TypeInterfaceSourceList.typeInterfaces += (IMailCollection,) TypeInterfaceSourceList.typeInterfaces += (IMailCollection,)
@implementer(IMailCollection)
class MailCollectionAdapter(ExternalCollectionAdapter): class MailCollectionAdapter(ExternalCollectionAdapter):
""" A concept adapter for accessing a mail collection. """ A concept adapter for accessing a mail collection.
May delegate access to a named utility. May delegate access to a named utility.
""" """
implements(IMailCollection)
_adapterAttributes = ExternalCollectionAdapter._adapterAttributes + ( _adapterAttributes = ExternalCollectionAdapter._adapterAttributes + (
'providerName', '_collectedObjects') 'providerName', '_collectedObjects')
_contextAttributes = list(IMailCollection) _contextAttributes = list(IMailCollection)

View file

@ -1,42 +1,23 @@
# # loops.integrator.mail.imap
# 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
#
""" """ 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. file system.
$Id$
""" """
from datetime import datetime from datetime import datetime
import email, email.Header import email, email.header, email.utils
from logging import getLogger from logging import getLogger
import os import os
import time import time
from zope.app.container.interfaces import INameChooser
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope import component from zope import component
from zope.component import adapts from zope.component import adapts
from zope.container.interfaces import INameChooser
from zope.event import notify from zope.event import notify
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
from zope.event import notify from zope.event import notify
from zope.interface import implements from zope.interface import implementer
from zope.traversing.api import getName, getParent from zope.traversing.api import getName, getParent
from loops.common import AdapterBase, adapted from loops.common import AdapterBase, adapted
@ -47,12 +28,11 @@ from loops.resource import Resource
from loops.setup import addAndConfigureObject from loops.setup import addAndConfigureObject
@implementer(IExternalCollectionProvider)
class IMAPCollectionProvider(object): class IMAPCollectionProvider(object):
""" A utility that provides access to an IMAP folder. """ A utility that provides access to an IMAP folder.
""" """
implements(IExternalCollectionProvider)
def collect(self, client): def collect(self, client):
client._collectedObjects = {} client._collectedObjects = {}
hostName = client.baseAddress hostName = client.baseAddress
@ -90,7 +70,7 @@ class IMAPCollectionProvider(object):
#raw_date = msg['Date'].rsplit(' ', 1)[0] #raw_date = msg['Date'].rsplit(' ', 1)[0]
#fmt = '%a, %d %b %Y %H:%M:%S' #fmt = '%a, %d %b %Y %H:%M:%S'
#date = datetime(*(time.strptime(raw_date, fmt)[0:6])) #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) parts = getPayload(msg)
if 'html' in parts: if 'html' in parts:
text = '<br /><br /><hr /><br /><br />'.join(parts['html']) text = '<br /><br /><hr /><br /><br />'.join(parts['html'])
@ -117,7 +97,7 @@ class IMAPCollectionProvider(object):
def decodeHeader(h): def decodeHeader(h):
result = [] result = []
for v, dec in email.Header.decode_header(h): for v, dec in email.header.decode_header(h):
if dec: if dec:
v = v.decode(dec) v = v.decode(dec)
result.append(v) result.append(v)

View file

@ -1,25 +1,6 @@
# # loops.integrator.mail.interfaces
# 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
#
""" """ Integrator interfaces for email representation.
Integrator interfaces for email representation.
$Id$
""" """
from zope.interface import Interface, Attribute from zope.interface import Interface, Attribute
@ -69,8 +50,8 @@ class IMailResource(ITextDocument):
title=_(u'External Address'), title=_(u'External Address'),
description=_(u'The full address of the email in the external ' description=_(u'The full address of the email in the external '
u'email system.'), u'email system.'),
default='', default=b'',
missing_value='', missing_value=b'',
required=False) required=False)
sender = schema.TextLine( sender = schema.TextLine(
title=_(u'Sender'), title=_(u'Sender'),

View file

@ -1,31 +1,12 @@
# # loops.integrator.mail.resouurce
# 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
#
""" """ Adapter for mail resources.
Adapter for mail resources.
$Id$
""" """
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope import component from zope import component
from zope.component import adapts from zope.component import adapts
from zope.interface import implements from zope.interface import implementer
from loops.integrator.mail.interfaces import IMailResource from loops.integrator.mail.interfaces import IMailResource
from loops.resource import TextDocumentAdapter from loops.resource import TextDocumentAdapter
@ -35,11 +16,10 @@ from loops.type import TypeInterfaceSourceList
TypeInterfaceSourceList.typeInterfaces += (IMailResource,) TypeInterfaceSourceList.typeInterfaces += (IMailResource,)
@implementer(IMailResource)
class MailResource(TextDocumentAdapter): class MailResource(TextDocumentAdapter):
""" A concept adapter for accessing a mail collection. """ A concept adapter for accessing a mail collection.
May delegate access to a named utility. May delegate access to a named utility.
""" """
implements(IMailResource)
_contextAttributes = list(IMailResource) _contextAttributes = list(IMailResource)

View file

@ -1,23 +1,6 @@
# # loops.integrator.office.base
# 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
#
""" """ Resource adapter(s) for MS Office files.
Resource adapter(s) for MS Office files.
""" """
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
@ -30,7 +13,7 @@ from zipfile import ZipFile, BadZipfile
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope import component from zope import component
from zope.component import adapts from zope.component import adapts
from zope.interface import implements from zope.interface import implementer
from zope.traversing.api import getName, getParent from zope.traversing.api import getName, getParent
from cybertools.storage.interfaces import IExternalStorage from cybertools.storage.interfaces import IExternalStorage
@ -45,13 +28,12 @@ from loops.versioning.interfaces import IVersionable
TypeInterfaceSourceList.typeInterfaces += (IOfficeFile,) TypeInterfaceSourceList.typeInterfaces += (IOfficeFile,)
@implementer(IOfficeFile)
class OfficeFile(ExternalFileAdapter): class OfficeFile(ExternalFileAdapter):
""" An external file that references a MS Office (2007/2010) file. """ An external file that references a MS Office (2007/2010) file.
It provides access to the document content and properties. It provides access to the document content and properties.
""" """
implements(IOfficeFile)
_adapterAttributes = (ExternalFileAdapter._adapterAttributes + _adapterAttributes = (ExternalFileAdapter._adapterAttributes +
('documentPropertiesAccessible',)) ('documentPropertiesAccessible',))
@ -98,7 +80,7 @@ class OfficeFile(ExternalFileAdapter):
try: try:
zf = ZipFile(fn, 'r') zf = ZipFile(fn, 'r')
self.documentPropertiesAccessible = True self.documentPropertiesAccessible = True
except (IOError, BadZipfile), e: except (IOError, BadZipfile) as e:
from logging import getLogger from logging import getLogger
self.logger.warn(e) self.logger.warn(e)
self.documentPropertiesAccessible = False self.documentPropertiesAccessible = False

View file

@ -1,37 +1,18 @@
# # loops.integrator.put
# 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
#
""" """ Traversal adapter for PUT requests, e.g. coming from loops.agent.
Traversal adapter for PUT requests, e.g. coming from loops.agent.
$Id$
""" """
from zope import interface, component 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.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.event import notify
from zope.filerepresentation.interfaces import IWriteFile from zope.filerepresentation.interfaces import IWriteFile
from zope.interface import implementer
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
from zope.publisher.interfaces import IPublishTraverse from zope.publisher.interfaces import IPublishTraverse
@ -42,9 +23,9 @@ from loops.interfaces import IResourceManager
from loops.resource import Resource from loops.resource import Resource
@implementer(IPublishTraverse)
class ResourceManagerTraverser(ItemTraverser): class ResourceManagerTraverser(ItemTraverser):
implements(IPublishTraverse)
adapts(IResourceManager) adapts(IResourceManager)
def publishTraverse(self, request, name): def publishTraverse(self, request, name):
@ -61,8 +42,8 @@ class ResourceManagerTraverser(ItemTraverser):
for i in range(len(stack)): for i in range(len(stack)):
# prevent further traversal # prevent further traversal
stack.pop() stack.pop()
#print '*** resources.PUT', name, path, machine, user, app #print('*** resources.PUT', name, path, machine, user, app)
print '*** resources.PUT', name, path print('*** resources.PUT', name, path)
resource = self.findResource(path) resource = self.findResource(path)
if resource is None: if resource is None:
resource = self.createResource(path) resource = self.createResource(path)
@ -118,9 +99,11 @@ class ResourceManagerTraverser(ItemTraverser):
base, ext = name.rsplit('.', 1) base, ext = name.rsplit('.', 1)
if ext.lower() in mimetypes.extensions.values(): if ext.lower() in mimetypes.extensions.values():
name = base name = base
return name.decode('UTF-8') return name
#return name.decode('UTF-8')
@implementer(IWriteFile)
class MetadataProxy(object): class MetadataProxy(object):
""" Processes a metadata file for an associated resource. """ Processes a metadata file for an associated resource.
""" """
@ -128,19 +111,16 @@ class MetadataProxy(object):
def __init__(self, resource): def __init__(self, resource):
self.resource = resource self.resource = resource
implements(IWriteFile)
def write(self, text): def write(self, text):
# TODO: provide/change concept assignments based on metadata # TODO: provide/change concept assignments based on metadata
print '*** metadata', repr(text) print('*** metadata', repr(text))
@implementer(IWriteFile)
class DummyResource(object): class DummyResource(object):
""" Just for testing """ Just for testing
""" """
implements(IWriteFile)
def write(self, text): def write(self, text):
print '*** content', repr(text) print('*** content', repr(text))

View file

@ -1,28 +1,11 @@
# # loops.integrator.source
# 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
#
""" """ 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 persistent.mapping import PersistentMapping
from zope import interface, component from zope import interface, component
from zope.interface import implements from zope.interface import implementer
from zope.component import adapts from zope.component import adapts
from loops.common import adapted, AdapterBase from loops.common import adapted, AdapterBase
@ -33,9 +16,9 @@ from loops.integrator.interfaces import IExternalSourceInfo
sourceInfoAttrName = '__loops_integrator_sourceinfo__' sourceInfoAttrName = '__loops_integrator_sourceinfo__'
@implementer(IExternalSourceInfo)
class ExternalSourceInfo(object): class ExternalSourceInfo(object):
implements(IExternalSourceInfo)
adapts(ILoopsObject) adapts(ILoopsObject)
def __init__(self, context): def __init__(self, context):

View file

@ -1,11 +1,12 @@
""" # loops.integrator.testsetup
Set up a loops site for testing.
""" Set up a loops site for testing.
""" """
import os import os
from zope import component from zope import component
from zope.app.catalog.interfaces import ICatalog from zope.catalog.interfaces import ICatalog
from zope.app.catalog.field import FieldIndex from zope.catalog.field import FieldIndex
from cybertools.storage.interfaces import IExternalStorage from cybertools.storage.interfaces import IExternalStorage
from cybertools.storage.filesystem import fullPathStorage from cybertools.storage.filesystem import fullPathStorage

View file

@ -276,7 +276,7 @@ class Resource(Image, Contained):
if newAdapted is not None and newOptions.get('storage') != oldAdapted.storageName: if newAdapted is not None and newOptions.get('storage') != oldAdapted.storageName:
data = oldAdapted.data data = oldAdapted.data
#print 'data', 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._storageName = None # let's take storage from new type options
context._storageParams = None # " context._storageParams = None # "
if data: # do not write empty files if data: # do not write empty files