--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/zmi/search.py Thu Oct 08 13:37:29 2015 +0200
@@ -0,0 +1,250 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from hypatia.interfaces import ICatalog
+from pyams_content.profile.interfaces import IAdminProfile
+from pyams_content.shared.common.interfaces import ISharedTool
+from pyams_content.shared.common.interfaces.zmi import ISharedToolDashboardTable
+from pyams_pagelet.interfaces import PageletCreatedEvent
+from pyams_sequence.interfaces import ISequentialIntIds
+from pyams_skin.interfaces import IPageHeader, IContentSearch
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
+from pyams_workflow.interfaces import IWorkflowVersions, IWorkflow
+from pyams_zmi.interfaces import IAdminView
+from z3c.table.interfaces import IValues
+from zope.dublincore.interfaces import IZopeDublinCore
+
+# import packages
+from hypatia.catalog import CatalogQuery
+from hypatia.query import Eq, Contains, Ge, Le
+from pyams_content.workflow import STATES_VOCABULARY
+from pyams_catalog.query import CatalogResultSet
+from pyams_form.search import SearchView, SearchForm, SearchResultsView, ISearchFields
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_security.schema import Principal
+from pyams_skin.page import DefaultPageHeaderAdapter
+from pyams_skin.table import BaseTable
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
+from pyams_utils.list import unique
+from pyams_utils.registry import get_utility
+from pyams_zmi.view import AdminView
+from pyramid.response import Response
+from pyramid.view import view_config
+from z3c.form import field
+from zope.interface import implementer
+from zope.schema import Date, Choice
+
+from pyams_content import _
+
+
+#
+# Quick search adapters
+#
+
+@view_config(name='quick-search.html', context=ISharedTool, request_type=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
+def shared_tool_quick_search_view(request):
+ """Shared tool quick search view"""
+ results = SharedToolQuickSearchResults(request.context, request)
+ results.update()
+ return Response(results.render())
+
+
+@implementer(ISharedToolDashboardTable)
+class SharedToolQuickSearchResults(BaseTable):
+ """Shared tool quick search results table"""
+
+ title = _("Quick search results")
+
+ sortOn = None
+
+ @property
+ def data_attributes(self):
+ attributes = super(SharedToolQuickSearchResults, self).data_attributes
+ attributes['table'] = {'data-ams-datatable-sorting': '[]',
+ 'data-ams-datatable-display-length':
+ IAdminProfile(self.request.principal).table_page_length}
+ return attributes
+
+
+@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolQuickSearchResults), provides=IValues)
+class SharedToolQuickSearchValues(ContextRequestViewAdapter):
+ """Shared tool quick search results view values adapter"""
+
+ @property
+ def values(self):
+ catalog = get_utility(ICatalog)
+ params = Eq(catalog['content_type'], self.context.shared_content_type)
+ query = self.request.params.get('query')
+ if query:
+ sequence = get_utility(ISequentialIntIds)
+ if query.startswith('+'):
+ params &= Eq(catalog['oid'], sequence.get_full_oid(query))
+ else:
+ query_params = Eq(catalog['oid'], sequence.get_full_oid(query))
+ index = catalog['title:' + self.request.registry.settings.get('pyramid.default_locale_name', 'en')]
+ if index.check_query(query):
+ query_params |= Contains(index, ' and '.join((w+'*' for w in query.split())))
+ params &= query_params
+ return unique(map(lambda x: IWorkflowVersions(x).get_last_versions()[0],
+ CatalogResultSet(CatalogQuery(catalog).query(params,
+ sort_index='modified_date',
+ reverse=True))))
+
+
+#
+# Advanced search adapters
+#
+
+class ISharedToolAdvancedSearchFields(ISearchFields):
+ """Shared tool advanced search fields"""
+
+ owner = Principal(title=_("Owner"),
+ required=False)
+
+ status = Choice(title=_("Status"),
+ vocabulary=STATES_VOCABULARY,
+ required=False)
+
+ created_after = Date(title=_("Created after..."),
+ required=False)
+
+ created_before = Date(title=_("Created before..."),
+ required=False)
+
+ modified_after = Date(title=_("Modified after..."),
+ required=False)
+
+ modified_before = Date(title=_("Modified before..."),
+ required=False)
+
+
+@template_config(template='templates/advanced-search.pt', layer=IPyAMSLayer)
+@implementer(IAdminView)
+class SharedToolAdvancedSearchForm(SearchForm):
+ """Shared tool advanced search form"""
+
+ legend = _("Advanced search")
+
+ ajax_handler = 'advanced-search-results.html'
+
+ def __init__(self, context, request):
+ super(SharedToolAdvancedSearchForm, self).__init__(context, request)
+ request.registry.notify(PageletCreatedEvent(self))
+
+ @property
+ def fields(self):
+ workflow = IWorkflow(self.context)
+ fields = field.Fields(ISharedToolAdvancedSearchFields)
+ fields['status'].vocabulary = workflow.states
+ return fields
+
+
+@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolAdvancedSearchForm), provides=IContentSearch)
+class SharedToolAdvancedSearchFormSearchAdapter(ContextRequestViewAdapter):
+ """Shared tool adavanced search form search adapter"""
+
+ def get_search_results(self, data):
+ catalog = get_utility(ICatalog)
+ params = Eq(catalog['content_type'], self.context.shared_content_type)
+ query = data.get('query')
+ if query:
+ sequence = get_utility(ISequentialIntIds)
+ if query.startswith('+'):
+ params &= Eq(catalog['oid'], sequence.get_full_oid(query))
+ else:
+ query_params = Eq(catalog['oid'], sequence.get_full_oid(query))
+ index = catalog['title:' + self.request.registry.settings.get('pyramid.default_locale_name', 'en')]
+ if index.check_query(query):
+ query_params |= Contains(index, ' and '.join((w+'*' for w in query.split())))
+ params &= query_params
+ if data.get('owner'):
+ params &= Eq(catalog['owner'], data['owner'])
+ if data.get('status'):
+ params &= Eq(catalog['workflow_state'], data['status'])
+ if data.get('created_after'):
+ params &= Ge(catalog['created_date'], data['created_after'])
+ if data.get('created_before'):
+ params &= Le(catalog['created_date'], data['created_before'])
+ if data.get('modified_after'):
+ params &= Ge(catalog['modified_date'], data['modified_after'])
+ if data.get('modified_before'):
+ params &= Le(catalog['modified_date'], data['modified_before'])
+ if data.get('status'):
+ return unique(map(lambda x: sorted(IWorkflowVersions(x).get_versions(data['status']),
+ key=lambda y: IZopeDublinCore(y).modified)[0],
+ CatalogResultSet(CatalogQuery(catalog).query(params,
+ sort_index='modified_date',
+ reverse=True))))
+ else:
+ return unique(map(lambda x: IWorkflowVersions(x).get_last_versions()[0],
+ CatalogResultSet(CatalogQuery(catalog).query(params,
+ sort_index='modified_date',
+ reverse=True))))
+
+
+@pagelet_config(name='advanced-search.html', context=ISharedTool, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
+class SharedToolAdvancedSearchView(AdminView, SearchView):
+ """Shared tool advanced search view"""
+
+ search_form_factory = SharedToolAdvancedSearchForm
+
+
+@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolAdvancedSearchView), provides=IPageHeader)
+class SharedToolAdvancedSearchHeaderAdapter(DefaultPageHeaderAdapter):
+ """Shared tool advanced search header adapter"""
+
+ back_url = '#dashboard.html'
+ back_target = None
+
+ icon_class = 'fa fa-fw fa-search'
+
+
+@view_config(name='advanced-search-results.html', context=ISharedTool, request_type=IPyAMSLayer,
+ permission=VIEW_SYSTEM_PERMISSION)
+@implementer(ISharedToolDashboardTable)
+class SharedToolAdvancedSearchResultsView(AdminView, SearchResultsView):
+ """Shared tool advanced search results view"""
+
+ title = _("Advanced search results")
+ search_form_factory = SharedToolAdvancedSearchForm
+
+ sortOn = None
+
+ def __init__(self, context, request):
+ super(SharedToolAdvancedSearchResultsView, self).__init__(context, request)
+ request.registry.notify(PageletCreatedEvent(self))
+
+ @property
+ def data_attributes(self):
+ attributes = super(SharedToolAdvancedSearchResultsView, self).data_attributes
+ attributes['table'] = {'data-ams-datatable-sorting': '[]',
+ 'data-ams-datatable-display-length':
+ IAdminProfile(self.request.principal).table_page_length}
+ return attributes
+
+
+@adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolAdvancedSearchResultsView), provides=IValues)
+class SearchResultsViewValuesAdapter(ContextRequestViewAdapter):
+ """Search results view values adapter"""
+
+ @property
+ def values(self):
+ form = self.view.search_form_factory(self.context, self.request)
+ return form.get_search_results()