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.
themis.indexer/themis/indexer/indexer.py

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