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

Last change on this file since 10843 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
Line 
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##
18"""Components to help cataloging and searching objects.
19"""
20import grok
21from hurry.query.interfaces import IQuery
22from hurry.query.query import Query
23from zope.catalog.catalog import ResultSet
24from zope.catalog.interfaces import ICatalog
25from zope.component import getUtility, queryUtility
26from zope.interface import implementer
27from zope.intid.interfaces import IIntIds
28from waeup.kofa.interfaces import (
29    IQueryResultItem, IFilteredQuery, IFilteredCatalogQuery)
30
31# not yet used
32@implementer(IQuery)
33class KofaQuery(Query):
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()
40
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
49
50grok.global_utility(KofaQuery)
51
52# not yet used
53@implementer(IQueryResultItem)
54class QueryResultItem(object):
55    url = None
56    title = None
57    description = None
58
59    def __init__(self, context, view):
60        self.context = context
61        self.url = view.url(context)
62        self.title = context.title
63        self.description = ''
64
65@implementer(IFilteredQuery)
66class FilteredQueryBase(object):
67    """A filter to find objects that match certain parameters.
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.
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):
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    """
114    cat_name = None
115
116    def query_catalog(self, catalog):
117        """Search ``catalog``.
118
119        Use `catalog`, some ``Catalog`` instance, to search objects
120        denoted by constructor keywords.
121        """
122        query = dict()
123        for idx_name, value in self._kw.items():
124            if idx_name == 'catalog':
125                continue
126            if value is not None and ('session' in idx_name
127                or 'level' in idx_name):
128                value = int(value)
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):
136        """Perform a query with parameters passed to constructor.
137
138        Returns some iterable, normally a list or a catalog result
139        set.
140        """
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.