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) |