src/pyams_content/shared/view/__init__.py
changeset 1121 852aa448da04
parent 1090 d6d041577ae0
child 1134 35e8b9cd9070
--- a/src/pyams_content/shared/view/__init__.py	Mon Nov 26 17:06:03 2018 +0100
+++ b/src/pyams_content/shared/view/__init__.py	Tue Nov 27 08:50:02 2018 +0100
@@ -13,10 +13,8 @@
 __docformat__ = 'restructuredtext'
 
 import logging
-logger = logging.getLogger("PyAMS (content)")
-
 from datetime import datetime
-from itertools import tee
+from itertools import islice, tee
 
 from hypatia.catalog import CatalogQuery
 from hypatia.interfaces import ICatalog
@@ -36,7 +34,8 @@
     IWfSharedContent
 from pyams_content.shared.common.interfaces.types import IWfTypedSharedContent
 from pyams_content.shared.view.interfaces import IView, IWfView, IWfViewFactory, IViewQuery, \
-    IViewQueryParamsExtension, IViewQueryFilterExtension, VIEW_CONTENT_TYPE, VIEW_CONTENT_NAME, IViewSettings
+    IViewQueryParamsExtension, IViewQueryFilterExtension, VIEW_CONTENT_TYPE, VIEW_CONTENT_NAME, IViewSettings, \
+    RELEVANCE_ORDER
 from pyams_utils.adapter import adapter_config, ContextAdapter
 from pyams_utils.interfaces import ICacheKeyValue
 from pyams_utils.list import unique_iter
@@ -45,6 +44,8 @@
 from pyams_workflow.interfaces import IWorkflow
 
 
+logger = logging.getLogger("PyAMS (content)")
+
 VIEWS_CACHE_REGION = 'views'
 VIEWS_CACHE_NAME = 'PyAMS::view'
 
@@ -103,7 +104,8 @@
             data_types |= set(self.selected_datatypes)
         return list(data_types)
 
-    def get_results(self, context, sort_index=None, reverse=None, limit=None, ignore_cache=False):
+    def get_results(self, context, sort_index=None, reverse=None,
+                    limit=None, start=0, length=999, ignore_cache=False, get_count=False):
         results = _MARKER
         if not ignore_cache:
             # check for cache
@@ -115,6 +117,7 @@
                 cache_key = VIEW_CACHE_KEY.format(view=ICacheKeyValue(self))
             try:
                 results = views_cache.get_value(cache_key)
+                count = views_cache.get_value(cache_key + '::count')
             except KeyError:
                 pass
         # Execute query
@@ -123,19 +126,25 @@
             adapter = registry.queryAdapter(self, IViewQuery, name='es')
             if adapter is None:
                 adapter = registry.getAdapter(self, IViewQuery)
-            results = adapter.get_results(context,
-                                          sort_index or self.order_by,
-                                          reverse if reverse is not None else self.reversed_order,
-                                          limit or self.limit)
-            intids = get_utility(IIntIds)
-            cache, results = tee(results)
+            if sort_index == RELEVANCE_ORDER:
+                sort_index = None  # keep natural order
+            else:
+                sort_index = self.order_by
+            results, count = adapter.get_results(context,
+                                                 sort_index,
+                                                 reverse if reverse is not None else self.reversed_order,
+                                                 limit or self.limit)
+            count = min(count, limit or self.limit or 999)
+            cache, results = tee(islice(results, start, start + length))
             if not ignore_cache:
+                intids = get_utility(IIntIds)
                 views_cache.set_value(cache_key, [intids.queryId(item) for item in cache])
+                views_cache.set_value(cache_key + '::count', count)
                 logger.debug("Storing view items to cache key {0}".format(cache_key))
         else:
             results = CatalogResultSet(results)
             logger.debug("Retrieving view items from cache key {0}".format(cache_key))
-        return results
+        return (results, count) if get_count else results
 
 
 register_content_type(WfView)
@@ -172,11 +181,11 @@
         do_search = True
         for name, adapter in sorted(registry.getAdapters((view,), IViewQueryParamsExtension),
                                     key=lambda x: x[1].weight):
-            new_params = adapter.get_params(context)
-            if isinstance(new_params, tuple):
-                new_params, do_search = new_params
-            if new_params:
-                params &= new_params
+            for new_params in adapter.get_params(context):
+                if isinstance(new_params, tuple):
+                    new_params, do_search = new_params
+                if new_params:
+                    params &= new_params
             if not do_search:
                 break
         # activate search
@@ -197,14 +206,18 @@
         catalog = get_utility(ICatalog)
         registry = get_current_registry()
         params = self.get_params(context)
-        items = CatalogResultSet(CatalogQuery(catalog).query(params,
-                                                             sort_index=sort_index,
-                                                             reverse=reverse,
-                                                             limit=limit))
+        if 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)
-        return unique_iter(items)
+        return unique_iter(items), total_count
 
 
 @subscriber(IObjectModifiedEvent, context_selector=IWfView)