Skip to content

Commit 131739f

Browse files
author
Gauvain Pocentek
committed
implement the todo API
1 parent 3e026d2 commit 131739f

File tree

10 files changed

+147
-1
lines changed

10 files changed

+147
-1
lines changed

docs/api-objects.rst

+1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ API objects manipulation
2121
gl_objects/runners
2222
gl_objects/settings
2323
gl_objects/system_hooks
24+
gl_objects/todos
2425
gl_objects/users

docs/gl_objects/issues.py

+4
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,7 @@
7373
# project issue move
7474
issue.move(new_project_id)
7575
# end project issue move
76+
77+
# project issue todo
78+
issue.todo()
79+
# end project issue todo

docs/gl_objects/issues.rst

+6
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,9 @@ Move an issue to another project:
9898
.. literalinclude:: issues.py
9999
:start-after: # project issue move
100100
:end-before: # end project issue move
101+
102+
Make an issue as todo:
103+
104+
.. literalinclude:: issues.py
105+
:start-after: # project issue todo
106+
:end-before: # end project issue todo

docs/gl_objects/mrs.py

+4
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@
5959
mr.subscribe()
6060
mr.unsubscribe()
6161
# end subscribe
62+
63+
# todo
64+
mr.todo()
65+
# end todo

docs/gl_objects/mrs.rst

+6
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,9 @@ Subscribe/unsubscribe a MR:
8383
.. literalinclude:: mrs.py
8484
:start-after: # subscribe
8585
:end-before: # end subscribe
86+
87+
Mark a MR as todo:
88+
89+
.. literalinclude:: mrs.py
90+
:start-after: # todo
91+
:end-before: # end todo

docs/gl_objects/todos.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# list
2+
todos = gl.todos.list()
3+
# end list
4+
5+
# filter
6+
todos = gl.todos.list(project_id=1)
7+
todos = gl.todos.list(state='done', type='Issue')
8+
# end filter
9+
10+
# get
11+
todo = gl.todos.get(todo_id)
12+
# end get
13+
14+
# delete
15+
gl.todos.delete(todo_id)
16+
# or
17+
todo.delete()
18+
# end delete
19+
20+
# all_delete
21+
nb_of_closed_todos = gl.todos.delete_all()
22+
# end all_delete

docs/gl_objects/todos.rst

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#####
2+
Todos
3+
#####
4+
5+
Use :class:`~gitlab.objects.Todo` objects to manipulate todos. The
6+
:attr:`gitlab.Gitlab.todos` manager object provides helper functions.
7+
8+
Examples
9+
--------
10+
11+
List active todos:
12+
13+
.. literalinclude:: todos.py
14+
:start-after: # list
15+
:end-before: # end list
16+
17+
You can filter the list using the following parameters:
18+
19+
* ``action``: can be ``assigned``, ``mentioned``, ``build_failed``, ``marked``,
20+
or ``approval_required``
21+
* ``author_id``
22+
* ``project_id``
23+
* ``state``: can be ``pending`` or ``done``
24+
* ``type``: can be ``Issue`` or ``MergeRequest``
25+
26+
For example:
27+
28+
.. literalinclude:: todos.py
29+
:start-after: # filter
30+
:end-before: # end filter
31+
32+
Get a single todo:
33+
34+
.. literalinclude:: todos.py
35+
:start-after: # get
36+
:end-before: # end get
37+
38+
Mark a todo as done:
39+
40+
.. literalinclude:: todos.py
41+
:start-after: # delete
42+
:end-before: # end delete
43+
44+
Mark all the todos as done:
45+
46+
.. literalinclude:: todos.py
47+
:start-after: # all_delete
48+
:end-before: # end all_delete

