Commits

Sebastian Rahlf committed 075dd14

Paginators will iterate over *items* and no longer result pages. To this end a
new method iterate() was added which will return a iterable containing the items
requested. To avoid confusion, extract_data() is now called paginator_data().

  • Participants
  • Parent commits 39b9ace

Comments (0)

Files changed (3)

amazonproduct/processors/__init__.py

     LIMIT = 10
 
     counter = None
+    items = None
 
     def __init__(self, fun, *args, **kwargs):
         """
         Iterate over all paginated results of ``fun``.
         """
         # return cached first page
-        yield self._first_page
+        for item in self.iterate(self._first_page):
+            yield item
         while self.current < self.pages and self.current < self.limit:
-            yield self.page(self.current + 1)
+            for item in self.iterate(self.page(self.current + 1)):
+                yield item
 
     def __len__(self):
         """
         """
         self.kwargs[self.counter] = index
         root = self.fun(*self.args, **self.kwargs)
-        self.current, self.pages, self.results = self.extract_data(root)
+        self.current, self.pages, self.results = self.paginator_data(root)
         return root
 
-    def extract_data(self, node):
+    def paginator_data(self, node):
         """
         Extracts pagination data from XML node.
         """
         raise NotImplementedError
+
+    def iterate(self, node):
+        """
+        Returns iterable over XML item nodes.
+        """
+        raise NotImplementedError
+

amazonproduct/processors/etree.py

 
     counter = current_page_xpath = total_pages_xpath = total_results_xpath = None
 
-    def extract_data(self, root):
+    def paginator_data(self, root):
         nspace = extract_nspace(root)
         def fetch_value(xpath, default):
             try:
             (self.total_results_xpath, 0)
         ])
 
+    def iterate(self, root):
+        nspace = extract_nspace(root)
+        xpath = self.items.replace('{}', nspace)
+        return root.findall(xpath)
+
 
 class ItemPaginator (XPathPaginator):
 
     current_page_xpath = './/{}Items/{}Request/{}ItemSearchRequest/{}ItemPage'
     total_pages_xpath = './/{}Items/{}TotalPages'
     total_results_xpath = './/{}Items/{}TotalResults'
-
+    items = './/{}Items/{}Item'
 
 class RelatedItemsPaginator (XPathPaginator):
 
     total_results_xpath = (
         './/{}Items/{}TotalResults'
         '|.//{}RelatedItems/{}RelatedItemCount')
+    items = './/{}Items/{}Item'

amazonproduct/processors/objectify.py

     result information from XML.
     """
 
-    def extract_data(self, root):
+    def paginator_data(self, root):
         nspace = root.nsmap.get(None, '')
         def fetch_value(xpath, default):
             try:
                 return root.xpath(xpath, namespaces={'aws' : nspace})[0]
             except AttributeError:
                 # node has no attribute pyval so it better be a number
-                return int(node)
+                return int(root)
             except IndexError:
                 return default
         return map(lambda a: fetch_value(*a), [
             (self.total_results_xpath, 0)
         ])
 
+    def iterate(self, root):
+        nspace = root.nsmap.get(None, '')
+        return root.xpath(self.items, namespaces={'aws' : nspace})
+
 
 class SearchPaginator (XPathPaginator):
 
     current_page_xpath = '//aws:Items/aws:Request/aws:ItemSearchRequest/aws:ItemPage'
     total_pages_xpath = '//aws:Items/aws:TotalPages'
     total_results_xpath = '//aws:Items/aws:TotalResults'
+    items = '//aws:Items/aws:Item'
 
 
 class RelatedItemsPaginator (XPathPaginator):
     current_page_xpath = '//aws:RelatedItemPage'
     total_pages_xpath = '//aws:Items/aws:TotalPages|//aws:RelatedItems/aws:RelatedItemPageCount'
     total_results_xpath = '//aws:Items/aws:TotalResults|//aws:RelatedItems/aws:RelatedItemCount'
+    items = '//aws:Items/aws:Item'