summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/api-objects.rst1
-rw-r--r--docs/gl_objects/issues.py4
-rw-r--r--docs/gl_objects/issues.rst6
-rw-r--r--docs/gl_objects/mrs.py4
-rw-r--r--docs/gl_objects/mrs.rst6
-rw-r--r--docs/gl_objects/todos.py22
-rw-r--r--docs/gl_objects/todos.rst48
-rw-r--r--gitlab/__init__.py2
-rw-r--r--gitlab/exceptions.py4
-rw-r--r--gitlab/objects.py51
10 files changed, 147 insertions, 1 deletions
diff --git a/docs/api-objects.rst b/docs/api-objects.rst
index 045b83c..31f9da9 100644
--- a/docs/api-objects.rst
+++ b/docs/api-objects.rst
@@ -21,4 +21,5 @@ API objects manipulation
gl_objects/runners
gl_objects/settings
gl_objects/system_hooks
+ gl_objects/todos
gl_objects/users
diff --git a/docs/gl_objects/issues.py b/docs/gl_objects/issues.py
index a378910..ad48dc8 100644
--- a/docs/gl_objects/issues.py
+++ b/docs/gl_objects/issues.py
@@ -73,3 +73,7 @@ issue.unsubscribe()
# project issue move
issue.move(new_project_id)
# end project issue move
+
+# project issue todo
+issue.todo()
+# end project issue todo
diff --git a/docs/gl_objects/issues.rst b/docs/gl_objects/issues.rst
index ac23043..d4cbf00 100644
--- a/docs/gl_objects/issues.rst
+++ b/docs/gl_objects/issues.rst
@@ -98,3 +98,9 @@ Move an issue to another project:
.. literalinclude:: issues.py
:start-after: # project issue move
:end-before: # end project issue move
+
+Make an issue as todo:
+
+.. literalinclude:: issues.py
+ :start-after: # project issue todo
+ :end-before: # end project issue todo
diff --git a/docs/gl_objects/mrs.py b/docs/gl_objects/mrs.py
index 1309923..0ef3b87 100644
--- a/docs/gl_objects/mrs.py
+++ b/docs/gl_objects/mrs.py
@@ -59,3 +59,7 @@ mr.closes_issues()
mr.subscribe()
mr.unsubscribe()
# end subscribe
+
+# todo
+mr.todo()
+# end todo
diff --git a/docs/gl_objects/mrs.rst b/docs/gl_objects/mrs.rst
index 2def079..6c83ab7 100644
--- a/docs/gl_objects/mrs.rst
+++ b/docs/gl_objects/mrs.rst
@@ -83,3 +83,9 @@ Subscribe/unsubscribe a MR:
.. literalinclude:: mrs.py
:start-after: # subscribe
:end-before: # end subscribe
+
+Mark a MR as todo:
+
+.. literalinclude:: mrs.py
+ :start-after: # todo
+ :end-before: # end todo
diff --git a/docs/gl_objects/todos.py b/docs/gl_objects/todos.py
new file mode 100644
index 0000000..74ec211
--- /dev/null
+++ b/docs/gl_objects/todos.py
@@ -0,0 +1,22 @@
+# list
+todos = gl.todos.list()
+# end list
+
+# filter
+todos = gl.todos.list(project_id=1)
+todos = gl.todos.list(state='done', type='Issue')
+# end filter
+
+# get
+todo = gl.todos.get(todo_id)
+# end get
+
+# delete
+gl.todos.delete(todo_id)
+# or
+todo.delete()
+# end delete
+
+# all_delete
+nb_of_closed_todos = gl.todos.delete_all()
+# end all_delete
diff --git a/docs/gl_objects/todos.rst b/docs/gl_objects/todos.rst
new file mode 100644
index 0000000..bd7f1fa
--- /dev/null
+++ b/docs/gl_objects/todos.rst
@@ -0,0 +1,48 @@
+#####
+Todos
+#####
+
+Use :class:`~gitlab.objects.Todo` objects to manipulate todos. The
+:attr:`gitlab.Gitlab.todos` manager object provides helper functions.
+
+Examples
+--------
+
+List active todos:
+
+.. literalinclude:: todos.py
+ :start-after: # list
+ :end-before: # end list
+
+You can filter the list using the following parameters:
+
+* ``action``: can be ``assigned``, ``mentioned``, ``build_failed``, ``marked``,
+ or ``approval_required``
+* ``author_id``
+* ``project_id``
+* ``state``: can be ``pending`` or ``done``
+* ``type``: can be ``Issue`` or ``MergeRequest``
+
+For example:
+
+.. literalinclude:: todos.py
+ :start-after: # filter
+ :end-before: # end filter
+
+Get a single todo:
+
+.. literalinclude:: todos.py
+ :start-after: # get
+ :end-before: # end get
+
+Mark a todo as done:
+
+.. literalinclude:: todos.py
+ :start-after: # delete
+ :end-before: # end delete
+
+Mark all the todos as done:
+
+.. literalinclude:: todos.py
+ :start-after: # all_delete
+ :end-before: # end all_delete
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
index fce2569..d70cea0 100644
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -124,6 +124,7 @@ class Gitlab(object):
team_members (TeamMemberManager): Manager for GitLab teams members
team_projects (TeamProjectManager): Manager for GitLab teams projects
teams (TeamManager): Manager for GitLab teams
+ todos (TodoManager): Manager for user todos
"""
def __init__(self, url, private_token=None, email=None, password=None,
@@ -191,6 +192,7 @@ class Gitlab(object):
self.team_members = TeamMemberManager(self)
self.team_projects = TeamProjectManager(self)
self.teams = TeamManager(self)
+ self.todos = TodoManager(self)
@staticmethod
def from_config(gitlab_id=None, config_files=None):
diff --git a/gitlab/exceptions.py b/gitlab/exceptions.py
index 41dad98..e07f0cc 100644
--- a/gitlab/exceptions.py
+++ b/gitlab/exceptions.py
@@ -111,6 +111,10 @@ class GitlabMROnBuildSuccessError(GitlabOperationError):
pass
+class GitlabTodoError(GitlabOperationError):
+ pass
+
+
def raise_error_from_response(response, error, expected_code=200):
"""Tries to parse gitlab error message from response and raises error.
diff --git a/gitlab/objects.py b/gitlab/objects.py
index 4db6354..0e9c75f 100644
--- a/gitlab/objects.py
+++ b/gitlab/objects.py
@@ -1237,6 +1237,17 @@ class ProjectIssue(GitlabObject):
raise_error_from_response(r, GitlabUpdateError, 201)
self._set_from_dict(r.json())
+ def todo(self, **kwargs):
+ """Create a todo for the issue.
+
+ Raises:
+ GitlabConnectionError: If the server cannot be reached.
+ """
+ url = ('/projects/%(project_id)s/issues/%(issue_id)s/todo' %
+ {'project_id': self.project_id, 'issue_id': self.id})
+ r = self.gitlab._raw_post(url, **kwargs)
+ raise_error_from_response(r, GitlabTodoError, [201, 304])
+
class ProjectIssueManager(BaseManager):
obj_cls = ProjectIssue
@@ -1498,6 +1509,17 @@ class ProjectMergeRequest(GitlabObject):
raise_error_from_response(r, errors)
self._set_from_dict(r.json())
+ def todo(self, **kwargs):
+ """Create a todo for the merge request.
+
+ Raises:
+ GitlabConnectionError: If the server cannot be reached.
+ """
+ url = ('/projects/%(project_id)s/merge_requests/%(mr_id)s/todo' %
+ {'project_id': self.project_id, 'mr_id': self.id})
+ r = self.gitlab._raw_post(url, **kwargs)
+ raise_error_from_response(r, GitlabTodoError, [201, 304])
+
class ProjectMergeRequestManager(BaseManager):
obj_cls = ProjectMergeRequest
@@ -2154,7 +2176,7 @@ class RunnerManager(BaseManager):
Raises:
GitlabConnectionError: If the server cannot be reached.
- GitlabListError; If the resource cannot be found
+ GitlabListError: If the resource cannot be found
"""
url = '/runners/all'
if scope is not None:
@@ -2170,6 +2192,33 @@ class TeamMember(GitlabObject):
shortPrintAttr = 'username'
+class Todo(GitlabObject):
+ _url = '/todos'
+ canGet = 'from_list'
+ canUpdate = False
+ canCreate = False
+ optionalListAttrs = ['action', 'author_id', 'project_id', 'state', 'type']
+
+
+class TodoManager(BaseManager):
+ obj_cls = Todo
+
+ def delete_all(self, **kwargs):
+ """Mark all the todos as done.
+
+ Raises:
+ GitlabConnectionError: If the server cannot be reached.
+ GitlabDeleteError: If the resource cannot be found
+
+ Returns:
+ The number of todos maked done.
+ """
+ url = '/todos'
+ r = self.gitlab._raw_delete(url, **kwargs)
+ raise_error_from_response(r, GitlabDeleteError)
+ return int(r.text)
+
+
class UserProject(GitlabObject):
_url = '/projects/user/%(user_id)s'
_constructorTypes = {'owner': 'User', 'namespace': 'Group'}