Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions api/base/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,26 +114,6 @@ def remove_invalid_fields(self, queryset, fields, view, request):
return valid_fields


class ElasticOSFOrderingFilter(OSFOrderingFilter):
""" This is too enable sorting for ES endpoints that use ES results instead of a typical queryset"""
def filter_queryset(self, request, queryset, view):
sorted_list = queryset.copy()
sort = request.query_params.get('sort')
reverse = False
if sort:
if sort.startswith('-'):
sort = sort.lstrip('-')
reverse = True

try:
source = view.get_serializer_class()._declared_fields[sort].source
sorted_list['results'] = sorted(queryset['results'], key=lambda item: item['_source'][source], reverse=reverse)
except KeyError:
pass

return sorted_list


class FilterMixin:
""" View mixin with helper functions for filtering. """

Expand Down
179 changes: 0 additions & 179 deletions api/base/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@
)
from api.base.serializers import is_anonymized
from api.base.settings import MAX_PAGE_SIZE, MAX_SIZE_OF_ES_QUERY
from api.base.utils import absolute_reverse

from osf.models import AbstractNode, Comment, Preprint, Guid, DraftRegistration
from website.search.elastic_search import DOC_TYPE_TO_MODEL


class JSONAPIPagination(pagination.PageNumberPagination):
Expand Down Expand Up @@ -263,180 +261,3 @@ class DraftRegistrationContributorPagination(NodeContributorPagination):
def get_resource(self, kwargs):
resource_id = kwargs.get('draft_id')
return DraftRegistration.load(resource_id)


class SearchPaginator(DjangoPaginator):

def __init__(self, object_list, per_page):
super().__init__(object_list, per_page)

def search_type_to_model(self, obj_id, obj_type):
model = DOC_TYPE_TO_MODEL[obj_type]
return model.load(obj_id)

def _get_count(self):
self._count = self.object_list['aggs']['total']
return self._count
count = property(_get_count)

def page(self, number):
number = self.validate_number(number)
results = self.object_list['results']
items = [
self.search_type_to_model(result.get('_id'), result.get('_type'))
for result in results
]
return self._get_page(items, number, self)


class SearchModelPaginator(SearchPaginator):

def __init__(self, object_list, per_page, model):
super().__init__(object_list, per_page)
self.model = model

def page(self, number):
number = self.validate_number(number)
results = self.object_list['results']
items = [
self.model.load(result.get('_id'))
for result in results
]
return self._get_page(items, number, self)


class SearchPagination(JSONAPIPagination):

def __init__(self):
super().__init__()
self.paginator = None

def paginate_queryset(self, queryset, request, view=None):
page_size = self.get_page_size(request)
if not page_size:
return None

# Pagination requires an order by clause, especially when using Postgres.
# see: https://docs.djangoproject.com/en/1.10/topics/pagination/#required-arguments
if isinstance(queryset, QuerySet) and not queryset.ordered:
queryset = queryset.order_by(queryset.model._meta.pk.name)

self.paginator = SearchPaginator(queryset, page_size)
model = getattr(request.parser_context['view'], 'model_class', None)
if model:
self.paginator = SearchModelPaginator(queryset, page_size, model)

page_number = request.query_params.get(self.page_query_param, 1)
if page_number in self.last_page_strings:
page_number = self.paginator.num_pages

try:
self.page = self.paginator.page(page_number)
except InvalidPage as exc:
msg = self.invalid_page_message.format(
page_number=page_number, message=str(exc),
)
raise NotFound(msg)

if self.paginator.num_pages > 1 and self.template is not None:
# The browsable API should display pagination controls.
self.display_page_controls = True

self.request = request
return list(self.page)

def get_search_field_url(self, field, query):
view_name = f'search:search-{field}'
return absolute_reverse(
view_name,
query_kwargs={
'q': query,
},
kwargs={
'version': self.request.parser_context['kwargs']['version'],
},
)

def get_search_field_total(self, field):
return self.paginator.object_list['counts'].get(field, 0)

def get_search_field(self, field, query):
return OrderedDict([
(
'related', OrderedDict([
('href', self.get_search_field_url(field, query)),
(
'meta', OrderedDict([
('total', self.get_search_field_total(field)),
]),
),
]),
),
])

