Skip to content

Commit 653843d

Browse files
author
Gauvain Pocentek
committed
Rework the API
objects can be created using the usual syntax, with one optioanl argument (int to get one object, dict to create an object, nothing to get a list of items). A save() method creates/updates the object on the server. A delete() method removes it from the server.
1 parent d1f80da commit 653843d

File tree

1 file changed

+81
-87
lines changed

1 file changed

+81
-87
lines changed

gitlab.py

Lines changed: 81 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ class GitlabCreateError(Exception):
3030
class GitlabUpdateError(Exception):
3131
pass
3232

33+
class GitlabDeleteError(Exception):
34+
pass
35+
3336
class GitlabAuthenticationError(Exception):
3437
pass
3538

@@ -113,26 +116,15 @@ def get(self, objClass, id, **kwargs):
113116
raise GitlabConnectionError('Can\'t connect to GitLab server (%s)'%self.url)
114117

115118
if r.status_code == 200:
116-
cls = objClass
117-
if objClass.returnClass:
118-
cls = objClass.returnClass
119-
120-
obj = cls(self, r.json)
121-
if kwargs:
122-
for k,v in kwargs.items():
123-
obj.__dict__[k] = v
124-
return obj
119+
return r.json
125120
elif r.status_code == 401:
126121
raise GitlabAuthenticationError(r.json['message'])
127122
else:
128123
raise GitlabGetError('%d: %s'%(r.status_code, r.text))
129124

130-
def delete(self, objClass, id, **kwargs):
131-
# FIXME: not working for project members, gitlab bug or not?
132-
url = objClass.url
133-
if kwargs:
134-
url = objClass.url % kwargs
135-
url = '%s%s/%d?private_token=%s'%(self.url, url, id, self.private_token)
125+
def delete(self, obj):
126+
url = obj.url % obj.__dict__
127+
url = '%s%s/%d?private_token=%s'%(self.url, url, obj.id, self.private_token)
136128

137129
try:
138130
r = requests.delete(url)
@@ -145,55 +137,50 @@ def delete(self, objClass, id, **kwargs):
145137
raise GitlabAuthenticationError(r.json['message'])
146138
return False
147139

148-
def create(self, objClass, objData, **kwargs):
149-
url = objClass.url
150-
if kwargs:
151-
url = objClass.url % kwargs
140+
def create(self, obj):
141+
url = obj.url % obj.__dict__
152142
url = '%s%s?private_token=%s'%(self.url, url, self.private_token)
153143

154144
try:
155-
r = requests.post(url, objData)
145+
# TODO: avoid too much work on the server side by filtering the __dict__ keys
146+
r = requests.post(url, obj.__dict__)
156147
except:
157148
raise GitlabConnectionError('Can\'t connect to GitLab server (%s)'%self.url)
158149

159150
if r.status_code == 201:
160-
cls = objClass
161-
if objClass.returnClass:
162-
cls = objClass.returnClass
163-
164-
return cls(self, r.json)
151+
return r.json
165152
elif r.status_code == 401:
166153
raise GitlabAuthenticationError(r.json['message'])
167154
else:
168155
raise GitlabCreateError('%d: %s'%(r.status_code, r.text))
169156

170-
def update(self, objClass, id, objData, **kwargs):
171-
url = objClass.url
172-
if kwargs:
173-
url = objClass.url % kwargs
174-
url = '%s%s/%d?private_token=%s'%(self.url, url, id, self.private_token)
157+
def update(self, obj):
158+
url = obj.url % obj.__dict__
159+
url = '%s%s/%d?private_token=%s'%(self.url, url, obj.id, self.private_token)
160+
161+
# build a dict of data that can really be sent to server
162+
d = {}
163+
for k,v in obj.__dict__.items():
164+
if type(v) in (int, str, unicode, bool):
165+
d[k] = v
175166

176167
try:
177-
r = requests.put(url, objData)
168+
r = requests.put(url, d)
178169
except:
179170
raise GitlabConnectionError('Can\'t connect to GitLab server (%s)'%self.url)
180171

181172
if r.status_code == 200:
182-
cls = objClass
183-
if objClass.returnClass:
184-
cls = objClass.returnClass
185-
186-
return cls(self, r.json)
173+
return r.json
187174
elif r.status_code == 401:
188175
raise GitlabAuthenticationError(r.json['message'])
189176
else:
190-
raise GitlabUpdateError('%d: %s'%(r.status_code, r.text))
177+
raise GitlabUpdateError('%d: %s' % (r.status_code, r.text))
191178

192179
def getListOrObject(self, cls, id, **kwargs):
193180
if id == None:
194181
return cls.list(self, **kwargs)
195182
else:
196-
return cls.get(self, id, **kwargs)
183+
return cls(self, id, **kwargs)
197184

198185
def Project(self, id=None):
199186
return self.getListOrObject(Project, id)
@@ -218,26 +205,6 @@ class GitlabObject(object):
218205
canUpdate = True
219206
canDelete = True
220207

