Skip to content

Commit

Permalink
Re-implement _custom_list in the Gitlab class
Browse files Browse the repository at this point in the history
Rename the method _raw_list. This adds support for the ``all=True``
option to enable automatic recursion and avoid pagination if requested
by the user.

Fixes #93
  • Loading branch information
Gauvain Pocentek committed Feb 18, 2016
1 parent 44d0dc5 commit 453224a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 21 deletions.
3 changes: 2 additions & 1 deletion docs/api-usage.rst
Expand Up @@ -112,11 +112,12 @@ You can use pagination to go throught long lists:
ten_first_groups = gl.groups.list(page=0, per_page=10)
Use the ``all`` parameter to get all the items:
Use the ``all`` parameter to get all the items when using listing methods:

.. code-block:: python
all_groups = gl.groups.list(all=True)
all_owned_projects = gl.projects.owned(all=True)
Sudo
====
Expand Down
25 changes: 25 additions & 0 deletions gitlab/__init__.py
Expand Up @@ -269,6 +269,31 @@ def _raw_get(self, path, content_type=None, **kwargs):
raise GitlabConnectionError(
"Can't connect to GitLab server (%s)" % e)

def _raw_list(self, path, cls, **kwargs):
r = self._raw_get(path, **kwargs)
raise_error_from_response(r, GitlabListError)

cls_kwargs = kwargs.copy()

# Add _from_api manually, because we are not creating objects
# through normal path
cls_kwargs['_from_api'] = True
get_all_results = kwargs.get('all', False)

# Remove parameters from kwargs before passing it to constructor
for key in ['all', 'page', 'per_page', 'sudo']:
if key in cls_kwargs:
del cls_kwargs[key]

results = [cls(self, item, **cls_kwargs) for item in r.json()
if item is not None]
if ('next' in r.links and 'url' in r.links['next']
and get_all_results is True):
args = kwargs.copy()
args['next_url'] = r.links['next']['url']
results.extend(self.list(cls, **args))
return results

def _raw_post(self, path, data=None, content_type=None, **kwargs):
url = '%s%s' % (self._url, path)
headers = self._create_headers(content_type)
Expand Down
37 changes: 17 additions & 20 deletions gitlab/objects.py
Expand Up @@ -155,18 +155,6 @@ def delete(self, id, **kwargs):
raise NotImplementedError
self.gitlab.delete(self.obj_cls, id, **args)

def _custom_list(self, url, cls, **kwargs):
r = self.gitlab._raw_get(url, **kwargs)
raise_error_from_response(r, GitlabListError)

l = []
for j in r.json():
o = cls(self.gitlab, j)
o._from_api = True
l.append(o)

return l


class GitlabObject(object):
"""Base class for all classes that interface with GitLab."""
Expand Down Expand Up @@ -569,6 +557,7 @@ def search(self, query, **kwargs):
Args:
query (str): The query string to send to GitLab for the search.
all (bool): If True, return all the items, without pagination
**kwargs: Additional arguments to send to GitLab.
Returns:
Expand All @@ -579,7 +568,7 @@ def search(self, query, **kwargs):
GitlabListError: If the server fails to perform the request.
"""
url = self.obj_cls._url + '?search=' + query
return self._custom_list(url, self.obj_cls, **kwargs)
return self.gitlab._raw_list(url, self.obj_cls, **kwargs)

def get_by_username(self, username, **kwargs):
"""Get a user by its username.
Expand All @@ -596,7 +585,7 @@ def get_by_username(self, username, **kwargs):
GitlabGetError: If the server fails to perform the request.
"""
url = self.obj_cls._url + '?username=' + username
results = self._custom_list(url, self.obj_cls, **kwargs)
results = self.gitlab._raw_list(url, self.obj_cls, **kwargs)
assert len(results) in (0, 1)
try:
return results[0]
Expand Down Expand Up @@ -712,10 +701,15 @@ class GroupManager(BaseManager):
def search(self, query, **kwargs):
"""Searches groups by name.
Returns a list of matching groups.
Args:
query (str): The search string
all (bool): If True, return all the items, without pagination
Returns:
list(Group): a list of matching groups.
"""
url = '/groups?search=' + query
return self._custom_list(url, Group, **kwargs)
return self.gitlab._raw_list(url, self.obj_cls, **kwargs)


class Hook(GitlabObject):
Expand Down Expand Up @@ -1524,35 +1518,38 @@ def search(self, query, **kwargs):
Args:
query (str): The query string to send to GitLab for the search.
all (bool): If True, return all the items, without pagination
**kwargs: Additional arguments to send to GitLab.
Returns:
list(Project): A list of matching projects.
"""
return self._custom_list("/projects/search/" + query, Project,
**kwargs)
return self.gitlab._raw_list("/projects/search/" + query, Project,
**kwargs)

def all(self, **kwargs):
"""List all the projects (need admin rights).
Args:
all (bool): If True, return all the items, without pagination
**kwargs: Additional arguments to send to GitLab.
Returns:
list(Project): The list of projects.
"""
return self._custom_list("/projects/all", Project, **kwargs)
return self.gitlab._raw_list("/projects/all", Project, **kwargs)

def owned(self, **kwargs):
"""List owned projects.
Args:
all (bool): If True, return all the items, without pagination
**kwargs: Additional arguments to send to GitLab.
Returns:
list(Project): The list of owned projects.
"""
return self._custom_list("/projects/owned", Project, **kwargs)
return self.gitlab._raw_list("/projects/owned", Project, **kwargs)


class UserProjectManager(BaseManager):
Expand Down

0 comments on commit 453224a

Please sign in to comment.