support reverse iteration in PaginatedList

This uses the 'last' and 'prev' links in the HTTP headers.
The usage is repo.get_issues().reversed
This commit is contained in:
davidbrai
2013-08-02 18:20:39 +03:00
parent 0a1e1fa488
commit ef4cf44ebd
4 changed files with 81 additions and 4 deletions
+25 -4
View File
@@ -110,6 +110,20 @@ class PaginatedList(PaginatedListBase):
self.__nextParams = firstParams or {}
if self.__requester.per_page != 30:
self.__nextParams["per_page"] = self.__requester.per_page
self._reversed = False
def _getLastPageUrl(self):
headers, data = self.__requester.requestJsonAndCheck("GET", self.__firstUrl, self.__nextParams, None)
links = self.__parseLinkHeader(headers)
lastUrl = links["last"]
return lastUrl
@property
def reversed(self):
self._reversed = True
self.__nextUrl = self._getLastPageUrl()
print "saved next url: %s" % self.__nextUrl
return self
def _couldGrow(self):
return self.__nextUrl is not None
@@ -118,21 +132,28 @@ class PaginatedList(PaginatedListBase):
headers, data = self.__requester.requestJsonAndCheck("GET", self.__nextUrl, self.__nextParams, None)
links = self.__parseLinkHeader(headers)
if len(data) > 0 and "next" in links:
self.__nextUrl = links["next"]
if len(data) > 0:
if self._reversed:
if "prev" in links:
self.__nextUrl = links["prev"]
elif "next" in links:
self.__nextUrl = links["next"]
else:
self.__nextUrl = None
self.__nextParams = None
return [
content = [
self.__contentClass(self.__requester, element, completed=False)
for element in data
]
if self._reversed:
return reversed(content)
return content
def __parseLinkHeader(self, headers):
links = {}
if "link" in headers:
linkHeaders = headers["link"].split(",")
linkHeaders = headers["link"].split(", ")
for linkHeader in linkHeaders:
(url, rel) = linkHeader.split("; ")
url = url[1:-1]
+13
View File
@@ -47,6 +47,19 @@ class PaginatedList(Framework.TestCase):
self.assertEqual(self.list[0].id, 4772349)
self.assertEqual(self.list[24].id, 4286936)
def testReversedIterationWithSinglePage(self):
r = self.list.reversed
self.assertEqual(r[0].id, 4286936)
self.assertEqual(r[1].id, 4317009)
def testReversedIterationWithMultiplePages(self):
r = self.list.reversed
self.assertEqual(r[0].id, 94898)
self.assertEqual(r[1].id, 104702)
self.assertEqual(r[13].id, 166211)
self.assertEqual(r[14].id, 166212)
self.assertEqual(r[15].id, 166214)
def testIntIndexingInThirdPage(self):
self.assertEqual(self.list[50].id, 3911629)
self.assertEqual(self.list[74].id, 3605277)
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long