221-
@classmethod
222-
def update(cls, gl, id, data, **kwargs):
223-
if not cls.canUpdate:
224-
raise NotImplementedError
225-
226-
if not cls.url:
227-
raise NotImplementedError
228-
229-
return gl.update(cls, id, data, **kwargs)
230-
231-
@classmethod
232-
def create(cls, gl, data, **kwargs):
233-
if not cls.canCreate:
234-
raise NotImplementedError
235-
236-
if not cls.url:
237-
raise NotImplementedError
238-
239-
return gl.create(cls, data, **kwargs)
240-
241208
@classmethod
242209
def list(cls, gl, **kwargs):
243210
if not cls.canGetList:
@@ -248,41 +215,25 @@ def list(cls, gl, **kwargs):
248215

249216
return gl.list(cls, **kwargs)
250217

251-
@classmethod
252-
def get(cls, gl, id, **kwargs):
253-
if not cls.canGet:
254-
raise NotImplementedError
255-
256-
if not cls.url:
257-
raise NotImplementedError
258-
259-
return gl.get(cls, id, **kwargs)
260-
261-
@classmethod
262-
def delete(cls, gl, id, **kwargs):
263-
if not cls.canDelete:
264-
raise NotImplementedError
265-
266-
if not cls.url:
267-
raise NotImplementedError
268-
269-
return gl.delete(cls, id, **kwargs)
270-
271218
def getListOrObject(self, cls, id, **kwargs):
272219
if id == None:
220+
if not cls.canGetList:
221+
raise GitlabGetError
222+
273223
return cls.list(self.gitlab, **kwargs)
274224
else:
275-
return cls.get(self.gitlab, id, **kwargs)
225+
if not cls.canGet:
226+
raise GitlabGetError
227+
228+
return cls(self.gitlab, id, **kwargs)
276229

277230
def getObject(self, k, v):
278231
if self.constructorTypes and k in self.constructorTypes:
279232
return globals()[self.constructorTypes[k]](self.gitlab, v)
280233
else:
281234
return v
282235

283-
def __init__(self, gl, data):
284-
self.gitlab = gl
285-
236+
def setFromDict(self, data):
286237
for k, v in data.items():
287238
if isinstance (v, list):
288239
self.__dict__[k] = []
@@ -293,6 +244,47 @@ def __init__(self, gl, data):
293244
else: # None object
294245
self.__dict__[k] = None
295246

247+
def _create(self):
248+
if not self.canCreate:
249+
raise NotImplementedError
250+
251+
json = self.gitlab.create(self)
252+
self.setFromDict(json)
253+
254+
def _update(self):
255+
if not self.canUpdate:
256+
raise NotImplementedError
257+
258+
json = self.gitlab.update(self)
259+
self.setFromDict(json)
260+
261+
def save(self):
262+
if hasattr(self, 'id'):
263+
self._update()
264+
else:
265+
self._create()
266+
267+
def delete(self):
268+
if not self.canDelete:
269+
raise NotImplementedError
270+
271+
if not hasattr(self, 'id'):
272+
raise GitlabDeleteError
273+
274+
return self.gitlab.delete(self)
275+
276+
def __init__(self, gl, data, **kwargs):
277+
self.gitlab = gl
278+
279+
if isinstance(data, int):
280+
data = self.gitlab.get(self.__class__, data, **kwargs)
281+
282+
self.setFromDict(data)
283+
284+
if kwargs:
285+
for k,v in kwargs.items():
286+
self.__dict__[k] = v
287+
296288
def __str__(self):
297289
return '%s => %s'%(type(self), str(self.__dict__))
298290

@@ -315,7 +307,7 @@ def Key(self, id=None):
315307
if id == None:
316308
return CurrentUserKey.list(self.gitlab)
317309
else:
318-
return CurrentUserKey.get(self.gitlab, id)
310+
return CurrentUserKey(self.gitlab, id)
319311

320312
class Group(GitlabObject):
321313
url = '/groups'
@@ -460,12 +452,14 @@ def Tag(self, id=None):
460452
gl = Gitlab('http://192.168.123.107:8080', 'JVNSESs8EwWRx5yDxM5q')
461453

462454
# get a list of projects
463-
for p in Project.list(gl):
455+
for p in gl.Project():
464456
print p.name
465457
# get associated issues
466-
issues = ProjectIssue.list(gl, project_id=p.id)
458+
issues = p.Issue()
467459
for issue in issues:
468-
print " %d => %s (closed: %d)"%(issue.id, issue.title, issue.closed)
460+
closed = 0 if not issue.closed else 1
461+
print " %d => %s (closed: %d)"%(issue.id, issue.title, closed)
469462
# and close them all
470-
ProjectIssue.update(gl, issue.id, {'closed': 1}, project_id=p.id)
463+
issue.closed = 1
464+
issue.save()
471465

0 commit comments

Comments
 (0)