first working version of fulltext and title search
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1317 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
		
							parent
							
								
									f8f9ee1fd8
								
							
						
					
					
						commit
						8ee75bbf77
					
				
					 9 changed files with 144 additions and 51 deletions
				
			
		| 
						 | 
				
			
			@ -25,12 +25,10 @@ $Id$
 | 
			
		|||
from zope.app import zapi
 | 
			
		||||
from zope.app.dublincore.interfaces import IZopeDublinCore
 | 
			
		||||
from zope.app.form.browser.interfaces import ITerms
 | 
			
		||||
from zope.app.intid.interfaces import IIntIds
 | 
			
		||||
from zope.cachedescriptors.property import Lazy
 | 
			
		||||
from zope.dottedname.resolve import resolve
 | 
			
		||||
from zope.formlib import form
 | 
			
		||||
from zope.formlib.form import FormFields
 | 
			
		||||
from zope.formlib.form import EditForm as BaseEditForm
 | 
			
		||||
from zope.formlib.form import AddForm as BaseAddForm
 | 
			
		||||
from zope.formlib.namedtemplate import NamedTemplate
 | 
			
		||||
from zope.interface import Interface, implements
 | 
			
		||||
from zope.app.publisher.browser import applySkin
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +42,7 @@ from cybertools.browser.view import GenericView
 | 
			
		|||
from cybertools.relation.interfaces import IRelationRegistry
 | 
			
		||||
from cybertools.typology.interfaces import IType
 | 
			
		||||
from loops.interfaces import IView
 | 
			
		||||
from loops import util
 | 
			
		||||
#from loops import util
 | 
			
		||||
from loops.util import _
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -64,13 +62,13 @@ class IAddForm(Interface):
 | 
			
		|||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AddForm(BaseAddForm):
 | 
			
		||||
class AddForm(form.AddForm):
 | 
			
		||||
 | 
			
		||||
    form_fields = FormFields(IAddForm)
 | 
			
		||||
    template = NamedTemplate('loops.pageform')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EditForm(BaseEditForm):
 | 
			
		||||
class EditForm(form.EditForm):
 | 
			
		||||
 | 
			
		||||
    template = NamedTemplate('loops.pageform')
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -181,10 +179,6 @@ class BaseView(GenericView):
 | 
			
		|||
        # this may depend on system and user settings...
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    #@Lazy
 | 
			
		||||
    #def inlineEditable(self):
 | 
			
		||||
    #    return self.inlineEditingActive and canWrite(self.context, 'title')
 | 
			
		||||
 | 
			
		||||
    inlineEditable = False
 | 
			
		||||
 | 
			
		||||
    def inlineEdit(self, id):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,9 @@ from zope.proxy import removeAllProxies
 | 
			
		|||
from zope.security import canAccess, canWrite
 | 
			
		||||
from zope.security.proxy import removeSecurityProxy
 | 
			
		||||
 | 
			
		||||
from zope.app.event.objectevent import ObjectModifiedEvent, Attributes
 | 
			
		||||
from zope.event import notify
 | 
			
		||||
 | 
			
		||||
from cybertools.ajax import innerHtml
 | 
			
		||||
from cybertools.browser import configurator
 | 
			
		||||
from cybertools.browser.view import GenericView
 | 
			
		||||
| 
						 | 
				
			
			@ -299,6 +302,7 @@ class InlineEdit(NodeView):
 | 
			
		|||
    def save(self):
 | 
			
		||||
        target = self.virtualTargetObject
 | 
			
		||||
        target.data = self.request.form['editorContent']
 | 
			
		||||
        notify(ObjectModifiedEvent(target, Attributes(IResource, 'data')))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# special (named) views for nodes
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								concept.py
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								concept.py
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -76,13 +76,13 @@ class ResourceRelation(BaseRelation):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
# concept
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
class Concept(Contained, Persistent):
 | 
			
		||||
 | 
			
		||||
    implements(IConcept, IConceptManagerContained, IRelatable)
 | 
			
		||||
 | 
			
		||||
    proxyInterface = IConceptView
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    _title = u''
 | 
			
		||||
    def getTitle(self): return self._title
 | 
			
		||||
    def setTitle(self, title): self._title = title
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ class Concept(Contained, Persistent):
 | 
			
		|||
        relationships = [ConceptRelation(None, self, p) for p in predicates]
 | 
			
		||||
        # TODO: sort...
 | 
			
		||||
        return getRelations(first=parent, second=self, relationships=relationships)
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    def getParents(self, predicates=None):
 | 
			
		||||
        return [r.first for r in self.getParentRelations(predicates)]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +158,7 @@ class Concept(Contained, Persistent):
 | 
			
		|||
 | 
			
		||||
    def deassignParent(self, parent, predicates=None):
 | 
			
		||||
        parent.deassignChild(self, predicates)
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    # resource relations
 | 
			
		||||
 | 
			
		||||
    def getResourceRelations(self, predicates=None, resource=None):
 | 
			
		||||
