loops.integrator: provide view for show and update external collections

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1690 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-04-14 21:40:02 +00:00
parent a0b113195d
commit 9133b0fb52
10 changed files with 104 additions and 15 deletions

View file

@ -44,6 +44,7 @@ from zope.security.proxy import removeSecurityProxy
from cybertools.typology.interfaces import IType, ITypeManager from cybertools.typology.interfaces import IType, ITypeManager
from loops.interfaces import IConcept from loops.interfaces import IConcept
from loops.interfaces import ITypeConcept
from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList
from loops.browser.common import EditForm, BaseView, LoopsTerms from loops.browser.common import EditForm, BaseView, LoopsTerms
from loops import util from loops import util
@ -133,20 +134,25 @@ class ConceptView(BaseView):
@Lazy @Lazy
def view(self): def view(self):
context = self.context
viewName = self.request.get('loops.viewName') or getattr(self, '_viewName', None) viewName = self.request.get('loops.viewName') or getattr(self, '_viewName', None)
if not viewName: if not viewName:
ti = IType(self.context).typeInterface ti = IType(context).typeInterface
# TODO: check the interface (maybe for a base interface IViewProvider) # TODO: check the interface (maybe for a base interface IViewProvider)
# instead of the viewName attribute: # instead of the viewName attribute:
if ti and 'viewName' in ti: if ti and ti != ITypeConcept and 'viewName' in ti:
typeAdapter = ti(self.context) typeAdapter = ti(self.context)
viewName = typeAdapter.viewName viewName = typeAdapter.viewName
if not viewName:
tp = IType(context).typeProvider
if tp:
viewName = ITypeConcept(tp).viewName
if viewName: if viewName:
# ??? Would it make sense to use a somehow restricted interface # ??? Would it make sense to use a somehow restricted interface
# that should be provided by the view like IQuery? # that should be provided by the view like IQuery?
#viewInterface = getattr(typeAdapter, 'viewInterface', None) or IQuery #viewInterface = getattr(typeAdapter, 'viewInterface', None) or IQuery
adapter = component.queryMultiAdapter((self.context, self.request), adapter = component.queryMultiAdapter((context, self.request),
interface.Interface, name=viewName) name=viewName)
if adapter is not None: if adapter is not None:
return adapter return adapter
#elif type provides view: use this #elif type provides view: use this

View file

@ -98,9 +98,11 @@ Working with the External Collection
>>> res = coll01.getResources() >>> res = coll01.getResources()
>>> len(res) >>> len(res)
2 2
>>> sorted((r.__name__, r.title) for r in res) >>> sorted((r.__name__, r.title, r._storageName) for r in res)
[(u'programming_beautifulprogram.pdf', u'BeautifulProgram'), [(u'programming_beautifulprogram.pdf', u'BeautifulProgram', 'fullpath'),
(u'programming_zope_zope3.txt', u'zope3')] (u'programming_zope_zope3.txt', u'zope3', 'fullpath')]
To do: Check storage parameters.
Fin de partie Fin de partie

48
integrator/browser.py Normal file
View file

