183 lines
6.0 KiB
Python
183 lines
6.0 KiB
Python
from zope.interface import Interface
|
|
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
|
|
|
|
from DateTime import DateTime
|
|
|
|
from document import IDocument
|
|
from dossier import IDossier
|
|
from question import IQuestion
|
|
|
|
def dateIndexer(obj):
|
|
if obj.date is None:
|
|
return None
|
|
return DateTime(obj.date.isoformat())
|
|
|
|
documentDateIndexer = indexer(IDocument)(dateIndexer)
|
|
dossierDateIndexer = indexer(IDossier)(dateIndexer)
|
|
questionDateIndexer = indexer(IQuestion)(dateIndexer)
|
|
|
|
grok.global_adapter(documentDateIndexer, name="dateDoc")
|
|
grok.global_adapter(dossierDateIndexer, name="dateDoc")
|
|
grok.global_adapter(questionDateIndexer, name="dateDoc")
|
|
|
|
|
|
def polgroupsIndexer(obj):
|
|
if not obj.polgroups:
|
|
return None
|
|
return [item.to_object.id for item in obj.polgroups]
|
|
|
|
documentPolgroupsIndexer = indexer(IDocument)(polgroupsIndexer)
|
|
dossierPolgroupsIndexer = indexer(IDossier)(polgroupsIndexer)
|
|
questionPolgroupsIndexer = indexer(IQuestion)(polgroupsIndexer)
|
|
|
|
grok.global_adapter(documentPolgroupsIndexer, name="polgroupsDoc")
|
|
grok.global_adapter(dossierPolgroupsIndexer, name="polgroupsDoc")
|
|
grok.global_adapter(questionPolgroupsIndexer, name="polgroupsDoc")
|
|
|
|
def authorsIndexer(obj):
|
|
if not obj.authors:
|
|
return None
|
|
return [item.to_object.id for item in obj.authors]
|
|
|
|
documentAuthorsIndexer = indexer(IDocument)(authorsIndexer)
|
|
dossierAuthorsIndexer = indexer(IDossier)(authorsIndexer)
|
|
questionAuthorsIndexer = indexer(IQuestion)(authorsIndexer)
|
|
|
|
grok.global_adapter(documentAuthorsIndexer, name="authorsDoc")
|
|
grok.global_adapter(dossierAuthorsIndexer, name="authorsDoc")
|
|
grok.global_adapter(questionAuthorsIndexer, name="authorsDoc")
|
|
|
|
def interveningPolgroupsIndexer(obj):
|
|
return None
|
|
|
|
documentInterveningPolgroupsIndexer = indexer(IDocument)(interveningPolgroupsIndexer)
|
|
dossierInterveningPolgroupsIndexer = indexer(IDossier)(interveningPolgroupsIndexer)
|
|
questionInterveningPolgroupsIndexer = indexer(IQuestion)(interveningPolgroupsIndexer)
|
|
|
|
grok.global_adapter(documentInterveningPolgroupsIndexer, name="interveningPolgroupsDoc")
|
|
grok.global_adapter(dossierInterveningPolgroupsIndexer, name="interveningPolgroupsDoc")
|
|
grok.global_adapter(questionInterveningPolgroupsIndexer, name="interveningPolgroupsDoc")
|
|
|
|
def interveningPersonsIndexer(obj):
|
|
if not obj.histolines:
|
|
return None
|
|
r = []
|
|
for line in obj.histolines:
|
|
if not line.authors:
|
|
continue
|
|
r.extend([item.to_object.id for item in line.authors])
|
|
return r
|
|
|
|
dossierInterveningPersonsIndexer = indexer(IDossier)(interveningPersonsIndexer)
|
|
questionInterveningPersonsIndexer = indexer(IQuestion)(interveningPersonsIndexer)
|
|
|
|
grok.global_adapter(dossierInterveningPersonsIndexer, name="interveningPersonsDoc")
|
|
grok.global_adapter(questionInterveningPersonsIndexer, name="interveningPersonsDoc")
|
|
|
|
|
|
class IAuthorsIndexer(Interface):
|
|
"""Dexterity behavior interface for enabling the dynamic SearchableText
|
|
indexer on Authors fields."""
|
|
|
|
|
|
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(IAuthorsIndexer)
|
|
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 ('title', 'authors',):
|
|
try:
|
|
value = getattr(obj, fieldname)
|
|
except AttributeError:
|
|
continue
|
|
|
|
if not value:
|
|
continue
|
|
|
|
if type(value) is list:
|
|
for item in value:
|
|
item_value = item.to_object.title
|
|
# be sure that it is utf-8 encoded
|
|
if isinstance(item_value, unicode):
|
|
item_value = item_value.encode('utf-8')
|
|
indexed.append(item_value)
|
|
else:
|
|
if isinstance(value, unicode):
|
|
value = value.encode('utf-8')
|
|
indexed.append(value)
|
|
|
|
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 ('title', 'authors',):
|
|
field = schema.getFields(schemata).get(name)
|
|
if field is None:
|
|
continue
|
|
fields.append(field)
|
|
|
|
if fields:
|
|
storage = schemata(obj)
|
|
yield storage, fields
|