| 
						 | 
				
			
			@ -184,7 +184,7 @@ class Concept(Contained, Persistent):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
# concept manager
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
class ConceptManager(BTreeContainer):
 | 
			
		||||
 | 
			
		||||
    implements(IConceptManager, ILoopsContained)
 | 
			
		||||
| 
						 | 
				
			
			@ -211,7 +211,7 @@ class ConceptManager(BTreeContainer):
 | 
			
		|||
 | 
			
		||||
    def getViewManager(self):
 | 
			
		||||
        return self.getLoopsRoot().getViewManager()
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# adapters and similar components
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -291,10 +291,12 @@ class IndexAttributes(object):
 | 
			
		|||
    def __init__(self, context):
 | 
			
		||||
        self.context = context
 | 
			
		||||
 | 
			
		||||
    # obsolete, use TextIndexNG (with indexableContent() method) instead
 | 
			
		||||
    def text(self):
 | 
			
		||||
        context = self.context
 | 
			
		||||
        return ' '.join((zapi.getName(context), context.title,))
 | 
			
		||||
 | 
			
		||||
    def title(self):
 | 
			
		||||
        return self.text()
 | 
			
		||||
        context = self.context
 | 
			
		||||
        return ' '.join((zapi.getName(context), context.title,))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -276,12 +276,22 @@
 | 
			
		|||
    <require like_class="zope.app.dublincore.annotatableadapter.ZDCAnnotatableAdapter" />
 | 
			
		||||
  </class>
 | 
			
		||||
 | 
			
		||||
  <adapter factory="loops.concept.IndexAttributes" />
 | 
			
		||||
  <adapter factory="loops.resource.IndexAttributes" />
 | 
			
		||||
  <adapter factory="loops.concept.IndexAttributes" trusted="True" />
 | 
			
		||||
  <class class="loops.concept.IndexAttributes">
 | 
			
		||||
    <allow interface="loops.interfaces.IIndexAttributes" />
 | 
			
		||||
  </class>
 | 
			
		||||
 | 
			
		||||
  <adapter factory="loops.resource.IndexAttributes" trusted="True" />
 | 
			
		||||
  <class class="loops.resource.IndexAttributes">
 | 
			
		||||
    <allow interface="loops.interfaces.IIndexAttributes" />
 | 
			
		||||
  </class>
 | 
			
		||||
 | 
			
		||||
  <adapter factory="loops.resource.IndexableResource" trusted="True" />
 | 
			
		||||
  <class class="loops.resource.IndexableResource">
 | 
			
		||||
    <require permission="zope.View"
 | 
			
		||||
             interface="loops.interfaces.IBaseResourceSchema" />
 | 
			
		||||
    <allow interface="textindexng.interfaces.IIndexableContent" />
 | 
			
		||||
  </class>
 | 
			
		||||
  <class class="textindexng.content.IndexContentCollector">
 | 
			
		||||
    <allow interface="textindexng.interfaces.IIndexContentCollector" />
 | 
			
		||||
  </class>
 | 
			
		||||
 | 
			
		||||
  <adapter factory="loops.resource.DocumentReadFileAdapter" />
 | 
			
		||||
