15
15
# You should have received a copy of the GNU Lesser General Public License
16
16
# along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
18
+ import gitlab
18
19
from gitlab import base
19
20
20
21
@@ -70,7 +71,10 @@ def list(self, **kwargs):
70
71
list(RESTObjectList).
71
72
"""
72
73
73
- obj = self .gitlab .http_list (self .path , ** kwargs )
74
+ # Allow to overwrite the path, handy for custom listings
75
+ path = kwargs .pop ('path' , self .path )
76
+
77
+ obj = self .gitlab .http_list (path , ** kwargs )
74
78
if isinstance (obj , list ):
75
79
return [self ._obj_cls (self , item ) for item in obj ]
76
80
else :
@@ -102,7 +106,7 @@ class RetrieveMixin(ListMixin, GetMixin):
102
106
103
107
104
108
class CreateMixin (object ):
105
- def _check_missing_attrs (self , data ):
109
+ def _check_missing_create_attrs (self , data ):
106
110
required , optional = self .get_create_attrs ()
107
111
missing = []
108
112
for attr in required :
@@ -119,13 +123,10 @@ def get_create_attrs(self):
119
123
tuple: 2 items: list of required arguments and list of optional
120
124
arguments for creation (in that order)
121
125
"""
122
- if hasattr (self , '_create_attrs' ):
123
- return (self ._create_attrs ['required' ],
124
- self ._create_attrs ['optional' ])
125
- return (tuple (), tuple ())
126
+ return getattr (self , '_create_attrs' , (tuple (), tuple ()))
126
127
127
128
def create (self , data , ** kwargs ):
128
- """Created a new object.
129
+ """Creates a new object.
129
130
130
131
Args:
131
132
data (dict): parameters to send to the server to create the
@@ -136,16 +137,17 @@ def create(self, data, **kwargs):
136
137
RESTObject: a new instance of the manage object class build with
137
138
the data sent by the server
138
139
"""
139
- self ._check_missing_attrs (data )
140
+ self ._check_missing_create_attrs (data )
140
141
if hasattr (self , '_sanitize_data' ):
141
142
data = self ._sanitize_data (data , 'create' )
142
- server_data = self .gitlab .http_post (self .path , post_data = data ,
143
- ** kwargs )
143
+ # Handle specific URL for creation
144
+ path = kwargs .get ('path' , self .path )
145
+ server_data = self .gitlab .http_post (path , post_data = data , ** kwargs )
144
146
return self ._obj_cls (self , server_data )
145
147
146
148
147
149
class UpdateMixin (object ):
148
- def _check_missing_attrs (self , data ):
150
+ def _check_missing_update_attrs (self , data ):
149
151
required , optional = self .get_update_attrs ()
150
152
missing = []
151
153
for attr in required :
@@ -162,10 +164,7 @@ def get_update_attrs(self):
162
164
tuple: 2 items: list of required arguments and list of optional
163
165
arguments for update (in that order)
164
166
"""
165
- if hasattr (self , '_update_attrs' ):
166
- return (self ._update_attrs ['required' ],
167
- self ._update_attrs ['optional' ])
168
- return (tuple (), tuple ())
167
+ return getattr (self , '_update_attrs' , (tuple (), tuple ()))
169
168
170
169
def update (self , id = None , new_data = {}, ** kwargs ):
171
170
"""Update an object on the server.
@@ -184,9 +183,11 @@ def update(self, id=None, new_data={}, **kwargs):
184
183
else :
185
184
path = '%s/%s' % (self .path , id )
186
185
187
- self ._check_missing_attrs (new_data )
186
+ self ._check_missing_update_attrs (new_data )
188
187
if hasattr (self , '_sanitize_data' ):
189
188
data = self ._sanitize_data (new_data , 'update' )
189
+ else :
190
+ data = new_data
190
191
server_data = self .gitlab .http_put (path , post_data = data , ** kwargs )
191
192
return server_data
192
193
@@ -205,3 +206,145 @@ def delete(self, id, **kwargs):
205
206
206
207
class CRUDMixin (GetMixin , ListMixin , CreateMixin , UpdateMixin , DeleteMixin ):
207
208
pass
209
+
210
+
211
+ class NoUpdateMixin (GetMixin , ListMixin , CreateMixin , DeleteMixin ):
212
+ pass
213
+
214
+
215
+ class SaveMixin (object ):
216
+ """Mixin for RESTObject's that can be updated."""
217
+ def _get_updated_data (self ):
218
+ updated_data = {}
219
+ required , optional = self .manager .get_update_attrs ()
220
+ for attr in required :
221
+ # Get everything required, no matter if it's been updated
222
+ updated_data [attr ] = getattr (self , attr )
223
+ # Add the updated attributes
224
+ updated_data .update (self ._updated_attrs )
225
+
226
+ return updated_data
227
+
228
+ def save (self , ** kwargs ):
229
+ """Saves the changes made to the object to the server.
230
+
231
+ Args:
232
+ **kwargs: Extra option to send to the server (e.g. sudo)
233
+
234
+ The object is updated to match what the server returns.
235
+ """
236
+ updated_data = self ._get_updated_data ()
237
+
238
+ # call the manager
239
+ obj_id = self .get_id ()
240
+ server_data = self .manager .update (obj_id , updated_data , ** kwargs )
241
+ self ._update_attrs (server_data )
242
+
243
+
244
+ class AccessRequestMixin (object ):
245
+ def approve (self , access_level = gitlab .DEVELOPER_ACCESS , ** kwargs ):
246
+ """Approve an access request.
247
+
248
+ Attrs:
249
+ access_level (int): The access level for the user.
250
+
251
+ Raises:
252
+ GitlabConnectionError: If the server cannot be reached.
253
+ GitlabUpdateError: If the server fails to perform the request.
254
+ """
255
+
256
+ path = '%s/%s/approve' % (self .manager .path , self .id )
257
+ data = {'access_level' : access_level }
258
+ server_data = self .manager .gitlab .http_put (url , post_data = data ,
259
+ ** kwargs )
260
+ self ._update_attrs (server_data )
261
+
262
+
263
+ class SubscribableMixin (object ):
264
+ def subscribe (self , ** kwarg ):
265
+ """Subscribe to the object notifications.
266
+
267
+ raises:
268
+ gitlabconnectionerror: if the server cannot be reached.
269
+ gitlabsubscribeerror: if the subscription cannot be done
270
+ """
271
+ path = '%s/%s/subscribe' % (self .manager .path , self .get_id ())
272
+ server_data = self .manager .gitlab .http_post (path , ** kwargs )
273
+ self ._update_attrs (server_data )
274
+
275
+ def unsubscribe (self , ** kwargs ):
276
+ """Unsubscribe from the object notifications.
277
+
278
+ raises:
279
+ gitlabconnectionerror: if the server cannot be reached.
280
+ gitlabunsubscribeerror: if the unsubscription cannot be done
281
+ """
282
+ path = '%s/%s/unsubscribe' % (self .manager .path , self .get_id ())
283
+ server_data = self .manager .gitlab .http_post (path , ** kwargs )
284
+ self ._update_attrs (server_data )
285
+
286
+
287
+ class TodoMixin (object ):
288
+ def todo (self , ** kwargs ):
289
+ """Create a todo associated to the object.
290
+
291
+ Raises:
292
+ GitlabConnectionError: If the server cannot be reached.
293
+ """
294
+ path = '%s/%s/todo' % (self .manager .path , self .get_id ())
295
+ self .manager .gitlab .http_post (path , ** kwargs )
296
+
297
+
298
+ class TimeTrackingMixin (object ):
299
+ def time_stats (self , ** kwargs ):
300
+ """Get time stats for the object.
301
+
302
+ Raises:
303
+ GitlabConnectionError: If the server cannot be reached.
304
+ """
305
+ path = '%s/%s/time_stats' % (self .manager .path , self .get_id ())
306
+ return self .manager .gitlab .http_get (path , ** kwargs )
307
+
308
+ def time_estimate (self , duration , ** kwargs ):
309
+ """Set an estimated time of work for the object.
310
+
311
+ Args:
312
+ duration (str): duration in human format (e.g. 3h30)
313
+
314
+ Raises:
315
+ GitlabConnectionError: If the server cannot be reached.
316
+ """
317
+ path = '%s/%s/time_estimate' % (self .manager .path , self .get_id ())
318
+ data = {'duration' : duration }
319
+ return self .manager .gitlab .http_post (path , post_data = data , ** kwargs )
320
+
321
+ def reset_time_estimate (self , ** kwargs ):
322
+ """Resets estimated time for the object to 0 seconds.
323
+
324
+ Raises:
325
+ GitlabConnectionError: If the server cannot be reached.
326
+ """
327
+ path = '%s/%s/rest_time_estimate' % (self .manager .path , self .get_id ())
328
+ return self .manager .gitlab .http_post (path , ** kwargs )
329
+
330
+ def add_spent_time (self , duration , ** kwargs ):
331
+ """Add time spent working on the object.
332
+
333
+ Args:
334
+ duration (str): duration in human format (e.g. 3h30)
335
+
336
+ Raises:
337
+ GitlabConnectionError: If the server cannot be reached.
338
+ """
339
+ path = '%s/%s/add_spent_time' % (self .manager .path , self .get_id ())
340
+ data = {'duration' : duration }
341
+ return self .manager .gitlab .http_post (path , post_data = data , ** kwargs )
342
+
343
+ def reset_spent_time (self , ** kwargs ):
344
+ """Resets the time spent working on the object.
345
+
346
+ Raises:
347
+ GitlabConnectionError: If the server cannot be reached.
348
+ """
349
+ path = '%s/%s/reset_spent_time' % (self .manager .path , self .get_id ())
350
+ return self .manager .gitlab .http_post (path , ** kwargs )
0 commit comments