Skip to content

Commit

Permalink
Re-introduce LazyCatalogResultSerializer with batching logic:
Browse files Browse the repository at this point in the history
The LazyCatalogResultSerializer has been removed in #99 without
a pressing need to do so. Therefore we re-introduce it here and
make it handle the batching logic that was previously left to
the SearchHandler.
  • Loading branch information
lukasgraf committed Jun 6, 2016
1 parent d6e5ed3 commit 70871aa
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 26 deletions.
30 changes: 4 additions & 26 deletions src/plone/restapi/search/handler.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
from plone.restapi.batching import HypermediaBatch
from plone.restapi.interfaces import ISerializeToJson
from plone.restapi.interfaces import ISerializeToJsonSummary
from plone.restapi.interfaces import IZCatalogCompatibleQuery
from Products.CMFCore.utils import getToolByName
from zope.component import getMultiAdapter
Expand Down Expand Up @@ -40,29 +38,9 @@ def search(self, query=None):
query = self._parse_query(query)
self._constrain_query_by_path(query)

catalog = getToolByName(self.context, 'portal_catalog')
brains = catalog(query)

batch = HypermediaBatch(self.context, self.request, brains)

results = {}
results['@id'] = batch.canonical_url
results['items_total'] = batch.items_total
if batch.links:
results['batching'] = batch.links

results['items'] = []
for brain in batch:
result = getMultiAdapter(
(brain, self.request), ISerializeToJsonSummary)()

if metadata_fields:
# Merge additional metadata into the summary we already have
metadata = getMultiAdapter(
(brain, self.request),
ISerializeToJson)(metadata_fields=metadata_fields)
result.update(metadata)

results['items'].append(result)
lazy_resultset = self.catalog.searchResults(query)
results = getMultiAdapter(
(lazy_resultset, self.request),
ISerializeToJson)(metadata_fields=metadata_fields)

return results
39 changes: 39 additions & 0 deletions src/plone/restapi/serializer/catalog.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from plone.restapi.batching import HypermediaBatch
from plone.restapi.interfaces import ISerializeToJson
from plone.restapi.interfaces import ISerializeToJsonSummary
from plone.restapi.serializer.converters import json_compatible
from Products.CMFCore.utils import getToolByName
from Products.ZCatalog.interfaces import ICatalogBrain
from Products.ZCatalog.Lazy import Lazy
from zope.component import adapter
from zope.component import getMultiAdapter
from zope.component.hooks import getSite
Expand Down Expand Up @@ -56,3 +58,40 @@ def __call__(self, metadata_fields=('_all',)):
result[attr] = value

return result


@implementer(ISerializeToJson)
@adapter(Lazy, Interface)
class LazyCatalogResultSerializer(object):
"""Serializes a ZCatalog resultset (one of the subclasses of `Lazy`) to
a Python data structure that can in turn be serialized to JSON.
"""

def __init__(self, lazy_resultset, request):
self.lazy_resultset = lazy_resultset
self.request = request

def __call__(self, metadata_fields=()):
batch = HypermediaBatch(self.request, self.lazy_resultset)

results = {}
results['@id'] = batch.canonical_url
results['items_total'] = batch.items_total
if batch.links:
results['batching'] = batch.links

results['items'] = []
for brain in batch:
result = getMultiAdapter(
(brain, self.request), ISerializeToJsonSummary)()

if metadata_fields:
# Merge additional metadata into the summary we already have
metadata = getMultiAdapter(
(brain, self.request),
ISerializeToJson)(metadata_fields=metadata_fields)
result.update(metadata)

results['items'].append(result)

return results
1 change: 1 addition & 0 deletions src/plone/restapi/serializer/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@
</configure>

<adapter factory=".catalog.BrainSerializer" />
<adapter factory=".catalog.LazyCatalogResultSerializer" />

</configure>
18 changes: 18 additions & 0 deletions src/plone/restapi/tests/test_serializer_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ def setUp(self):
IMutableUUID(self.doc).set('77779ffa110e45afb1ba502f75f77777')
self.doc.reindexObject()

def test_lazy_cat_serialization_empty_resultset(self):
# Force an empty resultset (Products.ZCatalog.Lazy.LazyCat)
lazy_cat = self.catalog(path='doesnt-exist')
results = getMultiAdapter((lazy_cat, self.request), ISerializeToJson)()

self.assertDictEqual(
{'@id': 'http://nohost', 'items': [], 'items_total': 0},
results)

def test_lazy_map_serialization(self):
# Test serialization of a Products.ZCatalog.Lazy.LazyMap
lazy_map = self.catalog()
results = getMultiAdapter((lazy_map, self.request), ISerializeToJson)()

self.assertDictContainsSubset({'@id': 'http://nohost'}, results)
self.assertDictContainsSubset({'items_total': 2}, results)
self.assertEqual(2, len(results['items']))

def test_brain_summary_representation(self):
lazy_map = self.catalog(path='/plone/my-folder/my-document')
brain = lazy_map[0]
Expand Down

0 comments on commit 70871aa

Please sign in to comment.