From 411e16964841f6d97c3c50774733dd8f6de17f38 Mon Sep 17 00:00:00 2001 From: helmutm Date: Sat, 5 May 2007 16:43:45 +0000 Subject: [PATCH] improving loops.integrator.collextion: identify external file via uniqueAddress property git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1717 fd906abe-77d9-0310-91a1-e0d9ade77398 --- common.py | 2 +- integrator/README.txt | 24 +++++++++++++++++------- integrator/collection.py | 5 ++++- integrator/testsetup.py | 4 ++++ organize/README.txt | 2 +- resource.py | 17 +++++++++-------- 6 files changed, 36 insertions(+), 18 deletions(-) diff --git a/common.py b/common.py index dd6bd65..0e0e7c3 100644 --- a/common.py +++ b/common.py @@ -76,7 +76,7 @@ class AdapterBase(object): def checkAttr(self, attr): if attr not in self._contextAttributes: - raise AttributeError(attr) + raise AttributeError('%s: %s' % (self, attr)) def __eq__(self, other): if other is None: diff --git a/integrator/README.txt b/integrator/README.txt index 215ee1f..bd9cc40 100644 --- a/integrator/README.txt +++ b/integrator/README.txt @@ -110,9 +110,9 @@ Working with the External Collection [(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. +We may update the collection after having changed the storage params. +This should also the settings for existing objects if they still +can be found. >>> import os >>> aColl01.address = os.path.join('topics', 'programming') @@ -120,10 +120,20 @@ will be removed and newly created. >>> res = sorted(coll01.getResources(), key=lambda x: getName(x)) >>> len(res) 2 - >>> xf1 = res[0] - >>> aXf1 = adapted(xf1) - >>> aXf1.storageParams - {'subdirectory': '...programming'} + >>> aXf1 = adapted(res[0]) + >>> aXf1.storageName, aXf1.storageParams, aXf1.externalAddress + ('fullpath', {'subdirectory': '...programming'}, 'BeautifulProgram.pdf') + +But if one of the referenced objects is not found any more it will be deleted. + + >>> aColl01.address = os.path.join('topics', 'programming', 'zope') + >>> aColl01.update() + >>> res = sorted(coll01.getResources(), key=lambda x: getName(x)) + >>> len(res) + 1 + >>> aXf1 = adapted(res[0]) + >>> aXf1.storageName, aXf1.storageParams, aXf1.externalAddress + ('fullpath', {'subdirectory': '...zope'}, 'zope3.txt') Fin de partie diff --git a/integrator/collection.py b/integrator/collection.py index f9fc25f..f21276c 100644 --- a/integrator/collection.py +++ b/integrator/collection.py @@ -64,7 +64,9 @@ class ExternalCollectionAdapter(AdapterBase): def update(self): existing = self.context.getResources() - old = dict((adapted(obj).externalAddress, obj) for obj in existing) + # TODO: use full address for checking for existing resources + old = dict((adapted(obj).uniqueAddress, obj) for obj in existing) + #old = dict((adapted(obj).externalAddress, obj) for obj in existing) new = [] oldFound = [] provider = component.getUtility(IExternalCollectionProvider, @@ -86,6 +88,7 @@ class ExternalCollectionAdapter(AdapterBase): for addr in old: if addr not in oldFound: # not part of the collection any more + # TODO: only remove from collection but keep object? self.remove(old[addr]) self.lastUpdated = datetime.today() diff --git a/integrator/testsetup.py b/integrator/testsetup.py index 83ab22f..5777a1c 100644 --- a/integrator/testsetup.py +++ b/integrator/testsetup.py @@ -7,6 +7,8 @@ $Id$ import os from zope import component +from cybertools.storage.interfaces import IExternalStorage +from cybertools.storage.filesystem import fullPathStorage from loops import util from loops.interfaces import IFile, IExternalFile from loops.concept import Concept @@ -31,6 +33,8 @@ class TestSite(BaseTestSite): component.provideAdapter(FileAdapter, provides=IFile) component.provideAdapter(ExternalFileAdapter, provides=IExternalFile) + component.provideUtility(fullPathStorage(), IExternalStorage, name='fullpath') + tType = concepts.getTypeConcept() tExtFile = addAndConfigureObject(concepts, Concept, 'extfile', title=u'External File', conceptType=tType, diff --git a/organize/README.txt b/organize/README.txt index d3f33bf..31761d7 100644 --- a/organize/README.txt +++ b/organize/README.txt @@ -71,7 +71,7 @@ The classes used in this package are just adapters to IConcept. >>> john.someOtherAttribute Traceback (most recent call last): ... - AttributeError: someOtherAttribute + AttributeError: ... someOtherAttribute We can use the age calculations from the base Person class: diff --git a/resource.py b/resource.py index 3c9853d..cc028ef 100644 --- a/resource.py +++ b/resource.py @@ -283,6 +283,8 @@ class FileAdapter(ResourceAdapterBase): _contextAttributes = list(IFile) + list(IBaseResource) _adapterAttributes = ResourceAdapterBase._adapterAttributes + ('data',) + externalAddress = None + def setData(self, data): #if self.storageName is None: # self.storageName = 'zopefile' @@ -308,7 +310,7 @@ class ExternalFileAdapter(FileAdapter): implements(IExternalFile) _adapterAttributes = (FileAdapter._adapterAttributes - + ('storageParams', 'externalAddress')) + + ('storageParams', 'externalAddress', 'uniqueAddress')) def getStorageParams(self): params = getattr(self.context, '_storageParams', None) @@ -328,13 +330,12 @@ class ExternalFileAdapter(FileAdapter): self.context._externalAddress = addr externalAddress = property(getExternalAddress, setExternalAddress) - #@Lazy - #def externalAddress(self): - # or is this an editable attribute? - # or some sort of subpath set during import? - # anyway: an attribute of the context object. - # TODO: use intId and store in special attribute for later reuse - #return self.context.__name__ + @property + def uniqueAddress(self): + storageParams = self.storageParams + storageName = self.storageName + storage = component.getUtility(IExternalStorage, name=storageName) + return storage.getUniqueAddress(self.externalAddress, storageParams) def setData(self, data): storageParams = self.storageParams