|
1 # |
|
2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net> |
|
3 # All Rights Reserved. |
|
4 # |
|
5 # This software is subject to the provisions of the Zope Public License, |
|
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
10 # FOR A PARTICULAR PURPOSE. |
|
11 # |
|
12 |
|
13 __docformat__ = 'restructuredtext' |
|
14 |
|
15 |
|
16 # import standard library |
|
17 |
|
18 # import interfaces |
|
19 from pyams_thesaurus.interfaces.index import IThesaurusTermFieldIndex, IThesaurusTermsListFieldIndex |
|
20 from zope.intid.interfaces import IIntIds |
|
21 |
|
22 # import packages |
|
23 from ZODB.broken import Broken |
|
24 from persistent import Persistent |
|
25 from pyams_catalog.index import KeywordIndexWithInterface |
|
26 from pyams_utils.registry import query_utility |
|
27 from zope.interface import implementer |
|
28 from zope.schema.fieldproperty import FieldProperty |
|
29 |
|
30 |
|
31 _marker = object() |
|
32 |
|
33 |
|
34 def get_terms(index, term): |
|
35 terms = [term, ] |
|
36 if index.include_parents: |
|
37 terms.extend(term.get_parents()) |
|
38 if index.include_synonyms: |
|
39 if term.usage is not None: |
|
40 terms.append(term.usage) |
|
41 else: |
|
42 terms.extend(term.used_for) |
|
43 return terms |
|
44 |
|
45 |
|
46 @implementer(IThesaurusTermFieldIndex) |
|
47 class ThesaurusTermFieldIndex(KeywordIndexWithInterface): |
|
48 """Thesaurus term field index""" |
|
49 |
|
50 include_parents = FieldProperty(IThesaurusTermFieldIndex['include_parents']) |
|
51 include_synonyms = FieldProperty(IThesaurusTermFieldIndex['include_synonyms']) |
|
52 |
|
53 def __init__(self, interface, discriminator, family=None, include_parents=False, include_synonyms=False): |
|
54 super(ThesaurusTermFieldIndex, self).__init__(interface, discriminator, family) |
|
55 self.include_parents = include_parents |
|
56 self.include_synonyms = include_synonyms |
|
57 |
|
58 def discriminate(self, obj, default): |
|
59 if self.interface is not None: |
|
60 obj = self.interface(obj, None) |
|
61 if obj is None: |
|
62 return default |
|
63 |
|
64 if callable(self.discriminator): |
|
65 value = self.discriminator(obj, _marker) |
|
66 else: |
|
67 value = getattr(obj, self.discriminator, _marker) |
|
68 if callable(value): |
|
69 value = value(obj) |
|
70 |
|
71 if value is _marker: |
|
72 return default |
|
73 |
|
74 if value: |
|
75 intids = query_utility(IIntIds) |
|
76 value = set([intids.register(term) for term in get_terms(self, value)]) |
|
77 |
|
78 if isinstance(value, Persistent): |
|
79 raise ValueError('Catalog cannot index persistent object {0!r}'.format(value)) |
|
80 |
|
81 if isinstance(value, Broken): |
|
82 raise ValueError('Catalog cannot index broken object {0!r}'.format(value)) |
|
83 |
|
84 return value |
|
85 |
|
86 |
|
87 @implementer(IThesaurusTermsListFieldIndex) |
|
88 class ThesaurusTermsListFieldIndex(KeywordIndexWithInterface): |
|
89 """Thesaurus terms list field index""" |
|
90 |
|
91 include_parents = FieldProperty(IThesaurusTermsListFieldIndex['include_parents']) |
|
92 include_synonyms = FieldProperty(IThesaurusTermsListFieldIndex['include_synonyms']) |
|
93 |
|
94 def __init__(self, interface, discriminator, family=None, include_parents=False, include_synonyms=False): |
|
95 super(ThesaurusTermsListFieldIndex, self).__init__(interface, discriminator, family) |
|
96 self.include_parents = include_parents |
|
97 self.include_synonyms = include_synonyms |
|
98 |
|
99 def discriminate(self, obj, default): |
|
100 if self.interface is not None: |
|
101 obj = self.interface(obj, None) |
|
102 if obj is None: |
|
103 return default |
|
104 |
|
105 if callable(self.discriminator): |
|
106 value = self.discriminator(obj, _marker) |
|
107 else: |
|
108 value = getattr(obj, self.discriminator, _marker) |
|
109 if callable(value): |
|
110 value = value(obj) |
|
111 |
|
112 if value is _marker: |
|
113 return default |
|
114 |
|
115 if value: |
|
116 terms = [] |
|
117 [terms.extend(get_terms(self, term)) for term in value] |
|
118 if terms: |
|
119 intids = query_utility(IIntIds) |
|
120 value = set([intids.register(term) for term in terms]) |
|
121 return value |