diff options
| author | Barry Warsaw | 2013-03-21 11:39:27 -0700 |
|---|---|---|
| committer | Barry Warsaw | 2013-03-21 11:39:27 -0700 |
| commit | 6ca91614fd0cc1c4a7c1b3baed2c3cbbeda33192 (patch) | |
| tree | 3a393592351daec3aa4ffe7ccab6e688d8386821 /src/mailman/rest/helpers.py | |
| parent | bc4776ba20441810f2ff22d8436f450d4be2b439 (diff) | |
| parent | 4dfa297d7aa68039782ad56262c3465d0a4dc31e (diff) | |
| download | mailman-6ca91614fd0cc1c4a7c1b3baed2c3cbbeda33192.tar.gz mailman-6ca91614fd0cc1c4a7c1b3baed2c3cbbeda33192.tar.zst mailman-6ca91614fd0cc1c4a7c1b3baed2c3cbbeda33192.zip | |
* Support pagination of some large collections (lists, users, members).
Given by Florian Fuchs. (LP: #1156529)
Diffstat (limited to 'src/mailman/rest/helpers.py')
| -rw-r--r-- | src/mailman/rest/helpers.py | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/mailman/rest/helpers.py b/src/mailman/rest/helpers.py index 197e74362..3a548cb10 100644 --- a/src/mailman/rest/helpers.py +++ b/src/mailman/rest/helpers.py @@ -38,6 +38,7 @@ from cStringIO import StringIO from datetime import datetime, timedelta from flufl.enum import Enum from lazr.config import as_boolean +from restish import http from restish.http import Response from restish.resource import MethodDecorator from webob.multidict import MultiDict @@ -101,10 +102,43 @@ def etag(resource): """ assert 'http_etag' not in resource, 'Resource already etagged' etag = hashlib.sha1(repr(resource)).hexdigest() + resource['http_etag'] = '"{0}"'.format(etag) 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): + try: + count = int(request.GET['count']) + page = int(request.GET['page']) + if count < 0 or page < 0: + return http.bad_request([], b'Invalid parameters') + # Wrong parameter types or no GET attribute in request object. + except (AttributeError, ValueError, TypeError): + return http.bad_request([], b'Invalid parameters') + # No count/page params. + except KeyError: + count = page = None + result = method(self, request, *args, **kwargs) + if count is None and page is None: + return result + list_start = int((page - 1) * count) + list_end = int(page * count) + return result[list_start:list_end] + return wrapper + + class CollectionMixin: """Mixin class for common collection-ish things.""" |
