This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
collective.dms.thesaurus/src/collective/dms/thesaurus/browser/thesaurusview.py

172 lines
5.3 KiB
Python

import re
from zope.interface import implementer
from zope.interface import implements
from zope.interface import Interface
from zope.component import adapter
from zope import schema
from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
from z3c.form.interfaces import IFormLayer, IFieldWidget, ITextWidget
from z3c.form.widget import FieldWidget
from z3c.form import form, field
from z3c.form.browser import text
from plone.formwidget.autocomplete.widget import AutocompleteSelectionWidget
from plone.formwidget.autocomplete.interfaces import IAutocompleteWidget
from plone.dexterity.browser.view import DefaultView
from plone.i18n.normalizer.fr import normalizer
from Products.Five import BrowserView
from Products.CMFCore.utils import getToolByName
from collective.dms.thesaurus import _
class IAutocompleteSearchWidget(IAutocompleteWidget):
"""Simple autocomplete search input widget
"""
class AutocompleteSearchWidget(AutocompleteSelectionWidget):
"""Search widget with autocompletion.
"""
implements(IAutocompleteSearchWidget)
klass = u'autocomplete-search-widget'
input_template = ViewPageTemplateFile('thesaurus_search_input.pt')
display_template = ViewPageTemplateFile('thesaurus_search_input.pt')
@adapter(IAutocompleteSearchWidget, IFormLayer)
@implementer(IFieldWidget)
def AutocompleteSearchFieldWidget(field, request):
return FieldWidget(field, AutocompleteSearchWidget(request))
class IKeywordSearchWidget(ITextWidget):
pass
class KeywordSearchWidget(text.TextWidget):
implements(IKeywordSearchWidget)
klass = u'keyword-search'
def KeywordSearchFieldWidget(field, request):
return FieldWidget(field, KeywordSearchWidget(request))
class IThesaurusForm(Interface):
keyword_search = schema.TextLine(
title=_(u"Quick Search"),
description=_(u"Search for a keyword in this Thesaurus"),
required=False)
class DmsThesaurusForm(form.Form):
implements(IThesaurusForm)
fields = field.Fields(IThesaurusForm)
fields['keyword_search'].widgetFactory = KeywordSearchFieldWidget
ignoreContext = True
template = ViewPageTemplateFile('thesaurus_form.pt')
class DmsThesaurusView(DefaultView):
def renderForm(self):
form = DmsThesaurusForm(self.context, self.request)
form.update()
return form.render()
class ListKeywordsView(BrowserView):
_items = None
def getItems(self, query=None):
context = self.context
if self._items is not None:
return self._items
titles = list()
self._items = list()
kwargs = {}
if query:
kwargs['SearchableText'] = query
catalog = getToolByName(context, 'portal_catalog')
path = '/'.join(context.getPhysicalPath())
for brain in catalog(portal_type='dmskeyword',
path={'query': path,'depth': 1},
**kwargs):
obj = brain.getObject()
normalized = normalizer.normalize(obj.title).lower()
if normalized in titles:
continue
self._items.append((normalized, obj.title, obj.id))
titles.append(normalized)
for equiv in (obj.equivs or []):
if not equiv:
continue
normalized = normalizer.normalize(equiv).lower()
if normalized in titles:
continue
self._items.append((normalized, equiv, obj.id))
def cmp_keyword(x, y):
return cmp(x[0].lower(), y[0].lower())
self._items.sort(cmp_keyword)
return self._items
def __call__(self):
self.request.response.setHeader('Content-type', 'text/plain')
query_string = unicode(self.request.form.get('q'), 'utf-8')
query_terms = [normalizer.normalize(x) for x in query_string.split()]
absolute_startswith = []
startswith = []
intermediate = []
other = []
q = query_string.lower()
regex = re.compile(r"[\s'()]")
items = self.getItems(query_string)
for normalized, title, id in items:
count_start = 0
count_in = 0
for term in query_terms:
for word in regex.split(normalized):
if word.lower().startswith(term):
count_start += 1
elif term in word.lower():
count_in += 1
item = '%s|%s' % (title, id)
if len(query_terms) == 1 and normalized.startswith(query_terms[0]):
absolute_startswith.append((normalized, item))
elif len(query_terms) > 1 and count_start == len(query_terms):
absolute_startswith.append((normalized, item))
elif count_start >= 1:
startswith.append((normalized, item))
elif count_in:
intermediate.append((normalized, item))
else:
other.append((normalized, item))
absolute_startswith.sort()
startswith.sort()
intermediate.sort()
other.sort()
result = list()
for _list in (absolute_startswith, startswith, intermediate, other):
for item in _list:
result.append(item[1])
if len(result) > 29:
return '\n'.join(result)
return '\n'.join(result)