work in progress: integration of IMAP folders

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3532 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2009-09-04 16:11:39 +00:00
parent 2338b2d9e8
commit fa21e41070
13 changed files with 410 additions and 14 deletions

View file

@ -63,6 +63,11 @@
</metal:textline>
<metal:textline define-macro="display_password">
<span>*****</span>
</metal:textline>
<metal:email define-macro="display_email">
<a href="#"
tal:attributes="href string:mailto:$value"

8
external/README.txt vendored
View file

@ -57,14 +57,14 @@ Creating the corresponding objects
Working with resources
----------------------
>>> import os
>>> from loops.external.tests import dataDirectory
>>> loader.resourceDirectory = os.path.join(dataDirectory, 'import')
>>> input = ("resource('doc04.txt', u'Document 4', 'textdocument')\n"
... "resourceRelation('myquery', 'doc04.txt', 'standard')")
>>> reader = PyReader()
>>> elements = reader.read(input)
>>> import os
>>> from loops.external.tests import dataDirectory
>>> loader = Loader(loopsRoot, os.path.join(dataDirectory, 'import'))
>>> loader.load(elements)
>>> sorted(resources)

14
external/base.py vendored
View file

@ -34,6 +34,7 @@ from zope.traversing.api import getName, getParent
from cybertools.composer.interfaces import IInstance
from cybertools.composer.schema.interfaces import ISchemaFactory
from cybertools.external.base import BaseLoader
from cybertools.typology.interfaces import IType
from loops.common import adapted
from loops.external.interfaces import ILoader, IExtractor, ISubExtractor
@ -70,25 +71,22 @@ class Base(object):
return self.concepts.getTypePredicate()
class Loader(Base, SetupManager):
class Loader(Base, BaseLoader, SetupManager):
implements(ILoader)
def __init__(self, context, resourceDirectory=None):
super(Loader, self).__init__(context, resourceDirectory)
#super(Loader, self).__init__(context, resourceDirectory)
Base.__init__(self, context, resourceDirectory)
BaseLoader.__init__(self, context)
self.logger = StringIO()
#self.logger = sys.stdout
def load(self, elements):
for element in elements:
element.execute(self)
if element.subElements is not None:
self.load(element.subElements)
# TODO: care for setting attributes via Instance (Editor)
# instead of using SetupManager methods:
# def addConcept(self, ...):
class Extractor(Base):
implements(IExtractor)

View file

@ -136,6 +136,39 @@ But if one of the referenced objects is not found any more it will be deleted.
('fullpath', {'subdirectory': '...zope'}, 'zope3.txt')
Mail Collections
================
>>> tType = concepts['type']
>>> from loops.integrator.mail.interfaces import IMailCollection, IMailResource
>>> tMailCollection = addObject(concepts, Concept, 'mailcollection',
... title=u'Mail Collection', conceptType=tType,
... typeInterface=IMailCollection)
>>> tMailResource = addObject(concepts, Concept, 'email',
... title=u'Mail Resource', conceptType=tType,
... typeInterface=IMailResource)
>>> mailColl = addObject(concepts, Concept, 'mails.user1',
... title=u'My Mails (User1)', conceptType=tMailCollection)
>>> from loops.integrator.mail.collection import MailCollectionAdapter
>>> aMailColl = MailCollectionAdapter(mailColl)
An external collection carries a set of attributes that control the access
to the external system:
>>> (aMailColl.providerName, aMailColl.baseAddress,
... aMailColl.address, aMailColl.pattern)
(u'imap', None, None, None)
>>> from loops.integrator.mail import testing
>>> from loops.integrator.mail.imap import IMAPCollectionProvider
>>> component.provideUtility(IMAPCollectionProvider(), name='imap')
>>> aMailColl.update()
*** 1 blubb
Uploading Resources with HTTP PUT Requests
==========================================

View file

@ -3,8 +3,7 @@
<configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
i18n_domain="zope"
>
i18n_domain="loops">
<zope:adapter factory="loops.integrator.collection.ExternalCollectionAdapter"
trusted="True" />
@ -55,5 +54,6 @@
permission="zope.Public" />
<include package=".content" />
<include package=".mail" />
</configure>

View file

@ -0,0 +1,4 @@
"""
$Id$
"""

View file

