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

View file

@ -98,9 +98,11 @@ Working with the External Collection
>>> res = coll01.getResources()
>>> len(res)
2
>>> sorted((r.__name__, r.title) for r in res)
[(u'programming_beautifulprogram.pdf', u'BeautifulProgram'),
(u'programming_zope_zope3.txt', u'zope3')]
>>> sorted((r.__name__, r.title, r._storageName) for r in res)
[(u'programming_beautifulprogram.pdf', u'BeautifulProgram', 'fullpath'),
(u'programming_zope_zope3.txt', u'zope3', 'fullpath')]
To do: Check storage parameters.
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):
if addr in old:
if mdate > self.lastUpdated:
# force reindexing
notify(ObjectModifiedEvent(old[addr]))
else:
new.append(addr)
@ -113,7 +114,7 @@ class DirectoryCollectionProvider(object):
title=title,
resourceType=extFileType,
externalAddress=addr,
storage='fullpath',
storageName='fullpath',
storageParams=dict(subdirectory=directory))
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
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>

View file

@ -8,9 +8,9 @@ import os
from zope import component
from loops import util
from loops.interfaces import IExternalFile
from loops.interfaces import IFile, IExternalFile
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.knowledge.setup import SetupManager as KnowledgeSetupManager
from loops.setup import SetupManager, addAndConfigureObject
@ -28,6 +28,9 @@ class TestSite(BaseTestSite):
component.provideAdapter(KnowledgeSetupManager, name='knowledge')
concepts, resources, views = self.baseSetup()
component.provideAdapter(FileAdapter, provides=IFile)
component.provideAdapter(ExternalFileAdapter, provides=IExternalFile)
tType = concepts.getTypeConcept()
tExtFile = addAndConfigureObject(concepts, Concept, 'extfile',
title=u'External File', conceptType=tType,

View file

@ -305,6 +305,9 @@ class ExternalFileAdapter(FileAdapter):
implements(IExternalFile)
_adapterAttributes = (FileAdapter._adapterAttributes
+ ('storageParams', 'externalAddress'))
def getStorageParams(self):
params = getattr(self.context, '_storageParams', 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])
obj = addObject(container, class_, name, **basicKw)
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]
for attr in adapterAttributes:
setattr(obj, attr, kw[attr])
setattr(adapted, attr, kw[attr])
notify(ObjectModifiedEvent(obj))
return obj

View file

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