| 
						 | 
				
			
			@ -350,6 +360,21 @@
 | 
			
		|||
      name="loops.PredicateSource"
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
<!-- textindexng converters -->
 | 
			
		||||
 | 
			
		||||
  <utility
 | 
			
		||||
      provides="textindexng.interfaces.IConverter"
 | 
			
		||||
      component="textindexng.converters.null.NullConverter"
 | 
			
		||||
      name="text/structured"
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
  <utility
 | 
			
		||||
      provides="textindexng.interfaces.IConverter"
 | 
			
		||||
      component="textindexng.converters.null.NullConverter"
 | 
			
		||||
      name="text/restructured"
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  <include package=".knowledge" />
 | 
			
		||||
  <include package=".organize" />
 | 
			
		||||
  <include package=".process" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,9 @@ from zope import schema
 | 
			
		|||
from persistent import Persistent
 | 
			
		||||
from cStringIO import StringIO
 | 
			
		||||
 | 
			
		||||
from zope.app.event.objectevent import ObjectModifiedEvent, Attributes
 | 
			
		||||
from zope.event import notify
 | 
			
		||||
 | 
			
		||||
from textindexng.interfaces import IIndexableContent
 | 
			
		||||
from textindexng.content import IndexContentCollector
 | 
			
		||||
from cybertools.relation.registry import getRelations
 | 
			
		||||
