From a5b6568179b9b17b2dd14b43bcccded15bf5025d Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Wed, 4 Nov 2015 11:33:07 +0100 Subject: Rework pagination to fix the 'start' and 'total_size' values --- src/mailman/rest/helpers.py | 59 +++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 34 deletions(-) (limited to 'src/mailman/rest/helpers.py') diff --git a/src/mailman/rest/helpers.py b/src/mailman/rest/helpers.py index 0bba86521..a78f5b379 100644 --- a/src/mailman/rest/helpers.py +++ b/src/mailman/rest/helpers.py @@ -114,31 +114,6 @@ def etag(resource): return json.dumps(resource, cls=ExtendedEncoder) -def paginate(method): - """Method decorator to paginate through collection result lists. - - Use this to return only a slice of a collection, specified in the request - itself. The request should use query parameters `count` and `page` to - specify the slice they want. The slice will start at index - ``(page - 1) * count`` and end (exclusive) at ``(page * count)``. - - Decorated methods must take ``self`` and ``request`` as the first two - arguments. - """ - def wrapper(self, request, *args, **kwargs): - # Allow falcon's HTTPBadRequest exceptions to percolate up. They'll - # get turned into HTTP 400 errors. - count = request.get_param_as_int('count', min=0) - page = request.get_param_as_int('page', min=1) - result = method(self, request, *args, **kwargs) - if count is None and page is None: - return result - list_start = (page - 1) * count - list_end = page * count - return result[list_start:list_end] - return wrapper - - class CollectionMixin: """Mixin class for common collection-ish things.""" @@ -170,22 +145,38 @@ class CollectionMixin: """ raise NotImplementedError + def _paginate(self, request, collection): + """Method to paginate through collection result lists. + + Use this to return only a slice of a collection, specified in the request + itself. The request should use query parameters `count` and `page` to + specify the slice they want. The slice will start at index + ``(page - 1) * count`` and end (exclusive) at ``(page * count)``. + """ + # Allow falcon's HTTPBadRequest exceptions to percolate up. They'll + # get turned into HTTP 400 errors. + count = request.get_param_as_int('count', min=0) + page = request.get_param_as_int('page', min=1) + total_size = len(collection) + if count is None and page is None: + return 0, total_size, collection + list_start = (page - 1) * count + list_end = page * count + return list_start, total_size, collection[list_start:list_end] + def _make_collection(self, request): """Provide the collection to the REST layer.""" - collection = self._get_collection(request) - if len(collection) == 0: - return dict(start=0, total_size=0) - else: + start, total_size, collection = self._paginate( + request, self._get_collection(request)) + result = dict(start=start, total_size=total_size) + if len(collection) != 0: entries = [self._resource_as_dict(resource) for resource in collection] # Tag the resources but use the dictionaries. [etag(resource) for resource in entries] # Create the collection resource - return dict( - start=0, - total_size=len(collection), - entries=entries, - ) + result['entries'] = entries + return result def path_to(self, resource): return path_to(resource, self.api_version) -- cgit v1.2.3-70-g09d2