diff --git a/search/README.txt b/search/README.txt
deleted file mode 100755
index fa33f30..0000000
--- a/search/README.txt
+++ /dev/null
@@ -1,239 +0,0 @@
-===================================================================
-loops.search - Provide search functionality for the loops framework
-===================================================================
-
- ($Id$)
-
-
-Let's do some basic set up
-
- >>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
- >>> 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
-ZCML setup):
-
- >>> from loops.concept import Concept
- >>> from loops.type import ConceptType, TypeConcept
- >>> from loops.interfaces import ITypeConcept
- >>> from loops.base import Loops
- >>> from loops.expert.testsetup import TestSite
- >>> t = TestSite(site)
- >>> concepts, resources, views = t.setup()
-
- >>> loopsRoot = site['loops']
- >>> query = concepts['query']
- >>> topic = concepts['topic']
-
-In addition we create a concept that holds the search page and a node
-(page) that links to this concept:
-
- >>> search = concepts['search'] = Concept(u'Search')
- >>> search.conceptType = query
-
- >>> from loops.view import Node
- >>> page = views['page'] = Node('Search Page')
- >>> page.target = search
-
-Search views
-------------
-
-Now we are ready to create a search view object:
-
- >>> from zope.publisher.browser import TestRequest
- >>> from loops.expert.browser.search import Search
- >>> searchView = Search(search, TestRequest())
-
-The search view provides values for identifying the search form itself
-and the parameter rows; the rowNum is auto-incremented, so it should be
-accessed exactly once per row:
-
- >>> searchView.rowNum
- 1
- >>> searchView.rowNum
- 2
-
-The search view provides vocabularies for types that allow the selection
-of types to search for; this needs an ITypeManager adapter registered via
-zcml in real life:
-
- >>> from loops.type import LoopsTypeManager
- >>> component.provideAdapter(LoopsTypeManager)
-
- >>> t = searchView.typesForSearch()
- >>> len(t)
- 14
- >>> t.getTermByToken('loops:resource:*').title
- 'Any Resource'
-
- >>> t = searchView.conceptTypesForSearch()
- >>> len(t)
- 11
- >>> t.getTermByToken('loops:concept:*').title
- 'Any Concept'
-
-To execute the search in the context of a node we have to set up a node
-view for our page. The submitReplacing method returns a JavaScript call
-that will replace the results part on the search page; as this registers
-the dojo library with the view's controller we also have to supply
-a controller attribute for the search view.
-
- >>> from loops.browser.node import NodeView
- >>> request = TestRequest()
- >>> pageView = NodeView(page, request)
-
- >>> from cybertools.browser.liquid.controller import Controller
- >>> searchView.controller = Controller(searchView, request)
-
- >>> searchView.submitReplacing('1.results', '1.search.form', pageView)
- 'submitReplacing("1.results", "1.search.form",
- "http://127.0.0.1/loops/views/page/.target80/@@searchresults.html");...'
-
-Basic (text/title) search
--------------------------
-
-The searchresults.html view, i.e. the SearchResults view class provides the
-result set of the search via its `results` property.
-
-Before accessing the `results` property we have to prepare a
-resource we can search for and index it in the catalog.
-
- >>> from loops.resource import Resource
- >>> rplone = resources['plone'] = Resource()
-
- >>> from zope.app.catalog.interfaces import ICatalog
- >>> from loops import util
- >>> catalog = component.getUtility(ICatalog)
- >>> catalog.index_doc(int(util.getUidForObject(rplone)), rplone)
-
- >>> from loops.expert.browser.search import SearchResults
- >>> form = {'search.2.title': True, 'search.2.text': u'plone'}
- >>> request = TestRequest(form=form)
- >>> resultsView = SearchResults(page, request)
-
- >>> results = list(resultsView.results)
- >>> len(results)
- 1
- >>> results[0].context == rplone
- True
-
- >>> form = {'search.2.title': True, 'search.2.text': u'foo'}
- >>> request = TestRequest(form=form)
- >>> resultsView = SearchResults(page, request)
- >>> len(list(resultsView.results))
- 0
-
-Search via related concepts
----------------------------
-
-We first have to prepare some test concepts (topics); we also assign our test
-resource (rplone) from above to one of the topics:
-
- >>> czope = concepts['zope'] = Concept(u'Zope')
- >>> czope2 = concepts['zope2'] = Concept(u'Zope 2')
- >>> czope3 = concepts['zope3'] = Concept(u'Zope 3')
- >>> cplone = concepts['plone'] = Concept(u'Plone')
- >>> for c in (czope, czope2, czope3, cplone):
- ... c.conceptType = topic
- ... catalog.index_doc(int(util.getUidForObject(c)), c)
- >>> czope.assignChild(czope2)
- >>> czope.assignChild(czope3)
- >>> czope2.assignChild(cplone)
- >>> rplone.assignConcept(cplone)
-
-Now we can fill our search form and execute the query; note that all concepts
-found are listed, plus all their children and all resources associated
-with them:
-
- >>> uid = util.getUidForObject(concepts['zope'])
- >>> form = {'search.3.type': 'loops:concept:topic', 'search.3.text': uid}
- >>> request = TestRequest(form=form)
- >>> resultsView = SearchResults(page, request)
- >>> results = list(resultsView.results)
- >>> len(results)
- 5
- >>> results[0].context.__name__
- u'plone'
-
- >>> uid = util.getUidForObject(concepts['zope3'])
- >>> form = {'search.3.type': 'loops:concept:topic', 'search.3.text': uid}
- >>> request = TestRequest(form=form)
- >>> resultsView = SearchResults(page, request)
- >>> results = list(resultsView.results)
- >>> len(results)
- 1
- >>> results[0].context.__name__
- u'zope3'
-
-To support easy entry of concepts to search for we can preselect the available
-concepts (optionally restricted to a certain type) by entering text parts
-of the concepts' titles:
-
- >>> form = {'searchType': 'loops:concept:topic', 'name': u'zope'}
- >>> request = TestRequest(form=form)
- >>> view = Search(page, request)
- >>> view.listConcepts()
- u"{identifier: 'id', items: [{label: 'Zope (Topic)', name: 'Zope', id: '85'}, {label: 'Zope 2 (Topic)', name: 'Zope 2', id: '87'}, {label: 'Zope 3 (Topic)', name: 'Zope 3', id: '89'}]}"
-
-Preset Concept Types on Search Forms
-------------------------------------
-
-Often we want to include certain types in our search. We can instruct
-the search form to include lines for these types by giving these types
-a certain qualifier, via the option attribute of the type interface.
-
-Let's start with a new type, the customer type.
-
- >>> customer = concepts['customer']
- >>> custType = ITypeConcept(customer)
- >>> custType.options
- []
-
- >>> cust1 = concepts['cust1']
- >>> cust2 = concepts['cust2']
- >>> for c in (cust1, cust2):
- ... c.conceptType = customer
- ... catalog.index_doc(int(util.getUidForObject(c)), c)
-
- >>> from cybertools.typology.interfaces import IType
- >>> IType(cust1).qualifiers
- ('concept',)
-
- >>> searchView = Search(search, TestRequest())
- >>> list(searchView.presetSearchTypes)
- []
-
-We can now add a 'search' qualifier to the customer type's options
-and thus include the customer type in the preset search types.
-
- >>> custType.options = ('qualifier:search',)
- >>> IType(cust1).qualifiers
- ('concept', 'search')
- >>> searchView = Search(search, TestRequest())
- >>> list(searchView.presetSearchTypes)
- [{'token': 'loops:concept:customer', 'title': u'Customer'}]
-
- >>> searchView.conceptsForType('loops:concept:customer')
- [{'token': 'none', 'title': u'not selected'},
- {'token': '58', 'title': u'Customer 1'},
- {'token': '60', 'title': u'Customer 2'},
- {'token': '62', 'title': u'Customer 3'}]
-
-Let's use this new search option for querying:
-
- >>> form = {'search.4.text_selected': u'58'}
- >>> resultsView = SearchResults(page, TestRequest(form=form))
- >>> results = list(resultsView.results)
- >>> results[0].title
- u'Customer 1'
-
-
-Automatic Filtering
--------------------
-
-TODO - more to come...
-
diff --git a/search/__init__.py b/search/__init__.py
deleted file mode 100644
index 4bc90fb..0000000
--- a/search/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-"""
-$Id$
-"""
-
diff --git a/search/browser.py b/search/browser.py
deleted file mode 100644
index 982a278..0000000
--- a/search/browser.py
+++ /dev/null
@@ -1,295 +0,0 @@
-#
-# Copyright (c) 2011 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
-#
-
-"""
-Definition of basic view classes and other browser related stuff for the
-loops.search package.
-
-$Id: browser.py 4160 2011-02-07 16:53:08Z helmutm $
-"""
-
-from zope import interface, component
-from zope import traversing
-from zope.app.pagetemplate import ViewPageTemplateFile
-from zope.cachedescriptors.property import Lazy
-from zope.formlib.namedtemplate import NamedTemplate, NamedTemplateImplementation
-from zope.i18nmessageid import MessageFactory
-
-from cybertools.ajax import innerHtml
-from cybertools.relation.interfaces import IRelationRegistry
-from cybertools.stateful.interfaces import IStateful, IStatesDefinition
-from cybertools.typology.interfaces import ITypeManager
-from loops.browser.common import BaseView
-from loops.browser.node import NodeView
-from loops.common import adapted, AdapterBase
-#from loops.expert.browser.search import searchMacrosTemplate as search_template
-from loops.expert.concept import ConceptQuery, FullQuery
-from loops.interfaces import IResource
-from loops.organize.personal.browser.filter import FilterView
-from loops import util
-from loops.util import _
-
-
-#search_template = ViewPageTemplateFile('search.pt')
-
-
-class Search(BaseView):
-
- maxRowNum = 0
-
- @Lazy
- def search_macros(self):
- return self.controller.getTemplateMacros('search', search_template)
-
- @Lazy
- def macro(self):
- return self.search_macros['search']
-
- @property
- def rowNum(self):
- """ Return the rowNum to be used for identifying the current search
- parameter row.
- """
- n = self.request.get('loops.rowNum', 0)
- if n: # if given directly we don't use the calculation
- return n
- n = (self.maxRowNum or self.request.get('loops.maxRowNum', 0)) + 1
- self.maxRowNum = n
- return n
-
- @Lazy
- def presetSearchTypes(self):
- """ Return a list of concept type info dictionaries (see BaseView)
- that should be displayed on a separate search parameter row.
- """
- #return ITypeManager(self.context).listTypes(include=('search',))
- return self.listTypesForSearch(include=('search',))
-
- def conceptsForType(self, token):
- result = ConceptQuery(self).query(type=token)
- fv = FilterView(self.context, self.request)
- result = fv.apply(result)
- result.sort(key=lambda x: x.title)
- noSelection = dict(token='none', title=u'not selected')
- return [noSelection] + [dict(title=adapted(o, self.languageInfo).title,
- token=util.getUidForObject(o))
- for o in result]
-
- def initDojo(self):
- self.registerDojo()
- cm = self.controller.macros
- jsCall = ('dojo.require("dojo.parser");'
- 'dojo.require("dijit.form.FilteringSelect");'
- 'dojo.require("dojox.data.QueryReadStore");')
- cm.register('js-execute', jsCall, jsCall=jsCall)
-
- def listConcepts(self, filterMethod=None):
- """ Used for dijit.FilteringSelect.
- """
- request = self.request
- request.response.setHeader('Content-Type', 'text/plain; charset=UTF-8')
- title = request.get('name')
- if title == '*':
- title = None
- types = request.get('searchType')
- data = []
- if title or types:
- if title is not None:
- title = title.replace('(', ' ').replace(')', ' ').replace(' -', ' ')
- #title = title.split(' ', 1)[0]
- if not types:
- types = ['loops:concept:*']
- if not isinstance(types, (list, tuple)):
- types = [types]
- for type in types:
- result = self.executeQuery(title=title or None, type=type,
- exclude=('hidden',))
- fv = FilterView(self.context, self.request)
- result = fv.apply(result)
- for o in result:
- if o.getLoopsRoot() == self.loopsRoot:
- adObj = adapted(o, self.languageInfo)
- if filterMethod is not None and not filterMethod(adObj):
- continue
- name = self.getRowName(adObj)
- if title and title.endswith('*'):
- title = title[:-1]
- sort = ((title and name.startswith(title) and '0' or '1')
- + name.lower())
- if o.conceptType is None:
- raise ValueError('Concept Type missing for %r.' % name)
- data.append({'label': self.getRowLabel(adObj, name),
- 'name': name,
- 'id': util.getUidForObject(o),
- 'sort': sort})
- data.sort(key=lambda x: x['sort'])
- if not title:
- data.insert(0, {'label': '', 'name': '', 'id': ''})
- json = []
- for item in data[:100]:
- json.append("{label: '%s', name: '%s', id: '%s'}" %
- (item['label'], item['name'], item['id']))
- json = "{identifier: 'id', items: [%s]}" % ', '.join(json)
- #print '***', json
- return json
-
- def executeQuery(self, **kw):
- return ConceptQuery(self).query(**kw)
-
- def getRowName(self, obj):
- return obj.getLongTitle()
-
- def getRowLabel(self, obj, name=None):
- if isinstance(obj, AdapterBase):
- obj = obj.context
- if name is None:
- name = obj.title
- return '%s (%s)' % (name, obj.conceptType.title)
-
- @Lazy
- def statesDefinitions(self):
- return [component.getUtility(IStatesDefinition, name=n)
- for n in self.globalOptions('organize.stateful.resource', ())]
-
- @Lazy
- def selectedStates(self):
- result = {}
- for k, v in self.request.form.items():
- if k.startswith('state.') and v:
- result[k] = v
- return result
-
- def submitReplacing(self, targetId, formId, view):
- self.registerDojo()
- return 'submitReplacing("%s", "%s", "%s"); return false;' % (
- targetId, formId,
- '%s/.target%s/@@searchresults.html' % (view.url, self.uniqueId))
-
- @Lazy
- def results(self):
- form = self.request.form
- type = form.get('search.1.text', 'loops:*')
- text = form.get('search.2.text')
- if text is not None:
- text = util.toUnicode(text, encoding='ISO8859-15') # IE hack!!!
- useTitle = form.get('search.2.title')
- useFull = form.get('search.2.full')
- conceptType = form.get('search.3.type', 'loops:concept:*')
- #conceptTitle = form.get('search.3.text')
- #if conceptTitle is not None:
- # conceptTitle = util.toUnicode(conceptTitle, encoding='ISO8859-15')
- conceptUid = form.get('search.3.text')
- result = FullQuery(self).query(text=text, type=type,
- useTitle=useTitle, useFull=useFull,
- #conceptTitle=conceptTitle,
- conceptUid=conceptUid,
- conceptType=conceptType)
- rowNum = 4
- while rowNum < 10:
- addCriteria = form.get('search.%i.text_selected' % rowNum)
- rowNum += 1
- if not addCriteria:
- break
- if addCriteria == 'none':
- continue
- addSelection = FullQuery(self).query(text=text, type=type,
- useTitle=useTitle, useFull=useFull,
- conceptUid=addCriteria)
- if result:
- result = [r for r in result if r in addSelection]
- else:
- result = addSelection
- result = [r for r in result if self.checkStates(r)]
- fv = FilterView(self.context, self.request)
- result = fv.apply(result)
- result = sorted(result, key=lambda x: x.title.lower())
- return self.viewIterator(result)
-
- def checkStates(self, obj):
- if not IResource.providedBy(obj):
- return True
- for std, states in self.selectedStates.items():
- if std.startswith('state.resource.'):
- std = std[len('state.resource.'):]
- else:
- continue
- stf = component.queryAdapter(obj, IStateful, name=std)
- if stf is None:
- continue
- for state in states:
- if stf.state == state:
- break
- else:
- return False
- return True
-
-
-#class SearchResults(BaseView):
-class SearchResults(NodeView):
- """ Provides results as inner HTML """
-
- @Lazy
- def search_macros(self):
- return self.controller.getTemplateMacros('search', search_template)
-
- @Lazy
- def macro(self):
- return self.search_macros['search_results']
-
- def __call__(self):
- return innerHtml(self)
-
- @Lazy
- def results(self):
- form = self.request.form
- type = form.get('search.1.text', 'loops:*')
- text = form.get('search.2.text')
- if text is not None:
- text = util.toUnicode(text, encoding='ISO8859-15') # IE hack!!!
- useTitle = form.get('search.2.title')
- useFull = form.get('search.2.full')
- conceptType = form.get('search.3.type', 'loops:concept:*')
- #conceptTitle = form.get('search.3.text')
- #if conceptTitle is not None:
- # conceptTitle = util.toUnicode(conceptTitle, encoding='ISO8859-15')
- conceptUid = form.get('search.3.text')
- result = FullQuery(self).query(text=text, type=type,
- useTitle=useTitle, useFull=useFull,
- #conceptTitle=conceptTitle,
- conceptUid=conceptUid,
- conceptType=conceptType)
- rowNum = 4
- while rowNum < 10:
- addCriteria = form.get('search.%i.text_selected' % rowNum)
- rowNum += 1
- if not addCriteria:
- break
- if addCriteria == 'none':
- continue
- addSelection = FullQuery(self).query(text=text, type=type,
- useTitle=useTitle, useFull=useFull,
- conceptUid=addCriteria)
- if result:
- result = [r for r in result if r in addSelection]
- else:
- result = addSelection
- fv = FilterView(self.context, self.request)
- result = fv.apply(result)
- result = sorted(result, key=lambda x: x.title.lower())
- return self.viewIterator(result)
-
diff --git a/search/configure.zcml b/search/configure.zcml
deleted file mode 100644
index cb773cb..0000000
--- a/search/configure.zcml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
- Search
-
-
-