This is a pre-production deployment of Warehouse, however changes made here WILL affect the production instance of PyPI.
Latest Version Dependencies status unknown Test status unknown Test coverage unknown
Project Description

\(dolmen.app.search\) provides components to search objects inside a Grok application.

Searchers

\(dolmen.app.search\) introduces a new component : the ISearcher. This component is dedicated in searching and returning a set of objects, using a search term.

The provided API is:

>>> from dolmen.app.search.interfaces import ISearchAPI
>>> interfaceDescription(ISearchAPI)
ISearcher: A component dedicated to search
ICatalogSearcher: A specialized ISearcher querying a catalog

Test environment

In order to test our searchers, we need an operationnal application with at least one index.

We prepare out imports:

>>> import grok
>>> from grok import index
>>> from zope.index.text.interfaces import ISearchableText
>>> from zope.interface import Interface
>>> from zope.schema import TextLine

We create a model that will be cataloged:

>>> class IRipper(Interface):
...   """A serial killer.
...   """
...   searchabletext = TextLine(title=u"Name of the ripper")

>>> class Ripper(grok.Model):
...   grok.implements(IRipper)
...
...   def __init__(self, searchabletext):
...     self.searchabletext = searchabletext

We create a Grok application, that will be out site manager:

>>> class Backstreet(grok.Container, grok.Application):
...   """A dark alley.
...   """

>>> grok.testing.grok_component('application', Backstreet)
True

We define an index that will be the base for our search:

>>> class RipperIndexes(grok.Indexes):
...  grok.site(Backstreet)
...  grok.context(IRipper)
...  searchabletext = index.Text()

>>> grok.testing.grok_component('indexes', RipperIndexes)
True

Now we persist our application and set it as the default site:

>>> from zope.site.hooks import setSite
>>> app = Backstreet()
>>> root = getRootFolder()
>>> root['berner_street'] = app

>>> setSite(app)

The Grok application has created the catalog:

>>> from zope.component import getUtility
>>> from zope.catalog.interfaces import ICatalog
>>> catalog = getUtility(ICatalog)
>>> catalog
<zope.catalog.catalog.Catalog object at ...>

Our index is there:

>>> catalog['searchabletext']
<zope.catalog.text.TextIndex object at ...>
>>> catalog['searchabletext'].documentCount()
0

Indexing

The catalog is ready. Now, if we create a content and persist it, the cataloging mechanism will do the work for us:

>>> jack = Ripper(u"Jack the knife")
>>> grok.notify(grok.ObjectCreatedEvent(jack))
>>> app['jack'] = jack

>>> catalog['searchabletext'].documentCount()
1

The searchabletext is set. That is what is cataloged in our site catalog:

>>> jack.searchabletext
u'Jack the knife'

Searching

An ISearcher can be used as an utility. \(dolmen.app.search\) provides a default implementation of an ICatalogSearcher. This component is used to query the site catalog:

>>> from dolmen.app.search import ICatalogSearcher
>>> searcher = getUtility(ICatalogSearcher, "searcher.sitecatalog")
>>> searcher
<dolmen.app.search.searchers.SiteCatalogSearcher object at ...>
>>> searcher.catalog == catalog
True

The search method of the ICatalogSearcher takes a search term and the name of the index. By default, it uses the \(searchabletext\) index:

>>> result = searcher.search(term="Jack")
>>> result
<dolmen.app.search.sets.PermissionAwareResultSet instance at ...>
>>> list(result)
[<dolmen.app.search.tests.Ripper object at ...>]

If we provide a non existing index name, an error is raised:

>>> result = searcher.search(term="Jack", index="non-existing")
Traceback (most recent call last):
...
ValueError: Index 'non-existing' does not exist

Wildcard

A wildcard can be given, when searching a text index:

>>> result = searcher.search("Ja")
>>> list(result)
[]

>>> result = searcher.search("Ja*")
>>> list(result)
[<dolmen.app.search.tests.Ripper object at ...>]

