From d503e5d0e5013669e08fe6cf727976374dbcd874 Mon Sep 17 00:00:00 2001 From: helmutm Date: Wed, 12 Mar 2008 13:02:34 +0000 Subject: [PATCH] added integrator.content package: transparent access to filesystem directories and files git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2443 fd906abe-77d9-0310-91a1-e0d9ade77398 --- README.txt | 1 - classifier/interfaces.py | 17 ++++++++ integrator/browser.py | 4 +- integrator/configure.zcml | 2 + integrator/content/README.txt | 72 +++++++++++++++++++++++++++++++ integrator/content/__init__.py | 4 ++ integrator/content/base.py | 54 +++++++++++++++++++++++ integrator/content/browser.py | 47 ++++++++++++++++++++ integrator/content/configure.zcml | 50 +++++++++++++++++++++ integrator/content/interfaces.py | 61 ++++++++++++++++++++++++++ integrator/content/tests.py | 23 ++++++++++ integrator/interfaces.py | 29 ++----------- 12 files changed, 335 insertions(+), 29 deletions(-) create mode 100644 integrator/content/README.txt create mode 100644 integrator/content/__init__.py create mode 100644 integrator/content/base.py create mode 100644 integrator/content/browser.py create mode 100644 integrator/content/configure.zcml create mode 100644 integrator/content/interfaces.py create mode 100755 integrator/content/tests.py diff --git a/README.txt b/README.txt index 2f7de08..5118104 100755 --- a/README.txt +++ b/README.txt @@ -30,7 +30,6 @@ Concepts and Relations Let's start with creating a few example concepts, putting them in a top-level loops container and a concept manager: - >>> from loops.base import Loops >>> from loops.tests.setup import TestSite >>> t = TestSite(site) >>> concepts, resources, views = t.setup() diff --git a/classifier/interfaces.py b/classifier/interfaces.py index b2a2fc0..376f702 100644 --- a/classifier/interfaces.py +++ b/classifier/interfaces.py @@ -105,3 +105,20 @@ class IStatement(Interface): relevance = Attribute('A number denoting the relevance or correctness ' 'of the statement') + +# more to come... + +class IOntologyExporter(Interface): + """ An adapter for creating an XML file with all appropriate informations + from the context and its children, selecting children via a + pattern or a set of selection criteria. + + This may then be used by an external tool for classifying + a set of external objects. + """ + + +class IClassificationImporter(Interface): + """ An Adapter for importing an XML file with classification + information for a collection of external objects." + """ diff --git a/integrator/browser.py b/integrator/browser.py index 1bbba07..0ecf9bd 100644 --- a/integrator/browser.py +++ b/integrator/browser.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2007 Helmut Merz helmutm@cy55.de +# Copyright (c) 2008 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 @@ -17,7 +17,7 @@ # """ -View class(es) for intergrating external objects. +View class(es) for integrating external objects. $Id$ """ diff --git a/integrator/configure.zcml b/integrator/configure.zcml index 5d7f06f..00c1eac 100644 --- a/integrator/configure.zcml +++ b/integrator/configure.zcml @@ -54,4 +54,6 @@ provides="zope.publisher.interfaces.IPublishTraverse" permission="zope.Public" /> + + diff --git a/integrator/content/README.txt b/integrator/content/README.txt new file mode 100644 index 0000000..cf9e76d --- /dev/null +++ b/integrator/content/README.txt @@ -0,0 +1,72 @@ +=============================================================== +loops - Linked Objects for Organization and Processing Services +=============================================================== + +Integration of external sources. + + ($Id$) + + +Setting up a loops Site and Utilities +===================================== + +Let's do some basic set up + + >>> from zope import component, interface + >>> from zope.traversing.api import getName + >>> from zope.app.testing.setup import placefulSetUp, placefulTearDown + >>> site = placefulSetUp(True) + +and build a simple loops site with a concept manager and some concepts +(with a relation registry, a catalog, and all the type machinery - what +in real life is done via standard ZCML setup or via local utility +configuration): + + >>> from loops.tests.setup import TestSite + >>> t = TestSite(site) + >>> concepts, resources, views = t.setup() + + >>> len(concepts) + len(resources) + 14 + + +Accessing a Directory in the Filesystem +======================================= + +Let's just reuse the settings of cybertools.integrator. + + >>> from cybertools.integrator.tests import testDir + >>> from cybertools.integrator.filesystem import ContainerFactory, FileFactory + >>> component.provideUtility(ContainerFactory(), name='filesystem') + >>> component.provideUtility(FileFactory(), name='filesystem') + + >>> from loops.integrator.content.base import ExternalAccess + >>> component.provideAdapter(ExternalAccess) + + >>> from loops.setup import addAndConfigureObject + >>> from loops.concept import Concept + >>> from loops.integrator.content.interfaces import IExternalAccess + >>> typeConcept = concepts.getTypeConcept() + >>> tExtAccess = addAndConfigureObject(concepts, Concept, 'extaccess', + ... conceptType=typeConcept, typeInterface=IExternalAccess) + + >>> xa01 = addAndConfigureObject(concepts, Concept, 'xa01', + ... conceptType=tExtAccess, + ... providerName='filesystem', baseAddress=testDir) + + >>> from loops.common import adapted + >>> xa01_ad =adapted(xa01) + + >>> directory = xa01_ad() + >>> sorted(directory) + ['index.html', 'sub'] + + +Traversing Content Trees +======================== + + +Fin de partie +============= + + >>> placefulTearDown() diff --git a/integrator/content/__init__.py b/integrator/content/__init__.py new file mode 100644 index 0000000..4bc90fb --- /dev/null +++ b/integrator/content/__init__.py @@ -0,0 +1,4 @@ +""" +$Id$ +""" + diff --git a/integrator/content/base.py b/integrator/content/base.py new file mode 100644 index 0000000..545e6e8 --- /dev/null +++ b/integrator/content/base.py @@ -0,0 +1,54 @@ +# +# Copyright (c) 2008 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 external objects. + +$Id$ +""" + +import os, re + +from zope import component +from zope.cachedescriptors.property import Lazy +from zope.component import adapts +from zope.interface import implements + +from cybertools.integrator.interfaces import IContainerFactory +from loops.common import AdapterBase, adapted +from loops.integrator.content.interfaces import IExternalAccess +from loops.interfaces import IConcept +from loops.type import TypeInterfaceSourceList + + +TypeInterfaceSourceList.typeInterfaces += (IExternalAccess,) + + +class ExternalAccess(AdapterBase): + """ A concept adapter for accessing external collection. + """ + + implements(IExternalAccess) + adapts(IConcept) + + _contextAttributes = list(IExternalAccess) + list(IConcept) + + def __call__(self): + factory = component.getUtility(IContainerFactory, self.providerName) + address = os.path.join(self.baseAddress, self.address or '') + return factory(address, __parent__=self.context) diff --git a/integrator/content/browser.py b/integrator/content/browser.py new file mode 100644 index 0000000..ef513e8 --- /dev/null +++ b/integrator/content/browser.py @@ -0,0 +1,47 @@ +# +# Copyright (c) 2008 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 +# + +""" +View class(es) for accessing external objects. + +$Id$ +""" + +from zope import interface, component +from zope.app.publisher.browser import getDefaultViewName +from zope.cachedescriptors.property import Lazy + +from loops.browser.concept import ConceptView +from loops.browser.node import NodeView +from loops.common import adapted + + +class ExternalAccessView(NodeView): + + @Lazy + def adapted(self): + return adapted(self.virtualTargetObject) + + def __call__(self): + obj = self.adapted() + name = getDefaultViewName(obj, self.request) + view = component.getMultiAdapter((obj, self.request), name=name) + return view() + + def publishTraverse(self, request, name): + return self.adapted()[name] diff --git a/integrator/content/configure.zcml b/integrator/content/configure.zcml new file mode 100644 index 0000000..0e6f7f9 --- /dev/null +++ b/integrator/content/configure.zcml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integrator/content/interfaces.py b/integrator/content/interfaces.py new file mode 100644 index 0000000..aa20db9 --- /dev/null +++ b/integrator/content/interfaces.py @@ -0,0 +1,61 @@ +# +# Copyright (c) 2008 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 +# + +""" +External content integration interfaces. + +$Id$ +""" + +from zope.interface import Interface, Attribute +from zope import interface, component, schema + +from loops.interfaces import IConceptSchema +from loops.util import _ + + +class IExternalAccess(IConceptSchema): + """ A concept adapter providing access to objects in an external system. + """ + + providerName = schema.TextLine( + title=_(u'Provider name'), + description=_(u'The name of a utility that provides access to the ' + 'external objects, typically a factory of proxy ' + 'objects.'), + required=False) + baseAddress = schema.TextLine( + title=_(u'Base address'), + description=_(u'A base path or URL for accessing the external ' + 'object.'), + required=True) + address = schema.TextLine( + title=_(u'Relative address'), + description=_(u'Optional second (local) part of the ' + 'external objects\'s address, e.g. a directory name.'), + required=False) + pattern = schema.TextLine( + title=_(u'Selection pattern'), + description=_(u'A regular expression for selecting external objects ' + 'that should be made accessible.'), + required=False) + + def __call__(): + """ Return an object representing the top-level external object. + This is typically a container proxy. + """ diff --git a/integrator/content/tests.py b/integrator/content/tests.py new file mode 100755 index 0000000..3e1f635 --- /dev/null +++ b/integrator/content/tests.py @@ -0,0 +1,23 @@ +# $Id$ + +import unittest, doctest +from zope.testing.doctestunit import DocFileSuite +from zope.interface.verify import verifyClass +#from loops.versioning import versionable + +class Test(unittest.TestCase): + "Basic tests for the loops.integrator.content package." + + def testSomething(self): + pass + + +def test_suite(): + flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS + return unittest.TestSuite(( + unittest.makeSuite(Test), + DocFileSuite('README.txt', optionflags=flags), + )) + +if __name__ == '__main__': + unittest.main(defaultTest='test_suite') diff --git a/integrator/interfaces.py b/integrator/interfaces.py index f1eeefa..7909275 100644 --- a/integrator/interfaces.py +++ b/integrator/interfaces.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2007 Helmut Merz helmutm@cy55.de +# Copyright (c) 2008 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 @@ -17,7 +17,7 @@ # """ -Intergrator interfaces. +Integrator interfaces. $Id$ """ @@ -98,28 +98,5 @@ class IExternalCollectionProvider(Interface): provided. Return the list of objects created. """ -# classification stuff - -class IAutoClassifier(Interface): - """ An adapter that more or less automagically assigns concepts to a - resource using some sort of selection criteria for the concepts - that should be considered. - """ - - -class IOntologyExporter(Interface): - """ An adapter for creating an XML file with all appropriate informations - from the context and its children, selecting children via a - pattern or a set of selection criteria. - - This may then be used by an external tool for classifying - a set of external objects. - """ - - -class IClassificationImporter(Interface): - """ An Adapter for importing an XML file with classification - information for a collection of external objects." - """ - +# classification stuff moved to loops.classifier