loops.integrator: integrating filesystem directories working

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1691 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-04-15 08:45:12 +00:00
parent 9133b0fb52
commit ea09e0d836
5 changed files with 84 additions and 16 deletions

View file

@ -31,10 +31,22 @@ from zope.interface import implements
from zope.cachedescriptors.property import Lazy
from cybertools.storage.interfaces import IStorageInfo
from cybertools.typology.interfaces import IType
from loops.interfaces import ILoopsObject, ILoopsContained, IConcept, IResource
from loops.interfaces import IResourceAdapter
def adapted(obj):
t = IType(obj, None)
if t is not None:
ti = t.typeInterface
if ti is not None:
adapted = ti(obj, None)
if adapted is not None:
return adapted
return obj
# type interface adapters
class AdapterBase(object):

View file

@ -86,9 +86,17 @@ Let's now create the corresponding resource objects.
u'programming_beautifulprogram.pdf'
>>> xf1.title
u'BeautifulProgram'
>>> xf1.contentType
'application/pdf'
>>> for r in res:
... del resources[r.__name__]
>>> 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
------------------------------------
@ -102,7 +110,20 @@ Working with the External Collection
[(u'programming_beautifulprogram.pdf', u'BeautifulProgram', 'fullpath'),
(u'programming_zope_zope3.txt', u'zope3', 'fullpath')]
To do: Check storage parameters.
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

View file

@ -26,19 +26,20 @@ $Id$
from datetime import datetime
import os, re, stat
from zope import component
from zope.lifecycleevent import ObjectModifiedEvent
from zope.event import notify
from zope.app.container.interfaces import INameChooser
from zope.component import adapts
from zope.interface import implements, Attribute
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.schema.interfaces import IField
from zope.traversing.api import getName, getParent
from cybertools.text import mimetypes
from cybertools.typology.interfaces import IType
from loops.common import AdapterBase
from loops.common import AdapterBase, adapted
from loops.interfaces import IResource, IConcept
from loops.integrator.interfaces import IExternalCollection
from loops.integrator.interfaces import IExternalCollectionProvider
@ -63,12 +64,16 @@ class ExternalCollectionAdapter(AdapterBase):
def update(self):
existing = self.context.getResources()
old = dict((obj.externalAddress, obj) for obj in existing)
old = dict((adapted(obj).externalAddress, obj) for obj in existing)
new = []
oldFound = []
provider = component.getUtility(IExternalCollectionProvider,
name=self.providerName or '')
for addr, mdate in provider.collect(self):
if addr in old:
# may be it would be better to return a file's hash
# for checking for changes...
oldFound.append(addr)
if mdate > self.lastUpdated:
# force reindexing
notify(ObjectModifiedEvent(old[addr]))
@ -78,8 +83,23 @@ class ExternalCollectionAdapter(AdapterBase):
newResources = provider.createExtFileObjects(self, new)
for r in newResources:
self.context.assignResource(r)
for addr in old:
if addr not in oldFound:
# not part of the collection any more
self.remove(old[addr])
self.lastUpdated = datetime.today()
def clear(self):
for obj in self.context.getResources():
self.remove(obj)
def remove(self, obj):
del self.resourceManager[getName(obj)]
@Lazy
def resourceManager(self):
return self.context.getLoopsRoot().getResourceManager()
class DirectoryCollectionProvider(object):
""" A utility that provides access to files in a directory.
@ -95,8 +115,6 @@ class DirectoryCollectionProvider(object):
del dirs[dirs.index('.svn')]
for f in files:
if pattern.match(f):
# may be it would be better to return a file's hash
# for checking for changes...
mtime = os.stat(os.path.join(path, f))[stat.ST_MTIME]
yield (os.path.join(path[len(directory)+1:], f),
datetime.fromtimestamp(mtime))
@ -115,7 +133,10 @@ class DirectoryCollectionProvider(object):
resourceType=extFileType,
externalAddress=addr,
storageName='fullpath',
storageParams=dict(subdirectory=directory))
storageParams=dict(subdirectory=directory),
contentType = guess_content_type(addr,
default='application/octet-stream')[0]
)
yield obj
def getDirectory(self, client):

View file

@ -9,20 +9,23 @@ from zope.app.catalog.catalog import Catalog
from zope.app.catalog.interfaces import ICatalog
from zope.app.catalog.field import FieldIndex
from zope.app.catalog.text import TextIndex
from zope.app.container.interfaces import IObjectRemovedEvent
from cybertools.relation.tests import IntIdsStub
from cybertools.relation.registry import RelationRegistry
from cybertools.relation.interfaces import IRelationRegistry
from cybertools.relation.interfaces import IRelation, IRelationRegistry
from cybertools.relation.interfaces import IRelationInvalidatedEvent
from cybertools.relation.registry import IndexableRelationAdapter
from cybertools.relation.registry import invalidateRelations, removeRelation
from cybertools.typology.interfaces import IType
from loops import Loops
from loops import util
from loops.common import NameChooser
from loops.interfaces import IIndexAttributes, IDocument
from loops.interfaces import ILoopsObject, IIndexAttributes, IDocument, IFile
from loops.concept import Concept
from loops.concept import IndexAttributes as ConceptIndexAttributes
from loops.resource import Resource
from loops.resource import Resource, FileAdapter
from loops.resource import IndexAttributes as ResourceIndexAttributes
from loops.setup import SetupManager, addObject
from loops.type import LoopsType, ConceptType, ResourceType, TypeConcept
@ -46,8 +49,14 @@ class TestSite(object):
component.provideAdapter(ConceptType)
component.provideAdapter(ResourceType, (IDocument,))
component.provideAdapter(TypeConcept)
component.provideAdapter(FileAdapter, provides=IFile)
component.provideAdapter(NameChooser)
component.getSiteManager().registerHandler(invalidateRelations,
(ILoopsObject, IObjectRemovedEvent))
component.getSiteManager().registerHandler(removeRelation,
(IRelation, IRelationInvalidatedEvent))
catalog = self.catalog = Catalog()
component.provideUtility(catalog, ICatalog)
catalog['loops_title'] = TextIndex('title', IIndexAttributes, True)

View file

@ -132,3 +132,8 @@ In addition it is possible to explicitly retrieve a certain version:
>>> IVersionable(getVersion(d001v1_2, TestRequest(form=dict(version='1.1')))).versionId
'1.1'
Fin de partie
=============
>>> placefulTearDown()