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):
|
def checkAttr(self, attr):
|
||||||
if attr not in self._contextAttributes:
|
if attr not in self._contextAttributes:
|
||||||
raise AttributeError(attr)
|
raise AttributeError('%s: %s' % (self, attr))
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if other is None:
|
if other is None:
|
||||||
|
|
|
@ -110,9 +110,9 @@ Working with the External Collection
|
||||||
[(u'programming_beautifulprogram.pdf', u'BeautifulProgram', 'fullpath'),
|
[(u'programming_beautifulprogram.pdf', u'BeautifulProgram', 'fullpath'),
|
||||||
(u'programming_zope_zope3.txt', u'zope3', 'fullpath')]
|
(u'programming_zope_zope3.txt', u'zope3', 'fullpath')]
|
||||||
|
|
||||||
If one of the referenced objects is not found any more it will be deleted.
|
We may update the collection after having changed the storage params.
|
||||||
So if we change one of the collection parameters probably all old resources
|
This should also the settings for existing objects if they still
|
||||||
will be removed and newly created.
|
can be found.
|
||||||
|
|
||||||
>>> import os
|
>>> import os
|
||||||
>>> aColl01.address = os.path.join('topics', 'programming')
|
>>> 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))
|
>>> res = sorted(coll01.getResources(), key=lambda x: getName(x))
|
||||||
>>> len(res)
|
>>> len(res)
|
||||||
2
|
2
|
||||||
>>> xf1 = res[0]
|
>>> aXf1 = adapted(res[0])
|
||||||
>>> aXf1 = adapted(xf1)
|
>>> aXf1.storageName, aXf1.storageParams, aXf1.externalAddress
|
||||||
>>> aXf1.storageParams
|
('fullpath', {'subdirectory': '...programming'}, 'BeautifulProgram.pdf')
|
||||||
{'subdirectory': '...programming'}
|
|
||||||
|
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
|
Fin de partie
|
||||||
|
|
|
@ -64,7 +64,9 @@ class ExternalCollectionAdapter(AdapterBase):
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
existing = self.context.getResources()
|
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 = []
|
new = []
|
||||||
oldFound = []
|
oldFound = []
|
||||||
provider = component.getUtility(IExternalCollectionProvider,
|
provider = component.getUtility(IExternalCollectionProvider,
|
||||||
|
@ -86,6 +88,7 @@ class ExternalCollectionAdapter(AdapterBase):
|
||||||
for addr in old:
|
for addr in old:
|
||||||
if addr not in oldFound:
|
if addr not in oldFound:
|
||||||
# not part of the collection any more
|
# not part of the collection any more
|
||||||
|
# TODO: only remove from collection but keep object?
|
||||||
self.remove(old[addr])
|
self.remove(old[addr])
|
||||||
self.lastUpdated = datetime.today()
|
self.lastUpdated = datetime.today()
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ $Id$
|
||||||
import os
|
import os
|
||||||
from zope import component
|
from zope import component
|
||||||
|
|
||||||
|
from cybertools.storage.interfaces import IExternalStorage
|
||||||
|
from cybertools.storage.filesystem import fullPathStorage
|
||||||
from loops import util
|
from loops import util
|
||||||
from loops.interfaces import IFile, IExternalFile
|
from loops.interfaces import IFile, IExternalFile
|
||||||
from loops.concept import Concept
|
from loops.concept import Concept
|
||||||
|
@ -31,6 +33,8 @@ class TestSite(BaseTestSite):
|
||||||
component.provideAdapter(FileAdapter, provides=IFile)
|
component.provideAdapter(FileAdapter, provides=IFile)
|
||||||
component.provideAdapter(ExternalFileAdapter, provides=IExternalFile)
|
component.provideAdapter(ExternalFileAdapter, provides=IExternalFile)
|
||||||
|
|
||||||
|
component.provideUtility(fullPathStorage(), IExternalStorage, name='fullpath')
|
||||||
|
|
||||||
tType = concepts.getTypeConcept()
|
tType = concepts.getTypeConcept()
|
||||||
tExtFile = addAndConfigureObject(concepts, Concept, 'extfile',
|
tExtFile = addAndConfigureObject(concepts, Concept, 'extfile',
|
||||||
title=u'External File', conceptType=tType,
|
title=u'External File', conceptType=tType,
|
||||||
|
|
|
@ -71,7 +71,7 @@ The classes used in this package are just adapters to IConcept.
|
||||||
>>> john.someOtherAttribute
|
>>> john.someOtherAttribute
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
AttributeError: someOtherAttribute
|
AttributeError: ... someOtherAttribute
|
||||||
|
|
||||||
We can use the age calculations from the base Person class:
|
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)
|
_contextAttributes = list(IFile) + list(IBaseResource)
|
||||||
_adapterAttributes = ResourceAdapterBase._adapterAttributes + ('data',)
|
_adapterAttributes = ResourceAdapterBase._adapterAttributes + ('data',)
|
||||||
|
|
||||||
|
externalAddress = None
|
||||||
|
|
||||||
def setData(self, data):
|
def setData(self, data):
|
||||||
#if self.storageName is None:
|
#if self.storageName is None:
|
||||||
# self.storageName = 'zopefile'
|
# self.storageName = 'zopefile'
|
||||||
|
@ -308,7 +310,7 @@ class ExternalFileAdapter(FileAdapter):
|
||||||
implements(IExternalFile)
|
implements(IExternalFile)
|
||||||
|
|
||||||
_adapterAttributes = (FileAdapter._adapterAttributes
|
_adapterAttributes = (FileAdapter._adapterAttributes
|
||||||
+ ('storageParams', 'externalAddress'))
|
+ ('storageParams', 'externalAddress', 'uniqueAddress'))
|
||||||
|
|
||||||
def getStorageParams(self):
|
def getStorageParams(self):
|
||||||
params = getattr(self.context, '_storageParams', None)
|
params = getattr(self.context, '_storageParams', None)
|
||||||
|
@ -328,13 +330,12 @@ class ExternalFileAdapter(FileAdapter):
|
||||||
self.context._externalAddress = addr
|
self.context._externalAddress = addr
|
||||||
externalAddress = property(getExternalAddress, setExternalAddress)
|
externalAddress = property(getExternalAddress, setExternalAddress)
|
||||||
|
|
||||||
#@Lazy
|
@property
|
||||||
#def externalAddress(self):
|
def uniqueAddress(self):
|
||||||
# or is this an editable attribute?
|
storageParams = self.storageParams
|
||||||
# or some sort of subpath set during import?
|
storageName = self.storageName
|
||||||
# anyway: an attribute of the context object.
|
storage = component.getUtility(IExternalStorage, name=storageName)
|
||||||
# TODO: use intId and store in special attribute for later reuse
|
return storage.getUniqueAddress(self.externalAddress, storageParams)
|
||||||
#return self.context.__name__
|
|
||||||
|
|
||||||
def setData(self, data):
|
def setData(self, data):
|
||||||
storageParams = self.storageParams
|
storageParams = self.storageParams
|
||||||
|
|
Loading…
Add table
Reference in a new issue