@ -0,0 +1,48 @@
#
# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
View class(es) for intergrating external objects.
$Id$
"""
from zope import interface, component
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from cybertools.typology.interfaces import IType
from loops.browser.concept import ConceptView
class ExternalCollectionView(ConceptView):
macro_template = ViewPageTemplateFile('collection_macros.pt')
@property
def macro(self):
return self.macro_template.macros['render_collection']
def update(self):
if 'update' in self.request.form:
ti = IType(self.context).typeInterface
if ti is not None:
adapted = ti(self.context)
adapted.update()
return True

View file

@ -70,6 +70,7 @@ class ExternalCollectionAdapter(AdapterBase):
for addr, mdate in provider.collect(self): for addr, mdate in provider.collect(self):
if addr in old: if addr in old:
if mdate > self.lastUpdated: if mdate > self.lastUpdated:
# force reindexing
notify(ObjectModifiedEvent(old[addr])) notify(ObjectModifiedEvent(old[addr]))
else: else:
new.append(addr) new.append(addr)
@ -113,7 +114,7 @@ class DirectoryCollectionProvider(object):
title=title, title=title,
resourceType=extFileType, resourceType=extFileType,
externalAddress=addr, externalAddress=addr,
storage='fullpath', storageName='fullpath',
storageParams=dict(subdirectory=directory)) storageParams=dict(subdirectory=directory))
yield obj yield obj

View file

@ -0,0 +1,11 @@
<metal:resources define-macro="render_collection"
tal:define="dummy item/update">
<metal:concept use-macro="item/template/macros/conceptdata" />
<form action="." method="post">
<input type="submit" name="update" value="Update Collection" />
</form>
</metal:resources>

View file

@ -19,4 +19,15 @@
<zope:utility <zope:utility
factory="loops.integrator.collection.DirectoryCollectionProvider" /> factory="loops.integrator.collection.DirectoryCollectionProvider" />
<!-- view(s) -->
<zope:adapter
name="collection.html"
for="loops.interfaces.IConcept
zope.publisher.interfaces.browser.IBrowserRequest"
provides="zope.interface.Interface"
factory="loops.integrator.browser.ExternalCollectionView"
permission="zope.View"
/>
</configure> </configure>

View file

@ -8,9 +8,9 @@ import os
from zope import component from zope import component
from loops import util from loops import util
from loops.interfaces import IExternalFile from loops.interfaces import IFile, IExternalFile
from loops.concept import Concept from loops.concept import Concept
from loops.resource import Resource from loops.resource import Resource, FileAdapter, ExternalFileAdapter
from loops.integrator.interfaces import IExternalCollection from loops.integrator.interfaces import IExternalCollection
from loops.knowledge.setup import SetupManager as KnowledgeSetupManager from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
from loops.setup import SetupManager, addAndConfigureObject from loops.setup import SetupManager, addAndConfigureObject
@ -28,6 +28,9 @@ class TestSite(BaseTestSite):
component.provideAdapter(KnowledgeSetupManager, name='knowledge') component.provideAdapter(KnowledgeSetupManager, name='knowledge')
concepts, resources, views = self.baseSetup() concepts, resources, views = self.baseSetup()
component.provideAdapter(FileAdapter, provides=IFile)
component.provideAdapter(ExternalFileAdapter, provides=IExternalFile)
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,

View file

@ -305,6 +305,9 @@ class ExternalFileAdapter(FileAdapter):
implements(IExternalFile) implements(IExternalFile)
_adapterAttributes = (FileAdapter._adapterAttributes
+ ('storageParams', 'externalAddress'))
def getStorageParams(self): def getStorageParams(self):
params = getattr(self.context, '_storageParams', None) params = getattr(self.context, '_storageParams', None)
if params is not None: if params is not None:

View file

@ -114,9 +114,12 @@ def addAndConfigureObject(container, class_, name, **kw):
basicKw = dict([(k, kw[k]) for k in kw if k in basicAttributes]) basicKw = dict([(k, kw[k]) for k in kw if k in basicAttributes])
obj = addObject(container, class_, name, **basicKw) obj = addObject(container, class_, name, **basicKw)
ti = IType(obj).typeInterface ti = IType(obj).typeInterface
adapted = ti is not None and ti(obj) or obj if ti is not None:
adapted = ti(obj)
else:
adapted = obj
adapterAttributes = [k for k in kw if k not in basicAttributes] adapterAttributes = [k for k in kw if k not in basicAttributes]
for attr in adapterAttributes: for attr in adapterAttributes:
setattr(obj, attr, kw[attr]) setattr(adapted, attr, kw[attr])
notify(ObjectModifiedEvent(obj)) notify(ObjectModifiedEvent(obj))
return obj return obj

View file

@ -19,13 +19,13 @@ from cybertools.typology.interfaces import IType
from loops import Loops from loops import Loops
from loops import util from loops import util
from loops.common import NameChooser from loops.common import NameChooser
from loops.interfaces import IIndexAttributes from loops.interfaces import IIndexAttributes, IDocument
from loops.concept import Concept from loops.concept import Concept
from loops.concept import IndexAttributes as ConceptIndexAttributes from loops.concept import IndexAttributes as ConceptIndexAttributes
from loops.resource import Resource from loops.resource import Resource
from loops.resource import IndexAttributes as ResourceIndexAttributes from loops.resource import IndexAttributes as ResourceIndexAttributes
from loops.setup import SetupManager, addObject from loops.setup import SetupManager, addObject
from loops.type import ConceptType, ResourceType, TypeConcept from loops.type import LoopsType, ConceptType, ResourceType, TypeConcept
class TestSite(object): class TestSite(object):
@ -42,8 +42,9 @@ class TestSite(object):
component.provideUtility(relations, IRelationRegistry) component.provideUtility(relations, IRelationRegistry)
component.provideAdapter(IndexableRelationAdapter) component.provideAdapter(IndexableRelationAdapter)
component.provideAdapter(LoopsType)
component.provideAdapter(ConceptType) component.provideAdapter(ConceptType)
component.provideAdapter(ResourceType) component.provideAdapter(ResourceType, (IDocument,))
component.provideAdapter(TypeConcept) component.provideAdapter(TypeConcept)
component.provideAdapter(NameChooser) component.provideAdapter(NameChooser)