loops/integrator
helmutm ea09e0d836 loops.integrator: integrating filesystem directories working
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1691 fd906abe-77d9-0310-91a1-e0d9ade77398
2007-04-15 08:45:12 +00:00
..
testdata/topics/programming work in progress: loops.integrator with DirectoryCollectionProvider 2007-04-12 15:29:44 +00:00
__init__.py new loops subpackage 'integrator' for importing and integrating operating system files and other external objects 2007-04-10 14:56:48 +00:00
browser.py loops.integrator: provide view for show and update external collections 2007-04-14 21:40:02 +00:00
collection.py loops.integrator: integrating filesystem directories working 2007-04-15 08:45:12 +00:00
collection_macros.pt loops.integrator: provide view for show and update external collections 2007-04-14 21:40:02 +00:00
configure.zcml loops.integrator: provide view for show and update external collections 2007-04-14 21:40:02 +00:00
interfaces.py loops.integrator: ExternalCollectionAdapter working 2007-04-14 16:52:39 +00:00
README.txt loops.integrator: integrating filesystem directories working 2007-04-15 08:45:12 +00:00
tests.py new loops subpackage 'integrator' for importing and integrating operating system files and other external objects 2007-04-10 14:56:48 +00:00
testsetup.py loops.integrator: provide view for show and update external collections 2007-04-14 21:40:02 +00:00

===============================================================
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.integrator.testsetup import TestSite
  >>> t = TestSite(site)
  >>> concepts, resources, views = t.setup()

  >>> len(concepts) + len(resources)
  18


External Collections
====================

The basis of our work will be ExternalCollection objects, i.e. concepts
of the 'extcollection' type. We use an adapter for providing the attributes
and methods of the external collect object.

  >>> from loops.concept import Concept
  >>> from loops.setup import addObject
  >>> from loops.integrator.collection import ExternalCollectionAdapter
  >>> tExternalCollection = concepts['extcollection']
  >>> coll01 = addObject(concepts, Concept, 'coll01',
  ...                    title=u'Collection One', conceptType=tExternalCollection)
  >>> aColl01 = ExternalCollectionAdapter(coll01)

An external collection carries a set of attributes that control the access
to the external system:

  >>> aColl01.providerName, aColl01.baseAddress, aColl01.address, aColl01.pattern
  (None, None, None, None)
  >>> from loops.integrator.testsetup import dataDir
  >>> aColl01.baseAddress = dataDir
  >>> aColl01.address = 'topics'

Directory Collection Provider
-----------------------------

The DirectoryCollectionProvider collects files from a directory in the
file system. The parameters (directory paths) are provided by the calling
object, the external collection itself.

  >>> from loops.integrator.collection import DirectoryCollectionProvider
  >>> dcp = DirectoryCollectionProvider()

  >>> sorted(dcp.collect(aColl01))
  [('programming/BeautifulProgram.pdf', datetime.datetime(2005, 4, 7, 12, 36, 56)),
   ('programming/zope/zope3.txt', datetime.datetime(2007, 4, 12, 15, 16, 13))]

If we provide a more selective pattern we get only part of the files:

  >>> aColl01.pattern = r'.*\.txt'
  >>> sorted(dcp.collect(aColl01))
  [('programming/zope/zope3.txt', datetime.datetime(2007, 4, 12, 15, 16, 13))]

Let's now create the corresponding resource objects.

  >>> aColl01.pattern = ''
  >>> addresses = [e[0] for e in dcp.collect(aColl01)]
  >>> res = list(dcp.createExtFileObjects(aColl01, addresses))
  >>> len(sorted(r.__name__ for r in res))
  2
  >>> xf1 = res[0]
  >>> xf1.__name__
  u'programming_beautifulprogram.pdf'
  >>> xf1.title
  u'BeautifulProgram'
  >>> xf1.contentType
  'application/pdf'

  >>> from loops.common import adapted
  >>> aXf1 = adapted(xf1)
  >>> aXf1.storageName
  'fullpath'
  >>> aXf1.storageParams
  {'subdirectory': '...topics'}

  >>> for r in res: del resources[r.__name__]

Working with the External Collection
------------------------------------

  >>> component.provideUtility(DirectoryCollectionProvider())
  >>> aColl01.update()
  >>> res = coll01.getResources()
  >>> 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')]

If one of the referenced objects is not found any more it will be deleted.
So if we change one of the collection parameters probably all old resources
will be removed and newly created.

  >>> import os
  >>> aColl01.address = os.path.join('topics', 'programming')
  >>> aColl01.update()
  >>> res = sorted(coll01.getResources(), key=lambda x: getName(x))
  >>> len(res)
  2
  >>> xf1 = res[0]
  >>> aXf1 = adapted(xf1)
  >>> aXf1.storageParams
  {'subdirectory': '...programming'}


Fin de partie
=============

  >>> placefulTearDown()