src/pyams_content/shared/view/__init__.py
changeset 92 3facc843c06f
parent 81 3e37d4dd8e3b
child 95 83d6b58ada5f
equal deleted inserted replaced
91:87e08c0f3e3c 92:3facc843c06f
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
    10 # FOR A PARTICULAR PURPOSE.
    10 # FOR A PARTICULAR PURPOSE.
    11 #
    11 #
    12 
    12 
    13 
       
    14 __docformat__ = 'restructuredtext'
    13 __docformat__ = 'restructuredtext'
    15 
    14 
    16 
    15 
    17 # import standard library
    16 # import standard library
       
    17 import logging
       
    18 logger = logging.getLogger("PyAMS (content)")
    18 
    19 
    19 # import interfaces
    20 # import interfaces
    20 from pyams_content.component.links.interfaces import ILinkContainerTarget
    21 from hypatia.interfaces import ICatalog
    21 from pyams_content.shared.view.interfaces import IWfView, IView, VIEW_CONTENT_TYPE, VIEW_CONTENT_NAME
    22 from pyams_content.shared.view.interfaces import IView, IWfView, IViewQuery, IViewQueryParamsExtension, \
       
    23     IViewQueryFilterExtension, VIEW_CONTENT_TYPE, VIEW_CONTENT_NAME
       
    24 from zope.intid.interfaces import IIntIds
    22 
    25 
    23 # import packages
    26 # import packages
       
    27 from hypatia.catalog import CatalogQuery
       
    28 from hypatia.query import Any
       
    29 from pyams_cache.beaker import get_cache
       
    30 from pyams_catalog.query import CatalogResultSet, or_
    24 from pyams_content.shared.common import WfSharedContent, register_content_type, SharedContent
    31 from pyams_content.shared.common import WfSharedContent, register_content_type, SharedContent
       
    32 from pyams_utils.adapter import adapter_config, ContextAdapter
       
    33 from pyams_utils.list import unique
       
    34 from pyams_utils.registry import get_utility
       
    35 from pyams_workflow.interfaces import IWorkflow
       
    36 from pyramid.threadlocal import get_current_registry
    25 from zope.interface import implementer
    37 from zope.interface import implementer
    26 from zope.schema.fieldproperty import FieldProperty
    38 from zope.schema.fieldproperty import FieldProperty
       
    39 
       
    40 
       
    41 VIEWS_CACHE_NAME = 'PyAMS::view'
       
    42 VIEWS_CACHE_KEY = 'view_{view}.context_{context}'
    27 
    43 
    28 
    44 
    29 @implementer(IWfView)
    45 @implementer(IWfView)
    30 class WfView(WfSharedContent):
    46 class WfView(WfSharedContent):
    31     """Base view"""
    47     """Base view"""
    33     content_type = VIEW_CONTENT_TYPE
    49     content_type = VIEW_CONTENT_TYPE
    34     content_name = VIEW_CONTENT_NAME
    50     content_name = VIEW_CONTENT_NAME
    35 
    51 
    36     selected_content_types = FieldProperty(IWfView['selected_content_types'])
    52     selected_content_types = FieldProperty(IWfView['selected_content_types'])
    37     order_by = FieldProperty(IWfView['order_by'])
    53     order_by = FieldProperty(IWfView['order_by'])
    38     reversed_order  =FieldProperty(IWfView['reversed_order'])
    54     reversed_order = FieldProperty(IWfView['reversed_order'])
       
    55 
       
    56     def get_results(self, context, limit=None):
       
    57         intids = get_utility(IIntIds)
       
    58         views_cache = get_cache('default', VIEWS_CACHE_NAME)
       
    59         cache_key = VIEWS_CACHE_KEY.format(view=intids.queryId(self),
       
    60                                            context=intids.queryId(context))
       
    61         try:
       
    62             results = views_cache.get_value(cache_key)
       
    63         except KeyError:
       
    64             registry = get_current_registry()
       
    65             adapter = registry.queryAdapter(self, IViewQuery, name='es')
       
    66             if adapter is None:
       
    67                 adapter = registry.getAdapter(self, IViewQuery)
       
    68             results = adapter.get_results(context)
       
    69             views_cache.set_value(cache_key, [intids.queryId(item) for item in results])
       
    70             logger.debug("Storing view items to cache key {0}".format(cache_key))
       
    71         else:
       
    72             results = CatalogResultSet(results)
       
    73             logger.debug("Retrieving view items from cache key {0}".format(cache_key))
       
    74         return results
    39 
    75 
    40 register_content_type(WfView)
    76 register_content_type(WfView)
    41 
    77 
    42 
    78 
    43 @implementer(IView)
    79 @implementer(IView)
    44 class View(SharedContent):
    80 class View(SharedContent):
    45     """Workflow managed view class"""
    81     """Workflow managed view class"""
    46 
    82 
    47     content_class = WfView
    83     content_class = WfView
       
    84 
       
    85 
       
    86 @adapter_config(context=IWfView, provides=IViewQuery)
       
    87 class ViewQuery(ContextAdapter):
       
    88     """View query"""
       
    89 
       
    90     def get_es_params(self, context):
       
    91         view = self.context
       
    92         catalog = get_utility(ICatalog)
       
    93         registry = get_current_registry()
       
    94         params = Any(catalog['content_type'], view.selected_content_types)
       
    95         wf_params = None
       
    96         for workflow in registry.getAllUtilitiesRegisteredFor(IWorkflow):
       
    97             wf_params = or_(wf_params, Any(catalog['workflow_state'], workflow.published_states))
       
    98         params &= wf_params
       
    99         for name, adapter in sorted(registry.getAdapters((view,), IViewQueryParamsExtension),
       
   100                                     key=lambda x: x[1].weight):
       
   101             new_params = adapter.get_params(context)
       
   102             if new_params:
       
   103                 params &= new_params
       
   104         return params
       
   105 
       
   106     def get_results(self, context, limit=None):
       
   107         view = self.context
       
   108         catalog = get_utility(ICatalog)
       
   109         registry = get_current_registry()
       
   110         params = self.get_es_params(context)
       
   111         items = CatalogResultSet(CatalogQuery(catalog).query(params,
       
   112                                                              sort_index=view.order_by,
       
   113                                                              reverse=view.reversed_order,
       
   114                                                              limit=limit))
       
   115         for name, adapter in sorted(registry.getAdapters((view,), IViewQueryFilterExtension),
       
   116                                     key=lambda x: x[1].weight):
       
   117             items = adapter.filter(context, items)
       
   118         return unique(items)