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
This commit is contained in:
parent
7f0a569dec
commit
411e169648
6 changed files with 36 additions and 18 deletions
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
17
resource.py
17
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
|
||||
|
|
Loading…
Add table
Reference in a new issue