def get_response_dict(self, data, url):
if isinstance(self.paginator, SearchModelPaginator):
return super().get_response_dict(data, url)
else:
query = self.request.query_params.get('q', '*')
return OrderedDict([
('data', data),
(
'search_fields', OrderedDict([
('files', self.get_search_field('file', query)),
('projects', self.get_search_field('project', query)),
('components', self.get_search_field('component', query)),
('registrations', self.get_search_field('registration', query)),
('users', self.get_search_field('user', query)),
('institutions', self.get_search_field('institution', query)),
]),
),
(
'meta', OrderedDict([
('total', self.page.paginator.count),
('per_page', self.page.paginator.per_page),
]),
),
(
'links', OrderedDict([
('self', self.get_self_real_link(url)),
('first', self.get_first_real_link(url)),
('last', self.get_last_real_link(url)),
('prev', self.get_previous_real_link(url)),
('next', self.get_next_real_link(url)),
]),
),
])

def get_response_dict_deprecated(self, data, url):
if isinstance(self.paginator, SearchModelPaginator):
return super().get_response_dict_deprecated(data, url)
else:
query = self.request.query_params.get('q', '*')
return OrderedDict([
('data', data),
(
'search_fields', OrderedDict([
('files', self.get_search_field('file', query)),
('projects', self.get_search_field('project', query)),
('components', self.get_search_field('component', query)),
('registrations', self.get_search_field('registration', query)),
('users', self.get_search_field('user', query)),
('institutions', self.get_search_field('institution', query)),
]),
),
(
'links', OrderedDict([
('first', self.get_first_real_link(url)),
('last', self.get_last_real_link(url)),
('prev', self.get_previous_real_link(url)),
('next', self.get_next_real_link(url)),
(
'meta', OrderedDict([
('total', self.page.paginator.count),
('per_page', self.page.paginator.per_page),
]),
),
]),
),
])
50 changes: 0 additions & 50 deletions api/base/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import time
import collections
from jsonschema import validate, ValidationError, Draft7Validator
from django.core.exceptions import ImproperlyConfigured
from rest_framework.parsers import JSONParser
from rest_framework.exceptions import ParseError, NotAuthenticated

Expand Down Expand Up @@ -307,52 +306,3 @@ def parse(self, stream, media_type=None, parser_context=None):
raise JSONAPIException(detail='Signature has expired')

return payload

class SearchParser(JSONAPIParser):

def parse(self, stream, media_type=None, parser_context=None):
try:
view = parser_context['view']
except KeyError:
raise ImproperlyConfigured('SearchParser requires "view" context.')
data = super().parse(stream, media_type=media_type, parser_context=parser_context)
if not data:
raise JSONAPIException(detail='Invalid Payload')

res = {
'query': {
'bool': {},
},
}

sort = parser_context['request'].query_params.get('sort')
if sort:
res['sort'] = [{
sort.lstrip('-'): {
'order': 'desc' if sort.startswith('-') else 'asc',
},
}]

try:
q = data.pop('q')
except KeyError:
pass
else:
res['query']['bool'].update({
'must': {
'query_string': {
'query': q,
'fields': view.search_fields,
},
},
})

if any(data.values()):
res['query']['bool'].update({'filter': []})
for key, val in data.items():
if val is not None:
if isinstance(val, list):
res['query']['bool']['filter'].append({'terms': {key: val}})
else:
res['query']['bool']['filter'].append({'term': {key: val}})
return res
1 change: 0 additions & 1 deletion api/base/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
re_path(r'^requests/', include(('api.requests.urls', 'requests'), namespace='requests')),
re_path(r'^resources/', include('api.resources.urls', namespace='resources')),
re_path(r'^scopes/', include('api.scopes.urls', namespace='scopes')),
re_path(r'^search/', include('api.search.urls', namespace='search')),
re_path(r'^sparse/', include('api.sparse.urls', namespace='sparse')),
re_path(r'^subjects/', include('api.subjects.urls', namespace='subjects')),
re_path(r'^subscriptions/', include('api.subscriptions.urls', namespace='subscriptions')),
Expand Down
Empty file removed api/search/__init__.py
Empty file.
8 changes: 0 additions & 8 deletions api/search/permissions.py

This file was deleted.

58 changes: 0 additions & 58 deletions api/search/serializers.py

This file was deleted.

19 changes: 0 additions & 19 deletions api/search/urls.py

This file was deleted.

Loading
Loading