Skip to content
This repository has been archived by the owner on May 3, 2020. It is now read-only.

Commit

Permalink
global: item revision endpoint
Browse files Browse the repository at this point in the history
* Adds the endpoint configuration for `Item.find_by_holding`.
  • Loading branch information
mvesper committed Dec 21, 2016
1 parent 90e0977 commit adbc09f
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
22 changes: 22 additions & 0 deletions invenio_circulation/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,28 @@
'item_route': '/circulation/items/<pid(crcitm):pid_value>',
'default_media_type': 'application/json',
'max_result_window': 10000,
},
'crcrev': {
'default_endpoint_prefix': True,
'pid_type': 'crcrev',
'pid_minter': 'circulation_item',
'pid_fetcher': 'circulation_item',
'record_class': 'invenio_circulation.api:Item',
'record_serializers': {
'application/json': ('invenio_records_rest.serializers'
':json_v1_response'),
},
'search_class': 'invenio_circulation.search:ItemRevisionSearch',
'search_index': None,
'search_type': None,
'search_serializers': {
'application/json': ('invenio_circulation.serializers'
':revision_serializer'),
},
'list_route': '/circulation/item_revisions/',
'item_route': '/circulation/item_revisions/<pid(crcitm):pid_value>',
'default_media_type': 'application/json',
'max_result_window': 10000,
}
}
"""Basic REST circulation configuration."""
Expand Down
79 changes: 79 additions & 0 deletions invenio_circulation/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
# as an Intergovernmental Organization or submit itself to any jurisdiction.

"""Configuration for circulation search."""
from elasticsearch_dsl.query import Bool, MultiMatch, Range

from invenio_search import RecordsSearch
from invenio_circulation.api import Item


class ItemSearch(RecordsSearch):
Expand All @@ -35,3 +37,80 @@ class Meta:

index = 'circulation-item'
doc_types = None


class ItemRevisionSearch(object):
"""Search class utilizing `Item.find_by_holding`.
Since this function doesn't utilize elasticsearch, ItemRevisionSearch
has to mimick certain aspects of `elasticsearch_dsl.Search`.
"""

class Meta:
"""Configuration for circulation search."""

index = 'circulation-item'
doc_types = None

class Results(object):
"""Substitution of `elasticsearch_dsl.result.Result."""

class Hits(object):
"""Wrapper class for the search hits."""

def __init__(self, results):
"""Constructor to wrap the search results."""
self.hits = self.Hits()
self.hits.total = len(results)
self.results = results

def to_dict(self):
"""Convert results into a dictionary."""
return {
'hits': {
'hits': self.results,
'total': self.hits.total
}
}

def __init__(self):
"""Constructor for `elasticsearch_dsl.result.Result substituion.
Adds dummy `_index` value.
"""
self._index = ['']
self._query = {}

def query(self, *args, **kwargs):
"""Set the desired query."""
q = args[0]
if type(q) is not Bool:
q = Bool(must=[q])
for must in q.must:
if type(must) == MultiMatch:
for field in must.fields:
self._query[field] = must.query
elif type(must) == Range:
for key, value in must._params.items():
self._query[key] = [value['gte'], value['lte']]
return self

def __getitem__(self, *args, **kwargs):
"""Support slicing of the search results. Currently not implemented."""
return self

def params(self, *args, **kwargs):
"""Specify query params to be used. Currently not implemented."""
return self

def execute(self):
"""Execute the search.
:returns: ItemRevisionSearch.Results
"""
res = []
for uuid, revision in Item.find_by_holding(**self._query):
item = Item.get_record(uuid)
res.append(item.revisions[revision-2])

return self.Results(res)
54 changes: 54 additions & 0 deletions invenio_circulation/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2016 CERN.
#
# Invenio is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.

"""Serializers for circulation search."""
import json

from invenio_records_rest.serializers import JSONSerializer
from invenio_records_rest.serializers.response import search_responsify
from invenio_records_rest.serializers.schemas.json import RecordSchemaJSONV1


class RevisionSerializer(JSONSerializer):
"""JSON serializer for items found by `Item.find_by_holding`."""

def serialize_search(self, _, search_result, links=None,
item_links_factory=None):
"""Serialize a search result.
:param search_result: Elasticsearch search result.
:param links: Dictionary of links to add to response.
"""
return json.dumps({
'hits': {
'hits': [hit for hit in search_result['hits']['hits']],
'total': search_result['hits']['total'],
},
'links': links or {},
'aggregations': search_result.get('aggregations', {}),
}, **self._format_args())


revision_serializer = search_responsify(RevisionSerializer(RecordSchemaJSONV1),
'application/json')

0 comments on commit adbc09f

Please sign in to comment.