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 = '