112 lines
3.4 KiB
Python
112 lines
3.4 KiB
Python
"""Contains the indexer and some helper methods for indexing.
|
|
"""
|
|
|
|
from themis.indexer.behavior import IThemisFieldIndexer
|
|
from five import grok
|
|
from plone.dexterity.utils import iterSchemata
|
|
from plone.indexer import indexer
|
|
from plone.z3cform import z2
|
|
from z3c.form.field import Field
|
|
from z3c.form.interfaces import DISPLAY_MODE, IFieldWidget
|
|
from z3c.form.interfaces import IContextAware, IFormLayer, IField
|
|
from zope import schema
|
|
from zope.component import getAdapters, getMultiAdapter
|
|
from zope.interface import alsoProvides
|
|
|
|
|
|
class FakeView(object):
|
|
"""This fake view is used for enabled z3c forms z2 mode on.
|
|
"""
|
|
|
|
def __init__(self, context, request):
|
|
self.context = context
|
|
self.request = request
|
|
|
|
|
|
@indexer(IThemisFieldIndexer)
|
|
def dynamic_searchable_text_indexer(obj):
|
|
"""Dynamic searchable text indexer.
|
|
"""
|
|
|
|
# We need to make sure that we have z2 mode switched on for z3c form.
|
|
# Since we do not really have any view to do this on, we just use
|
|
# a fake view. For switching z2 mode on, it's only necessary that
|
|
# there is a view.request.
|
|
view = FakeView(obj, obj.REQUEST)
|
|
z2.switch_on(view, request_layer=IFormLayer)
|
|
|
|
indexed = []
|
|
|
|
for fieldname in ('numero_courrier', 'mail_ref_id'):
|
|
try:
|
|
value = getattr(obj, fieldname)
|
|
except AttributeError:
|
|
continue
|
|
|
|
if not value:
|
|
continue
|
|
|
|
# be sure that it is utf-8 encoded
|
|
if isinstance(value, unicode):
|
|
value = value.encode('utf-8')
|
|
|
|
# only accept strings
|
|
assert isinstance(value, str), 'expected converted ' + \
|
|
'value of IDexterityTextIndexFieldConverter to be a str'
|
|
|
|
indexed.append(value)
|
|
|
|
if fieldname in ('numero_courrier', 'mail_ref_id'):
|
|
# also index mail number without the leading 0
|
|
value_no_zero = value.lstrip('0')
|
|
if value_no_zero != value:
|
|
indexed.append(value_no_zero)
|
|
|
|
return ' '.join(indexed)
|
|
|
|
|
|
grok.global_adapter(dynamic_searchable_text_indexer,
|
|
name='SearchableText')
|
|
|
|
|
|
def get_field_widget(obj, field):
|
|
"""Returns the field widget of a field in display mode without
|
|
touching any form.
|
|
The `field` should be a z3c form field, not a zope schema field.
|
|
"""
|
|
|
|
assert IField.providedBy(field), 'field is not a form field'
|
|
|
|
if field.widgetFactory.get(DISPLAY_MODE) is not None:
|
|
factory = field.widgetFactory.get(DISPLAY_MODE)
|
|
widget = factory(field.field, obj.REQUEST)
|
|
else:
|
|
widget = getMultiAdapter(
|
|
(field.field, obj.REQUEST), IFieldWidget)
|
|
widget.name = '' + field.__name__ # prefix not needed
|
|
widget.id = widget.name.replace('.', '-')
|
|
widget.context = obj
|
|
alsoProvides(widget, IContextAware)
|
|
widget.mode = DISPLAY_MODE
|
|
widget.update()
|
|
return widget
|
|
|
|
|
|
def get_searchable_contexts_and_fields(obj):
|
|
"""Returns a generator of tuples, which contains a storage object for
|
|
each schema (adapted `obj`) and a list of fields on this schema which
|
|
are searchable.
|
|
"""
|
|
|
|
for schemata in iterSchemata(obj):
|
|
fields = []
|
|
for name in ('numero_courrier',):
|
|
field = schema.getFields(schemata).get(name)
|
|
if field is None:
|
|
continue
|
|
fields.append(fields)
|
|
|
|
if fields:
|
|
storage = schemata(obj)
|
|
yield storage, fields
|