src/pyams_content/root/zmi/search.py
changeset 1407 85e615286c7a
parent 1395 8184dadefc8b
child 1408 916c81459d6b
equal deleted inserted replaced
1406:a568b9d2f7dd 1407:85e615286c7a
     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 __docformat__ = 'restructuredtext'
       
    14 
       
    15 from hypatia.catalog import CatalogQuery
    13 from hypatia.catalog import CatalogQuery
    16 from hypatia.interfaces import ICatalog
    14 from hypatia.interfaces import ICatalog
    17 from hypatia.query import Any, Contains, Eq, Ge, Le
    15 from hypatia.query import Any, Contains, Eq, Ge, Le
       
    16 from pyramid.decorator import reify
    18 from pyramid.view import view_config
    17 from pyramid.view import view_config
    19 from z3c.form import field
    18 from z3c.form import field
    20 from z3c.table.interfaces import IValues
    19 from z3c.table.interfaces import IValues
    21 from zope.interface import implementer
    20 from zope.interface import implementer
    22 from zope.intid import IIntIds
    21 from zope.intid import IIntIds
    29 from pyams_content.root import ISiteRoot
    28 from pyams_content.root import ISiteRoot
    30 from pyams_content.shared.common import CONTENT_TYPES
    29 from pyams_content.shared.common import CONTENT_TYPES
    31 from pyams_content.shared.common.interfaces import CONTENT_TYPES_VOCABULARY
    30 from pyams_content.shared.common.interfaces import CONTENT_TYPES_VOCABULARY
    32 from pyams_content.shared.common.interfaces.zmi import ISiteRootDashboardTable
    31 from pyams_content.shared.common.interfaces.zmi import ISiteRootDashboardTable
    33 from pyams_content.zmi.interfaces import IAllContentsMenu
    32 from pyams_content.zmi.interfaces import IAllContentsMenu
       
    33 from pyams_form.interfaces.form import ISearchFormFactory, ISearchFormResultsFactory
    34 from pyams_form.search import ISearchFields, SearchForm, SearchResultsView, SearchView
    34 from pyams_form.search import ISearchFields, SearchForm, SearchResultsView, SearchView
    35 from pyams_i18n.interfaces import INegotiator
    35 from pyams_i18n.interfaces import INegotiator
    36 from pyams_pagelet.interfaces import PageletCreatedEvent
    36 from pyams_pagelet.interfaces import PageletCreatedEvent
    37 from pyams_pagelet.pagelet import pagelet_config
    37 from pyams_pagelet.pagelet import pagelet_config
    38 from pyams_security.schema import Principal
    38 from pyams_security.schema import Principal
    54 from pyams_utils.url import absolute_url
    54 from pyams_utils.url import absolute_url
    55 from pyams_viewlet.viewlet import viewlet_config
    55 from pyams_viewlet.viewlet import viewlet_config
    56 from pyams_zmi.layer import IAdminLayer
    56 from pyams_zmi.layer import IAdminLayer
    57 from pyams_zmi.view import AdminView
    57 from pyams_zmi.view import AdminView
    58 
    58 
       
    59 
       
    60 __docformat__ = 'restructuredtext'
       
    61 
    59 from pyams_content import _
    62 from pyams_content import _
    60 
    63 
    61 
    64 
    62 #
    65 #
    63 # Quick search adapters
    66 # Quick search adapters
    95 
    98 
    96     @property
    99     @property
    97     def data_attributes(self):
   100     def data_attributes(self):
    98         attributes = super(SiteRootQuickSearchResults, self).data_attributes
   101         attributes = super(SiteRootQuickSearchResults, self).data_attributes
    99         attributes['table'] = {
   102         attributes['table'] = {
   100             'data-ams-datatable-sorting': '{0},{1}'.format(len(self.columns) - 1, self.dt_sort_order),
   103             'data-ams-datatable-sorting':
   101             'data-ams-datatable-display-length': IAdminProfile(self.request.principal).table_page_length
   104                 '{0},{1}'.format(len(self.columns) - 1, self.dt_sort_order),
       
   105             'data-ams-datatable-display-length':
       
   106                 IAdminProfile(self.request.principal).table_page_length
   102         }
   107         }
   103         return attributes
   108         return attributes
   104 
   109 
   105 
   110 
   106 @adapter_config(context=(ISiteRoot, IPyAMSLayer, SiteRootQuickSearchResults), provides=IValues)
   111 @adapter_config(context=(ISiteRoot, IPyAMSLayer, SiteRootQuickSearchResults), provides=IValues)
   120             else:
   125             else:
   121                 params = Eq(catalog['parents'], intids.register(self.context)) & \
   126                 params = Eq(catalog['parents'], intids.register(self.context)) & \
   122                          Any(catalog['content_type'], CONTENT_TYPES.keys())
   127                          Any(catalog['content_type'], CONTENT_TYPES.keys())
   123                 query_params = Eq(catalog['oid'], sequence.get_full_oid(query))
   128                 query_params = Eq(catalog['oid'], sequence.get_full_oid(query))
   124                 negotiator = get_utility(INegotiator)
   129                 negotiator = get_utility(INegotiator)
   125                 for lang in {self.request.registry.settings.get('pyramid.default_locale_name', 'en'),
   130                 for lang in {self.request.registry.settings.get('pyramid.default_locale_name',
       
   131                                                                 'en'),
   126                              self.request.locale_name,
   132                              self.request.locale_name,
   127                              negotiator.server_language} | negotiator.offered_languages:
   133                              negotiator.server_language} | negotiator.offered_languages:
   128                     index_name = 'title:{0}'.format(lang)
   134                     index_name = 'title:{0}'.format(lang)
   129                     if index_name in catalog:
   135                     if index_name in catalog:
   130                         index = catalog[index_name]
   136                         index = catalog[index_name]
   131                         if index.check_query(query):
   137                         if index.check_query(query):
   132                             query_params |= Contains(index, ' and '.join((w+'*' for w in query.split())))
   138                             query_params |= Contains(index,
       
   139                                                      ' and '.join((w+'*' for w in query.split())))
   133                 params &= query_params
   140                 params &= query_params
   134             return unique(map(get_last_version,
   141             return unique(map(get_last_version,
   135                               CatalogResultSet(CatalogQuery(catalog).query(params,
   142                               CatalogResultSet(CatalogQuery(catalog).query(
   136                                                                            sort_index='modified_date',
   143                                   params, sort_index='modified_date', reverse=True))))
   137                                                                            reverse=True))))
       
   138         else:
   144         else:
   139             return ()
   145             return ()
   140 
   146 
   141 
   147 
   142 #
   148 #
   192     def __init__(self, context, request):
   198     def __init__(self, context, request):
   193         super(SiteRootAdvancedSearchForm, self).__init__(context, request)
   199         super(SiteRootAdvancedSearchForm, self).__init__(context, request)
   194         request.registry.notify(PageletCreatedEvent(self))
   200         request.registry.notify(PageletCreatedEvent(self))
   195         apply_skin(self.request, 'PyAMS admin skin')
   201         apply_skin(self.request, 'PyAMS admin skin')
   196 
   202 
   197     fields = field.Fields(ISiteRootAdvancedSearchFields)
   203     fields_interface = ISiteRootAdvancedSearchFields
   198     fields['tags'].widgetFactory = ThesaurusTermsTreeFieldWidget
   204 
   199     fields['collections'].widgetFactory = ThesaurusTermsTreeFieldWidget
   205     @property
       
   206     def fields(self):
       
   207         fields = field.Fields(self.fields_interface)
       
   208         fields['tags'].widgetFactory = ThesaurusTermsTreeFieldWidget
       
   209         fields['collections'].widgetFactory = ThesaurusTermsTreeFieldWidget
       
   210         return fields
       
   211 
   200     ajax_handler = 'advanced-search-results.html'
   212     ajax_handler = 'advanced-search-results.html'
   201 
   213 
   202     def updateWidgets(self, prefix=None):
   214     def updateWidgets(self, prefix=None):
   203         super(SiteRootAdvancedSearchForm, self).updateWidgets(prefix)
   215         super(SiteRootAdvancedSearchForm, self).updateWidgets(prefix)
   204         if 'tags' in self.widgets:
   216         if 'tags' in self.widgets:
   211             manager = ICollectionsManager(self.request.root)
   223             manager = ICollectionsManager(self.request.root)
   212             widget.thesaurus_name = manager.thesaurus_name
   224             widget.thesaurus_name = manager.thesaurus_name
   213             widget.extract_name = manager.extract_name
   225             widget.extract_name = manager.extract_name
   214 
   226 
   215 
   227 
   216 @adapter_config(context=(ISiteRoot, IPyAMSLayer, SiteRootAdvancedSearchForm), provides=IContentSearch)
   228 @adapter_config(context=(ISiteRoot, IPyAMSLayer, SiteRootAdvancedSearchForm),
       
   229                 provides=IContentSearch)
   217 class SiteRootAdvancedSearchFormSearchAdapter(ContextRequestViewAdapter):
   230 class SiteRootAdvancedSearchFormSearchAdapter(ContextRequestViewAdapter):
   218     """Site root advanced search form search adapter"""
   231     """Site root advanced search form search adapter"""
   219 
   232 
   220     def get_search_results(self, data):
   233     def get_search_results(self, data):
   221         intids = get_utility(IIntIds)
   234         intids = get_utility(IIntIds)
   259             params &= Any(catalog['tags'], tags)
   272             params &= Any(catalog['tags'], tags)
   260         if data.get('collections'):
   273         if data.get('collections'):
   261             tags = [intids.register(term) for term in data['collections']]
   274             tags = [intids.register(term) for term in data['collections']]
   262             params &= Any(catalog['collections'], tags)
   275             params &= Any(catalog['collections'], tags)
   263         return unique(map(get_last_version,
   276         return unique(map(get_last_version,
   264                           CatalogResultSet(CatalogQuery(catalog).query(params,
   277                           CatalogResultSet(CatalogQuery(catalog).query(
   265                                                                        sort_index='modified_date',
   278                               params, sort_index='modified_date', reverse=True))))
   266                                                                        reverse=True))))
       
   267 
   279 
   268 
   280 
   269 @pagelet_config(name='advanced-search.html', context=ISiteRoot, layer=IPyAMSLayer,
   281 @pagelet_config(name='advanced-search.html', context=ISiteRoot, layer=IPyAMSLayer,
   270                 permission=VIEW_SYSTEM_PERMISSION)
   282                 permission=VIEW_SYSTEM_PERMISSION)
   271 class SiteRootAdvancedSearchView(SearchView):
   283 class SiteRootAdvancedSearchView(SearchView):
   272     """Site root advanced search view"""
   284     """Site root advanced search view"""
   273 
   285 
   274     search_form_factory = SiteRootAdvancedSearchForm
   286     search_form_factory = SiteRootAdvancedSearchForm
   275 
   287 
   276 
   288 
   277 @adapter_config(context=(ISiteRoot, IPyAMSLayer, SiteRootAdvancedSearchView), provides=IPageHeader)
   289 @adapter_config(context=(ISiteRoot, IPyAMSLayer, SiteRootAdvancedSearchView),
       
   290                 provides=IPageHeader)
   278 class SiteRootAdvancedSearchHeaderAdapter(DefaultPageHeaderAdapter):
   291 class SiteRootAdvancedSearchHeaderAdapter(DefaultPageHeaderAdapter):
   279     """Site root advanced search header adapter"""
   292     """Site root advanced search header adapter"""
   280 
   293 
   281     back_url = '#dashboard.html'
   294     back_url = '#dashboard.html'
   282     back_target = None
   295     back_target = None
   298 
   311 
   299     def __init__(self, context, request):
   312     def __init__(self, context, request):
   300         super(SiteRootAdvancedSearchResultsView, self).__init__(context, request)
   313         super(SiteRootAdvancedSearchResultsView, self).__init__(context, request)
   301         request.registry.notify(PageletCreatedEvent(self))
   314         request.registry.notify(PageletCreatedEvent(self))
   302 
   315 
       
   316     @reify
       
   317     def search_form(self):
       
   318         form = self.request.registry.queryMultiAdapter((self.context, self.request, self),
       
   319                                                        ISearchFormResultsFactory)
       
   320         if form is None:
       
   321             form = self.request.registry.queryMultiAdapter((self.context, self.request, self),
       
   322                                                            ISearchFormFactory)
       
   323         if form is None:
       
   324             form = self.search_form_factory(self.context, self.request)
       
   325         return form
       
   326 
   303     @property
   327     @property
   304     def data_attributes(self):
   328     def data_attributes(self):
   305         attributes = super(SiteRootAdvancedSearchResultsView, self).data_attributes
   329         attributes = super(SiteRootAdvancedSearchResultsView, self).data_attributes
   306         attributes['table'] = {
   330         attributes['table'] = {
   307             'data-ams-datatable-sorting': "{0},{1}".format(len(self.columns) - 1, self.dt_sort_order),
   331             'data-ams-datatable-sorting':
   308             'data-ams-datatable-display-length': IAdminProfile(self.request.principal).table_page_length
   332                 "{0},{1}".format(len(self.columns) - 1, self.dt_sort_order),
       
   333             'data-ams-datatable-display-length':
       
   334                 IAdminProfile(self.request.principal).table_page_length
   309         }
   335         }
   310         return attributes
   336         return attributes
   311 
   337 
   312 
   338 
   313 @adapter_config(context=(ISiteRoot, IPyAMSLayer, SiteRootAdvancedSearchResultsView), provides=IValues)
   339 @adapter_config(context=(ISiteRoot, IPyAMSLayer, SiteRootAdvancedSearchResultsView),
       
   340                 provides=IValues)
   314 class SearchResultsViewValuesAdapter(ContextRequestViewAdapter):
   341 class SearchResultsViewValuesAdapter(ContextRequestViewAdapter):
   315     """Search results view values adapter"""
   342     """Search results view values adapter"""
   316 
   343 
   317     @property
   344     @property
   318     def values(self):
   345     def values(self):
   319         form = self.view.search_form_factory(self.context, self.request)
   346         return self.view.search_form.get_search_results() or ()
   320         return form.get_search_results() or ()