rer.solrpush 1.3.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rer/solrpush/__init__.py +7 -0
- rer/solrpush/adapters/__init__.py +1 -0
- rer/solrpush/adapters/configure.zcml +13 -0
- rer/solrpush/adapters/file.py +52 -0
- rer/solrpush/adapters/rss_feed.py +28 -0
- rer/solrpush/behaviors/__init__.py +0 -0
- rer/solrpush/behaviors/configure.zcml +16 -0
- rer/solrpush/behaviors/solr_fields.py +41 -0
- rer/solrpush/browser/__init__.py +0 -0
- rer/solrpush/browser/configure.zcml +111 -0
- rer/solrpush/browser/controlpanel.py +96 -0
- rer/solrpush/browser/elevate_settings.py +35 -0
- rer/solrpush/browser/maintenance.py +476 -0
- rer/solrpush/browser/query_debug.py +12 -0
- rer/solrpush/browser/querybuilder.py +168 -0
- rer/solrpush/browser/scales.py +80 -0
- rer/solrpush/browser/static/.gitkeep +0 -0
- rer/solrpush/browser/static/dist/dev/main.js +58240 -0
- rer/solrpush/browser/static/dist/dev/main.js.map +180 -0
- rer/solrpush/browser/static/dist/prod/main.js +9604 -0
- rer/solrpush/browser/static/dist/prod/main.js.map +1 -0
- rer/solrpush/browser/static/javascripts/FacetsContainer/index.js +46 -0
- rer/solrpush/browser/static/javascripts/ProgressBar/index.js +40 -0
- rer/solrpush/browser/static/javascripts/ProgressBarContainer/index.js +66 -0
- rer/solrpush/browser/static/javascripts/index.js +14 -0
- rer/solrpush/browser/static/package.json +13 -0
- rer/solrpush/browser/static/styles.css +22 -0
- rer/solrpush/browser/static/styles.css.map +1 -0
- rer/solrpush/browser/static/styles.scss +27 -0
- rer/solrpush/browser/static/yarn.lock +1408 -0
- rer/solrpush/browser/templates/controlpanel_layout.pt +49 -0
- rer/solrpush/browser/templates/query_debug.pt +17 -0
- rer/solrpush/browser/templates/reindex_solr.pt +35 -0
- rer/solrpush/configure.zcml +81 -0
- rer/solrpush/indexer.py +120 -0
- rer/solrpush/interfaces/__init__.py +8 -0
- rer/solrpush/interfaces/adapter.py +13 -0
- rer/solrpush/interfaces/elevate.py +98 -0
- rer/solrpush/interfaces/layer.py +6 -0
- rer/solrpush/interfaces/queueprocessor.py +6 -0
- rer/solrpush/interfaces/settings.py +194 -0
- rer/solrpush/locales/README.rst +37 -0
- rer/solrpush/locales/__init__.py +0 -0
- rer/solrpush/locales/en/LC_MESSAGES/rer.solrpush.mo +0 -0
- rer/solrpush/locales/en/LC_MESSAGES/rer.solrpush.po +399 -0
- rer/solrpush/locales/it/LC_MESSAGES/rer.solrpush.mo +0 -0
- rer/solrpush/locales/it/LC_MESSAGES/rer.solrpush.po +399 -0
- rer/solrpush/locales/rer.solrpush.pot +402 -0
- rer/solrpush/locales/update.py +71 -0
- rer/solrpush/locales/update.sh +12 -0
- rer/solrpush/parser.py +211 -0
- rer/solrpush/permissions.zcml +18 -0
- rer/solrpush/profiles/default/actions.xml +21 -0
- rer/solrpush/profiles/default/browserlayer.xml +7 -0
- rer/solrpush/profiles/default/catalog.xml +4 -0
- rer/solrpush/profiles/default/controlpanel.xml +31 -0
- rer/solrpush/profiles/default/metadata.xml +8 -0
- rer/solrpush/profiles/default/registry/bundle.xml +25 -0
- rer/solrpush/profiles/default/registry/criteria.xml +55 -0
- rer/solrpush/profiles/default/registry/settings.xml +6 -0
- rer/solrpush/profiles/default/rolemap.xml +13 -0
- rer/solrpush/profiles/default/types/Document.xml +12 -0
- rer/solrpush/profiles/to_1100/componentregistry.xml +9 -0
- rer/solrpush/profiles/to_1100/metadata.xml +5 -0
- rer/solrpush/profiles/to_1300/controlpanel.xml +13 -0
- rer/solrpush/profiles/to_1300/registry.xml +5 -0
- rer/solrpush/profiles/uninstall/browserlayer.xml +7 -0
- rer/solrpush/profiles/uninstall/controlpanel.xml +21 -0
- rer/solrpush/profiles/uninstall/registry.xml +17 -0
- rer/solrpush/restapi/__init__.py +0 -0
- rer/solrpush/restapi/configure.zcml +8 -0
- rer/solrpush/restapi/services/__init__.py +0 -0
- rer/solrpush/restapi/services/configure.zcml +8 -0
- rer/solrpush/restapi/services/elevate_schema/__init__.py +0 -0
- rer/solrpush/restapi/services/elevate_schema/configure.zcml +14 -0
- rer/solrpush/restapi/services/elevate_schema/get.py +12 -0
- rer/solrpush/restapi/services/solr_search/__init__.py +0 -0
- rer/solrpush/restapi/services/solr_search/batch.py +129 -0
- rer/solrpush/restapi/services/solr_search/configure.zcml +14 -0
- rer/solrpush/restapi/services/solr_search/get.py +25 -0
- rer/solrpush/restapi/services/solr_search/solr_search_handler.py +86 -0
- rer/solrpush/setuphandlers.py +20 -0
- rer/solrpush/testing.py +161 -0
- rer/solrpush/tests/__init__.py +0 -0
- rer/solrpush/tests/docs/example.docx +0 -0
- rer/solrpush/tests/docs/example.ods +0 -0
- rer/solrpush/tests/docs/example.pdf +0 -0
- rer/solrpush/tests/docs/plone_logo.png +0 -0
- rer/solrpush/tests/test_behaviors.py +61 -0
- rer/solrpush/tests/test_elevate.py +124 -0
- rer/solrpush/tests/test_events.py +181 -0
- rer/solrpush/tests/test_image_tags.py +85 -0
- rer/solrpush/tests/test_maintenance.py +165 -0
- rer/solrpush/tests/test_querybuilder.py +272 -0
- rer/solrpush/tests/test_restapi_search.py +127 -0
- rer/solrpush/tests/test_search.py +177 -0
- rer/solrpush/tests/test_setup.py +67 -0
- rer/solrpush/tests/test_solr_interface.py +359 -0
- rer/solrpush/tests/test_tika.py +85 -0
- rer/solrpush/tests/test_vocabularies.py +113 -0
- rer/solrpush/upgrades.py +76 -0
- rer/solrpush/upgrades.zcml +86 -0
- rer/solrpush/utils/__init__.py +6 -0
- rer/solrpush/utils/solr_common.py +122 -0
- rer/solrpush/utils/solr_indexer.py +295 -0
- rer/solrpush/utils/solr_search.py +352 -0
- rer/solrpush/vocabularies.py +50 -0
- rer.solrpush-1.3.4-py3.10-nspkg.pth +1 -0
- rer.solrpush-1.3.4.dist-info/LICENSE.GPL +339 -0
- rer.solrpush-1.3.4.dist-info/LICENSE.rst +15 -0
- rer.solrpush-1.3.4.dist-info/METADATA +507 -0
- rer.solrpush-1.3.4.dist-info/RECORD +116 -0
- rer.solrpush-1.3.4.dist-info/WHEEL +5 -0
- rer.solrpush-1.3.4.dist-info/entry_points.txt +5 -0
- rer.solrpush-1.3.4.dist-info/namespace_packages.txt +1 -0
- rer.solrpush-1.3.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from plone import api
|
|
3
|
+
from rer.solrpush import _
|
|
4
|
+
from rer.solrpush.interfaces import IElevateSettings
|
|
5
|
+
from zope.i18n import translate
|
|
6
|
+
from rer.solrpush.utils.solr_common import get_solr_connection
|
|
7
|
+
from rer.solrpush.utils.solr_common import get_setting
|
|
8
|
+
from rer.solrpush.utils.solr_common import get_index_fields
|
|
9
|
+
from rer.solrpush.interfaces.settings import IRerSolrpushSettings
|
|
10
|
+
from rer.solrpush.utils.solr_indexer import parse_date_str
|
|
11
|
+
from DateTime import DateTime
|
|
12
|
+
from pysolr import safe_urlencode
|
|
13
|
+
from zope.annotation.interfaces import IAnnotations
|
|
14
|
+
from zope.globalrequest import getRequest
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
import json
|
|
18
|
+
import re
|
|
19
|
+
import requests
|
|
20
|
+
import six
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
TRIM = re.compile(r"\s+")
|
|
26
|
+
ESCAPE_CHARS_RE = re.compile(r'(?<!\\)(?P<char>[&|+\-!(){}[\]^"~*?:])')
|
|
27
|
+
|
|
28
|
+
# HELPER METHODS
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def fix_value(value, index_type="", wrap=True):
|
|
32
|
+
operator = "or"
|
|
33
|
+
if isinstance(value, dict):
|
|
34
|
+
query = value.get("query", "")
|
|
35
|
+
range = value.get("range", "")
|
|
36
|
+
operator = value.get("operator", "or")
|
|
37
|
+
if not query:
|
|
38
|
+
return ""
|
|
39
|
+
if range:
|
|
40
|
+
if range == "min":
|
|
41
|
+
value = "[{} TO *]".format(parse_date_str(query))
|
|
42
|
+
if range == "max":
|
|
43
|
+
value = "[* TO {}]".format(parse_date_str(query))
|
|
44
|
+
if range == "minmax":
|
|
45
|
+
value = "[{} TO {}]".format(
|
|
46
|
+
parse_date_str(query[0]), parse_date_str(query[1])
|
|
47
|
+
)
|
|
48
|
+
return value
|
|
49
|
+
else:
|
|
50
|
+
value = query
|
|
51
|
+
if isinstance(value, DateTime):
|
|
52
|
+
return "[{} TO *]".format(parse_date_str(value))
|
|
53
|
+
if isinstance(value, six.string_types):
|
|
54
|
+
if index_type == "date":
|
|
55
|
+
if "TO" not in value:
|
|
56
|
+
return "[{} TO *]".format(parse_date_str(value))
|
|
57
|
+
else:
|
|
58
|
+
return value
|
|
59
|
+
return escape_special_characters(value, wrap)
|
|
60
|
+
elif isinstance(value, list):
|
|
61
|
+
join_str = " {} ".format(operator.upper())
|
|
62
|
+
return "({})".format(
|
|
63
|
+
join_str.join([escape_special_characters(x, wrap) for x in value])
|
|
64
|
+
)
|
|
65
|
+
logger.warning(
|
|
66
|
+
"[fix_value]: unable to escape value: {}. skipping".format(value)
|
|
67
|
+
)
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def escape_special_characters(value, wrap):
|
|
72
|
+
new_value = ESCAPE_CHARS_RE.sub(r"\\\g<char>", value)
|
|
73
|
+
if six.PY2 and isinstance(new_value, six.string_types):
|
|
74
|
+
try:
|
|
75
|
+
new_value = new_value.encode("utf-8")
|
|
76
|
+
except UnicodeDecodeError:
|
|
77
|
+
pass
|
|
78
|
+
if wrap:
|
|
79
|
+
return '"{}"'.format(new_value)
|
|
80
|
+
return new_value
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def set_sort_parameter(query):
|
|
84
|
+
sort_on = query.get("sort_on")
|
|
85
|
+
if sort_on == "sortable_title":
|
|
86
|
+
sort_on = "Title"
|
|
87
|
+
sort_order = query.get("sort_order", "asc")
|
|
88
|
+
if sort_order in ["reverse", "descending"]:
|
|
89
|
+
sort_order = "desc"
|
|
90
|
+
if sort_order in ["ascending"]:
|
|
91
|
+
sort_order = "asc"
|
|
92
|
+
return "{sort_on} {sort_order}".format(
|
|
93
|
+
sort_on=sort_on, sort_order=sort_order
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def generate_query(
|
|
98
|
+
query,
|
|
99
|
+
fl=None,
|
|
100
|
+
facets=False,
|
|
101
|
+
facet_fields=["Subject", "portal_type"],
|
|
102
|
+
):
|
|
103
|
+
solr_query = {
|
|
104
|
+
"q": "",
|
|
105
|
+
"fq": [],
|
|
106
|
+
"facet": facets and "true" or "false",
|
|
107
|
+
"start": query.get("b_start", 0),
|
|
108
|
+
"rows": query.get("b_size", 20),
|
|
109
|
+
"json.nl": "arrmap",
|
|
110
|
+
}
|
|
111
|
+
solr_query.update(extract_from_query(query=query))
|
|
112
|
+
|
|
113
|
+
if not solr_query["q"]:
|
|
114
|
+
solr_query["q"] = "*:*"
|
|
115
|
+
if "sort_on" in query:
|
|
116
|
+
solr_query["sort"] = set_sort_parameter(query)
|
|
117
|
+
if facets:
|
|
118
|
+
solr_query["facet.field"] = facet_fields
|
|
119
|
+
solr_query["facet.mincount"] = 1
|
|
120
|
+
solr_query["facet.limit"] = -1
|
|
121
|
+
if fl:
|
|
122
|
+
if "UID" not in fl:
|
|
123
|
+
# we need it because if we ask for [elevated] value, solr returns
|
|
124
|
+
# error if we don't ask also the primary key
|
|
125
|
+
if isinstance(fl, six.text_type):
|
|
126
|
+
fl = "{} UID".format(fl)
|
|
127
|
+
elif isinstance(fl, list):
|
|
128
|
+
fl.append("UID")
|
|
129
|
+
solr_query["fl"] = fl
|
|
130
|
+
|
|
131
|
+
solr_query.update(add_query_tweaks())
|
|
132
|
+
# elevate
|
|
133
|
+
elevate = manage_elevate(query=query)
|
|
134
|
+
if elevate.get("enableElevation", False):
|
|
135
|
+
solr_query.update(manage_elevate(query=query))
|
|
136
|
+
if "fl" not in solr_query:
|
|
137
|
+
solr_query["fl"] = "* [elevated]"
|
|
138
|
+
else:
|
|
139
|
+
if "[elevated]" not in solr_query["fl"]:
|
|
140
|
+
if isinstance(solr_query["fl"], six.text_type):
|
|
141
|
+
solr_query["fl"] = "{} [elevated]".format(solr_query["fl"])
|
|
142
|
+
elif isinstance(solr_query["fl"], list):
|
|
143
|
+
solr_query["fl"].append("[elevated]")
|
|
144
|
+
return solr_query
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def manage_elevate(query):
|
|
148
|
+
params = {}
|
|
149
|
+
params["enableElevation"] = "false"
|
|
150
|
+
searchableText = query.get("SearchableText", "").rstrip("*")
|
|
151
|
+
if not searchableText:
|
|
152
|
+
return params
|
|
153
|
+
if not searchableText.replace(" ", ""):
|
|
154
|
+
return params
|
|
155
|
+
elevate_schema = extract_elevate_schema(query=query)
|
|
156
|
+
|
|
157
|
+
if not elevate_schema:
|
|
158
|
+
return params
|
|
159
|
+
try:
|
|
160
|
+
if six.PY2:
|
|
161
|
+
text = (
|
|
162
|
+
TRIM.sub(" ", searchableText).strip().decode("utf-8").lower()
|
|
163
|
+
)
|
|
164
|
+
else:
|
|
165
|
+
text = TRIM.sub(" ", searchableText).strip().lower()
|
|
166
|
+
except Exception:
|
|
167
|
+
logger.exception("error parsing %r", searchableText)
|
|
168
|
+
text = None
|
|
169
|
+
if text:
|
|
170
|
+
for config in elevate_schema:
|
|
171
|
+
# exact match
|
|
172
|
+
# if text == s:
|
|
173
|
+
|
|
174
|
+
# contains
|
|
175
|
+
# if s in text:
|
|
176
|
+
|
|
177
|
+
# contains regexp
|
|
178
|
+
for word in config.get("text", []):
|
|
179
|
+
if re.search("(^|\s+)" + word + "(\s+|$)", text): # noqa
|
|
180
|
+
uids = [x.get("UID", "") for x in config.get("uid", [])]
|
|
181
|
+
params["enableElevation"] = "true"
|
|
182
|
+
params["elevateIds"] = ",".join(uids)
|
|
183
|
+
break
|
|
184
|
+
return params
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def extract_elevate_schema(query):
|
|
188
|
+
"""
|
|
189
|
+
If no site_name is passed in query and remote_elevate_schema is set,
|
|
190
|
+
return the schema from remote site.
|
|
191
|
+
"""
|
|
192
|
+
local_schema_json = get_setting(
|
|
193
|
+
field="elevate_schema", interface=IElevateSettings
|
|
194
|
+
)
|
|
195
|
+
remote_schema = get_setting(
|
|
196
|
+
field="remote_elevate_schema", interface=IRerSolrpushSettings
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# if local_schema is set and there is a filter on site_name, return the
|
|
200
|
+
# local elevate schema
|
|
201
|
+
if local_schema_json:
|
|
202
|
+
local_schema = json.loads(local_schema_json)
|
|
203
|
+
if local_schema:
|
|
204
|
+
if query.get("site_name", []):
|
|
205
|
+
return local_schema
|
|
206
|
+
if not remote_schema:
|
|
207
|
+
return local_schema
|
|
208
|
+
if remote_schema:
|
|
209
|
+
try:
|
|
210
|
+
resp = requests.get(
|
|
211
|
+
remote_schema, headers={"Accept": "application/json"}
|
|
212
|
+
)
|
|
213
|
+
except requests.exceptions.RequestException as err:
|
|
214
|
+
logger.error("Connection problem:\n{0}".format(err))
|
|
215
|
+
return []
|
|
216
|
+
if resp.status_code != 200:
|
|
217
|
+
logger.error(
|
|
218
|
+
"Problems fetching schema:\n{0}\n{1}".format(
|
|
219
|
+
resp.status_code, resp.reason
|
|
220
|
+
)
|
|
221
|
+
)
|
|
222
|
+
return []
|
|
223
|
+
return resp.json()
|
|
224
|
+
return []
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def extract_from_query(query):
|
|
228
|
+
index_fields = get_index_fields()
|
|
229
|
+
params = {"q": "", "fq": []}
|
|
230
|
+
for index, value in query.items():
|
|
231
|
+
if not value and value is not False:
|
|
232
|
+
continue
|
|
233
|
+
if index == "*":
|
|
234
|
+
params["q"] = "*:*"
|
|
235
|
+
continue
|
|
236
|
+
if index in ["", "SearchableText"]:
|
|
237
|
+
params["q"] = fix_value(value, wrap=False)
|
|
238
|
+
|
|
239
|
+
continue
|
|
240
|
+
index_infos = index_fields.get(index, {})
|
|
241
|
+
if not index_infos:
|
|
242
|
+
continue
|
|
243
|
+
# other indexes will be added in fq
|
|
244
|
+
value = fix_value(value=value, index_type=index_infos.get("type", ""))
|
|
245
|
+
if value or value is False:
|
|
246
|
+
if index == "path":
|
|
247
|
+
index = "path_parents"
|
|
248
|
+
params["fq"].append(
|
|
249
|
+
"{index}:{value}".format(index=index, value=value)
|
|
250
|
+
)
|
|
251
|
+
can_access_inactive = api.user.has_permission(
|
|
252
|
+
"Access inactive portal content"
|
|
253
|
+
)
|
|
254
|
+
if not can_access_inactive:
|
|
255
|
+
# do not show expired or not yet published items
|
|
256
|
+
if "expires" not in query:
|
|
257
|
+
params["fq"].append("expires:[NOW TO *]")
|
|
258
|
+
if "effective" not in query:
|
|
259
|
+
params["fq"].append("effective:[* TO NOW]")
|
|
260
|
+
return params
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def add_query_tweaks():
|
|
264
|
+
"""
|
|
265
|
+
Add query tweaks set in control panel
|
|
266
|
+
"""
|
|
267
|
+
params = {}
|
|
268
|
+
for id in ["qf", "bq", "bf"]:
|
|
269
|
+
value = get_setting(field=id)
|
|
270
|
+
if value:
|
|
271
|
+
params[id] = value
|
|
272
|
+
if params:
|
|
273
|
+
params["defType"] = "edismax"
|
|
274
|
+
return params
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
# END HELPER METHODS
|
|
278
|
+
|
|
279
|
+
# LIBRARY METHODS
|
|
280
|
+
def search(
|
|
281
|
+
query,
|
|
282
|
+
fl=None,
|
|
283
|
+
facets=False,
|
|
284
|
+
facet_fields=["Subject", "portal_type"],
|
|
285
|
+
**kwargs
|
|
286
|
+
):
|
|
287
|
+
"""[summary] TODO
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
query ([type]): [description] TODO
|
|
291
|
+
fl (str, optional): [description]. Defaults to "".
|
|
292
|
+
facets (bool, optional): [description]. Defaults to False.
|
|
293
|
+
facet_fields (list, optional): [description].
|
|
294
|
+
Defaults to ["Subject", "portal_type"].
|
|
295
|
+
|
|
296
|
+
Returns:
|
|
297
|
+
[type]: [description]
|
|
298
|
+
"""
|
|
299
|
+
solr = get_solr_connection()
|
|
300
|
+
if not solr:
|
|
301
|
+
msg = u"Unable to search using solr. Configuration is incomplete."
|
|
302
|
+
logger.error(msg)
|
|
303
|
+
return {
|
|
304
|
+
"error": True,
|
|
305
|
+
"message": translate(
|
|
306
|
+
_("solr_configuration_error_label", default=msg),
|
|
307
|
+
context=api.portal.get().REQUEST,
|
|
308
|
+
),
|
|
309
|
+
}
|
|
310
|
+
solr_query = generate_query(
|
|
311
|
+
query,
|
|
312
|
+
fl=fl,
|
|
313
|
+
facets=facets,
|
|
314
|
+
facet_fields=facet_fields,
|
|
315
|
+
)
|
|
316
|
+
try:
|
|
317
|
+
_set_query_debug(solr=solr, params=solr_query)
|
|
318
|
+
res = solr.search(**solr_query)
|
|
319
|
+
return res
|
|
320
|
+
except Exception as e:
|
|
321
|
+
logger.exception(e)
|
|
322
|
+
return {
|
|
323
|
+
"error": True,
|
|
324
|
+
"message": translate(
|
|
325
|
+
_(
|
|
326
|
+
"search_error_label",
|
|
327
|
+
default=u"Unable to perform a search with SOLR."
|
|
328
|
+
u" Please contact the site administrator or wait some"
|
|
329
|
+
u" minutes.",
|
|
330
|
+
),
|
|
331
|
+
context=api.portal.get().REQUEST,
|
|
332
|
+
),
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _set_query_debug(solr, params):
|
|
337
|
+
try:
|
|
338
|
+
if not get_setting(
|
|
339
|
+
field="query_debug", interface=IRerSolrpushSettings
|
|
340
|
+
):
|
|
341
|
+
return
|
|
342
|
+
except KeyError:
|
|
343
|
+
# key not available: do not save data
|
|
344
|
+
return
|
|
345
|
+
request = getRequest()
|
|
346
|
+
annotations = IAnnotations(request)
|
|
347
|
+
annotations["solr_query"] = {
|
|
348
|
+
"url": "{url}/select?{params}".format(
|
|
349
|
+
url=solr.url, params=safe_urlencode(params, True)
|
|
350
|
+
),
|
|
351
|
+
"params": params,
|
|
352
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from rer.solrpush.utils import search
|
|
3
|
+
from zope.interface import implementer
|
|
4
|
+
from zope.schema.interfaces import IVocabularyFactory
|
|
5
|
+
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FacetsVocabulary(object):
|
|
9
|
+
def get_terms(self):
|
|
10
|
+
solr_results = search(
|
|
11
|
+
query={"*": "*", "b_size": 1},
|
|
12
|
+
fl="UID",
|
|
13
|
+
facets=True,
|
|
14
|
+
facet_fields=self.facet_field,
|
|
15
|
+
)
|
|
16
|
+
if isinstance(solr_results, dict) and solr_results.get("error", False):
|
|
17
|
+
return []
|
|
18
|
+
facets = solr_results.facets["facet_fields"].get(self.facet_field, [])
|
|
19
|
+
if not facets:
|
|
20
|
+
return []
|
|
21
|
+
terms = []
|
|
22
|
+
for facet in facets:
|
|
23
|
+
for key in facet.keys():
|
|
24
|
+
terms.append(
|
|
25
|
+
SimpleTerm(value=key, token=key.encode("utf-8"), title=key)
|
|
26
|
+
)
|
|
27
|
+
return terms
|
|
28
|
+
|
|
29
|
+
def __call__(self, context):
|
|
30
|
+
return SimpleVocabulary(self.get_terms(), swallow_duplicates=True)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@implementer(IVocabularyFactory)
|
|
34
|
+
class AvailableSitesVocabularyFactory(FacetsVocabulary):
|
|
35
|
+
facet_field = "site_name"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@implementer(IVocabularyFactory)
|
|
39
|
+
class AvailableSubjectsVocabularyFactory(FacetsVocabulary):
|
|
40
|
+
facet_field = "Subject"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@implementer(IVocabularyFactory)
|
|
44
|
+
class AvailablePortalTypesVocabularyFactory(FacetsVocabulary):
|
|
45
|
+
facet_field = "portal_type"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
AvailablePortalTypesVocabulary = AvailablePortalTypesVocabularyFactory()
|
|
49
|
+
AvailableSitesVocabulary = AvailableSitesVocabularyFactory()
|
|
50
|
+
AvailableSubjectsVocabulary = AvailableSubjectsVocabularyFactory()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import sys, types, os;has_mfs = sys.version_info > (3, 5);p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('rer',));importlib = has_mfs and __import__('importlib.util');has_mfs and __import__('importlib.machinery');m = has_mfs and sys.modules.setdefault('rer', importlib.util.module_from_spec(importlib.machinery.PathFinder.find_spec('rer', [os.path.dirname(p)])));m = m or sys.modules.setdefault('rer', types.ModuleType('rer'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p)
|