src/pyams_content/shared/common/zmi/search.py
changeset 0 7c0001cacf8e
child 3 cdcc8fa70047
equal deleted inserted replaced
-1:000000000000 0:7c0001cacf8e
       
     1 #
       
     2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
       
     3 # All Rights Reserved.
       
     4 #
       
     5 # This software is subject to the provisions of the Zope Public License,
       
     6 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
       
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
       
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
       
    10 # FOR A PARTICULAR PURPOSE.
       
    11 #
       
    12 
       
    13 __docformat__ = 'restructuredtext'
       
    14 
       
    15 
       
    16 # import standard library
       
    17 
       
    18 # import interfaces
       
    19 from hypatia.interfaces import ICatalog
       
    20 from pyams_content.profile.interfaces import IAdminProfile
       
    21 from pyams_content.shared.common.interfaces import ISharedTool
       
    22 from pyams_content.shared.common.interfaces.zmi import ISharedToolDashboardTable
       
    23 from pyams_pagelet.interfaces import PageletCreatedEvent
       
    24 from pyams_sequence.interfaces import ISequentialIntIds
       
    25 from pyams_skin.interfaces import IPageHeader, IContentSearch
       
    26 from pyams_skin.layer import IPyAMSLayer
       
    27 from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
       
    28 from pyams_workflow.interfaces import IWorkflowVersions, IWorkflow
       
    29 from pyams_zmi.interfaces import IAdminView
       
    30 from z3c.table.interfaces import IValues
       
    31 from zope.dublincore.interfaces import IZopeDublinCore
       
    32 
       
    33 # import packages
       
    34 from hypatia.catalog import CatalogQuery
       
    35 from hypatia.query import Eq, Contains, Ge, Le
       
    36 from pyams_content.workflow import STATES_VOCABULARY
       
    37 from pyams_catalog.query import CatalogResultSet
       
    38 from pyams_form.search import SearchView, SearchForm, SearchResultsView, ISearchFields
       
    39 from pyams_pagelet.pagelet import pagelet_config
       
    40 from pyams_security.schema import Principal
       
    41 from pyams_skin.page import DefaultPageHeaderAdapter
       
    42 from pyams_skin.table import BaseTable
       
    43 from pyams_template.template import template_config
       
    44 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
       
    45 from pyams_utils.list import unique
       
    46 from pyams_utils.registry import get_utility
       
    47 from pyams_zmi.view import AdminView
       
    48 from pyramid.response import Response
       
    49 from pyramid.view import view_config
       
    50 from z3c.form import field
       
    51 from zope.interface import implementer
       
    52 from zope.schema import Date, Choice
       
    53 
       
    54 from pyams_content import _
       
    55 
       
    56 
       
    57 #
       
    58 # Quick search adapters
       
    59 #
       
    60 
       
    61 @view_config(name='quick-search.html', context=ISharedTool, request_type=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
       
    62 def shared_tool_quick_search_view(request):
       
    63     """Shared tool quick search view"""
       
    64     results = SharedToolQuickSearchResults(request.context, request)
       
    65     results.update()
       
    66     return Response(results.render())
       
    67 
       
    68 
       
    69 @implementer(ISharedToolDashboardTable)
       
    70 class SharedToolQuickSearchResults(BaseTable):
       
    71     """Shared tool quick search results table"""
       
    72 
       
    73     title = _("Quick search results")
       
    74 
       
    75     sortOn = None
       
    76 
       
    77     @property
       
    78     def data_attributes(self):
       
    79         attributes = super(SharedToolQuickSearchResults, self).data_attributes
       
    80         attributes['table'] = {'data-ams-datatable-sorting': '[]',
       
    81                                'data-ams-datatable-display-length':
       
    82                                    IAdminProfile(self.request.principal).table_page_length}
       
    83         return attributes
       
    84 
       
    85 
       
    86 @adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolQuickSearchResults), provides=IValues)
       
    87 class SharedToolQuickSearchValues(ContextRequestViewAdapter):
       
    88     """Shared tool quick search results view values adapter"""
       
    89 
       
    90     @property
       
    91     def values(self):
       
    92         catalog = get_utility(ICatalog)
       
    93         params = Eq(catalog['content_type'], self.context.shared_content_type)
       
    94         query = self.request.params.get('query')
       
    95         if query:
       
    96             sequence = get_utility(ISequentialIntIds)
       
    97             if query.startswith('+'):
       
    98                 params &= Eq(catalog['oid'], sequence.get_full_oid(query))
       
    99             else:
       
   100                 query_params = Eq(catalog['oid'], sequence.get_full_oid(query))
       
   101                 index = catalog['title:' + self.request.registry.settings.get('pyramid.default_locale_name', 'en')]
       
   102                 if index.check_query(query):
       
   103                     query_params |= Contains(index, ' and '.join((w+'*' for w in query.split())))
       
   104                 params &= query_params
       
   105         return unique(map(lambda x: IWorkflowVersions(x).get_last_versions()[0],
       
   106                           CatalogResultSet(CatalogQuery(catalog).query(params,
       
   107                                                                        sort_index='modified_date',
       
   108                                                                        reverse=True))))
       
   109 
       
   110 
       
   111 #
       
   112 # Advanced search adapters
       
   113 #
       
   114 
       
   115 class ISharedToolAdvancedSearchFields(ISearchFields):
       
   116     """Shared tool advanced search fields"""
       
   117 
       
   118     owner = Principal(title=_("Owner"),
       
   119                       required=False)
       
   120 
       
   121     status = Choice(title=_("Status"),
       
   122                     vocabulary=STATES_VOCABULARY,
       
   123                     required=False)
       
   124 
       
   125     created_after = Date(title=_("Created after..."),
       
   126                          required=False)
       
   127 
       
   128     created_before = Date(title=_("Created before..."),
       
   129                           required=False)
       
   130 
       
   131     modified_after = Date(title=_("Modified after..."),
       
   132                           required=False)
       
   133 
       
   134     modified_before = Date(title=_("Modified before..."),
       
   135                            required=False)
       
   136 
       
   137 
       
   138 @template_config(template='templates/advanced-search.pt', layer=IPyAMSLayer)
       
   139 @implementer(IAdminView)
       
   140 class SharedToolAdvancedSearchForm(SearchForm):
       
   141     """Shared tool advanced search form"""
       
   142 
       
   143     legend = _("Advanced search")
       
   144 
       
   145     ajax_handler = 'advanced-search-results.html'
       
   146 
       
   147     def __init__(self, context, request):
       
   148         super(SharedToolAdvancedSearchForm, self).__init__(context, request)
       
   149         request.registry.notify(PageletCreatedEvent(self))
       
   150 
       
   151     @property
       
   152     def fields(self):
       
   153         workflow = IWorkflow(self.context)
       
   154         fields = field.Fields(ISharedToolAdvancedSearchFields)
       
   155         fields['status'].vocabulary = workflow.states
       
   156         return fields
       
   157 
       
   158 
       
   159 @adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolAdvancedSearchForm), provides=IContentSearch)
       
   160 class SharedToolAdvancedSearchFormSearchAdapter(ContextRequestViewAdapter):
       
   161     """Shared tool adavanced search form search adapter"""
       
   162 
       
   163     def get_search_results(self, data):
       
   164         catalog = get_utility(ICatalog)
       
   165         params = Eq(catalog['content_type'], self.context.shared_content_type)
       
   166         query = data.get('query')
       
   167         if query:
       
   168             sequence = get_utility(ISequentialIntIds)
       
   169             if query.startswith('+'):
       
   170                 params &= Eq(catalog['oid'], sequence.get_full_oid(query))
       
   171             else:
       
   172                 query_params = Eq(catalog['oid'], sequence.get_full_oid(query))
       
   173                 index = catalog['title:' + self.request.registry.settings.get('pyramid.default_locale_name', 'en')]
       
   174                 if index.check_query(query):
       
   175                     query_params |= Contains(index, ' and '.join((w+'*' for w in query.split())))
       
   176                 params &= query_params
       
   177         if data.get('owner'):
       
   178             params &= Eq(catalog['owner'], data['owner'])
       
   179         if data.get('status'):
       
   180             params &= Eq(catalog['workflow_state'], data['status'])
       
   181         if data.get('created_after'):
       
   182             params &= Ge(catalog['created_date'], data['created_after'])
       
   183         if data.get('created_before'):
       
   184             params &= Le(catalog['created_date'], data['created_before'])
       
   185         if data.get('modified_after'):
       
   186             params &= Ge(catalog['modified_date'], data['modified_after'])
       
   187         if data.get('modified_before'):
       
   188             params &= Le(catalog['modified_date'], data['modified_before'])
       
   189         if data.get('status'):
       
   190             return unique(map(lambda x: sorted(IWorkflowVersions(x).get_versions(data['status']),
       
   191                                                key=lambda y: IZopeDublinCore(y).modified)[0],
       
   192                               CatalogResultSet(CatalogQuery(catalog).query(params,
       
   193                                                                            sort_index='modified_date',
       
   194                                                                            reverse=True))))
       
   195         else:
       
   196             return unique(map(lambda x: IWorkflowVersions(x).get_last_versions()[0],
       
   197                               CatalogResultSet(CatalogQuery(catalog).query(params,
       
   198                                                                            sort_index='modified_date',
       
   199                                                                            reverse=True))))
       
   200 
       
   201 
       
   202 @pagelet_config(name='advanced-search.html', context=ISharedTool, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
       
   203 class SharedToolAdvancedSearchView(AdminView, SearchView):
       
   204     """Shared tool advanced search view"""
       
   205 
       
   206     search_form_factory = SharedToolAdvancedSearchForm
       
   207 
       
   208 
       
   209 @adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolAdvancedSearchView), provides=IPageHeader)
       
   210 class SharedToolAdvancedSearchHeaderAdapter(DefaultPageHeaderAdapter):
       
   211     """Shared tool advanced search header adapter"""
       
   212 
       
   213     back_url = '#dashboard.html'
       
   214     back_target = None
       
   215 
       
   216     icon_class = 'fa fa-fw fa-search'
       
   217 
       
   218 
       
   219 @view_config(name='advanced-search-results.html', context=ISharedTool, request_type=IPyAMSLayer,
       
   220              permission=VIEW_SYSTEM_PERMISSION)
       
   221 @implementer(ISharedToolDashboardTable)
       
   222 class SharedToolAdvancedSearchResultsView(AdminView, SearchResultsView):
       
   223     """Shared tool advanced search results view"""
       
   224 
       
   225     title = _("Advanced search results")
       
   226     search_form_factory = SharedToolAdvancedSearchForm
       
   227 
       
   228     sortOn = None
       
   229 
       
   230     def __init__(self, context, request):
       
   231         super(SharedToolAdvancedSearchResultsView, self).__init__(context, request)
       
   232         request.registry.notify(PageletCreatedEvent(self))
       
   233 
       
   234     @property
       
   235     def data_attributes(self):
       
   236         attributes = super(SharedToolAdvancedSearchResultsView, self).data_attributes
       
   237         attributes['table'] = {'data-ams-datatable-sorting': '[]',
       
   238                                'data-ams-datatable-display-length':
       
   239                                    IAdminProfile(self.request.principal).table_page_length}
       
   240         return attributes
       
   241 
       
   242 
       
   243 @adapter_config(context=(ISharedTool, IPyAMSLayer, SharedToolAdvancedSearchResultsView), provides=IValues)
       
   244 class SearchResultsViewValuesAdapter(ContextRequestViewAdapter):
       
   245     """Search results view values adapter"""
       
   246 
       
   247     @property
       
   248     def values(self):
       
   249         form = self.view.search_form_factory(self.context, self.request)
       
   250         return form.get_search_results()