gitlab/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class Gitlab(object):
124124
team_members (TeamMemberManager): Manager for GitLab teams members
125125
team_projects (TeamProjectManager): Manager for GitLab teams projects
126126
teams (TeamManager): Manager for GitLab teams
127+
todos (TodoManager): Manager for user todos
127128
"""
128129

129130
def __init__(self, url, private_token=None, email=None, password=None,
@@ -191,6 +192,7 @@ def __init__(self, url, private_token=None, email=None, password=None,
191192
self.team_members = TeamMemberManager(self)
192193
self.team_projects = TeamProjectManager(self)
193194
self.teams = TeamManager(self)
195+
self.todos = TodoManager(self)
194196

195197
@staticmethod
196198
def from_config(gitlab_id=None, config_files=None):

gitlab/exceptions.py

+4
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ class GitlabMROnBuildSuccessError(GitlabOperationError):
111111
pass
112112

113113

114+
class GitlabTodoError(GitlabOperationError):
115+
pass
116+
117+
114118
def raise_error_from_response(response, error, expected_code=200):
115119
"""Tries to parse gitlab error message from response and raises error.
116120

gitlab/objects.py

+50-1
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,17 @@ def move(self, to_project_id, **kwargs):
12371237
raise_error_from_response(r, GitlabUpdateError, 201)
12381238
self._set_from_dict(r.json())
12391239

1240+
def todo(self, **kwargs):
1241+
"""Create a todo for the issue.
1242+
1243+
Raises:
1244+
GitlabConnectionError: If the server cannot be reached.
1245+
"""
1246+
url = ('/projects/%(project_id)s/issues/%(issue_id)s/todo' %
1247+
{'project_id': self.project_id, 'issue_id': self.id})
1248+
r = self.gitlab._raw_post(url, **kwargs)
1249+
raise_error_from_response(r, GitlabTodoError, [201, 304])
1250+
12401251

12411252
class ProjectIssueManager(BaseManager):
12421253
obj_cls = ProjectIssue
@@ -1498,6 +1509,17 @@ def merge(self, merge_commit_message=None,
14981509
raise_error_from_response(r, errors)
14991510
self._set_from_dict(r.json())
15001511

1512+
def todo(self, **kwargs):
1513+
"""Create a todo for the merge request.
1514+
1515+
Raises:
1516+
GitlabConnectionError: If the server cannot be reached.
1517+
"""
1518+
url = ('/projects/%(project_id)s/merge_requests/%(mr_id)s/todo' %
1519+
{'project_id': self.project_id, 'mr_id': self.id})
1520+
r = self.gitlab._raw_post(url, **kwargs)
1521+
raise_error_from_response(r, GitlabTodoError, [201, 304])
1522+
15011523

15021524
class ProjectMergeRequestManager(BaseManager):
15031525
obj_cls = ProjectMergeRequest
@@ -2154,7 +2176,7 @@ def all(self, scope=None, **kwargs):
21542176
21552177
Raises:
21562178
GitlabConnectionError: If the server cannot be reached.
2157-
GitlabListError; If the resource cannot be found
2179+
GitlabListError: If the resource cannot be found
21582180
"""
21592181
url = '/runners/all'
21602182
if scope is not None:
@@ -2170,6 +2192,33 @@ class TeamMember(GitlabObject):
21702192
shortPrintAttr = 'username'
21712193

21722194

2195+
class Todo(GitlabObject):
2196+
_url = '/todos'
2197+
canGet = 'from_list'
2198+
canUpdate = False
2199+
canCreate = False
2200+
optionalListAttrs = ['action', 'author_id', 'project_id', 'state', 'type']
2201+
2202+
2203+
class TodoManager(BaseManager):
2204+
obj_cls = Todo
2205+
2206+
def delete_all(self, **kwargs):
2207+
"""Mark all the todos as done.
2208+
2209+
Raises:
2210+
GitlabConnectionError: If the server cannot be reached.
2211+
GitlabDeleteError: If the resource cannot be found
2212+
2213+
Returns:
2214+
The number of todos maked done.
2215+
"""
2216+
url = '/todos'
2217+
r = self.gitlab._raw_delete(url, **kwargs)
2218+
raise_error_from_response(r, GitlabDeleteError)
2219+
return int(r.text)
2220+
2221+
21732222
class UserProject(GitlabObject):
21742223
_url = '/projects/user/%(user_id)s'
21752224
_constructorTypes = {'owner': 'User', 'namespace': 'Group'}

0 commit comments

Comments
 (0)