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.
Files changed (116) hide show
  1. rer/solrpush/__init__.py +7 -0
  2. rer/solrpush/adapters/__init__.py +1 -0
  3. rer/solrpush/adapters/configure.zcml +13 -0
  4. rer/solrpush/adapters/file.py +52 -0
  5. rer/solrpush/adapters/rss_feed.py +28 -0
  6. rer/solrpush/behaviors/__init__.py +0 -0
  7. rer/solrpush/behaviors/configure.zcml +16 -0
  8. rer/solrpush/behaviors/solr_fields.py +41 -0
  9. rer/solrpush/browser/__init__.py +0 -0
  10. rer/solrpush/browser/configure.zcml +111 -0
  11. rer/solrpush/browser/controlpanel.py +96 -0
  12. rer/solrpush/browser/elevate_settings.py +35 -0
  13. rer/solrpush/browser/maintenance.py +476 -0
  14. rer/solrpush/browser/query_debug.py +12 -0
  15. rer/solrpush/browser/querybuilder.py +168 -0
  16. rer/solrpush/browser/scales.py +80 -0
  17. rer/solrpush/browser/static/.gitkeep +0 -0
  18. rer/solrpush/browser/static/dist/dev/main.js +58240 -0
  19. rer/solrpush/browser/static/dist/dev/main.js.map +180 -0
  20. rer/solrpush/browser/static/dist/prod/main.js +9604 -0
  21. rer/solrpush/browser/static/dist/prod/main.js.map +1 -0
  22. rer/solrpush/browser/static/javascripts/FacetsContainer/index.js +46 -0
  23. rer/solrpush/browser/static/javascripts/ProgressBar/index.js +40 -0
  24. rer/solrpush/browser/static/javascripts/ProgressBarContainer/index.js +66 -0
  25. rer/solrpush/browser/static/javascripts/index.js +14 -0
  26. rer/solrpush/browser/static/package.json +13 -0
  27. rer/solrpush/browser/static/styles.css +22 -0
  28. rer/solrpush/browser/static/styles.css.map +1 -0
  29. rer/solrpush/browser/static/styles.scss +27 -0
  30. rer/solrpush/browser/static/yarn.lock +1408 -0
  31. rer/solrpush/browser/templates/controlpanel_layout.pt +49 -0
  32. rer/solrpush/browser/templates/query_debug.pt +17 -0
  33. rer/solrpush/browser/templates/reindex_solr.pt +35 -0
  34. rer/solrpush/configure.zcml +81 -0
  35. rer/solrpush/indexer.py +120 -0
  36. rer/solrpush/interfaces/__init__.py +8 -0
  37. rer/solrpush/interfaces/adapter.py +13 -0
  38. rer/solrpush/interfaces/elevate.py +98 -0
  39. rer/solrpush/interfaces/layer.py +6 -0
  40. rer/solrpush/interfaces/queueprocessor.py +6 -0
  41. rer/solrpush/interfaces/settings.py +194 -0
  42. rer/solrpush/locales/README.rst +37 -0
  43. rer/solrpush/locales/__init__.py +0 -0
  44. rer/solrpush/locales/en/LC_MESSAGES/rer.solrpush.mo +0 -0
  45. rer/solrpush/locales/en/LC_MESSAGES/rer.solrpush.po +399 -0
  46. rer/solrpush/locales/it/LC_MESSAGES/rer.solrpush.mo +0 -0
  47. rer/solrpush/locales/it/LC_MESSAGES/rer.solrpush.po +399 -0
  48. rer/solrpush/locales/rer.solrpush.pot +402 -0
  49. rer/solrpush/locales/update.py +71 -0
  50. rer/solrpush/locales/update.sh +12 -0
  51. rer/solrpush/parser.py +211 -0
  52. rer/solrpush/permissions.zcml +18 -0
  53. rer/solrpush/profiles/default/actions.xml +21 -0
  54. rer/solrpush/profiles/default/browserlayer.xml +7 -0
  55. rer/solrpush/profiles/default/catalog.xml +4 -0
  56. rer/solrpush/profiles/default/controlpanel.xml +31 -0
  57. rer/solrpush/profiles/default/metadata.xml +8 -0
  58. rer/solrpush/profiles/default/registry/bundle.xml +25 -0
  59. rer/solrpush/profiles/default/registry/criteria.xml +55 -0
  60. rer/solrpush/profiles/default/registry/settings.xml +6 -0
  61. rer/solrpush/profiles/default/rolemap.xml +13 -0
  62. rer/solrpush/profiles/default/types/Document.xml +12 -0
  63. rer/solrpush/profiles/to_1100/componentregistry.xml +9 -0
  64. rer/solrpush/profiles/to_1100/metadata.xml +5 -0
  65. rer/solrpush/profiles/to_1300/controlpanel.xml +13 -0
  66. rer/solrpush/profiles/to_1300/registry.xml +5 -0
  67. rer/solrpush/profiles/uninstall/browserlayer.xml +7 -0
  68. rer/solrpush/profiles/uninstall/controlpanel.xml +21 -0
  69. rer/solrpush/profiles/uninstall/registry.xml +17 -0
  70. rer/solrpush/restapi/__init__.py +0 -0
  71. rer/solrpush/restapi/configure.zcml +8 -0
  72. rer/solrpush/restapi/services/__init__.py +0 -0
  73. rer/solrpush/restapi/services/configure.zcml +8 -0
  74. rer/solrpush/restapi/services/elevate_schema/__init__.py +0 -0
  75. rer/solrpush/restapi/services/elevate_schema/configure.zcml +14 -0
  76. rer/solrpush/restapi/services/elevate_schema/get.py +12 -0
  77. rer/solrpush/restapi/services/solr_search/__init__.py +0 -0
  78. rer/solrpush/restapi/services/solr_search/batch.py +129 -0
  79. rer/solrpush/restapi/services/solr_search/configure.zcml +14 -0
  80. rer/solrpush/restapi/services/solr_search/get.py +25 -0
  81. rer/solrpush/restapi/services/solr_search/solr_search_handler.py +86 -0
  82. rer/solrpush/setuphandlers.py +20 -0
  83. rer/solrpush/testing.py +161 -0
  84. rer/solrpush/tests/__init__.py +0 -0
  85. rer/solrpush/tests/docs/example.docx +0 -0
  86. rer/solrpush/tests/docs/example.ods +0 -0
  87. rer/solrpush/tests/docs/example.pdf +0 -0
  88. rer/solrpush/tests/docs/plone_logo.png +0 -0
  89. rer/solrpush/tests/test_behaviors.py +61 -0
  90. rer/solrpush/tests/test_elevate.py +124 -0
  91. rer/solrpush/tests/test_events.py +181 -0
  92. rer/solrpush/tests/test_image_tags.py +85 -0
  93. rer/solrpush/tests/test_maintenance.py +165 -0
  94. rer/solrpush/tests/test_querybuilder.py +272 -0
  95. rer/solrpush/tests/test_restapi_search.py +127 -0
  96. rer/solrpush/tests/test_search.py +177 -0
  97. rer/solrpush/tests/test_setup.py +67 -0
  98. rer/solrpush/tests/test_solr_interface.py +359 -0
  99. rer/solrpush/tests/test_tika.py +85 -0
  100. rer/solrpush/tests/test_vocabularies.py +113 -0
  101. rer/solrpush/upgrades.py +76 -0
  102. rer/solrpush/upgrades.zcml +86 -0
  103. rer/solrpush/utils/__init__.py +6 -0
  104. rer/solrpush/utils/solr_common.py +122 -0
  105. rer/solrpush/utils/solr_indexer.py +295 -0
  106. rer/solrpush/utils/solr_search.py +352 -0
  107. rer/solrpush/vocabularies.py +50 -0
  108. rer.solrpush-1.3.4-py3.10-nspkg.pth +1 -0
  109. rer.solrpush-1.3.4.dist-info/LICENSE.GPL +339 -0
  110. rer.solrpush-1.3.4.dist-info/LICENSE.rst +15 -0
  111. rer.solrpush-1.3.4.dist-info/METADATA +507 -0
  112. rer.solrpush-1.3.4.dist-info/RECORD +116 -0
  113. rer.solrpush-1.3.4.dist-info/WHEEL +5 -0
  114. rer.solrpush-1.3.4.dist-info/entry_points.txt +5 -0
  115. rer.solrpush-1.3.4.dist-info/namespace_packages.txt +1 -0
  116. rer.solrpush-1.3.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,18 @@
