10 # FOR A PARTICULAR PURPOSE. |
10 # FOR A PARTICULAR PURPOSE. |
11 # |
11 # |
12 |
12 |
13 __docformat__ = 'restructuredtext' |
13 __docformat__ = 'restructuredtext' |
14 |
14 |
|
15 from hypatia.interfaces import ICatalog |
|
16 from hypatia.query import Contains, Or |
15 from zope.interface import implementer |
17 from zope.interface import implementer |
16 from zope.schema.fieldproperty import FieldProperty |
18 from zope.schema.fieldproperty import FieldProperty |
17 |
19 |
18 from pyams_content.component.illustration import IIllustrationTarget, ILinkIllustrationTarget |
20 from pyams_content.component.illustration import IIllustrationTarget, ILinkIllustrationTarget |
19 from pyams_content.features.preview.interfaces import IPreviewTarget |
21 from pyams_content.features.preview.interfaces import IPreviewTarget |
20 from pyams_content.features.search.interfaces import ISearchFolder, ISearchFolderRoles |
22 from pyams_content.features.search.interfaces import ISearchFolder, ISearchFolderRoles |
21 from pyams_content.interfaces import MANAGE_SITE_PERMISSION, MANAGER_ROLE, GUEST_ROLE |
23 from pyams_content.interfaces import GUEST_ROLE, MANAGER_ROLE, MANAGE_SITE_PERMISSION |
22 from pyams_content.shared.view import WfView |
24 from pyams_content.shared.view import IViewQuery, ViewQuery, WfView |
|
25 from pyams_content.shared.view.interfaces import IViewUserQuery |
23 from pyams_form.interfaces.form import IFormContextPermissionChecker |
26 from pyams_form.interfaces.form import IFormContextPermissionChecker |
24 from pyams_portal.interfaces import IPortalContext, DESIGNER_ROLE |
27 from pyams_i18n.interfaces import INegotiator |
|
28 from pyams_portal.interfaces import DESIGNER_ROLE, IPortalContext |
25 from pyams_utils.adapter import ContextAdapter, adapter_config |
29 from pyams_utils.adapter import ContextAdapter, adapter_config |
|
30 from pyams_utils.registry import get_utility |
|
31 from pyams_utils.request import check_request |
26 |
32 |
27 from pyams_content import _ |
33 from pyams_content import _ |
28 |
34 |
29 |
35 |
30 @implementer(ISearchFolder, ISearchFolderRoles, IIllustrationTarget, ILinkIllustrationTarget, |
36 @implementer(ISearchFolder, ISearchFolderRoles, IIllustrationTarget, ILinkIllustrationTarget, |
35 __roles__ = (MANAGER_ROLE, DESIGNER_ROLE, GUEST_ROLE) |
41 __roles__ = (MANAGER_ROLE, DESIGNER_ROLE, GUEST_ROLE) |
36 roles_interface = ISearchFolderRoles |
42 roles_interface = ISearchFolderRoles |
37 |
43 |
38 content_name = _("Search folder") |
44 content_name = _("Search folder") |
39 |
45 |
40 handle_content_url = True |
|
41 handle_header = True |
46 handle_header = True |
42 handle_description = True |
47 handle_description = True |
43 |
48 |
44 sequence_name = '' # use default sequence generator |
49 sequence_name = '' # use default sequence generator |
45 sequence_prefix = '' |
50 sequence_prefix = '' |
46 |
51 |
47 selected_content_types = FieldProperty(ISearchFolder['selected_content_types']) |
52 selected_content_types = FieldProperty(ISearchFolder['selected_content_types']) |
48 selected_datatypes = FieldProperty(ISearchFolder['selected_datatypes']) |
53 selected_datatypes = FieldProperty(ISearchFolder['selected_datatypes']) |
49 |
54 |
|
55 order_by = FieldProperty(ISearchFolder['order_by']) |
50 visible_in_list = FieldProperty(ISearchFolder['visible_in_list']) |
56 visible_in_list = FieldProperty(ISearchFolder['visible_in_list']) |
51 navigation_title = FieldProperty(ISearchFolder['navigation_title']) |
57 navigation_title = FieldProperty(ISearchFolder['navigation_title']) |
52 |
58 |
53 @staticmethod |
59 @staticmethod |
54 def is_deletable(): |
60 def is_deletable(): |
55 return True |
61 return True |
56 |
62 |
|
63 def get_results(self, context, sort_index=None, reverse=None, limit=None, |
|
64 start=0, length=None, ignore_cache=False, get_count=False): |
|
65 if not ignore_cache: |
|
66 request = check_request() |
|
67 ignore_cache = bool(request.params) |
|
68 return super(SearchFolder, self).get_results(context, sort_index, reverse, limit, |
|
69 start, length, ignore_cache, get_count) |
|
70 |
57 |
71 |
58 @adapter_config(context=ISearchFolder, provides=IFormContextPermissionChecker) |
72 @adapter_config(context=ISearchFolder, provides=IFormContextPermissionChecker) |
59 class SearchFolderPermissionChecker(ContextAdapter): |
73 class SearchFolderPermissionChecker(ContextAdapter): |
60 """Search folder edit permission checker""" |
74 """Search folder edit permission checker""" |
61 |
75 |
62 edit_permission = MANAGE_SITE_PERMISSION |
76 edit_permission = MANAGE_SITE_PERMISSION |
|
77 |
|
78 |
|
79 @adapter_config(context=ISearchFolder, provides=IViewQuery) |
|
80 class SearchFolderQuery(ViewQuery): |
|
81 """Search folder query adapter""" |
|
82 |
|
83 def get_params(self, context): |
|
84 params = super(SearchFolderQuery, self).get_params(context) |
|
85 request = check_request() |
|
86 registry = request.registry |
|
87 for name, adapter in registry.getAdapters((self,), IViewUserQuery): |
|
88 for user_param in adapter.get_user_params(request): |
|
89 params &= user_param |
|
90 return params |
|
91 |
|
92 |
|
93 @adapter_config(name='user_search', context=SearchFolderQuery, provides=IViewUserQuery) |
|
94 class SearchFolderUserQuery(ContextAdapter): |
|
95 """Search folder user query""" |
|
96 |
|
97 @staticmethod |
|
98 def get_user_params(request): |
|
99 params = request.params |
|
100 fulltext = params.get('user_search') |
|
101 if fulltext: |
|
102 catalog = get_utility(ICatalog) |
|
103 negotiator = get_utility(INegotiator) |
|
104 query_params = [] |
|
105 for lang in {request.registry.settings.get('pyramid.default_locale_name', 'en'), |
|
106 request.locale_name, |
|
107 negotiator.server_language} | negotiator.offered_languages: |
|
108 index_name = 'title:{0}'.format(lang) |
|
109 if index_name in catalog: |
|
110 index = catalog[index_name] |
|
111 if index.check_query(fulltext): |
|
112 query_params.append(Contains(index, ' and '.join((w + '*' for w in fulltext.split())))) |
|
113 yield Or(*query_params) |