| 
						 | 
				
			
			@ -205,6 +208,7 @@ class DocumentWriteFileAdapter(object):
 | 
			
		|||
 | 
			
		||||
    def write(self, data):
 | 
			
		||||
        self.context.data = unicode(data.replace('\r', ''), 'UTF-8')
 | 
			
		||||
        notify(ObjectModifiedEvent(self.context, Attributes(IDocument, 'data')))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DocumentReadFileAdapter(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -230,6 +234,7 @@ class IndexAttributes(object):
 | 
			
		|||
    def __init__(self, context):
 | 
			
		||||
        self.context = context
 | 
			
		||||
 | 
			
		||||
    # obsolete, use TextIndexNG (with indexableContent() method) instead
 | 
			
		||||
    def text(self):
 | 
			
		||||
        context = self.context
 | 
			
		||||
        return ' '.join((zapi.getName(context), context.title, context.data)).strip()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ Let's do some basic set up
 | 
			
		|||
  >>> site = placefulSetUp(True)
 | 
			
		||||
 | 
			
		||||
  >>> from zope import component, interface
 | 
			
		||||
  >>> from zope.interface import implements
 | 
			
		||||
 | 
			
		||||
and setup a simple loops site with a concept manager and some concepts
 | 
			
		||||
(with all the type machinery, what in real life is done via standard
 | 
			
		||||
| 
						 | 
				
			
			@ -81,3 +82,22 @@ a controller attribute for the search view.
 | 
			
		|||
  'return submitReplacing("1.results", "1.search.form",
 | 
			
		||||
       "http://127.0.0.1/loops/views/page/.target19/@@searchresults.html")'
 | 
			
		||||
 | 
			
		||||
The searchresults.html view, i.e. the SearchResults view class provides the
 | 
			
		||||
result set of the search via its `results` property.
 | 
			
		||||
 | 
			
		||||
  >>> from loops.search.browser import SearchResults
 | 
			
		||||
  >>> form = {'search.2.title': 'yes', 'search.2.text': u'foo' }
 | 
			
		||||
  >>> request = TestRequest(form=form)
 | 
			
		||||
  >>> resultsView = SearchResults(page, request)
 | 
			
		||||
 | 
			
		||||
Before accessing the `results` property we have to prepare a catalog.
 | 
			
		||||
 | 
			
		||||
  >>> from zope.app.catalog.interfaces import ICatalog
 | 
			
		||||
  >>> class DummyCat(object):
 | 
			
		||||
  ...     implements(ICatalog)
 | 
			
		||||
  ...     def searchResults(self, **criteria):
 | 
			
		||||
  ...         return []
 | 
			
		||||
  >>> component.provideUtility(DummyCat())
 | 
			
		||||
 | 
			
		||||
  >>> resultsView.results
 | 
			
		||||
  []
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@ $Id$
 | 
			
		|||
"""
 | 
			
		||||
 | 
			
		||||
from zope import interface, component
 | 
			
		||||
from zope.app.catalog.interfaces import ICatalog
 | 
			
		||||
from zope.app.pagetemplate import ViewPageTemplateFile
 | 
			
		||||
from zope.cachedescriptors.property import Lazy
 | 
			
		||||
from zope.formlib.namedtemplate import NamedTemplate, NamedTemplateImplementation
 | 
			
		||||
| 
						 | 
				
			
			@ -75,3 +76,22 @@ class SearchResults(BaseView):
 | 
			
		|||
    def __call__(self):
 | 
			
		||||
        return innerHtml(self)
 | 
			
		||||
 | 
			
		||||
    @Lazy
 | 
			
		||||
    def results(self):
 | 
			
		||||
        request = self.request
 | 
			
		||||
        text = request.get('search.2.text')
 | 
			
		||||
        if not text:
 | 
			
		||||
            return set()
 | 
			
		||||
        useTitle = request.get('search.2.title')
 | 
			
		||||
        useFull = request.get('search.2.full')
 | 
			
		||||
        r1 = r2 = set()
 | 
			
		||||
        cat = component.getUtility(ICatalog)
 | 
			
		||||
        if useFull:
 | 
			
		||||
            criteria = {'loops_resource_textng': {'query': text},}
 | 
			
		||||
            r1 = set(cat.searchResults(**criteria))
 | 
			
		||||
        if useTitle:
 | 
			
		||||
            criteria = {'loops_title': text,}
 | 
			
		||||
            r2 = set(cat.searchResults(**criteria))
 | 
			
		||||
        result = [BaseView(r, request) for r in r1.union(r2)]
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,19 +1,23 @@
 | 
			
		|||
<metal:search define-macro="search">
 | 
			
		||||
  <div id="search"
 | 
			
		||||
       tal:define="macros item/template/macros">
 | 
			
		||||
       tal:define="macros item/template/macros;
 | 
			
		||||
                   idPrefix string:${view/itemNum}.search;
 | 
			
		||||
                   formId string:$idPrefix.form;
 | 
			
		||||
                   resultsId string:$idPrefix.results">
 | 
			
		||||
    <h3 tal:attributes="class string:content-$level;
 | 
			
		||||
                        ondblclick item/openEditWindow">
 | 
			
		||||
      Search
 | 
			
		||||
    </h3>
 | 
			
		||||
 | 
			
		||||
    <div metal:define-macro="search_form" class="searchForm"
 | 
			
		||||
         tal:define="idPrefix string:${view/itemNum}.search;
 | 
			
		||||
                     formId string:$idPrefix.form">
 | 
			
		||||
    <div metal:define-macro="search_form" class="searchForm">
 | 
			
		||||
      <fieldset class="box">
 | 
			
		||||
        <form action="." method="post" id="1.search.form"
 | 
			
		||||
              tal:attributes="id formId">
 | 
			
		||||
          <input type="hidden" name="search.submitted" value="yes" />
 | 
			
		||||
          <input type="hidden" name="search.resultsId" value="1.results"
 | 
			
		||||
                 tal:attributes="value resultsId" />
 | 
			
		||||
          <table cellpadding="3">
 | 
			
		||||
            <tal:block repeat="search_selection python: ['type', 'text']">
 | 
			
		||||
            <tal:block repeat="search_param python: ['type', 'text']">
 | 
			
		||||
              <metal:row use-macro="macros/search_row" />
 | 
			
		||||
            </tal:block>
 | 
			
		||||
            <tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -24,10 +28,9 @@
 | 
			
		|||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
              <td colspan="2">
 | 
			
		||||
                <input type="submit" name="1.search" value="Search" class="submit"
 | 
			
		||||
                       tal:attributes="name string:$idPrefix.submit;
 | 
			
		||||
                                       onclick python:
 | 
			
		||||
                                item.submitReplacing('1.results', formId, view)" />
 | 
			
		||||
                <input type="submit" name="button.search" value="Search" class="submit"
 | 
			
		||||
                       tal:attributes="onclick python:
 | 
			
		||||
                                item.submitReplacing(resultsId, formId, view)" />
 | 
			
		||||
              </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
          </table>
 | 
			
		||||
| 
						 | 
				
			
			@ -35,11 +38,17 @@
 | 
			
		|||
      </fieldset>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div metal:define-macro="search_results"
 | 
			
		||||
         id="1.results">
 | 
			
		||||
      <fieldset class="box">
 | 
			
		||||
        Search results
 | 
			
		||||
        <p tal:content="python:request.get('2.search.1.text', 'nothing')" />
 | 
			
		||||
    <div metal:define-macro="search_results" id="1.search.results"
 | 
			
		||||
         tal:attributes="id resultsId | request/search.resultsId">
 | 
			
		||||
      <fieldset class="box"
 | 
			
		||||
                tal:condition="request/search.submitted | nothing">
 | 
			
		||||
        <legend>Search results</legend>
 | 
			
		||||
        <div tal:repeat="row view/results">
 | 
			
		||||
          <div>
 | 
			
		||||
            <a tal:attributes="href string:${view/url}/.target${row/uniqueId}"
 | 
			
		||||
               tal:content="row/title" />
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </fieldset>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -47,18 +56,22 @@
 | 
			
		|||
</metal:search>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<tr metal:define-macro="search_row" id="search.row.1.1"
 | 
			
		||||
<tr metal:define-macro="search_row" id="1.1.row"
 | 
			
		||||
    tal:define="rowNum item/rowNum;
 | 
			
		||||
                idPrefix string:$idPrefix.$rowNum;
 | 
			
		||||
                selection search_selection | item/searchSelection"
 | 
			
		||||
                namePrefix string:search.$rowNum;
 | 
			
		||||
                param search_param | item/searchParam"
 | 
			
		||||
    tal:attributes="id string:$idPrefix.row">
 | 
			
		||||
  <td style="width: 30px">
 | 
			
		||||
    <input type="hidden" name="paramtype" value="type"
 | 
			
		||||
           tal:attributes="name string:$namePrefix.paramtype;
 | 
			
		||||
                           value param" />
 | 
			
		||||
    <input type="button" value="−"
 | 
			
		||||
           title="Remove search parameter"
 | 
			
		||||
           tal:condition="python: selection not in ['type', 'text']" /> 
 | 
			
		||||
           tal:condition="python: param not in ['type', 'text']" /> 
 | 
			
		||||
  </td>
 | 
			
		||||
  <td>
 | 
			
		||||
    <div metal:use-macro="macros/?selection" />
 | 
			
		||||
    <div metal:use-macro="macros/?param" />
 | 
			
		||||
  </td>
 | 
			
		||||
</tr>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +82,7 @@
 | 
			
		|||
    <label for="text"
 | 
			
		||||
           tal:attributes="for string:$idPrefix.text">Type:</label>
 | 
			
		||||
    <select name="text"
 | 
			
		||||
            tal:attributes="name string:$idPrefix.text;
 | 
			
		||||
            tal:attributes="name string:$namePrefix.text;
 | 
			
		||||
                            id string:$idPrefix.text;">
 | 
			
		||||
      <option value=".loops/concepts/topic">Topic</option>
 | 
			
		||||
      <option value="loops.resource.Document">Document</option>
 | 
			
		||||
| 
						 | 
				
			
			@ -84,21 +97,21 @@
 | 
			
		|||
  <div>
 | 
			
		||||
    <h3>Search text</h3>
 | 
			
		||||
    <input type="checkbox" checked
 | 
			
		||||
           name="title" id="title"
 | 
			
		||||
           tal:attributes="name string:$idPrefix.title;
 | 
			
		||||
           name="title" id="title" value="yes"
 | 
			
		||||
           tal:attributes="name string:$namePrefix.title;
 | 
			
		||||
                           id string:$idPrefix.title;" />
 | 
			
		||||
    <label for="title"
 | 
			
		||||
           tal:attributes="for string:$idPrefix.title">Title</label>
 | 
			
		||||
    <input type="checkbox"
 | 
			
		||||
           name="full" id="full"
 | 
			
		||||
           tal:attributes="name string:$idPrefix.full;
 | 
			
		||||
           name="full" id="full" value="yes"
 | 
			
		||||
           tal:attributes="name string:$namePrefix.full;
 | 
			
		||||
                           id string:$idPrefix.full;" />
 | 
			
		||||
    <label for="full"
 | 
			
		||||
           tal:attributes="for string:$idPrefix.full">Full text</label>  
 | 
			
		||||
    <label for="text"
 | 
			
		||||
           tal:attributes="for string:$idPrefix.text">Search words:</label>
 | 
			
		||||
    <input type="text" name="text"
 | 
			
		||||
           tal:attributes="name string:$idPrefix.text;
 | 
			
		||||
           tal:attributes="name string:$namePrefix.text;
 | 
			
		||||
                           id string:$idPrefix.text;" />
 | 
			
		||||
    <input type="button" value="+"
 | 
			
		||||
           title="Add search word" /> 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								target.py
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								target.py
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -31,8 +31,10 @@ from zope.interface import implements
 | 
			
		|||
from zope import schema
 | 
			
		||||
from zope.security.proxy import removeSecurityProxy
 | 
			
		||||
 | 
			
		||||
from loops.interfaces import IResource
 | 
			
		||||
from loops.interfaces import IDocument, IMediaAsset
 | 
			
		||||
from zope.app.event.objectevent import ObjectModifiedEvent, Attributes
 | 
			
		||||
from zope.event import notify
 | 
			
		||||
 | 
			
		||||
from loops.interfaces import ILoopsObject, IResource, IDocument, IMediaAsset
 | 
			
		||||
from loops.interfaces import IDocumentView, IMediaAssetView
 | 
			
		||||
from loops.interfaces import IView
 | 
			
		||||
from loops.interfaces import IConcept, IConceptView
 | 
			
		||||
| 
						 | 
				
			
			@ -52,10 +54,13 @@ class TargetProxy(object):
 | 
			
		|||
    @Lazy
 | 
			
		||||
    def target(self):
 | 
			
		||||
        return self.context.target
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    def getTitle(self):
 | 
			
		||||
        return self.target.title
 | 
			
		||||
    def setTitle(self, title): self.target.title = title
 | 
			
		||||
    def setTitle(self, title):
 | 
			
		||||
        self.target.title = title
 | 
			
		||||
        notify(ObjectModifiedEvent(self.target,
 | 
			
		||||
                                   Attributes(ILoopsObject, 'title')))
 | 
			
		||||
    title = property(getTitle, setTitle)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +70,9 @@ class ConceptProxy(TargetProxy):
 | 
			
		|||
    adapts(IConceptView)
 | 
			
		||||
 | 
			
		||||
    def getConceptType(self): return self.target.conceptType
 | 
			
		||||
    def setConceptType(self, conceptType): self.target.conceptType = conceptType
 | 
			
		||||
    def setConceptType(self, conceptType):
 | 
			
		||||
        self.target.conceptType = conceptType
 | 
			
		||||
        notify(ObjectModifiedEvent(self.target, Attributes(IConcept, 'conceptType')))
 | 
			
		||||
    conceptType = property(getConceptType, setConceptType)
 | 
			
		||||
 | 
			
		||||
    def getChildren(self, predicates=None):
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +88,7 @@ class ConceptProxy(TargetProxy):
 | 
			
		|||
class ResourceProxy(TargetProxy):
 | 
			
		||||
 | 
			
		||||
    def setContentType(self, contentType):
 | 
			
		||||
        notify(ObjectModifiedEvent(self.target, Attributes(IResource, 'contentType')))
 | 
			
		||||
        self.target.contentType = contentType
 | 
			
		||||
    def getContentType(self): return self.target.contentType
 | 
			
		||||
    contentType = property(getContentType, setContentType)
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +99,9 @@ class DocumentProxy(ResourceProxy):
 | 
			
		|||
    implements(IDocument)
 | 
			
		||||
    adapts(IDocumentView)
 | 
			
		||||
 | 
			
		||||
    def setData(self, data): self.target.data = data
 | 
			
		||||
    def setData(self, data):
 | 
			
		||||
        self.target.data = data
 | 
			
		||||
        notify(ObjectModifiedEvent(self.target, Attributes(IDocument, 'data')))
 | 
			
		||||
    def getData(self): return self.target.data
 | 
			
		||||
    data = property(getData, setData)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue