# HG changeset patch # User Thierry Florac # Date 1429100746 -7200 # Node ID 5bc708f1d1863b879a00de69e9436d31a1a4ce32 # Parent 47700a43ef3fb2dee415158b3cf1a8f36e5702d7 Added thesaurus fields indexes diff -r 47700a43ef3f -r 5bc708f1d186 src/pyams_thesaurus/index.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_thesaurus/index.py Wed Apr 15 14:25:46 2015 +0200 @@ -0,0 +1,121 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_thesaurus.interfaces.index import IThesaurusTermFieldIndex, IThesaurusTermsListFieldIndex +from zope.intid.interfaces import IIntIds + +# import packages +from ZODB.broken import Broken +from persistent import Persistent +from pyams_catalog.index import KeywordIndexWithInterface +from pyams_utils.registry import query_utility +from zope.interface import implementer +from zope.schema.fieldproperty import FieldProperty + + +_marker = object() + + +def get_terms(index, term): + terms = [term, ] + if index.include_parents: + terms.extend(term.get_parents()) + if index.include_synonyms: + if term.usage is not None: + terms.append(term.usage) + else: + terms.extend(term.used_for) + return terms + + +@implementer(IThesaurusTermFieldIndex) +class ThesaurusTermFieldIndex(KeywordIndexWithInterface): + """Thesaurus term field index""" + + include_parents = FieldProperty(IThesaurusTermFieldIndex['include_parents']) + include_synonyms = FieldProperty(IThesaurusTermFieldIndex['include_synonyms']) + + def __init__(self, interface, discriminator, family=None, include_parents=False, include_synonyms=False): + super(ThesaurusTermFieldIndex, self).__init__(interface, discriminator, family) + self.include_parents = include_parents + self.include_synonyms = include_synonyms + + def discriminate(self, obj, default): + if self.interface is not None: + obj = self.interface(obj, None) + if obj is None: + return default + + if callable(self.discriminator): + value = self.discriminator(obj, _marker) + else: + value = getattr(obj, self.discriminator, _marker) + if callable(value): + value = value(obj) + + if value is _marker: + return default + + if value: + intids = query_utility(IIntIds) + value = set([intids.register(term) for term in get_terms(self, value)]) + + if isinstance(value, Persistent): + raise ValueError('Catalog cannot index persistent object {0!r}'.format(value)) + + if isinstance(value, Broken): + raise ValueError('Catalog cannot index broken object {0!r}'.format(value)) + + return value + + +@implementer(IThesaurusTermsListFieldIndex) +class ThesaurusTermsListFieldIndex(KeywordIndexWithInterface): + """Thesaurus terms list field index""" + + include_parents = FieldProperty(IThesaurusTermsListFieldIndex['include_parents']) + include_synonyms = FieldProperty(IThesaurusTermsListFieldIndex['include_synonyms']) + + def __init__(self, interface, discriminator, family=None, include_parents=False, include_synonyms=False): + super(ThesaurusTermsListFieldIndex, self).__init__(interface, discriminator, family) + self.include_parents = include_parents + self.include_synonyms = include_synonyms + + def discriminate(self, obj, default): + if self.interface is not None: + obj = self.interface(obj, None) + if obj is None: + return default + + if callable(self.discriminator): + value = self.discriminator(obj, _marker) + else: + value = getattr(obj, self.discriminator, _marker) + if callable(value): + value = value(obj) + + if value is _marker: + return default + + if value: + terms = [] + [terms.extend(get_terms(self, term)) for term in value] + if terms: + intids = query_utility(IIntIds) + value = set([intids.register(term) for term in terms]) + return value