1
+ <configure
2
+ xmlns="http://namespaces.zope.org/zope"
3
+ xmlns:zcml="http://namespaces.zope.org/zcml"
4
+ i18n_domain="plone">
5
+
6
+ <configure zcml:condition="installed AccessControl.security">
7
+ <permission
8
+ id="rer.solrpush.editElevate"
9
+ title="rer.solrpush: Edit Elevate"
10
+ />
11
+ <permission
12
+ id="rer.solrpush.editSettings"
13
+ title="rer.solrpush: Edit Settings"
14
+ />
15
+
16
+ </configure>
17
+
18
+ </configure>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0"?>
2
+ <object name="portal_actions" meta_type="Plone Actions Tool"
3
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n">
4
+ <object name="user" meta_type="CMF Action Category" purge="False">
5
+ <object name="solr-elevate"
6
+ meta_type="CMF Action"
7
+ i18n:domain="rer.solrpush"
8
+ insert-before="logout">
9
+ <property name="title" i18n:translate="">Elevate configuration</property>
10
+ <property name="description" i18n:translate=""></property>
11
+ <property
12
+ name="url_expr">string:${portal_url}/@@elevate-settings</property>
13
+ <property name="icon_expr"></property>
14
+ <property name="available_expr">python:member is not None</property>
15
+ <property name="permissions">
16
+ <element value="rer.solrpush: Edit Elevate"/>
17
+ </property>
18
+ <property name="visible">True</property>
19
+ </object>
20
+ </object>
21
+ </object>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <layers>
3
+ <layer
4
+ name="rer.solrpush"
5
+ interface="rer.solrpush.interfaces.IRerSolrpushLayer"
6
+ />
7
+ </layers>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0"?>
2
+ <object name="portal_catalog">
3
+ <!--<column value="my_meta_column"/>-->
4
+ </object>
@@ -0,0 +1,31 @@
1
+ <?xml version="1.0"?>
2
+ <object
3
+ name="portal_controlpanel"
4
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
5
+ i18n:domain="rer.bandisolr">
6
+
7
+ <configlet
8
+ title="Configurazione RER SolrPush"
9
+ action_id="solrpush.configuration"
10
+ appId="solrpush"
11
+ category="Products"
12
+ condition_expr=""
13
+ url_expr="string:${portal_url}/@@solrpush-settings"
14
+ icon_expr=""
15
+ visible="True"
16
+ i18n:attributes="title">
17
+ <permission>rer.solrpush: Edit Settings</permission>
18
+ </configlet>
19
+ <configlet
20
+ title="Configurazione Elevate"
21
+ action_id="solrpush.elevate"
22
+ appId="solrpush-elevate"
23
+ category="Products"
24
+ condition_expr=""
25
+ url_expr="string:${portal_url}/@@elevate-settings"
26
+ icon_expr=""
27
+ visible="True"
28
+ i18n:attributes="title">
29
+ <permission>rer.solrpush: Edit Elevate</permission>
30
+ </configlet>
31
+ </object>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metadata>
3
+ <version>2000</version>
4
+ <dependencies>
5
+ <dependency>profile-collective.z3cform.jsonwidget:default</dependency>
6
+ <dependency>profile-plone.restapi:default</dependency>
7
+ </dependencies>
8
+ </metadata>
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0"?>
2
+ <registry xmlns:i18n="http://xml.zope.org/namespaces/i18n"
3
+ i18n:domain="rer.solrpush">
4
+
5
+ <!-- RESOURCE -->
6
+ <records prefix="plone.resources/rer-solrpush-css"
7
+ interface='Products.CMFPlone.interfaces.IResourceRegistry'>
8
+ <value key="css">
9
+ <element>++plone++rer.solrpush/styles.css</element>
10
+ </value>
11
+ </records>
12
+
13
+ <!-- BUNDLE -->
14
+ <records prefix="plone.bundles/rer-solrpush-css-bundle"
15
+ interface='Products.CMFPlone.interfaces.IBundleRegistry'>
16
+ <value key="enabled">True</value>
17
+ <value key="resources" purge="false">
18
+ <element>rer-solrpush-css</element>
19
+ </value>
20
+ <value key="csscompilation">++plone++rer.solrpush/styles.css</value>
21
+ <value key="last_compilation">2020-11-17 00:00:00</value>
22
+ <value key="compile">True</value>
23
+ <value key="depends">plone</value>
24
+ </records>
25
+ </registry>
@@ -0,0 +1,55 @@
1
+ <?xml version="1.0"?>
2
+ <registry xmlns:i18n="http://xml.zope.org/namespaces/i18n"
3
+ i18n:domain="rer.solrpush">
4
+
5
+ <records interface="plone.app.querystring.interfaces.IQueryField"
6
+ prefix="plone.app.querystring.field.searchWithSolr">
7
+ <value key="title" i18n:translate="">Search with Solr</value>
8
+ <value key="description"
9
+ i18n:translate="Select if perform search with SOLR or with Plone (local) catalog.">
10
+ </value>
11
+ <value key="enabled">True</value>
12
+ <value key="sortable">False</value>
13
+ <value key="operations">
14
+ <element>plone.app.querystring.operation.boolean.isTrue</element>
15
+ <element>plone.app.querystring.operation.boolean.isFalse</element>
16
+ </value>
17
+ <value key="group" i18n:translate="">SOLR</value>
18
+ </records>
19
+ <records interface="plone.app.querystring.interfaces.IQueryField"
20
+ prefix="plone.app.querystring.field.solr_sites">
21
+ <value key="title" i18n:translate="">Sites</value>
22
+ <value key="description" i18n:translate="">A list of (SOLR indexed) sites where search items.</value>
23
+ <value key="enabled">True</value>
24
+ <value key="sortable">False</value>
25
+ <value key="operations">
26
+ <element>plone.app.querystring.operation.selection.any</element>
27
+ </value>
28
+ <value key="vocabulary">rer.solrpush.vocabularies.AvailableSites</value>
29
+ <value key="group" i18n:translate="">SOLR</value>
30
+ </records>
31
+ <records interface="plone.app.querystring.interfaces.IQueryField"
32
+ prefix="plone.app.querystring.field.solr_subjects">
33
+ <value key="title" i18n:translate="">Keywords in SOLR</value>
34
+ <value key="description" i18n:translate="">A complete list of keywords stored in SOLR.</value>
35
+ <value key="enabled">True</value>
36
+ <value key="sortable">False</value>
37
+ <value key="operations">
38
+ <element>plone.app.querystring.operation.selection.any</element>
39
+ </value>
40
+ <value key="vocabulary">rer.solrpush.vocabularies.AvailableSubjects</value>
41
+ <value key="group" i18n:translate="">SOLR</value>
42
+ </records>
43
+ <records interface="plone.app.querystring.interfaces.IQueryField"
44
+ prefix="plone.app.querystring.field.solr_portal_types">
45
+ <value key="title" i18n:translate="">Portal types in SOLR</value>
46
+ <value key="description" i18n:translate="">A complete list of portal_types stored in SOLR.</value>
47
+ <value key="enabled">True</value>
48
+ <value key="sortable">False</value>
49
+ <value key="operations">
50
+ <element>plone.app.querystring.operation.selection.any</element>
51
+ </value>
52
+ <value key="vocabulary">rer.solrpush.vocabularies.AvailablePortalTypes</value>
53
+ <value key="group" i18n:translate="">SOLR</value>
54
+ </records>
55
+ </registry>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0"?>
2
+ <registry xmlns:i18n="http://xml.zope.org/namespaces/i18n"
3
+ i18n:domain="rer.solrpush">
4
+ <records interface="rer.solrpush.interfaces.settings.IRerSolrpushSettings" />
5
+ <records interface="rer.solrpush.interfaces.IElevateSettings" />
6
+ </registry>
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0"?>
2
+ <rolemap>
3
+ <permissions>
4
+ <permission name="rer.solrpush: Edit Elevate" acquire="True">
5
+ <role name="Manager" />
6
+ <role name="Site Administrator" />
7
+ </permission>
8
+ <permission name="rer.solrpush: Edit Settings" acquire="True">
9
+ <role name="Manager" />
10
+ <role name="Site Administrator" />
11
+ </permission>
12
+ </permissions>
13
+ </rolemap>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0"?>
2
+ <object
3
+ name="Document"
4
+ meta_type="Dexterity FTI"
5
+ i18n:domain="plone"
6
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n">
7
+
8
+ <property name="behaviors" purge="false">
9
+ <element value="rer.solrpush.behaviors.solr_fields.ISolrFields" />
10
+ </property>
11
+
12
+ </object>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0"?>
2
+ <componentregistry>
3
+ <utilities>
4
+ <utility
5
+ interface="rer.solrpush.interfaces.ISolrIndexQueueProcessor"
6
+ name="solrpush.utility"
7
+ remove="True" />
8
+ </utilities>
9
+ </componentregistry>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metadata>
3
+ <dependencies>
4
+ </dependencies>
5
+ </metadata>
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0"?>
2
+ <object
3
+ name="portal_controlpanel"
4
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
5
+ i18n:domain="rer.bandisolr">
6
+
7
+ <configlet
8
+ title="Configurazione Elevate"
9
+ action_id="solrpush.elevate"
10
+ appId="solrpush-elevate"
11
+ remove="True">
12
+ </configlet>
13
+ </object>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0"?>
2
+ <registry xmlns:i18n="http://xml.zope.org/namespaces/i18n"
3
+ i18n:domain="rer.solrpush">
4
+ <records interface="rer.solrpush.interfaces.IElevateSettings" remove="True"/>
5
+ </registry>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <layers>
3
+ <layer
4
+ name="rer.solrpush"
5
+ remove="true"
6
+ />
7
+ </layers>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0"?>
2
+ <object
3
+ name="portal_controlpanel"
4
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
5
+ i18n:domain="rer.solrpush">
6
+
7
+ <configlet
8
+ title="Configurazione RER SolrPush"
9
+ action_id="solrpush.configuration"
10
+ appId="solrpush"
11
+ category="SOLR"
12
+ remove="True">
13
+ </configlet>
14
+ <configlet
15
+ title="Configurazione Elevate"
16
+ action_id="solrpush.elevate"
17
+ appId="solrpush-elevate"
18
+ category="SOLR"
19
+ remove="True">
20
+ </configlet>
21
+ </object>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0"?>
2
+ <registry>
3
+ <!-- -*- extra stuff goes here -*- -->
4
+ <records interface="rer.solrpush.interfaces.settings.IRerSolrpushSettings" remove="True"/>
5
+ <records interface="rer.solrpush.interfaces.IElevateSettings" remove="True"/>
6
+
7
+ <!-- RESOURCE -->
8
+ <records prefix="plone.resources/rer-solrpush-css"
9
+ interface='Products.CMFPlone.interfaces.IResourceRegistry' remove="True">
10
+ </records>
11
+
12
+ <!-- BUNDLE -->
13
+ <records prefix="plone.bundles/rer-solrpush-css-bundle"
14
+ interface='Products.CMFPlone.interfaces.IBundleRegistry' remove="True">
15
+ </records>
16
+
17
+ </registry>
File without changes
@@ -0,0 +1,8 @@
1
+ <configure
2
+ xmlns="http://namespaces.zope.org/zope"
3
+ xmlns:plone="http://namespaces.plone.org/plone">
4
+
5
+ <include package="plone.restapi" file="configure.zcml"/>
6
+ <include package=".services" />
7
+
8
+ </configure>
File without changes
@@ -0,0 +1,8 @@
1
+ <configure
2
+ xmlns="http://namespaces.zope.org/zope"
3
+ xmlns:plone="http://namespaces.plone.org/plone">
4
+
5
+ <include package=".elevate_schema" />
6
+ <include package=".solr_search" />
7
+
8
+ </configure>
@@ -0,0 +1,14 @@
1
+ <configure
2
+ xmlns="http://namespaces.zope.org/zope"
3
+ xmlns:plone="http://namespaces.plone.org/plone">
4
+
5
+ <plone:service
6
+ method="GET"
7
+ for="zope.interface.Interface"
8
+ factory=".get.ElevateSchemaGet"
9
+ name="@elevate-schema"
10
+ permission="zope2.View"
11
+ layer="rer.solrpush.interfaces.IRerSolrpushLayer"
12
+ />
13
+
14
+ </configure>
@@ -0,0 +1,12 @@
1
+ # -*- coding: utf-8 -*-
2
+ from plone.restapi.services import Service
3
+ from rer.solrpush.utils.solr_common import get_setting
4
+ from rer.solrpush.interfaces import IElevateSettings
5
+
6
+ import json
7
+
8
+
9
+ class ElevateSchemaGet(Service):
10
+ def reply(self):
11
+ data = get_setting(field="elevate_schema", interface=IElevateSettings)
12
+ return json.loads(data)
File without changes
@@ -0,0 +1,129 @@
1
+ # -*- coding: utf-8 -*-
2
+ from plone.restapi.deserializer import json_body
3
+ from six.moves.urllib.parse import parse_qsl
4
+ from six.moves.urllib.parse import urlencode
5
+
6
+
7
+ DEFAULT_BATCH_SIZE = 25
8
+
9
+
10
+ class SolrHypermediaBatch(object):
11
+ def __init__(self, request, results):
12
+ self.request = request
13
+
14
+ self.b_start = int(
15
+ json_body(self.request).get("b_start", False)
16
+ ) or int(self.request.form.get("b_start", 0))
17
+ self.b_size = int(json_body(self.request).get("b_size", False)) or int(
18
+ self.request.form.get("b_size", DEFAULT_BATCH_SIZE)
19
+ )
20
+
21
+ self.hits = getattr(results, "hits", 0)
22
+
23
+ @property
24
+ def canonical_url(self):
25
+ """Return the canonical URL to the batched collection-like resource,
26
+ preserving query string params, but stripping all batching related
27
+ params from it.
28
+ """
29
+ url = self.request["ACTUAL_URL"]
30
+ qs_params = parse_qsl(self.request["QUERY_STRING"])
31
+
32
+ # Remove any batching / sorting related parameters.
33
+ # Also take care to preserve list-like query string params.
34
+ for key, value in qs_params[:]:
35
+ if key in (
36
+ "b_size",
37
+ "b_start",
38
+ "sort_on",
39
+ "sort_order",
40
+ "sort_limit",
41
+ ):
42
+ qs_params.remove((key, value))
43
+
44
+ qs = urlencode(qs_params)
45
+
46
+ if qs_params:
47
+ url = "?".join((url, qs))
48
+ return url
49
+
50
+ @property
51
+ def current_batch_url(self):
52
+ url = self.request["ACTUAL_URL"]
53
+ qs = self.request["QUERY_STRING"]
54
+ if qs:
55
+ url = "?".join((url, qs))
56
+ return url
57
+
58
+ @property
59
+ def links(self):
60
+ """Get a dictionary with batching links.
61
+ """
62
+ # Don't provide batching links if resultset isn't batched
63
+ if self.hits <= self.b_size:
64
+ return None
65
+
66
+ links = {}
67
+
68
+ last = self._last_page()
69
+ next = self._next_page()
70
+ prev = self._prev_page()
71
+
72
+ links["@id"] = self.current_batch_url
73
+ links["first"] = self._url_for_batch(0)
74
+ links["last"] = self._url_for_batch(last)
75
+
76
+ if next:
77
+ links["next"] = self._url_for_batch(next)
78
+
79
+ if prev:
80
+ links["prev"] = self._url_for_batch(prev)
81
+
82
+ return links
83
+
84
+ def _url_for_batch(self, pagenumber):
85
+ """Return a new Batch object for the given pagenumber.
86
+ """
87
+ new_start = pagenumber * self.b_size
88
+ return self._url_with_params(params={"b_start": new_start})
89
+
90
+ def _last_page(self):
91
+ page = self.hits / self.b_size
92
+ if self.hits % self.b_size == 0:
93
+ return page - 1
94
+ return page
95
+
96
+ def _next_page(self):
97
+ curr_page = self.b_start / self.b_size
98
+ if curr_page == self._last_page():
99
+ return None
100
+ return curr_page + 1
101
+
102
+ def _prev_page(self):
103
+ curr_page = self.b_start / self.b_size
104
+ if curr_page == 0:
105
+ return None
106
+ return curr_page - 1
107
+
108
+ def _url_with_params(self, params):
109
+ """Build an URL based on the actual URL of the current request URL
110
+ and add or update some query string parameters in it.
111
+ """
112
+ url = self.request["ACTUAL_URL"]
113
+ qs_params = parse_qsl(
114
+ self.request["QUERY_STRING"], keep_blank_values=1
115
+ )
116
+
117
+ # Take care to preserve list-like query string arguments (same QS
118
+ # param repeated multiple times). In other words, don't turn the
119
+ # result of parse_qsl into a dict!
120
+
121
+ # Drop params to be updated, then prepend new params in order
122
+ qs_params = [x for x in qs_params if x[0] not in list(params)]
123
+ qs_params = sorted(params.items()) + qs_params
124
+
125
+ qs = urlencode(qs_params)
126
+
127
+ if qs_params:
128
+ url = "?".join((url, qs))
129
+ return url
@@ -0,0 +1,14 @@
1
+ <configure
2
+ xmlns="http://namespaces.zope.org/zope"
3
+ xmlns:plone="http://namespaces.plone.org/plone">
4
+
5
+ <plone:service
6
+ method="GET"
7
+ for="zope.interface.Interface"
8
+ factory=".get.SearchGet"
9
+ name="@solr-search"
10
+ permission="zope2.View"
11
+ layer="rer.solrpush.interfaces.IRerSolrpushLayer"
12
+ />
13
+
14
+ </configure>
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ from plone.restapi.search.utils import unflatten_dotted_dict
3
+ from plone.restapi.services import Service
4
+ from rer.solrpush.restapi.services.solr_search.solr_search_handler import (
5
+ SolrSearchHandler,
6
+ )
7
+ from plone.restapi.search.handler import SearchHandler
8
+ from rer.solrpush.interfaces.settings import IRerSolrpushSettings
9
+ from plone import api
10
+
11
+
12
+ class SearchGet(Service):
13
+ def reply(self):
14
+ query = self.request.form.copy()
15
+ query = unflatten_dotted_dict(query)
16
+ handler = SearchHandler
17
+ try:
18
+ search_enabled = api.portal.get_registry_record(
19
+ "search_enabled", interface=IRerSolrpushSettings
20
+ )
21
+ except Exception:
22
+ return handler(self.context, self.request).search(query)
23
+ if search_enabled:
24
+ handler = SolrSearchHandler
25
+ return handler(self.context, self.request).search(query)
@@ -0,0 +1,86 @@
1
+ # -*- coding: utf-8 -*-
2
+ from copy import deepcopy
3
+ from Products.CMFCore.utils import getToolByName
4
+ from plone.restapi.search.handler import SearchHandler as BaseHandler
5
+ from rer.solrpush.utils import search as solr_search
6
+ from rer.solrpush.restapi.services.solr_search.batch import SolrHypermediaBatch
7
+ from plone.restapi.deserializer import boolean_value
8
+
9
+ DEFAULT_METADATA_FIELDS = set(
10
+ ["@id", "@type", "description", "review_state", "title"]
11
+ )
12
+ FIELD_ACCESSORS = {
13
+ "@id": "getURL",
14
+ "@type": "PortalType",
15
+ "description": "Description",
16
+ "title": "Title",
17
+ }
18
+
19
+ NON_METADATA_ATTRIBUTES = set(["getPath", "getURL"])
20
+
21
+ BLACKLISTED_ATTRIBUTES = set(["getDataOrigin", "getObject", "getUserData"])
22
+
23
+
24
+ class SolrSearchHandler(BaseHandler):
25
+ """Executes a solr search based on a query dict, and returns
26
+ JSON compatible results.
27
+ """
28
+
29
+ def __init__(self, context, request):
30
+ self.context = context
31
+ self.request = request
32
+ self.catalog = getToolByName(self.context, "portal_catalog")
33
+
34
+ def search(self, query=None):
35
+ if query is None:
36
+ solr_query = {}
37
+ else:
38
+ solr_query = deepcopy(query)
39
+ fl = self.get_fields_list(solr_query)
40
+ facets = boolean_value(solr_query.get("facets", False))
41
+ facet_fields = solr_query.get("facet_fields", [])
42
+ query_params = {"fl": fl}
43
+ if facets:
44
+ query_params["facets"] = facets
45
+ if facet_fields:
46
+ query_params["facet_fields"] = facet_fields
47
+ del solr_query["facet_fields"]
48
+ if "facets" in solr_query:
49
+ del solr_query["facets"]
50
+ query_params["query"] = solr_query
51
+ return self.serialize_results(solr_search(**query_params))
52
+
53
+ def get_fields_list(self, query):
54
+ if "fullobjects" in query:
55
+ del query["fullobjects"]
56
+ return []
57
+ fields = []
58
+ for field in self.metadata_fields(query):
59
+ if field.startswith("_") or field in BLACKLISTED_ATTRIBUTES:
60
+ continue
61
+ fields.append(field)
62
+ return fields
63
+
64
+ def metadata_fields(self, query):
65
+ additional_metadata_fields = query.get("metadata_fields", [])
66
+ if not isinstance(additional_metadata_fields, list):
67
+ additional_metadata_fields = [additional_metadata_fields]
68
+ additional_metadata_fields = set(additional_metadata_fields)
69
+ if additional_metadata_fields:
70
+ del query["metadata_fields"]
71
+ return DEFAULT_METADATA_FIELDS | additional_metadata_fields
72
+
73
+ def serialize_results(self, solr_results):
74
+ batch = SolrHypermediaBatch(self.request, solr_results)
75
+ results = {}
76
+ results["@id"] = batch.canonical_url
77
+ results["items_total"] = solr_results.hits
78
+ if solr_results.facets:
79
+ results["facets"] = solr_results.facets.get("facet_fields", {})
80
+ links = batch.links
81
+ if links:
82
+ results["batching"] = links
83
+
84
+ results["items"] = solr_results.docs
85
+
86
+ return results
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+ from Products.CMFPlone.interfaces import INonInstallable
3
+ from zope.interface import implementer
4
+
5
+
6
+ @implementer(INonInstallable)
7
+ class HiddenProfiles(object):
8
+ def getNonInstallableProfiles(self):
9
+ """Hide uninstall profile from site-creation and quickinstaller."""
10
+ return ["rer.solrpush:uninstall", "rer.solrpush:1100"]
11
+
12
+
13
+ def post_install(context):
14
+ """Post install script"""
15
+ # Do something at the end of the installation of this package.
16
+
17
+
18
+ def uninstall(context):
19
+ """Uninstall script"""
20
+ # Do something at the end of the uninstallation of this package.