aboutsummaryrefslogtreecommitdiffstats
path: root/pygithub3
diff options
context:
space:
mode:
authorDavid Medina <davidmedina9@gmail.com>2012-02-04 15:00:13 +0100
committerDavid Medina <davidmedina9@gmail.com>2012-02-04 15:00:13 +0100
commit381e60a506b764849789a19cadffcc9032c2a990 (patch)
tree128d22bb6f728f47619e00f4cc1fe03dd591a5b8 /pygithub3
parentlink_header third party library (diff)
downloadpython-github3-381e60a506b764849789a19cadffcc9032c2a990.tar.xz
python-github3-381e60a506b764849789a19cadffcc9032c2a990.zip
Full support to Result dynamic and lazy iterator
It paginate the requests that needs and does the real requests in the final moment
Diffstat (limited to 'pygithub3')
-rw-r--r--pygithub3/core/result.py171
1 files changed, 171 insertions, 0 deletions
diff --git a/pygithub3/core/result.py b/pygithub3/core/result.py
new file mode 100644
index 0000000..5c1466d
--- /dev/null
+++ b/pygithub3/core/result.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+from urlparse import urlparse, parse_qs
+
+from .third_libs.link_header import parse_link_value
+
+
+class Method(object):
+
+ def __init__(self, method, resource, **method_args):
+ self.method = method
+ self.resource = resource
+ self.args = method_args
+ self.cache = {}
+
+ def cached(func):
+ def wrapper(self, page=1):
+ if self.cache.has_key(str(page)):
+ return self.cache[str(page)]
+ return func(self, page)
+ return wrapper
+
+ def if_needs_lastpage(func):
+ def wrapper(self, response):
+ #import ipdb; ipdb.set_trace()
+ has_link = response.headers.get('link')
+ has_last_page = hasattr(self, 'last_page')
+ if not has_last_page and has_link:
+ return func(self, response)
+ elif not has_last_page and not has_link:
+ self.last_page = 1
+ return wrapper
+
+ @if_needs_lastpage
+ def __set_last_page_from(self, response):
+ #import ipdb; ipdb.set_trace()
+ link_parsed = parse_link_value(response.headers['link'])
+ def get_last(url):
+ url_rels = link_parsed[url]
+ return (url_rels.get('rel') == 'last')
+ url_last = filter(get_last, link_parsed)
+ query = urlparse(url_last.pop()).query
+ self.last_page = int(parse_qs(query).get('page').pop())
+
+ @cached
+ def __call__(self, page=1):
+ all_args = self.args.copy()
+ all_args.update(page=page)
+ response = self.method(self.resource, **all_args)
+ self.__set_last_page_from(response)
+ model = self.resource.get_model()
+ self.cache[str(page)] = model.loads(response.content)
+ return self.cache[str(page)]
+
+ @property
+ def last(self):
+ if not hasattr(self, 'last_page'):
+ self()
+ return self.last_page
+
+class Page(object):
+ """ """
+
+ def __init__(self, getter, page=1):
+ """ """
+ self.getter = getter
+ self.page = page
+
+ def __iter__(self):
+ return self
+
+ def __add__(self, number):
+ return self.page + number
+
+ def __radd__(self, number):
+ return number + self.page
+
+ def __sub__(self, number):
+ return self.page - number
+
+ def __rsub__(self, number):
+ return number - self.page
+
+ def __lt__(self, number):
+ return self.page < number
+
+ def __le__(self, number):
+ return self.page <= number
+
+ def __eq__(self, number):
+ return self.page == number
+
+ def __ne__(self, number):
+ return self.page != number
+
+ def __gt__(self, number):
+ return self.page > number
+
+ def __ge__(self, number):
+ return self.page >= number
+
+ @property
+ def resources(self):
+ return getattr(self, '_count', None) or u"~"
+
+ def get_content(func):
+ def wrapper(self):
+ if not hasattr(self, '_count'):
+ content = self.getter(self.page)
+ self._count = len(content)
+ self.iterable = iter(content)
+ return func(self)
+ return wrapper
+
+ @get_content
+ def __next__(self):
+ try:
+ return self.iterable.next()
+ except StopIteration:
+ self.iterable = iter(self.getter(self.page))
+ raise StopIteration
+
+ def next(self):
+ return self.__next__()
+
+ def __str__(self):
+ return '<{name}{page} resources={resources}>'.format(
+ name=self.__class__.__name__,
+ page=self.page,
+ resources=self.resources)
+
+ def __repr__(self):
+ return "%s[%d]" % (self.__str__(), id(self))
+
+
+class Result(object):
+ """ """
+
+ def __init__(self, client, resource, **kwargs):
+ """ """
+ self.getter = Method(client.get, resource, **kwargs)
+ self.page = Page(self.getter)
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.page <= self.pages:
+ page_to_return = self.page
+ self.page = Page(self.getter, page_to_return + 1)
+ return page_to_return
+ self.page = Page(self.getter)
+ raise StopIteration
+
+ def next(self):
+ return self.__next__()
+
+ @property
+ def pages(self):
+ return self.getter.last
+
+ def get_page(self, page):
+ if page in xrange(1, self.pages + 1):
+ return Page(self.getter, page)
+ return None
+
+ def all(self):
+ for page in self:
+ for resource in page:
+ yield resource