--- a/src/pyams_content/shared/view/__init__.py Mon Jan 07 11:36:09 2019 +0100
+++ b/src/pyams_content/shared/view/__init__.py Tue Jan 08 14:02:06 2019 +0100
@@ -9,6 +9,9 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
+from copy import deepcopy
+
+from jedi.evaluate.helpers import deep_ast_copy
__docformat__ = 'restructuredtext'
@@ -112,7 +115,7 @@
def get_results(self, context, sort_index=None, reverse=None, limit=None,
start=0, length=999, ignore_cache=False, get_count=False, request=None):
- results = _MARKER
+ results, count = _MARKER, 0
if not ignore_cache:
# check for cache
views_cache = get_cache(VIEWS_CACHE_REGION, VIEWS_CACHE_NAME)
@@ -129,11 +132,13 @@
# Execute query
if results is _MARKER:
registry = get_current_registry()
+ # Look for Elasticsearch query adapter, if available...
adapter = registry.queryAdapter(self, IViewQuery, name='es')
if adapter is None:
adapter = registry.getAdapter(self, IViewQuery)
if not sort_index:
sort_index = self.order_by
+ # Get query results
results, count = adapter.get_results(context,
sort_index,
reverse if reverse is not None else self.reversed_order,
@@ -189,25 +194,27 @@
for new_params in adapter.get_params(context, request):
if isinstance(new_params, tuple):
new_params, do_search = new_params
- if new_params:
+ if new_params is None:
+ return None
+ else:
params &= new_params
if not do_search:
break
# activate search
if do_search:
- params &= Gt(catalog['push_end_date'], now)
+ filters = Gt(catalog['push_end_date'], now)
# check content path
content_path = view.get_content_path(context)
if content_path is not None:
- params &= Eq(catalog['parents'], content_path)
+ filters &= Eq(catalog['parents'], content_path)
# check content types
content_types = view.get_content_types(context)
if content_types:
- params &= Any(catalog['content_type'], content_types)
+ filters &= Any(catalog['content_type'], content_types)
# check data types
data_types = view.get_data_types(context)
if data_types:
- params &= Any(catalog['data_type'], data_types)
+ filters &= Any(catalog['data_type'], data_types)
return params
def get_results(self, context, sort_index, reverse, limit, request=None):
@@ -215,14 +222,18 @@
catalog = get_utility(ICatalog)
registry = get_current_registry()
params = self.get_params(context, request)
- if (not sort_index) or (sort_index == RELEVANCE_ORDER):
- sort_index = None
- query = CatalogQuery(catalog).query(params,
- sort_index=sort_index,
- reverse=reverse,
- limit=limit)
- total_count = query[0]
- items = CatalogResultSet(query)
+ if params is None:
+ items = CatalogResultSet([])
+ total_count = 0
+ else:
+ if (not sort_index) or (sort_index == RELEVANCE_ORDER):
+ sort_index = None
+ query = CatalogQuery(catalog).query(params,
+ sort_index=sort_index,
+ reverse=reverse,
+ limit=limit)
+ total_count = query[0]
+ items = CatalogResultSet(query)
for name, adapter in sorted(registry.getAdapters((view,), IViewQueryFilterExtension),
key=lambda x: x[1].weight):
items = adapter.filter(context, items, request)
--- a/src/pyams_content/shared/view/interfaces.py Mon Jan 07 11:36:09 2019 +0100
+++ b/src/pyams_content/shared/view/interfaces.py Tue Jan 08 14:02:06 2019 +0100
@@ -168,7 +168,13 @@
"""View query extension interface"""
def get_params(self, context, request=None):
- """Add params to catalog query"""
+ """Add params to catalog query
+
+ This method may return an iterator.
+ If defined settings are such that no result can be found (for example, if the view is
+ defined to use context themes but context doesn't have any), method can yield a "None"
+ value which will cancel query execution.
+ """
class IViewQueryEsParamsExtension(IViewQueryExtension):
--- a/src/pyams_content/shared/view/merge.py Mon Jan 07 11:36:09 2019 +0100
+++ b/src/pyams_content/shared/view/merge.py Tue Jan 08 14:02:06 2019 +0100
@@ -12,23 +12,19 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
from heapq import merge
-from random import shuffle
from itertools import chain, zip_longest
+from random import shuffle
-# import interfaces
-from pyams_content.shared.view.interfaces import VIEWS_MERGERS_VOCABULARY, IViewsMerger, CREATION_DATE_ORDER, \
- UPDATE_DATE_ORDER, PUBLICATION_DATE_ORDER, FIRSTPUBLICATION_DATE_ORDER
-from pyams_workflow.interfaces import IWorkflowPublicationInfo
+from zope.componentvocabulary.vocabulary import UtilityTerm, UtilityVocabulary
from zope.dublincore.interfaces import IZopeDublinCore
-# import packages
+from pyams_content.shared.view.interfaces import CREATION_DATE_ORDER, FIRSTPUBLICATION_DATE_ORDER, IViewsMerger, \
+ PUBLICATION_DATE_ORDER, UPDATE_DATE_ORDER, VIEWS_MERGERS_VOCABULARY
from pyams_utils.registry import utility_config
from pyams_utils.request import check_request
from pyams_utils.vocabulary import vocabulary_config
-from zope.componentvocabulary.vocabulary import UtilityVocabulary, UtilityTerm
+from pyams_workflow.interfaces import IWorkflowPublicationInfo
from pyams_content import _
--- a/src/pyams_content/shared/view/reference.py Mon Jan 07 11:36:09 2019 +0100
+++ b/src/pyams_content/shared/view/reference.py Tue Jan 08 14:02:06 2019 +0100
@@ -47,7 +47,7 @@
refs = []
if self.select_context_references:
references = IInternalReferencesList(context, None)
- if references is not None:
+ if (references is not None) and references.references:
refs.extend(references.references)
if self.references:
refs.extend(self.references)
@@ -70,31 +70,44 @@
def get_params(self, context, request=None):
settings = IViewInternalReferencesSettings(self.context)
- catalog = get_utility(ICatalog)
- # check view settings
- if settings.exclude_context:
- sequence = ISequentialIdInfo(context, None)
- if sequence is not None:
- oid = sequence.hex_oid
- yield NotEq(catalog['oid'], oid)
# check view references mode
if settings.references_mode == ONLY_REFERENCE_MODE:
- yield Any(catalog['oid'], settings.references), False
+ # references are retrieved by query filter extension, so no params are required!
+ yield None
+ else:
+ # check view settings
+ if settings.exclude_context:
+ sequence = ISequentialIdInfo(context, None)
+ if sequence is not None:
+ oid = sequence.hex_oid
+ catalog = get_utility(ICatalog)
+ yield NotEq(catalog['oid'], oid)
@adapter_config(name='references', context=IWfView, provides=IViewQueryFilterExtension)
class ViewInternalReferencesQueryFilterExtension(ContextAdapter):
- """View internal references filter extension"""
+ """View internal references filter extension
+
+ If internal references are selected, these references are forced.
+ """
weight = 999
def filter(self, context, items, request=None):
settings = IViewInternalReferencesSettings(self.context)
- if not settings.references:
+ references = settings.get_references(context)
+ if not references:
return items
- if (not items) or (settings.references_mode == ALWAYS_REFERENCE_MODE):
+ excluded_oid = None
+ if settings.exclude_context:
+ sequence = ISequentialIdInfo(context, None)
+ if sequence is not None:
+ excluded_oid = sequence.hex_oid
+ if (not items) or (settings.references_mode in (ALWAYS_REFERENCE_MODE, ONLY_REFERENCE_MODE)):
catalog = get_utility(ICatalog)
- for reference in settings.references:
+ for reference in reversed(references):
+ if reference == excluded_oid:
+ continue
params = Eq(catalog['oid'], reference) & \
Any(catalog['workflow_state'], VISIBLE_STATES)
items.prepend(CatalogResultSet(CatalogQuery(catalog).query(params)))
--- a/src/pyams_content/shared/view/theme.py Mon Jan 07 11:36:09 2019 +0100
+++ b/src/pyams_content/shared/view/theme.py Tue Jan 08 14:02:06 2019 +0100
@@ -82,6 +82,8 @@
tags = settings.get_tags_index(context)
if tags:
yield Any(catalog['tags'], tags)
+ elif settings.select_context_tags:
+ yield None
@adapter_config(name='tags', context=SearchFolderQuery, provides=IViewUserQuery)
@@ -156,6 +158,8 @@
themes = settings.get_themes_index(context)
if themes:
yield Any(catalog['themes'], themes)
+ elif settings.select_context_themes:
+ yield None
#
@@ -209,3 +213,5 @@
collections = settings.get_collections_index(context)
if collections:
yield Any(catalog['collections'], collections)
+ elif settings.select_context_collections:
+ yield None