plone.app.querystring 3.0.0a2__tar.gz → 3.0.0a3__tar.gz
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.
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/CHANGES.rst +20 -0
- {plone_app_querystring-3.0.0a2/src/plone.app.querystring.egg-info → plone_app_querystring-3.0.0a3}/PKG-INFO +21 -1
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/pyproject.toml +2 -2
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/setup.py +1 -2
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/indexmodifiers/configure.zcml +0 -5
- plone_app_querystring-3.0.0a3/src/plone/app/querystring/indexmodifiers/query_index_modifiers.py +62 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/querybuilder.py +8 -50
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/queryparser.py +0 -1
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/registryreader.py +0 -1
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/registry_testdata.py +0 -1
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/testIndexmodifiers.py +0 -18
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/testQueryBuilder.py +0 -74
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/testQueryParser.py +0 -1
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/vocabularies.py +0 -1
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3/src/plone.app.querystring.egg-info}/PKG-INFO +21 -1
- plone_app_querystring-3.0.0a2/src/plone/app/querystring/indexmodifiers/query_index_modifiers.py +0 -107
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/CONTRIBUTING.rst +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/MANIFEST.in +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/README.rst +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/docs/LICENSE.GPL +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/docs/LICENSE.txt +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/setup.cfg +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/__init__.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/configure.zcml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/hiddenprofiles.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/indexmodifiers/__init__.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/interfaces.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/default/metadata.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/default/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/upgrades/to_10/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/upgrades/to_11/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/upgrades/to_14/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/upgrades/to_3/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/upgrades/to_5/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/upgrades/to_6/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/upgrades/to_7/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/upgrades/to_8/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles/upgrades/to_9/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/profiles.zcml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/querymodifiers.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/results.pt +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/testing.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/__init__.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/configure.zcml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/index_testmodifier.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/profiles/registry/metadata.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/profiles/registry/registry.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/registry_minimal_correct.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/registry_test_missing_operator.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/registry_test_vocabulary.xml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/testQueryBuilderModifiers.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/testRegistryIntegration.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/testRegistryReader.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/tests/testVocabularies.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/upgrades.py +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/upgrades.zcml +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone.app.querystring.egg-info/SOURCES.txt +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone.app.querystring.egg-info/dependency_links.txt +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone.app.querystring.egg-info/entry_points.txt +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone.app.querystring.egg-info/not-zip-safe +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone.app.querystring.egg-info/requires.txt +0 -0
- {plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone.app.querystring.egg-info/top_level.txt +0 -0
|
@@ -8,6 +8,26 @@ Changelog
|
|
|
8
8
|
|
|
9
9
|
.. towncrier release notes start
|
|
10
10
|
|
|
11
|
+
3.0.0a3 (2026-03-30)
|
|
12
|
+
--------------------
|
|
13
|
+
|
|
14
|
+
Bug fixes:
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
- Fix multi-word search so all word parts get wildcard prefix matching, not just the last one.
|
|
18
|
+
Use ``munge_search_term`` from ``plone.base.utils``, deprecate old import path.
|
|
19
|
+
@jensens (#4205)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Internal:
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
- Remove Subject index modifier — a Python 2 leftover that was already a no-op.
|
|
26
|
+
@jensens (#155)
|
|
27
|
+
- Update configuration files.
|
|
28
|
+
[plone devs]
|
|
29
|
+
|
|
30
|
+
|
|
11
31
|
3.0.0a2 (2025-11-26)
|
|
12
32
|
--------------------
|
|
13
33
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plone.app.querystring
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.0a3
|
|
4
4
|
Summary: A queryparser, querybuilder and extra helper tools, to parse stored queries to actual results, used in new style Plone collections
|
|
5
5
|
Home-page: https://github.com/plone/plone.app.querystring
|
|
6
6
|
Author: Plone Foundation
|
|
@@ -88,6 +88,26 @@ Changelog
|
|
|
88
88
|
|
|
89
89
|
.. towncrier release notes start
|
|
90
90
|
|
|
91
|
+
3.0.0a3 (2026-03-30)
|
|
92
|
+
--------------------
|
|
93
|
+
|
|
94
|
+
Bug fixes:
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
- Fix multi-word search so all word parts get wildcard prefix matching, not just the last one.
|
|
98
|
+
Use ``munge_search_term`` from ``plone.base.utils``, deprecate old import path.
|
|
99
|
+
@jensens (#4205)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
Internal:
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
- Remove Subject index modifier — a Python 2 leftover that was already a no-op.
|
|
106
|
+
@jensens (#155)
|
|
107
|
+
- Update configuration files.
|
|
108
|
+
[plone devs]
|
|
109
|
+
|
|
110
|
+
|
|
91
111
|
3.0.0a2 (2025-11-26)
|
|
92
112
|
--------------------
|
|
93
113
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# https://github.com/plone/meta/tree/main/src/plone/meta/default
|
|
3
3
|
# See the inline comments on how to expand/tweak this configuration file
|
|
4
4
|
[build-system]
|
|
5
|
-
requires = ["setuptools>=68.2,<
|
|
5
|
+
requires = ["setuptools>=68.2,<83", "wheel"]
|
|
6
6
|
|
|
7
7
|
[tool.towncrier]
|
|
8
8
|
directory = "news/"
|
|
@@ -60,7 +60,7 @@ profile = "plone"
|
|
|
60
60
|
##
|
|
61
61
|
|
|
62
62
|
[tool.black]
|
|
63
|
-
target-version = ["
|
|
63
|
+
target-version = ["py310"]
|
|
64
64
|
|
|
65
65
|
##
|
|
66
66
|
# Add extra configuration options in .meta.toml:
|
|
@@ -3,11 +3,6 @@
|
|
|
3
3
|
i18n_domain="plone"
|
|
4
4
|
>
|
|
5
5
|
|
|
6
|
-
<utility
|
|
7
|
-
factory=".query_index_modifiers.Subject"
|
|
8
|
-
provides="..interfaces.IParsedQueryIndexModifier"
|
|
9
|
-
name="Subject"
|
|
10
|
-
/>
|
|
11
6
|
<utility
|
|
12
7
|
factory=".query_index_modifiers.Date"
|
|
13
8
|
provides="..interfaces.IParsedQueryIndexModifier"
|
plone_app_querystring-3.0.0a3/src/plone/app/querystring/indexmodifiers/query_index_modifiers.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from dateutil.parser import parse
|
|
2
|
+
from plone.app.querystring.interfaces import IParsedQueryIndexModifier
|
|
3
|
+
from zope.interface import implementer
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@implementer(IParsedQueryIndexModifier)
|
|
7
|
+
class base:
|
|
8
|
+
"""DateIndex query modifier
|
|
9
|
+
see Products.PluginIndexes.DateIndex.DateIndex.DateIndex._convert function
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __call__(self, value):
|
|
13
|
+
def _normalize(val):
|
|
14
|
+
"""Encode value, parse dates."""
|
|
15
|
+
|
|
16
|
+
if isinstance(val, str):
|
|
17
|
+
try:
|
|
18
|
+
val = parse(val)
|
|
19
|
+
except (ValueError, AttributeError):
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
return val
|
|
23
|
+
|
|
24
|
+
query = value["query"]
|
|
25
|
+
query = _normalize(query)
|
|
26
|
+
|
|
27
|
+
if isinstance(query, list):
|
|
28
|
+
aux = list()
|
|
29
|
+
for item in query:
|
|
30
|
+
aux.append(_normalize(item))
|
|
31
|
+
query = aux
|
|
32
|
+
|
|
33
|
+
value["query"] = query
|
|
34
|
+
return (self.__class__.__name__, value)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Date(base):
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class created(base):
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class effective(base):
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class end(base):
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class expires(base):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class modified(base):
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class start(base):
|
|
62
|
+
pass
|
|
@@ -4,71 +4,29 @@ from plone.app.querystring import queryparser
|
|
|
4
4
|
from plone.app.querystring.interfaces import IParsedQueryIndexModifier
|
|
5
5
|
from plone.app.querystring.interfaces import IQueryModifier
|
|
6
6
|
from plone.app.querystring.interfaces import IQuerystringRegistryReader
|
|
7
|
+
from plone.base.utils import munge_search_term as _munge_search_term
|
|
7
8
|
from plone.batching import Batch
|
|
8
9
|
from plone.registry.interfaces import IRegistry
|
|
9
10
|
from Products.CMFCore.utils import getToolByName
|
|
10
11
|
from zope.component import getMultiAdapter
|
|
11
12
|
from zope.component import getUtilitiesFor
|
|
12
13
|
from zope.component import getUtility
|
|
14
|
+
from zope.deferredimport import deprecated
|
|
13
15
|
from zope.i18n import translate
|
|
14
16
|
from zope.i18nmessageid import MessageFactory
|
|
15
17
|
from zope.publisher.browser import BrowserView
|
|
16
18
|
|
|
17
19
|
import json
|
|
18
20
|
import logging
|
|
19
|
-
import re
|
|
20
|
-
|
|
21
21
|
|
|
22
22
|
logger = logging.getLogger("plone.app.querystring")
|
|
23
23
|
_ = MessageFactory("plone")
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def _quote_chars(s):
|
|
32
|
-
# We need to quote parentheses when searching text indices
|
|
33
|
-
if "(" in s:
|
|
34
|
-
s = s.replace("(", '"("')
|
|
35
|
-
if ")" in s:
|
|
36
|
-
s = s.replace(")", '")"')
|
|
37
|
-
if _MULTISPACE in s:
|
|
38
|
-
s = s.replace(_MULTISPACE, " ")
|
|
39
|
-
return s
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def _quote(term):
|
|
43
|
-
# The terms and, or and not must be wrapped in quotes to avoid
|
|
44
|
-
# being parsed as logical query atoms.
|
|
45
|
-
if term.lower() in ("and", "or", "not"):
|
|
46
|
-
term = '"%s"' % term
|
|
47
|
-
return _quote_chars(term)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def munge_search_term(query):
|
|
51
|
-
original_query = query
|
|
52
|
-
for char in _BAD_CHARS:
|
|
53
|
-
query = query.replace(char, " ")
|
|
54
|
-
|
|
55
|
-
# extract quoted phrases first
|
|
56
|
-
quoted_phrases = re.findall(r'"([^"]*)"', query)
|
|
57
|
-
r = []
|
|
58
|
-
for qp in quoted_phrases:
|
|
59
|
-
# remove from original query
|
|
60
|
-
query = query.replace(f'"{qp}"', "")
|
|
61
|
-
# replace with cleaned leading/trailing whitespaces
|
|
62
|
-
# and skip empty phrases
|
|
63
|
-
clean_qp = qp.strip()
|
|
64
|
-
if not clean_qp:
|
|
65
|
-
continue
|
|
66
|
-
r.append(f'"{clean_qp}"')
|
|
67
|
-
|
|
68
|
-
r += map(_quote, query.strip().split())
|
|
69
|
-
r = " AND ".join(r)
|
|
70
|
-
r = r + ("*" if r and not original_query.endswith('"') else "")
|
|
71
|
-
return r
|
|
25
|
+
deprecated(
|
|
26
|
+
"Moved to plone.base.utils. Import from there instead "
|
|
27
|
+
"(will be removed in Plone 7).",
|
|
28
|
+
munge_search_term="plone.base.utils:munge_search_term",
|
|
29
|
+
)
|
|
72
30
|
|
|
73
31
|
|
|
74
32
|
class ContentListingView(BrowserView):
|
|
@@ -268,7 +226,7 @@ class QueryBuilder(BrowserView):
|
|
|
268
226
|
return query
|
|
269
227
|
|
|
270
228
|
def munge_search_term(self, q):
|
|
271
|
-
return
|
|
229
|
+
return _munge_search_term(q)
|
|
272
230
|
|
|
273
231
|
|
|
274
232
|
class RegistryConfiguration(BrowserView):
|
|
@@ -6,24 +6,6 @@ import unittest
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class TestIndexModifiers(unittest.TestCase):
|
|
9
|
-
def test_subject_encoded(self):
|
|
10
|
-
self.assertEqual(
|
|
11
|
-
query_index_modifiers.Subject()({"query": "foobar"}),
|
|
12
|
-
("Subject", {"query": "foobar"}),
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
def test_subject_encoded__list(self):
|
|
16
|
-
self.assertEqual(
|
|
17
|
-
query_index_modifiers.Subject()({"query": ["foobar"]}),
|
|
18
|
-
("Subject", {"query": ["foobar"]}),
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
def test_subject_encoded__list_not(self):
|
|
22
|
-
self.assertEqual(
|
|
23
|
-
query_index_modifiers.Subject()({"not": ["foobar"]}),
|
|
24
|
-
("Subject", {"not": ["foobar"]}),
|
|
25
|
-
)
|
|
26
|
-
|
|
27
9
|
def test_date_modifier(self):
|
|
28
10
|
modifier = query_index_modifiers.start()
|
|
29
11
|
self.assertTrue(
|
|
@@ -333,80 +333,6 @@ class TestQuerybuilder(unittest.TestCase):
|
|
|
333
333
|
self.assertEqual(len(results), 1)
|
|
334
334
|
self.assertEqual(results[0].Title(), "Collectionstestpage 2")
|
|
335
335
|
|
|
336
|
-
def test_munge_search_term(self):
|
|
337
|
-
from plone.app.querystring.querybuilder import _BAD_CHARS
|
|
338
|
-
from plone.app.querystring.querybuilder import munge_search_term
|
|
339
|
-
|
|
340
|
-
search_term_tests = [
|
|
341
|
-
(
|
|
342
|
-
# search term
|
|
343
|
-
"spam ham",
|
|
344
|
-
"spam AND ham*",
|
|
345
|
-
),
|
|
346
|
-
(
|
|
347
|
-
# quoted term
|
|
348
|
-
'"spam ham"',
|
|
349
|
-
'"spam ham"',
|
|
350
|
-
),
|
|
351
|
-
(
|
|
352
|
-
# cleanup quoted terms
|
|
353
|
-
'" spam ham "',
|
|
354
|
-
'"spam ham"',
|
|
355
|
-
),
|
|
356
|
-
(
|
|
357
|
-
# quoted term with inner parenthesis
|
|
358
|
-
'"spam (ham)"',
|
|
359
|
-
'"spam (ham)"',
|
|
360
|
-
),
|
|
361
|
-
(
|
|
362
|
-
# quoted term with inner parenthesis
|
|
363
|
-
'"spam" (ham)',
|
|
364
|
-
'"spam" AND "("ham")"*',
|
|
365
|
-
),
|
|
366
|
-
(
|
|
367
|
-
# quoted term with inner parenthesis
|
|
368
|
-
'"(spam ham)"',
|
|
369
|
-
'"(spam ham)"',
|
|
370
|
-
),
|
|
371
|
-
(
|
|
372
|
-
# mixed cases
|
|
373
|
-
"Spam hAm",
|
|
374
|
-
"Spam AND hAm*",
|
|
375
|
-
),
|
|
376
|
-
(
|
|
377
|
-
# mix quoting and unquoted
|
|
378
|
-
'let\'s eat some "ham and eggs " without spam ',
|
|
379
|
-
'"ham and eggs" AND let\'s AND eat AND some ' "AND without AND spam*",
|
|
380
|
-
),
|
|
381
|
-
(
|
|
382
|
-
'test "Welcome" to "Plone" retest',
|
|
383
|
-
'"Welcome" AND "Plone" AND test AND to AND retest*',
|
|
384
|
-
),
|
|
385
|
-
(
|
|
386
|
-
# parentheses
|
|
387
|
-
"spam (ham)",
|
|
388
|
-
'spam AND "("ham")"*',
|
|
389
|
-
),
|
|
390
|
-
(
|
|
391
|
-
# special keywords
|
|
392
|
-
"spam or not ham and eggs",
|
|
393
|
-
'spam AND "or" AND "not" AND ham AND "and" AND eggs*',
|
|
394
|
-
),
|
|
395
|
-
(
|
|
396
|
-
# bad characters
|
|
397
|
-
" ".join(_BAD_CHARS),
|
|
398
|
-
"",
|
|
399
|
-
),
|
|
400
|
-
(
|
|
401
|
-
# weird input
|
|
402
|
-
'test ""Welcome" to "Plone"" retest',
|
|
403
|
-
'"to" AND test AND WelcomePlone AND retest*',
|
|
404
|
-
),
|
|
405
|
-
]
|
|
406
|
-
|
|
407
|
-
for _in, _out in search_term_tests:
|
|
408
|
-
self.assertEqual(munge_search_term(_in), _out)
|
|
409
|
-
|
|
410
336
|
def test_query_builder_unknown_sort(self):
|
|
411
337
|
results = self.querybuilder(query=self.query, sort_on="unknown")
|
|
412
338
|
self.assertEqual(len(results), 1)
|
|
@@ -5,7 +5,6 @@ from zope.component.hooks import getSite
|
|
|
5
5
|
from zope.interface import implementer
|
|
6
6
|
from zope.schema.interfaces import IVocabularyFactory
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
# this vocabulary is in this package by intend.
|
|
10
9
|
# since plone.app.querystring depends on plone.app.vocabularies
|
|
11
10
|
# we can not put it over there without creating a circular dependency.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plone.app.querystring
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.0a3
|
|
4
4
|
Summary: A queryparser, querybuilder and extra helper tools, to parse stored queries to actual results, used in new style Plone collections
|
|
5
5
|
Home-page: https://github.com/plone/plone.app.querystring
|
|
6
6
|
Author: Plone Foundation
|
|
@@ -88,6 +88,26 @@ Changelog
|
|
|
88
88
|
|
|
89
89
|
.. towncrier release notes start
|
|
90
90
|
|
|
91
|
+
3.0.0a3 (2026-03-30)
|
|
92
|
+
--------------------
|
|
93
|
+
|
|
94
|
+
Bug fixes:
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
- Fix multi-word search so all word parts get wildcard prefix matching, not just the last one.
|
|
98
|
+
Use ``munge_search_term`` from ``plone.base.utils``, deprecate old import path.
|
|
99
|
+
@jensens (#4205)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
Internal:
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
- Remove Subject index modifier — a Python 2 leftover that was already a no-op.
|
|
106
|
+
@jensens (#155)
|
|
107
|
+
- Update configuration files.
|
|
108
|
+
[plone devs]
|
|
109
|
+
|
|
110
|
+
|
|
91
111
|
3.0.0a2 (2025-11-26)
|
|
92
112
|
--------------------
|
|
93
113
|
|
plone_app_querystring-3.0.0a2/src/plone/app/querystring/indexmodifiers/query_index_modifiers.py
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
from dateutil.parser import parse
|
|
2
|
-
from plone.app.querystring.interfaces import IParsedQueryIndexModifier
|
|
3
|
-
from zope.interface import implementer
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@implementer(IParsedQueryIndexModifier)
|
|
7
|
-
class Subject:
|
|
8
|
-
"""
|
|
9
|
-
The Subject field in Plone currently uses a utf-8 encoded string.
|
|
10
|
-
When a catalog query tries to compare a unicode string from the
|
|
11
|
-
parsedquery with existing utf-8 encoded string indexes unindexing
|
|
12
|
-
will fail with a UnicodeDecodeError. To prevent this from happening
|
|
13
|
-
we always encode the Subject query.
|
|
14
|
-
|
|
15
|
-
XXX: As soon as Plone uses unicode for all indexes, this code can
|
|
16
|
-
be removed.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
def __call__(self, value):
|
|
20
|
-
return ("Subject", value)
|
|
21
|
-
|
|
22
|
-
# Get the query operator
|
|
23
|
-
op = None
|
|
24
|
-
if "query" in value:
|
|
25
|
-
op = "query"
|
|
26
|
-
elif "not" in value:
|
|
27
|
-
op = "not"
|
|
28
|
-
|
|
29
|
-
query = value[op]
|
|
30
|
-
# query can be a unicode string or a list of unicode strings.
|
|
31
|
-
if isinstance(query, str):
|
|
32
|
-
query = query.encode("utf-8")
|
|
33
|
-
elif isinstance(query, list):
|
|
34
|
-
# We do not want to change the collections' own query string,
|
|
35
|
-
# therefore we create a new copy of the list.
|
|
36
|
-
copy_of_query = list(query)
|
|
37
|
-
# Iterate over all query items and encode them if they are
|
|
38
|
-
# unicode strings
|
|
39
|
-
i = 0
|
|
40
|
-
for item in copy_of_query:
|
|
41
|
-
if isinstance(item, str):
|
|
42
|
-
copy_of_query[i] = item.encode("utf-8")
|
|
43
|
-
i += 1
|
|
44
|
-
query = copy_of_query
|
|
45
|
-
else:
|
|
46
|
-
pass
|
|
47
|
-
value[op] = query
|
|
48
|
-
return ("Subject", value)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@implementer(IParsedQueryIndexModifier)
|
|
52
|
-
class base:
|
|
53
|
-
"""DateIndex query modifier
|
|
54
|
-
see Products.PluginIndexes.DateIndex.DateIndex.DateIndex._convert function
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
def __call__(self, value):
|
|
58
|
-
def _normalize(val):
|
|
59
|
-
"""Encode value, parse dates."""
|
|
60
|
-
|
|
61
|
-
if isinstance(val, str):
|
|
62
|
-
try:
|
|
63
|
-
val = parse(val)
|
|
64
|
-
except (ValueError, AttributeError):
|
|
65
|
-
pass
|
|
66
|
-
|
|
67
|
-
return val
|
|
68
|
-
|
|
69
|
-
query = value["query"]
|
|
70
|
-
query = _normalize(query)
|
|
71
|
-
|
|
72
|
-
if isinstance(query, list):
|
|
73
|
-
aux = list()
|
|
74
|
-
for item in query:
|
|
75
|
-
aux.append(_normalize(item))
|
|
76
|
-
query = aux
|
|
77
|
-
|
|
78
|
-
value["query"] = query
|
|
79
|
-
return (self.__class__.__name__, value)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
class Date(base):
|
|
83
|
-
pass
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
class created(base):
|
|
87
|
-
pass
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class effective(base):
|
|
91
|
-
pass
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class end(base):
|
|
95
|
-
pass
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
class expires(base):
|
|
99
|
-
pass
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
class modified(base):
|
|
103
|
-
pass
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
class start(base):
|
|
107
|
-
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/results.pt
RENAMED
|
File without changes
|
{plone_app_querystring-3.0.0a2 → plone_app_querystring-3.0.0a3}/src/plone/app/querystring/testing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|