source: main/waeup.kofa/trunk/src/waeup/kofa/catalog.py @ 10831

Last change on this file since 10831 was 9847, checked in by Henrik Bettermann, 12 years ago

Forms provide unicode not str values.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.9 KB
RevLine 
[7193]1## $Id: catalog.py 9847 2013-01-09 06:33:17Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
[5090]18"""Components to help cataloging and searching objects.
19"""
[3521]20import grok
[5090]21from hurry.query.interfaces import IQuery
22from hurry.query.query import Query
23from zope.catalog.catalog import ResultSet
[9767]24from zope.catalog.interfaces import ICatalog
25from zope.component import getUtility, queryUtility
26from zope.interface import implementer
[5090]27from zope.intid.interfaces import IIntIds
[9767]28from waeup.kofa.interfaces import (
29    IQueryResultItem, IFilteredQuery, IFilteredCatalogQuery)
[3521]30
[6447]31# not yet used
[9767]32@implementer(IQuery)
[7819]33class KofaQuery(Query):
[6207]34    """A hurry.query-like query that supports also ``apply``.
35    """
36    def apply(self, query):
37        """Get a catalog's BTree set of intids conforming to a query.
38        """
39        return query.apply()
[5090]40
[6207]41    def searchResults(self, query):
42        """Get a set of ZODB objects conforming to a query.
43        """
44        results = self.apply(query)
45        if results is not None:
46            uidutil = getUtility(IIntIds)
47            results = ResultSet(results, uidutil)
48        return results
[5090]49
[7819]50grok.global_utility(KofaQuery)
[5090]51
[6447]52# not yet used
[9767]53@implementer(IQueryResultItem)
[4789]54class QueryResultItem(object):
[6207]55    url = None
56    title = None
57    description = None
[6116]58
[6207]59    def __init__(self, context, view):
60        self.context = context
61        self.url = view.url(context)
62        self.title = context.title
63        self.description = ''
[9767]64
65@implementer(IFilteredQuery)
66class FilteredQueryBase(object):
67    """A filter to find objects that match certain parameters.
[9773]68
69    Parameters are passed to constructor as keyword arguments. The
70    real data retrieval then happens when `query()` is called.
71
72    The `defaults` attribute, a dict, can set certain default values
73    for parameters that are used if the constructor is called without
74    any parameters.
[9767]75    """
76    defaults = dict()
77
78    def __init__(self, **kw):
79        self._kw = dict(self.defaults)
80        self._kw.update(kw)
81        return
82
83    def query(self, context=None):
84        err_msg = 'class %s does not implement the query() method.' % (
85            self.__class__.__name__, )
86        raise NotImplementedError(err_msg)
87
88@implementer(IFilteredCatalogQuery)
89class FilteredCatalogQueryBase(FilteredQueryBase):
[9773]90    """Base for filtered queries based on catalog lookups.
91
92    This type of query asks a catalog to find objects.
93
94    You would normally use this type of query like this:
95
96      >>> query = FilteredCatalogQueryBase(name='bob')
97      >>> objects = query.query()
98
99    The name of the catalog to use can be set via `cat_name`
100    attribute.
101
102    Looked up are all objects that match keywords passed to
103    constructor where the keyword names must match a certain index of
104    the chosen catalog. So, if some catalog has indexes `name` and
105    `age`, then keywords `name='bob', age='12'` would search for all
106    objects with name ``bob`` and age ``12``.
107
108    This query supports single values (exact matches) and ranges of
109    values passed in via ``(min_value, max_value)`` tuples. So,
110    constructor keyword args `name=('a', 'd')` would find objects with
111    name ``alice``, ``bob``, ``d``, but not ``donald``, ``john``, or
112    ``zak``.
113    """
[9767]114    cat_name = None
115
116    def query_catalog(self, catalog):
[9773]117        """Search ``catalog``.
118
119        Use `catalog`, some ``Catalog`` instance, to search objects
120        denoted by constructor keywords.
121        """
[9767]122        query = dict()
123        for idx_name, value in self._kw.items():
[9845]124            if idx_name == 'catalog':
[9843]125                continue
[9847]126            if value is not None and ('session' in idx_name
[9846]127                or 'level' in idx_name):
128                value = int(value)
[9767]129            if not isinstance(value, tuple):
130                value = (value, value)
131            query[idx_name] = value
132        result = catalog.searchResults(**query)
133        return result
134
135    def query(self):
[9773]136        """Perform a query with parameters passed to constructor.
137
138        Returns some iterable, normally a list or a catalog result
139        set.
140        """
[9767]141        catalog = queryUtility(
142            ICatalog, name=self.cat_name, default=None)
143        if catalog is None:
144            return []
145        return self.query_catalog(catalog)
Note: See TracBrowser for help on using the repository browser.