@ -0,0 +1,56 @@
#
# 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
file system.
$Id$
"""
from zope.cachedescriptors.property import Lazy
from zope import component
from zope.component import adapts
from zope.interface import implements
from loops.integrator.collection import ExternalCollectionAdapter
from loops.integrator.mail.interfaces import IMailCollection
from loops.type import TypeInterfaceSourceList
TypeInterfaceSourceList.typeInterfaces += (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)
_collectedObjects = None
def getProviderName(self):
return getattr(self.context, '_providerName', None) or u'imap'
def setProviderName(self, value):
self.context._providerName = value
providerName = property(getProviderName, setProviderName)

View file

@ -0,0 +1,23 @@
<!-- $Id$ -->
<configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
i18n_domain="loops" >
<zope:adapter factory="loops.integrator.mail.collection.MailCollectionAdapter"
provides="loops.integrator.mail.interfaces.IMailCollection"
trusted="True" />
<zope:class class="loops.integrator.mail.collection.MailCollectionAdapter">
<require permission="zope.View"
interface="loops.integrator.mail.interfaces.IMailCollection" />
<require permission="zope.ManageContent"
set_schema="loops.integrator.mail.interfaces.IMailCollection" />
</zope:class>
<zope:utility
factory="loops.integrator.mail.imap.IMAPCollectionProvider"
name="imap" />
</configure>

88
integrator/mail/imap.py Normal file
View file

@ -0,0 +1,88 @@
#
# 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
#
"""
Concept adapter(s) for external collections, e.g. a directory in the
file system.
$Id$
"""
from datetime import datetime
from logging import getLogger
from zope.app.container.interfaces import INameChooser
from zope.cachedescriptors.property import Lazy
from zope import component
from zope.component import adapts
from zope.event import notify
from zope.lifecycleevent import ObjectModifiedEvent
from zope.interface import implements
from zope.traversing.api import getName, getParent
from loops.common import AdapterBase, adapted
from loops.interfaces import IResource, IConcept
from loops.integrator.interfaces import IExternalCollectionProvider
from loops.integrator.mail.system import IMAP4
from loops.resource import Resource
from loops.setup import addAndConfigureObject
class IMAPCollectionProvider(object):
""" A utility that provides access to an IMAP folder.
"""
implements(IExternalCollectionProvider)
def collect(self, client):
client._collectedObjects = {}
imap = IMAP4(client.baseAddress)
imap.login(client.userName, client.password)
mailbox = 'INBOX'
addr = client.address
if addr:
mailbox = mailbox + '.' + addr.replace('/', '.')
imap.select(mailbox)
type, data = imap.search(None, 'ALL')
for num in data[0].split():
type, data = imap.fetch(num, '(RFC822)')
externalAddress = num
obj = data
mtime = datetime.today()
client._collectedObjects[externalAddress] = obj
yield externalAddress, mtime
def createExtFileObjects(self, client, addresses, extFileTypes=None):
loopsRoot = client.context.getLoopsRoot()
container = loopsRoot.getResourceManager()
contentType = 'text/plain'
resourceType = loopsRoot.getConceptManager()['email']
for addr in addresses:
print '***', addr, client._collectedObjects[addr]
return []
def _dummy(self):
name = self.generateName(container, addr)
title = self.generateTitle(addr)
obj = addAndConfigureObject(
container, Resource, name,
title=title,
resourceType=extFileType,
contentType=contentType,
)
yield obj

View file

@ -0,0 +1,75 @@
#
# 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.
$Id$
"""
from zope.interface import Interface, Attribute
from zope import interface, component, schema
from loops.integrator.interfaces import IExternalCollection
from loops.interfaces import ITextDocument
from loops.util import _
# mail collections
class IMailCollection(IExternalCollection):
""" A concept representing a collection of emails that may be
actively retrieved from an external system using the parameters
given.
"""
providerName = schema.TextLine(
title=_(u'Provider name'),
description=_(u'The name of a utility that provides the '
u'external objects; default is an IMAP '
u'collection provider.'),
default=u'imap',
required=False)
baseAddress = schema.TextLine(
title=_(u'Host name'),
description=_(u'The host name part for accessing the '
u'external mail system, i.e. the mail server.'),
required=True)
userName = schema.TextLine(
title=_(u'User name'),
description=_(u'The user name for logging in to the mail server.'),
required=False)
password = schema.Password(
title=_(u'Password'),
description=_(u'The password for logging in to the mail server.'),
required=False)
# mail resources
class IMailResource(ITextDocument):
""" A resource adapter representing an email.
"""
externalAddress = schema.BytesLine(
title=_(u'External Address'),
description=_(u'The full address of the email in the external '
u'email system.'),
default='',
missing_value='',
required=False)

View file

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

25
integrator/mail/system.py Normal file
View file

@ -0,0 +1,25 @@
#
# 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
#
"""
Access to system libraries.
$Id$
"""
from imaplib import IMAP4

View file

@ -0,0 +1,44 @@
#
# 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
#
"""
Fake access to system libraries for testing.
$Id$
"""
class IMAP4(object):
def __init__(self, host=None):
pass
def login(self, user, password):
pass
def select(self, mailbox):
return 1
def search(self, charset, criterion):
return 'OK', ['1']
def fetch(self, idx, parts):
return 'OK', 'blubb'
from loops.integrator.mail import system
system.IMAP4 = IMAP4