diff --git a/gitlab b/gitlab index 4c8fb198c..565a0d2b3 100755 --- a/gitlab +++ b/gitlab @@ -316,7 +316,7 @@ try: except: die("Unknown object: %s" % what) -if gitlab.GitlabObject not in getmro(cls): +if gitlab.GitlabObject not in getmro(cls) or cls == gitlab.GitlabObject: die("Unknown object: %s" % what) if action == "help": diff --git a/gitlab.py b/gitlab.py index a64fdcada..01040d641 100644 --- a/gitlab.py +++ b/gitlab.py @@ -28,6 +28,12 @@ __copyright__ = 'Copyright 2013 Gauvain Pocentek' +def stdout_encode(text): + if None != sys.stdout.encoding: + return text.encode(sys.stdout.encoding, "replace") + return text.encode("iso8859-1", 'replace') + + class jsonEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, GitlabObject): @@ -108,9 +114,9 @@ def credentials_auth(self): r = self.rawPost('/session', {'email': self.email, 'password': self.password}) if r.status_code == 201: - self.user = CurrentUser(self, r.json()) + self.user = CurrentUser(self, r.json) else: - raise GitlabAuthenticationError(r.json()['message']) + raise GitlabAuthenticationError(r.json['message']) self.setToken(self.user.private_token) @@ -180,6 +186,17 @@ def rawDelete(self, path): def list(self, obj_class, **kwargs): missing = [] for k in obj_class.requiredListAttrs: + if k not in kwargs: + if k == 'group_id' and 'group' in kwargs: + name = kwargs['group'] + for g in self.list(Group): + if g.__dict__['name'] == name: + kwargs['group_id'] = g.__dict__['id'] + if k == 'project_id' and 'project' in kwargs: + name = kwargs['project'] + for p in self.list(Project): + if p.__dict__['path_with_namespace'] == name: + kwargs['project_id'] = p.__dict__['id'] if k not in kwargs: missing.append(k) if missing: @@ -202,7 +219,7 @@ def list(self, obj_class, **kwargs): cls = obj_class if obj_class._returnClass: cls = obj_class._returnClass - l = [cls(self, item) for item in r.json() if item is not None] + l = [cls(self, item) for item in r.json if item is not None] if kwargs: for k, v in kwargs.items(): if k in ('page', 'per_page'): @@ -211,7 +228,7 @@ def list(self, obj_class, **kwargs): obj.__dict__[k] = str(v) return l elif r.status_code == 401: - raise GitlabAuthenticationError(r.json()['message']) + raise GitlabAuthenticationError(r.json['message']) else: raise GitlabGetError('%d: %s' % (r.status_code, r.text)) @@ -237,9 +254,9 @@ def get(self, obj_class, id=None, **kwargs): "Can't connect to GitLab server (%s)" % self._url) if r.status_code == 200: - return r.json() + return r.json elif r.status_code == 401: - raise GitlabAuthenticationError(r.json()['message']) + raise GitlabAuthenticationError(r.json['message']) elif r.status_code == 404: raise GitlabGetError("Object doesn't exist") else: @@ -260,9 +277,9 @@ def delete(self, obj): if r.status_code == 200: return True elif r.status_code == 401: - raise GitlabAuthenticationError(r.json()['message']) + raise GitlabAuthenticationError(r.json['message']) else: - raise GitlabDeleteError(r.json()['message']) + raise GitlabDeleteError(r.json['message']) return False def create(self, obj): @@ -286,9 +303,9 @@ def create(self, obj): "Can't connect to GitLab server (%s)" % self._url) if r.status_code == 201: - return r.json() + return r.json elif r.status_code == 401: - raise GitlabAuthenticationError(r.json()['message']) + raise GitlabAuthenticationError(r.json['message']) else: raise GitlabCreateError('%d: %s' % (r.status_code, r.text)) @@ -302,7 +319,7 @@ def update(self, obj): if type(v) in (int, str, bool): d[k] = str(v) elif type(v) == unicode: - d[k] = str(v.encode(sys.stdout.encoding, "replace")) + d[k] = str(stdout_encode(v)) try: r = requests.put(url, d, @@ -313,9 +330,9 @@ def update(self, obj): "Can't connect to GitLab server (%s)" % self._url) if r.status_code == 200: - return r.json() + return r.json elif r.status_code == 401: - raise GitlabAuthenticationError(r.json()['message']) + raise GitlabAuthenticationError(r.json['message']) else: raise GitlabUpdateError('%d: %s' % (r.status_code, r.text)) @@ -365,7 +382,7 @@ def _list_projects(self, url, **kwargs): raise GitlabListError l = [] - for o in r.json(): + for o in r.json: l.append(Project(self, o)) return l @@ -574,7 +591,7 @@ def _obj_to_str(obj): s = ", ".join([GitlabObject._obj_to_str(x) for x in obj]) return "[ %s ]" % s elif isinstance(obj, unicode): - return obj.encode(sys.stdout.encoding, "replace") + return stdout_encode(obj) else: return str(obj) @@ -585,19 +602,18 @@ def pretty_print(self, depth=0): if k == self.idAttr: continue v = self.__dict__[k] - pretty_k = k.replace('_', '-').encode(sys.stdout.encoding, - "replace") + pretty_k = stdout_encode(k.replace('_', '-')) if isinstance(v, GitlabObject): if depth == 0: print("%s:" % pretty_k) v.pretty_print(1) else: - print("%s: %s" % (pretty_k, v.id)) + print(u"{}: {}".format(pretty_k, v.id)) else: if isinstance(v, Gitlab): continue - v = GitlabObject._obj_to_str(v) - print("%s%s: %s" % (" " * depth * 2, pretty_k, v)) + v = stdout_encode(GitlabObject._obj_to_str(v)) + print(u"{0}{1}: {2}".format(u" " * depth * 2, pretty_k, v)) def json(self): return json.dumps(self.__dict__, cls=jsonEncoder) @@ -653,6 +669,7 @@ class GroupMember(GitlabObject): canGet = False canUpdate = False requiredCreateAttrs = ['group_id', 'user_id', 'access_level'] + requiredListAttrs = ['group_id'] requiredDeleteAttrs = ['group_id', 'user_id'] shortPrintAttr = 'username' @@ -740,7 +757,7 @@ def diff(self): {'project_id': self.project_id, 'commit_id': self.id} r = self.gitlab.rawGet(url) if r.status_code == 200: - return r.json() + return r.json raise GitlabGetError @@ -761,6 +778,7 @@ class ProjectKey(GitlabObject): requiredListAttrs = ['project_id'] requiredGetAttrs = ['project_id'] requiredCreateAttrs = ['project_id', 'title', 'key'] + shortPrintAttr = 'title' class ProjectEvent(GitlabObject): @@ -936,7 +954,7 @@ class Project(GitlabObject): 'merge_requests_enabled', 'wiki_enabled', 'snippets_enabled', 'public', 'visibility_level', 'namespace_id', 'description'] - shortPrintAttr = 'path' + shortPrintAttr = 'path_with_namespace' def Branch(self, id=None, **kwargs): return self._getListOrObject(ProjectBranch, id, @@ -1008,7 +1026,7 @@ def tree(self, path='', ref_name=''): url += '?path=%s&ref_name=%s' % (path, ref_name) r = self.gitlab.rawGet(url) if r.status_code == 200: - return r.json() + return r.json raise GitlabGetError @@ -1057,7 +1075,7 @@ def delete_file(self, path, branch, message): class TeamMember(GitlabObject): - _url = '/user_teams/%(team_id)s/members' + _url = '/groups/%(team_id)s/members' canUpdate = False requiredCreateAttrs = ['team_id', 'user_id', 'access_level'] requiredDeleteAttrs = ['team_id'] @@ -1067,7 +1085,7 @@ class TeamMember(GitlabObject): class TeamProject(GitlabObject): - _url = '/user_teams/%(team_id)s/projects' + _url = '/groups/%(team_id)s' _constructorTypes = {'owner': 'User', 'namespace': 'Group'} canUpdate = False requiredCreateAttrs = ['team_id', 'project_id', 'greatest_access_level'] @@ -1078,7 +1096,7 @@ class TeamProject(GitlabObject): class Team(GitlabObject): - _url = '/user_teams' + _url = '/groups' shortPrintAttr = 'name' requiredCreateAttrs = ['name', 'path'] canUpdate = False