Permission

By default, our searcher checks the \(zope.View\) permission on the objects of the result set. We can provide another permission explicitly:

>>> result = searcher.search("knife", permission="i-do-not-exist")
>>> list(result)
[]

A \(grok.Permision\) class can be used instead of a string:

>>> from dolmen.app.security import CanViewContent
>>> result = searcher.search("knife", permission=CanViewContent)
>>> list(result)
[<dolmen.app.search.tests.Ripper object at ...>]

If permission is set to None, nothing is checked:

>>> result = searcher.search("knife", permission=None)
>>> list(result)
[<dolmen.app.search.tests.Ripper object at ...>]

View and viewlet

\(dolmen.app.search\) comes with two browser components. A search form viewlet and a result page.

Search viewlet

A search viewlet is registered to display a search form input. In order to test the output of the viewlet, we need a view:

>>> class GasLamp(grok.View):
...   """A view where the air's cold and damp
...   """
...   grok.context(IRipper)

>>> grok.testing.grok_component('view', GasLamp)
True

We get the view to render the viewlet:

>>> from zope.publisher.browser import TestRequest
>>> from zope.component import getMultiAdapter

>>> request = TestRequest()
>>> view = getMultiAdapter((jack, request), name="gaslamp")

The \(Search\) viewlet is registered for the \(dolmen.app.layout.Top\) manager. We construct this manager:

>>> from dolmen.app.layout import Top
>>> manager = Top(jack, request, view)

We can now call, update and render the Search viewlet:

>>> from dolmen.app.search.browser import Search
>>> search = Search(jack, request, view, manager)
>>> search.update()
>>> print search.render()
<form id="searchbox" method="post"
      action="http://127.0.0.1/berner_street/search.result">
  <input type="text" autocomplete="off" name="search_term"
         id="search-widget" value="" />
  <input type="submit" name="search_button"
         id="search-button" title="Search" alt="Search"
         value="Search" />
</form>

Result page

The viewlet posts the data to the \(search.result\) view. This view fetches the \(search_term\) from the request, queries the ICatalogSearcher and displays the results:

>>> request = TestRequest(form = {'search_term': 'jack'})
>>> results = getMultiAdapter((jack, request), name="search.result")
>>> results
<dolmen.app.search.browser.Results object at ...>

>>> results.update()
>>> print results.content()
<div class="search-result">
  <div class="search-header">
    <h1>Search</h1>
    <h3>Found 1 results for jack</h3>
  </div>
  <dl class="search-results content-listing">
    <dt>
      <a href="http://127.0.0.1/berner_street/jack"
         title="jack">
        <span>jack</span>
      </a>
    </dt>
  </dl>
</div>

Changelog

0.4 (2010-11-05)

  • The package now works for Grok 1.2.
  • The icon is now using the “icon” and no longer “contenttype_icon” view.
  • The dependencies have been reviewed and slimmed down.

0.3.1 (2010-07-24)

  • 0.3 release was broken because of missing locales directory.

0.3 (2010-07-24)

  • Added French translation.

0.2.2 (2009-01-08)

  • Declare all dependencies and some cleanup.
  • Require dolmen.content.View permission for Search viewlet.

0.2.1 (2009-12-01)

  • Removed all imports from zope.app.* for intid and catalog. Using now the new packages. This makes dolmen.app.search compatible with grok1.1a2.

0.2 (2009-12-01)

  • Modified the imports to make it compatible with grok 1.1 (ztk 1.0)

0.1 (2009-11-08)

  • Initial release
Release History

Release History

0.4

This version

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.3.1

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.3

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.2.2

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.2.1

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.2

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

Download Files

Download Files

TODO: Brief introduction on what you do with files - including link to relevant help section.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
dolmen.app.search-0.4.tar.gz (9.8 kB) Copy SHA256 Checksum SHA256 Source Nov 5, 2010

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting